diff --git a/anisoap/representations/ellipsoidal_density_projection.py b/anisoap/representations/ellipsoidal_density_projection.py index 1ed0569..3bc340b 100644 --- a/anisoap/representations/ellipsoidal_density_projection.py +++ b/anisoap/representations/ellipsoidal_density_projection.py @@ -668,7 +668,9 @@ def transform(self, frames, show_progress=False, normalize=True, rust_moments=Tr else: return features - def power_spectrum(self, frames, sum_over_samples=True): + def power_spectrum( + self, frames, mean_over_samples=True, show_progress=False, rust_moments=True + ): """Function to compute the power spectrum of AniSOAP computes the power spectrum of AniSOAP with the inputs of AniSOAP hyperparameters @@ -684,7 +686,7 @@ def power_spectrum(self, frames, sum_over_samples=True): 'c_diameter[1]', 'c_diameter[2]', 'c_diameter[3]', 'c_q', 'positions', and 'numbers'. It only accepts c_q for the angular attribute of each frame. - sum_over_sample: bool + mean_over_samples: bool A function that returns the sum of coefficients of the frames in the sample. Returns @@ -721,7 +723,9 @@ def power_spectrum(self, frames, sum_over_samples=True): if "quaternion" in array: raise ValueError(f"frame should contain c_q rather than quaternion") - mvg_coeffs = self.transform(frames, show_progress=True) + mvg_coeffs = self.transform( + frames, show_progress=show_progress, rust_moments=rust_moments + ) mvg_nu1 = standardize_keys(mvg_coeffs) # Combines the mvg_nu1 with itself using the Clebsch-Gordan coefficients. @@ -734,10 +738,10 @@ def power_spectrum(self, frames, sum_over_samples=True): other_keys_match=["types_center"], ) - # If sum_over_samples = True, it returns simplified form of coefficients with fewer dimensions in the TensorMap for subsequent visualization. + # If mean_over_samples = True, it returns simplified form of coefficients with fewer dimensions in the TensorMap for subsequent visualization. # If not, it returns raw numerical data of coefficients in mvg_nu2 TensorMap - if sum_over_samples: - x_asoap_raw = metatensor.sum_over_samples(mvg_nu2, sample_names="center") + if mean_over_samples: + x_asoap_raw = metatensor.mean_over_samples(mvg_nu2, sample_names="center") x_asoap_raw = x_asoap_raw.block().values.squeeze() return x_asoap_raw else: diff --git a/anisoap/representations/radial_basis.py b/anisoap/representations/radial_basis.py index d2b1b27..aa05284 100644 --- a/anisoap/representations/radial_basis.py +++ b/anisoap/representations/radial_basis.py @@ -77,7 +77,7 @@ def gto_square_norm(n, sigma): def gto_prefactor(n, sigma): """Computes the normalization prefactor of an unnormalized GTO. - This prefactor is simply :math:`\\frac{1}{\\sqrt(\\text{square_norm_area)}}`. + This prefactor is simply :math:`\\frac{1}{\\sqrt{\\text{square_norm_area}}}`. Scaling a GTO by this prefactor will ensure that the GTO has square norm equal to 1. @@ -155,7 +155,7 @@ def monomial_square_norm(n, r_cut): def monomial_prefactor(n, r_cut): """ Computes the normalization prefactor of an unnormalized monomial basis. - This prefactor is simply :math:`1/sqrt{square_norm_area}`. + This prefactor is simply :math:`1/\sqrt{square\_norm\_area}`. Scaling a basis by this prefactor will ensure that the basis has square norm equal to 1. Parameters @@ -183,8 +183,8 @@ def monomial_overlap(n, m, r_cut): .. math:: \langle \phi_n, \phi_m \rangle &= \int_0^\infty dr r^2 r^n r^m \\ - &= \int_0^r_{cut} dr r^2 |r^{(n+m)/2}|^2 \\ - &= \int_0^r_{cut} dr r^2 |r^{n_{eff}}|^2 + &= \int_0^{r_{cut}} dr r^2 |r^{(n+m)/2}|^2 \\ + &= \int_0^{r_{cut}} dr r^2 |r^{n_{eff}}|^2 Parameters ---------- @@ -315,7 +315,7 @@ class MonomialBasis(_RadialBasis): For monomial basis with coupled :math:`n_{\text{max}}` and :math:`l_{\text{max}}`, our radial basis set consists of monomials of order :math:`n=0` to - :math:`n=\text{max}{l_{\text{max}} + 2n_{\text{max}}}` + :math:`n=\max{l_{\text{max}} + 2n_{\text{max}}}` Monomials are not square-integrable from :math:`[0, \infty]`, so we orthonormalize by integrating up to the cutoff radius @@ -362,7 +362,7 @@ def calc_overlap_matrix(self): The overlap matrix is a Gram matrix whose entries are the overlap: .. math:: - S_{ij} = \int_{0}^{r_{cut} dr r^2 phi_i phi_j + S_{ij} = \int_{0}^{r_{cut}} dr r^2 \phi_i \phi_j The overlap has an analytic solution (see above functions). @@ -442,7 +442,7 @@ def get_basis(self, rs): If lmax and nmax defined, then the number of functions outputted is lmax*(nmax+1) - If lmax and nmax coupled, then the number of functions outputted is \sum_{l=0}^{lmax} (number_of_radial_functions_per_l) + If lmax and nmax coupled, then the number of functions outputted is :math:`\sum_{l=0}^{lmax} (number\_of\_radial\_functions\_per\_l)` Parameters ---------- @@ -543,8 +543,7 @@ def calc_overlap_matrix(self): The overlap matrix is a Gram matrix whose entries are the overlap: .. math:: - - S_{ij} = \\int_0^\\infty dr \\, r^2 \\phi_i \\phi_j + S_{ij} = \int_0^\infty dr r^2 \phi_i \phi_j The overlap has an analytic solution (see above functions). diff --git a/anisoap/utils/spherical_to_cartesian.py b/anisoap/utils/spherical_to_cartesian.py index bd437ed..4f9a00f 100644 --- a/anisoap/utils/spherical_to_cartesian.py +++ b/anisoap/utils/spherical_to_cartesian.py @@ -86,8 +86,8 @@ def binom(n, k): def spherical_to_cartesian(lmax, num_ns): """ Finds the coefficients for the cartesian polynomial form of solid harmonics - :math:`R_{lm} = sqrt((4pi)/(2l+1))*r^l*Y_{lm}`. Note that our AniSOAP - expansion does not contain the sqrt((4pi)/(2l+1)), so in calculating + :math:`R_{lm} = \sqrt{(4\pi)/(2l+1)}*r^l*Y_{lm}`. Note that our AniSOAP + expansion does not contain the :math:`\sqrt{(4\pi)/(2l+1)}` prefactor, so in calculating expansion coefficients, we need to divide by that coefficient. Parameters diff --git a/docs/build/doctrees/api.doctree b/docs/build/doctrees/api.doctree new file mode 100644 index 0000000..9e8ec63 Binary files /dev/null and b/docs/build/doctrees/api.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle new file mode 100644 index 0000000..380fa76 Binary files /dev/null and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/getting_started.doctree b/docs/build/doctrees/getting_started.doctree new file mode 100644 index 0000000..0ac8897 Binary files /dev/null and b/docs/build/doctrees/getting_started.doctree differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree new file mode 100644 index 0000000..2e475df Binary files /dev/null and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/installation.doctree b/docs/build/doctrees/installation.doctree new file mode 100644 index 0000000..7abc1a4 Binary files /dev/null and b/docs/build/doctrees/installation.doctree differ diff --git a/docs/build/doctrees/usage.doctree b/docs/build/doctrees/usage.doctree new file mode 100644 index 0000000..68eb1f2 Binary files /dev/null and b/docs/build/doctrees/usage.doctree differ diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo new file mode 100644 index 0000000..6b4deb1 --- /dev/null +++ b/docs/build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 659e0c65a11d76910d18ee3f5a4960ac +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_sources/api.rst.txt b/docs/build/html/_sources/api.rst.txt new file mode 100644 index 0000000..9d37fdc --- /dev/null +++ b/docs/build/html/_sources/api.rst.txt @@ -0,0 +1,41 @@ +API Reference +============= + +Representations +--------------- +.. automodule:: anisoap.representations.ellipsoidal_density_projection + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.representations.radial_basis + :members: + :show-inheritance: + :inherited-members: + +Utilities +--------- +.. automodule:: anisoap.utils.cyclic_list + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.utils.metatensor_utils + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.utils.moment_generator + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.utils.monomial_iterator + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.utils.shortcuts + :members: + :show-inheritance: + :inherited-members: +.. automodule:: anisoap.utils.spherical_to_cartesian + :members: + :show-inheritance: + :inherited-members: + diff --git a/docs/build/html/_sources/getting_started.rst.txt b/docs/build/html/_sources/getting_started.rst.txt new file mode 100644 index 0000000..a5af607 --- /dev/null +++ b/docs/build/html/_sources/getting_started.rst.txt @@ -0,0 +1,31 @@ +=============== +Getting Started +=============== + +Introduction +------------ +AniSOAP is a package for creating machine-learnable representations of systems +of particles in a way that preserves geometrical information. AniSOAP works +similarly to SOAP (Smooth Overlap of Atomic Potentials) in many ways, with the +chief difference being AniSOAP's ability to represent ellipsoidal particles. + +First Steps +----------- +AniSOAP depends on and utilizes the packages `featomic (aka rascaline) +`_, `metatensor `_, +and `ase `_. +It may be helpful to familiarize yourself with these packages before diving into +AniSOAP. + +Key Concepts +------------ +In the AniSOAP representation, particles are treated as multivariate Gaussians (MVGs). +For each particle, we can consider its n-body interactions with nearby particles. +Each local density field is then decomposed in terms of spherical harmonics and +some choice of radial basis functions in order to be compactly represented in +vector form. + +A single AniSOAP vector represents the environment of a single central ellipsoid. +A system of such particles can then be represented, for example, as a matrix of +AniSOAP vectors. + diff --git a/docs/build/html/_sources/index.rst.txt b/docs/build/html/_sources/index.rst.txt new file mode 100644 index 0000000..2a6dd39 --- /dev/null +++ b/docs/build/html/_sources/index.rst.txt @@ -0,0 +1,29 @@ +=================================== +Welcome to AniSOAP's documentation! +=================================== + +**AniSOAP** is a Python library for creating descriptors of chemical systems +suitable for machine learning use. This project aims to extend the popular Smooth Overlap of Atomic Positions (SOAP) +descriptors to coarse-grained systems consisting of aspherical particles +with anisotropic interactions. + +.. note:: + + This project is under active development. + +.. note:: + + AniSOAP documentation is a work in progress; please contact us with questions + not yet addressed here. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + installation + getting_started + auto_examples/index + usage + api + + diff --git a/docs/build/html/_sources/installation.rst.txt b/docs/build/html/_sources/installation.rst.txt new file mode 100644 index 0000000..95f4b5a --- /dev/null +++ b/docs/build/html/_sources/installation.rst.txt @@ -0,0 +1,44 @@ +============ +Installation +============ + +Dependencies +------------ + +Before installing AniSOAP, please make sure you have the following installed (We recommend using an environment manager like `conda `_): + +* `Python: 3.9 or 3.10 `_ +* `numPy: 1.13 or higher `_ +* `sciPy: 1.4.0 or higher `_ +* `Atomic Simulation Environment (ASE): 3.18 or higher `_ +* `Metatensor `_ +* `Featomic (aka Rascaline) `_ +* `Rust -- We reccommend using 'rustup `_ + + +Installing AniSOAP +------------------ + +Navigate to the directory where you would like the AniSOAP package to be located, then copy and paste the +following into your shell:: + + git clone https://github.com/cersonsky-lab/AniSOAP + +Then navigate to the AniSOAP directory with:: + + cd AniSOAP + +Now use pip to install the library:: + + pip install . + + +Testing +------- + +AniSOAP is still under active development, so you may want to run some tests to ensure that your installation is working properly. From the main directory you can run the internal tests with:: + + pytest tests/. + + + diff --git a/docs/build/html/_sources/usage.rst.txt b/docs/build/html/_sources/usage.rst.txt new file mode 100644 index 0000000..e3eebd9 --- /dev/null +++ b/docs/build/html/_sources/usage.rst.txt @@ -0,0 +1,5 @@ +Usage +===== + +AniSOAP interoperates heavily with `ASE `_ and +`Metatensor `_. diff --git a/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css new file mode 100644 index 0000000..7ebbd6d --- /dev/null +++ b/docs/build/html/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/html/_static/css/badge_only.css b/docs/build/html/_static/css/badge_only.css new file mode 100644 index 0000000..88ba55b --- /dev/null +++ b/docs/build/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.eot b/docs/build/html/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.svg b/docs/build/html/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/docs/build/html/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.woff b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-bold-italic.woff b/docs/build/html/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-bold.woff b/docs/build/html/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-bold.woff2 b/docs/build/html/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-normal-italic.woff b/docs/build/html/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-normal.woff b/docs/build/html/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-normal.woff2 b/docs/build/html/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/build/html/_static/css/theme.css b/docs/build/html/_static/css/theme.css new file mode 100644 index 0000000..0f14f10 --- /dev/null +++ b/docs/build/html/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/build/html/_static/custom.css b/docs/build/html/_static/custom.css new file mode 100644 index 0000000..319be8b --- /dev/null +++ b/docs/build/html/_static/custom.css @@ -0,0 +1,3 @@ +.wy-nav-content { + max-width: 90%; +} diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js new file mode 100644 index 0000000..0398ebb --- /dev/null +++ b/docs/build/html/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/docs/build/html/_static/documentation_options.js b/docs/build/html/_static/documentation_options.js new file mode 100644 index 0000000..d1f2291 --- /dev/null +++ b/docs/build/html/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.0.1', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/build/html/_static/file.png b/docs/build/html/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/build/html/_static/file.png differ diff --git a/docs/build/html/_static/jquery.js b/docs/build/html/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/docs/build/html/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/docs/build/html/_static/minus.png b/docs/build/html/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/docs/build/html/_static/minus.png differ diff --git a/docs/build/html/_static/plus.png b/docs/build/html/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/docs/build/html/_static/plus.png differ diff --git a/docs/build/html/_static/pygments.css b/docs/build/html/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/docs/build/html/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/build/html/_static/searchtools.js b/docs/build/html/_static/searchtools.js new file mode 100644 index 0000000..2c774d1 --- /dev/null +++ b/docs/build/html/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/docs/build/html/_static/sphinx_highlight.js b/docs/build/html/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/docs/build/html/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/docs/build/html/api.html b/docs/build/html/api.html new file mode 100644 index 0000000..eb67070 --- /dev/null +++ b/docs/build/html/api.html @@ -0,0 +1,1063 @@ + + + + + + + + + API Reference — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

API Reference

+
+

Representations

+
+
+class anisoap.representations.ellipsoidal_density_projection.EllipsoidalDensityProjection(max_angular, radial_basis_name, cutoff_radius, compute_gradients=False, subtract_center_contribution=False, radial_gaussian_width=None, max_radial=None, rotation_key='quaternion', rotation_type='quaternion', basis_rcond=0, basis_tol=1e-08)
+

Bases: object

+

Class for computing spherical projection coefficients.

+

Compute the spherical projection coefficients for a system of ellipsoids +assuming a multivariate Gaussian density.

+

Initialize the calculator using the hyperparameters.

+
+
Parameters:
+
    +
  • max_angular (int) – Number of angular functions

  • +
  • radial_basis (_RadialBasis) – The radial basis. Currently implemented are +‘gto’, ‘monomial’.

  • +
  • compute_gradients (bool) – Compute gradients

  • +
  • subtract_center_contribution (bool) – Subtract contribution from the central atom.

  • +
  • rotation_key (string) – Key under which rotations are stored in ase frames arrays

  • +
  • rotation_type (string) – Type of rotation object being passed. Currently implemented +are ‘quaternion’ and ‘matrix’

  • +
  • max_radial (None, int, list of int) – Number of radial bases to use. Can either correspond to number of +bases per spherical harmonic or a value to use with every harmonic. +If None, then for every l, (max_angular - l) // 2 + 1 will +be used.

  • +
+
+
+
+
+features
+
+
Type:
+

numpy.ndarray

+
+
+
+ +
+
+feature_gradients
+
+
Type:
+

numpy.ndarray

+
+
+
+ +
+
+power_spectrum(frames, mean_over_samples=True, show_progress=False, rust_moments=True)
+

Function to compute the power spectrum of AniSOAP

+

computes the power spectrum of AniSOAP with the inputs of AniSOAP hyperparameters +and ellipsoidal frames using ellipsoidal density projection. It checks if +each ellipsoidal frame contains all required attributes and processes +Clebsch-Gordan coefficients for the angular component of the AniSOAP descriptors.

+
+
Parameters:
+
    +
  • frames (list) – A list of ellipsoidal frames, where each frame contains attributes: +‘c_diameter[1]’, ‘c_diameter[2]’, ‘c_diameter[3]’, ‘c_q’, ‘positions’, and ‘numbers’. +It only accepts c_q for the angular attribute of each frame.

  • +
  • mean_over_samples (bool) – A function that returns the sum of coefficients of the frames in the sample.

  • +
+
+
Returns:
+

    +
  • x_asoap_raw when kwarg sum_over_samples=True or mvg_nu2 when sum_over_samples=False

  • +
  • x_asoap_raw (A 2-dimensional np.array with shape (n_samples, n_features). This AniSOAP power spectrum aggregates (sums) over each sample.)

  • +
  • mvg_nu2 (a TensorMap of unaggregated power spectrum features.)

  • +
+

+
+
+
+ +
+
+transform(frames, show_progress=False, normalize=True, rust_moments=True)
+

Computes features and gradients for frames

+

Computes the features and (if compute_gradients == True) gradients +for all the provided frames. The features and gradients are stored in +features and feature_gradients attribute.

+
+
Parameters:
+
    +
  • frames (ase.Atoms) – List containing all ase.Atoms types

  • +
  • show_progress (bool) – Show progress bar for frame analysis and feature generation

  • +
  • normalize (bool) – Whether to perform Lowdin Symmetric Orthonormalization or not.

  • +
  • rust_moments (bool) – Use the ported rust code, which should result in increased speed. Default = True. +In the future, once we ensure integrity checks with the original python code, +this kwarg will be deprecated, and the rust version will always be used.

  • +
+
+
Returns:
+

    +
  • None, but stores the projection coefficients and (if desired)

  • +
  • gradients as arrays as features and features_gradients.

  • +
+

+
+
+
+ +
+ +
+
+anisoap.representations.ellipsoidal_density_projection.contract_pairwise_feat(pair_ellip_feat, types, show_progress=False)
+

Function to sum over the pairwise expansion

+
+\[\sum_{j \in a} \langle anlm|\rho_{ij} \rangle + = \langle anlm|\rho_i \rangle\]
+
+
Parameters:
+
    +
  • pair_ellip_feat (metatensor.TensorMap) – TensorMap returned from “pairwise_ellip_expansion()” with keys +(types_1, types_2,l) enumerating the possible species pairs and the +angular channels.

  • +
  • types (list of ints) – List of atomic numbers present across the data frames

  • +
  • show_progress (bool) – Show progress bar for frame analysis and feature generation

  • +
+
+
Returns:
+

A metatensor TensorMap with keys (types, l) “types” takes the value +of the atomic numbers present in the dataset and “l” is the angular +channel. Each block of this tensormap has as samples (“type”, “center”), +yielding the indices of the frames and atoms that correspond to “species” +are present. block.value is a 3D array of the form (num_samples, num_components, properties) +where num_components take on the same values as in the pair_ellip_feat_feat.block. +block.properties now has an additional index for neighbor_species that +corresponds to “a” in \(\langle anlm|rho_i \rangle\)

+
+
Return type:
+

TensorMap

+
+
+
+ +
+
+anisoap.representations.ellipsoidal_density_projection.pairwise_ellip_expansion(lmax, neighbor_list, types, frame_to_global_atom_idx, rotation_matrices, ellipsoid_lengths, sph_to_cart, radial_basis, show_progress=False, rust_moments=True)
+

Computes pairwise expansion

+

Function to compute the pairwise expansion \(\langle anlm|\rho_{ij} \rangle\) +by combining the moments and the spherical to Cartesian transformation.

+
+
Parameters:
+
    +
  • lmax (int) – Maximum angular

  • +
  • neighbor_list (metatensor.TensorMap) – Full neighborlist with keys (types_1, types_2) enumerating the possible +species pairs. Each block contains as samples, the atom indices of +(first_atom, second_atom) that correspond to the key, and block.value is +a 3D array of the form (num_samples, num_components,properties), with +num_components=3 corresponding to the (x,y,z) components of the vector +from first_atom to second_atom. Depending on the cutoff some species +pairs may not appear. Self pairs are not present but in PBC, pairs between +copies of the same atom are accounted for.

  • +
  • types (list of ints) – List of atomic numbers present across the data frames

  • +
  • frame_to_global_atom_idx (list of ints) – The length of the list equals the number of frames, each entry enumerating +the number of atoms in corresponding frame

  • +
  • rotation_matrices (np.array of dimension ((num_atoms,3,3)))

  • +
  • ellipsoid_lengths (np.array of dimension ((num_atoms,3)))

  • +
  • radial_basis (Instance of the RadialBasis Class) – anisoap.representations.radial_basis.RadialBasis that has been instantiated +appropriately with the cutoff radius, radial basis type.

  • +
  • show_progress (bool) – Show progress bar for frame analysis and feature generation

  • +
  • rust_moments (bool) – Use the ported rust code, which should result in increased speed. Default = True. +In the future, once we ensure integrity checks with the original python code, +this kwarg will be deprecated, and the rust version will always be used.

  • +
+
+
Returns:
+

A metatensor TensorMap with keys (types_1, types_2, l) where +(“types_1”, “types_2”) is key in the neighbor_list and “l” is the +angular channel. Each block of this tensormap has the same samples as the +corresponding block of the neighbor_list. block.value is a 3D array of +the form (num_samples, num_components, properties) where num_components +form the 2*l+1 values for the corresponding angular channel and the +properties dimension corresponds to the radial channel.

+
+
Return type:
+

TensorMap

+
+
+
+ +
+
+class anisoap.representations.radial_basis.GTORadialBasis(max_angular, cutoff_radius, *, radial_gaussian_width, max_radial=None, rcond=1e-08, tol=0.001)
+

Bases: _RadialBasis

+

A subclass of _RadialBasis that contains attributes and methods required for the GTO basis.

+

The GTO basis of order n is defined to be \(R(r) = r^n e^{(-r^2/(2\sigma^2))}\).

+

For GTO basis with defined nmax and lmax, our radial basis set consists of GTO of order n=0 to n=lmax + 2nmax.

+

For GTO basis with coupled nmax and lmax, our radial basis set consists of GTO of order n=0 to n=max(lmax + 2nmax)

+
+
+calc_overlap_matrix()
+

Computes the overlap matrix for GTOs.

+

The overlap matrix is a Gram matrix whose entries are the overlap:

+
+\[S_{ij} = \int_0^\infty dr r^2 \phi_i \phi_j\]
+

The overlap has an analytic solution (see above functions).

+

The overlap matrix is the first step to generating an orthonormal basis +set of functions (Lodwin Symmetric Orthonormalization). The actual +orthonormalization matrix cannot be fully precomputed because each tensor +block uses a different set of GTOs. Hence, we precompute the full overlap +matrix of dim l_max, and while orthonormalizing each tensor block, we +generate the respective orthonormal matrices from slices of the full +overlap matrix.

+
+
Returns:
+

The overlap matrix

+
+
Return type:
+

2D array

+
+
+
+ +
+
+get_basis(rs)
+

Evaluate orthonormalized GTO basis functions on mesh rs.

+

If lmax and nmax defined, then the number of functions outputted is lmax*(nmax+1)

+

If lmax and nmax coupled, then the number of functions outputted is +\(\sum_{l=0}^{\text{lmax}} (\text{number_of_radial_functions_per_l})\)

+
+
Parameters:
+

rs (np.array) – a mesh to evaluate the basis functions

+
+
Returns:
+

a matrix containing orthonormalized GTO basis functions evaluated on rs

+
+
Return type:
+

np.array

+
+
+
+ +
+
+get_num_radial_functions()
+

Output the number of radial basis functions considered per value of l. +If max_angular and max_radial are both specified, then the list will contain repeated values of max_radial +Otherwise, the outputted list will specify the number of radial basis functions per l, which may be automatically +calculated if max_radial=None. If a custom list of max_radial is specified when initializing, then it will +return the same inputted list.

+
+
Returns:
+

The attribute self.num_radial_functions, which is a list containing +the number of radial basis functions considered per l.

+
+
Return type:
+

array_like

+
+
+
+ +
+
+orthonormalize_basis(features: TensorMap)
+

Applies in-place orthonormalization on the features.

+

Apply an in-place orthonormalization on the features, using Lodwin Symmetric +Orthonormalization. Each block in the features TensorMap uses a GTO set +of l + 2n, so we must take the appropriate slices of the overlap matrix +to compute the orthonormalization matrix. An instructive example of Lodwin +Symmetric Orthonormalization of a 2-element basis set is found here: +https://booksite.elsevier.com/9780444594365/downloads/16755_10030.pdf

+
+
Parameters:
+
    +
  • features (TensorMap) – contains blocks whose values we wish to orthonormalize. Note that +features is modified in place, so a copy of features must be made +before the function if you wish to retain the unnormalized values.

  • +
  • radial_basis (RadialBasis)

  • +
+
+
Returns:
+

features containing values multiplied by normalization factors.

+
+
Return type:
+

TensorMap

+
+
+
+ +
+
+plot_basis(n_r=100)
+

Plot the normalized basis functions used in calculating the expansion +coefficients

+
+
Parameters:
+

n_r (int) – number of mesh points. Default: 100

+
+
+
+ +
+ +
+
+class anisoap.representations.radial_basis.MonomialBasis(max_angular, cutoff_radius, max_radial=None, rcond=1e-08, tol=0.001)
+

Bases: _RadialBasis

+

A subclass of _RadialBasis that contains attributes and methods required for +the Monomial basis.

+

The monomial basis of order n is defined to be \(R(r) = r^n\).

+

For monomial basis with defined \(n_{\text{max}}\) and \(l_{\text{max}}\), +our radial basis set consists of monomials of order \(n=0\) to +\(n=l_{\text{max}} + 2n_{\text{max}}\).

+

For monomial basis with coupled \(n_{\text{max}}\) and \(l_{\text{max}}\), +our radial basis set consists of monomials of order \(n=0\) to +\(n=\max{l_{\text{max}} + 2n_{\text{max}}}\)

+

Monomials are not square-integrable from \([0, \infty]\), so we orthonormalize +by integrating up to the cutoff radius

+
+
+calc_overlap_matrix()
+

Computes the overlap matrix for Monomnials over a fixed interval.

+

The overlap matrix is a Gram matrix whose entries are the overlap:

+
+
+\[S_{ij} = \int_{0}^{r_{cut}} dr r^2 \phi_i \phi_j\]
+
+

The overlap has an analytic solution (see above functions).

+

The overlap matrix is the first step to generating an orthonormal basis set of functions (Lodwin Symmetric +Orthonormalization). The actual orthonormalization matrix cannot be fully precomputed because each tensor +block use a different set of bases. Hence, we precompute the full overlap matrix of dim l_max, and while +orthonormalizing each tensor block, we generate the respective orthonormal matrices from slices of the full +overlap matrix.

+
+
Returns:
+

The overlap matrix

+
+
Return type:
+

2D array

+
+
+
+ +
+
+get_basis(rs)
+

Evaluate orthonormalized monomial basis functions on mesh rs.

+

If lmax and nmax defined, then the number of functions outputted is lmax*(nmax+1)

+

If lmax and nmax coupled, then the number of functions outputted is \(\sum_{l=0}^{lmax} (number\_of\_radial\_functions\_per\_l)\)

+
+
Parameters:
+

rs (np.array) – a mesh to evaluate the basis functions

+
+
Returns:
+

a matrix containing orthonormalized monomial basis functions evaluated on rs

+
+
Return type:
+

np.array

+
+
+
+ +
+
+get_num_radial_functions()
+

Output the number of radial basis functions considered per value of l. +If max_angular and max_radial are both specified, then the list will contain repeated values of max_radial +Otherwise, the outputted list will specify the number of radial basis functions per l, which may be automatically +calculated if max_radial=None. If a custom list of max_radial is specified when initializing, then it will +return the same inputted list.

+
+
Returns:
+

The attribute self.num_radial_functions, which is a list containing +the number of radial basis functions considered per l.

+
+
Return type:
+

array_like

+
+
+
+ +
+
+orthonormalize_basis(features: TensorMap)
+

Apply an in-place orthonormalization on the features, using Lodwin Symmetric Orthonormalization. +Each block in the features TensorMap uses a basis set of l + 2n, so we must take the appropriate slices of +the overlap matrix to compute the orthonormalization matrix. +An instructive example of Lodwin Symmetric Orthonormalization of a 2-element basis set is found here: +https://booksite.elsevier.com/9780444594365/downloads/16755_10030.pdf

+
+
Parameters:
+
    +
  • features (TensorMap) – A TensorMap whose blocks’ values we wish to orthonormalize. Note that +features is modified in place, so a copy of features must be made +before the function if you wish to retain the unnormalized values.

  • +
  • radial_basis (_RadialBasis)

  • +
+
+
Returns:
+

features containing values multiplied by proper normalization factors.

+
+
Return type:
+

TensorMap

+
+
+
+ +
+
+plot_basis(n_r=100)
+

Plot the normalized basis functions used in calculating the expansion +coefficients

+
+
Parameters:
+

n_r (int) – number of mesh points. Default: 100

+
+
+
+ +
+ +
+
+anisoap.representations.radial_basis.gto_overlap(n, m, sigma_n, sigma_m)
+

Compute overlap of two normalized GTOs

+

Note that the overlap of two GTOs can be modeled as the square norm of one +GTO, with an effective \(n\) and \(\sigma\). All we need to do is to +calculate those effective parameters, then compute the normalization prefactor.

+
+\[\begin{split}\langle \phi_n, \phi_m \rangle &= \int_0^\infty dr \, r^2 r^n e^{-r^2/(2\sigma_n^2)} \, r^m e^{-r^2/(2\sigma_m^2)} \\ + &= \int_0^\infty dr \, r^2 \lvert r^{(n+m)/2} e^{-r^2/4 (1/\sigma_n^2 + 1/\sigma_m^2)}\rvert^2 \\ + &= \int_0^\infty dr \, r^2 r^n_\text{eff} e^{-r^2/(2\sigma_\text{eff}^2)}\end{split}\]
+
+
Parameters:
+
    +
  • n – order of the first GTO

  • +
  • m – order of the second GTO

  • +
  • sigma_n – sigma parameter of the first GTO

  • +
  • sigma_m – sigma parameter of the second GTO

  • +
+
+
Returns:
+

overlap of the two normalized GTOs

+
+
Return type:
+

float

+
+
+
+ +
+
+anisoap.representations.radial_basis.gto_prefactor(n, sigma)
+

Computes the normalization prefactor of an unnormalized GTO.

+

This prefactor is simply \(\frac{1}{\sqrt{\text{square_norm_area}}}\). +Scaling a GTO by this prefactor will ensure that the GTO has square norm +equal to 1.

+
+
Parameters:
+
    +
  • n – order of GTO

  • +
  • sigma – width of GTO

  • +
+
+
Returns:
+

The normalization constant

+
+
Return type:
+

float

+
+
+
+ +
+
+anisoap.representations.radial_basis.gto_square_norm(n, sigma)
+

Compute the square norm of GTOs (inner product of itself over \(R^3\)).

+

An unnormalized GTO of order n is \(\phi_n = r^n e^{-r^2/(2*\sigma^2)}\) +The square norm of the unnormalized GTO has an analytic solution:

+
+\[\begin{split}\braket{\phi_n | \phi_n} &= \int_0^\infty dr \, r^2 \lvert\phi_n\rvert^2 \\ + &= \frac{1}{2} \sigma^{2n+3} \Gamma(n+\frac{3}{2})\end{split}\]
+

This function uses the above expression.

+
+
Parameters:
+
    +
  • n – order of the GTO

  • +
  • sigma – width of the GTO

  • +
+
+
Returns:
+

The square norm of the unnormalized GTO

+
+
Return type:
+

float

+
+
+
+ +
+
+anisoap.representations.radial_basis.inverse_matrix_sqrt(matrix: array, rcond=1e-08, tol=0.001)
+

Returns the inverse matrix square root.

+

The inverse square root of the overlap matrix (or slices of the overlap matrix) +yields the orthonormalization matrix

+
+
Parameters:
+
    +
  • matrix (np.array) – Symmetric square matrix to find the inverse square root of

  • +
  • rcond (float) – Lower bound for eigenvalues for inverse square root

  • +
  • tol (float) – Tolerance for differences between original matrix and reconstruction via +inverse square root

  • +
+
+
Returns:
+

\(S^{-1/2}\)

+
+
Return type:
+

inverse_sqrt_matrix

+
+
+
+ +
+
+anisoap.representations.radial_basis.monomial_overlap(n, m, r_cut)
+

Compute overlap of two normalized monomials

+

Note that the overlap of two monomials can be modeled as the square norm of +one monomial, with an effective n. All we need to do is to calculate those +effective parameters, then compute the normalization:

+
+
+\[\begin{split}\langle \phi_n, \phi_m \rangle &= \int_0^\infty dr r^2 r^n r^m \\ + &= \int_0^{r_{cut}} dr r^2 |r^{(n+m)/2}|^2 \\ + &= \int_0^{r_{cut}} dr r^2 |r^{n_{eff}}|^2\end{split}\]
+
+
+
Parameters:
+
    +
  • n – order of the first monomial

  • +
  • m – order of the second monomial

  • +
  • r_cut (float) – cutoff radius

  • +
+
+
Returns:
+

overlap of the two normalized monomial

+
+
Return type:
+

float

+
+
+
+ +
+
+anisoap.representations.radial_basis.monomial_prefactor(n, r_cut)
+

Computes the normalization prefactor of an unnormalized monomial basis. +This prefactor is simply \(1/\sqrt{square\_norm\_area}\). +Scaling a basis by this prefactor will ensure that the basis has square norm equal to 1.

+
+
Parameters:
+

n – order of the basis

+
+
Returns:
+

normalization constant

+
+
Return type:
+

float

+
+
+
+ +
+
+anisoap.representations.radial_basis.monomial_square_norm(n, r_cut)
+

Compute the square norm of monomials (inner product of itself over R^3).

+
+
Parameters:
+

n – order of the basis

+
+
Returns:
+

The square norm of the unnormalized basis

+
+
Return type:
+

float

+
+
+
+ +
+
+

Utilities

+
+
+class anisoap.utils.cyclic_list.CGRCacheList(size: int)
+

Bases: object

+

This is a simple class that only exists to be used as a “private” cache +for computed ClebschGordanReal matrices (self._cg)

+

It only stores last n CG matrices computed for distinct l_max values. Since +it is specialized to store (l_max, cg matrix) pair, it is NOT supposed to be +used to cache any other things. While type of “value” (in (key, value) pair) +does not matter as much, the type of key MUST BE A 32-BIT INTEGER with +most significant bit unused, as it performs bitwise operations on the most +significant bit to store and check the replacement flags.

+

It will replace the entries using something called “clock algorithm” for page +replacement, which mimics the “least recently used” algorithm but with less +computation requirement.

+

[Link to clock algorithm](https://en.wikipedia.org/wiki/Page_replacement_algorithm#Clock)

+
+
+clear_cache() None
+

Resets the cache (makes list empty)

+
+ +
+
+get_val(key: int) dict
+

Obtains the value for given key. Raises IndexError if the given key +is not found in the list.

+
+ +
+
+insert(key: int, value: dict) None
+

This insert algorithm mimics the “clock algorithm” for page replacement +technique. The algorithm works like this: +1. Get the entry that the “clock hand” (self._ins_index) points to. +2. Keep advancing the “clock hand” until key with replacement flag = 0 +is found. Replacement flag, in this case, is the most significant bit +3. Insert the new [key, value] pair into the list, with replacement flag = 1. +Advance “clock hand” by one position. +Note that clock hand wraps around the list, should it reach the end of the list.

+
+ +
+
+keys() List[int]
+

Return list of keys, with keys

+
+ +
+ +
+
+anisoap.utils.metatensor_utils.cg_combine(x_a, x_b, feature_names=None, clebsch_gordan=None, lcut=None, other_keys_match=None)
+

Performs a CG product of two sets of equivariants.

+

The only requirement is that sparse indices are labeled as +(“inversion_sigma”, “spherical_harmonics_l”, “order_nu”).

+
+
Parameters:
+
    +
  • x_a – First set of equivariants

  • +
  • x_b – Second set of equivariants

  • +
  • feature_names (list, optional) – Overrides automatically-generated names of output features. By default, +all other key labels are combined via their outer product, i.e. if there +is a key-side neighbor-species in both x_a and x_b, the returned +keys will have two neighbor_species labels, corresponding to the parent +features.

  • +
  • clebsch_gordan (ClebschGordanReal, optional)

  • +
  • lcut (np.ndarray()) – Cutoff in new features

  • +
  • other_keys_match (list, optional) – List of keys that should match. These will not need to have their outer +product taken, but will instead be merged into a new key. For instance, +passing [“types center”] will combine the keys with the same type +center, yielding a single key with the same types_center in the results.

  • +
+
+
Returns:
+

The Clebsch-Gordan product of x_a and x_b

+
+
Return type:
+

TensorMap

+
+
+
+ +
+
+anisoap.utils.metatensor_utils.standardize_keys(descriptor)
+

Standardize the naming scheme of density expansion coefficient blocks (nu=1)

+
+ +
+
+anisoap.utils.moment_generator.compute_moments_diagonal_inefficient_implementation(principal_components, a, maxdeg)
+

Computes all moments for a diagonal dilation matrix.

+

The implementation focuses on conceptual simplicity, while sacrificing memory +efficiency. To be specific, the moments array allows access to the value +of the moment \(\langle x^{n_0} y^{n_1} z^{n_2} \rangle\) simply as +moments[n0, n1, n2]. This leads to more intuitive code, at the cost of +wasting around a third of the memory in the array to store zeros.

+
+
Parameters:
+
    +
  • principal_components (np.ndarray of shape (3,)) – Array containing the three principal components

  • +
  • a (np.ndarray of shape (3,)) – Vectorial center of the trivariate Gaussian

  • +
  • maxdeg (int) – Maximum degree for which the moments need to be computed.

  • +
+
+
Returns:
+

Moments calculated. moments[n0,n1,n2] is the \(\left(n_0,n_1,n_2\right)^\text{th}\) +moment of the Gaussian defined as

+
+\[\langle x^{n_0} y^{n_1} z^{n_2} \rangle = + \int(x^{n_0} y^{n_1} z^{n_2}) e^{-\frac{1}{2}(r-a)^T \Sigma (r-a)} dx\,dy\,dz\, + \sum_{i=1}^{\infty} x_{i}\]
+

where \(\Sigma\) is the covariance matrix.

+

+
+
Return type:
+

np.ndarray of shape (3, maxdeg + 1)

+
+
+
+

Note

+

The term “moments” in probability theory are defined for normalized Gaussian +distributions. Here, we take the Gaussian without prefactor, meaning that +all moments are scaled by a global factor.

+
+
+ +
+
+anisoap.utils.moment_generator.compute_moments_inefficient_implementation(A, a, maxdeg)
+

Computes all moments for a general dilation matrix.

+
+
Parameters:
+
    +
  • A (np.ndarray of shape (3,3)) – Dilation matrix of the Gaussian that determines its shape. It can be +written as \(\mathbf{A} = \mathbf{R}\mathbf{D}\mathbf{R}^T\), where +R is a rotation matrix that specifies the orientation of the three principal +axes, while \(\mathbf{D}\) is a diagonal matrix whose three diagonal +elements are the lengths of the principal axes.

  • +
  • a (np.ndarray of shape (3,)) – Vectorial center of the trivariate Gaussian.

  • +
  • maxdeg (int) – Maximum degree for which the moments need to be computed.

  • +
+
+
Returns:
+

The list of moments defined as

+
+\[\langle x^{n_0} y^{n_1} z^{n_2} \rangle = + \int(x^{n_0} y^{n_1} z^{n_2}) \exp(-0.5(r-a)^T \Sigma (r-a)) dx\,dy\,dz\, + \sum_{i=1}^{\infty} x_{i}\]
+

where \(\Sigma\) is the covariance matrix.

+

+
+
Return type:
+

np.ndarray

+
+
+
+

Note

+

Note that the term “moments” in probability theory are defined for normalized Gaussian distributions. These +recursive relations find the moments of a normalized Gaussian, but we actually want to find the moments of +the unnormalized underlying gaussian (as seen in the equation above) because calculating expansion +coefficients of any density should not involve normalization. Therefore, we scale the end-result by +global_factor, which is the reciprocal of the normalizing constant in front of any gaussian.

+
+
+ +
+
+anisoap.utils.moment_generator.compute_moments_single_variable(A, a, maxdeg)
+

Computes all moments for a single variable Gaussian.

+
+
Parameters:
+
    +
  • A (float) – inverse of variance (see below for exact mathematical form)

  • +
  • a (float) – Center of Gaussian function

  • +
  • maxdeg (int) – Maximum degree for which the moments need to be computed.

  • +
+
+
Returns:
+

A numpy array of size (maxdeg + 1,) containing the moments defined as

+
+\[\langle x^n \rangle = \int x^n e^{-A(x-a)^2/2} dx\]
+

+
+
Return type:
+

np.array

+
+
+
+

Note

+

The Gaussian is not normalized, meaning that we need to multiply +all results by a global factor if we wish to interpret these as moments of +a probability density.

+
+
+ +
+
+class anisoap.utils.monomial_iterator.TrivariateMonomialIndices(deg)
+

Bases: object

+

Class for generating an iterator object over trivariate monomials.

+

Generates an iterator object over trivariate monomials of the form +\(f(x,y,z) = x^{n_0} y^{n_1} z^{n_2}\) sorted in lexicographical order.

+

Without this class, iterating over all monomials at some fixed degree +requires the use of a double loop of the form:

+
idx = 0
+for n0 in range(deg, -1, -1):
+        for n1 in range(deg-n0, -1, -1):
+        n2 = deg - n0 - n1
+
+        ... # do something with exponents (n0,n1,n2)
+
+        idx += 1
+
+
+

Instead, with this class, these lines can be reduced to:

+
myiter = iter(TrivariateMonomialIndices(deg=2))
+for idx, n0, n1, n2 in myiter:
+    ... # do something with exponents (n0, n1, n2)
+
+
+
+
+find_idx(exponents)
+

Finds the index of a given tuple of exponents.

+
+
Parameters:
+

exponents (3-tuple of the form (n0, n1, n2)) – The exponents of the monomial \(x^{n_0} y^{n_1} z^{n_2}\)

+
+
Return type:
+

The index of the tuple in lexicographical order

+
+
+
+ +
+ +
+
+anisoap.utils.spherical_to_cartesian.prefact_minus1(l)
+

Computes the prefactor that multiplies the \(T_{l-1}^\text{th}\) term in the iteration.

+

For \(m \in \left[-l, -l+2, ..., l \right]\), compute the factor as

+
+\[\left( \frac{\sqrt{(l+1-m)!}}{(l+1+m)!} \right) \left( \frac{\sqrt{(l+m)!}}{(l-m)!} \right) + \left( \frac{2l+1}{l+1-m} \right)\]
+
+
Parameters:
+

l (int) – Term immediately proceeding the term for which the prefactor is computed.

+
+
Returns:
+

corresponds to the prefactor that multiplies the \(T_{l-1}^\text{th}\) +term in the iteration

+
+
Return type:
+

list of size (2l + 1)

+
+
+
+ +
+
+anisoap.utils.spherical_to_cartesian.prefact_minus2(l)
+

Computes the prefactor that multiplies the \(T_{l-2}^\text{th}\) term in the iteration.

+

For \(m \in \left[-l+1, -l+2, ..., l-1\right]\), compute the factor as

+
+\[\left( \frac{\sqrt{(l+1-m)!}}{(l+1+m)!} \right) \left(\frac{\sqrt{(l-1+m)!}}{(l-1-m)!} \right) + \left( \frac{l+m}{l-m+1} \right)\]
+
+
Parameters:
+

l (int) – Term two places after the term for which the prefactor is computed

+
+
Returns:
+

Corresponds to the prefactor that multiplies the term in question

+
+
Return type:
+

list of size (2l - 1)

+
+
+
+ +
+
+anisoap.utils.spherical_to_cartesian.spherical_to_cartesian(lmax, num_ns)
+

Finds the coefficients for the cartesian polynomial form of solid harmonics +\(R_{lm} = \sqrt{(4\pi)/(2l+1)}*r^l*Y_{lm}\). Note that our AniSOAP +expansion does not contain the \(\sqrt{(4\pi)/(2l+1)}\) prefactor, so in calculating +expansion coefficients, we need to divide by that coefficient.

+
+
Parameters:
+
    +
  • lmax (int)

  • +
  • num_ns (int)

  • +
+
+
+
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html new file mode 100644 index 0000000..7361179 --- /dev/null +++ b/docs/build/html/genindex.html @@ -0,0 +1,385 @@ + + + + + + + + Index — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ A + | C + | E + | F + | G + | I + | K + | M + | O + | P + | S + | T + +
+

A

+ + + +
    +
  • + anisoap.representations.ellipsoidal_density_projection + +
  • +
  • + anisoap.representations.radial_basis + +
  • +
  • + anisoap.utils.cyclic_list + +
  • +
  • + anisoap.utils.metatensor_utils + +
  • +
    +
  • + anisoap.utils.moment_generator + +
  • +
  • + anisoap.utils.monomial_iterator + +
  • +
  • + anisoap.utils.shortcuts + +
  • +
  • + anisoap.utils.spherical_to_cartesian + +
  • +
+ +

C

+ + + +
+ +

E

+ + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

I

+ + + +
+ +

K

+ + +
+ +

M

+ + + +
+ +

O

+ + +
+ +

P

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/getting_started.html b/docs/build/html/getting_started.html new file mode 100644 index 0000000..4788581 --- /dev/null +++ b/docs/build/html/getting_started.html @@ -0,0 +1,148 @@ + + + + + + + + + Getting Started — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Getting Started

+
+

Introduction

+

AniSOAP is a package for creating machine-learnable representations of systems +of particles in a way that preserves geometrical information. AniSOAP works +similarly to SOAP (Smooth Overlap of Atomic Potentials) in many ways, with the +chief difference being AniSOAP’s ability to represent ellipsoidal particles.

+
+
+

First Steps

+

AniSOAP depends on and utilizes the packages featomic (aka rascaline), metatensor, +and ase. +It may be helpful to familiarize yourself with these packages before diving into +AniSOAP.

+
+
+

Key Concepts

+

In the AniSOAP representation, particles are treated as multivariate Gaussians (MVGs). +For each particle, we can consider its n-body interactions with nearby particles. +Each local density field is then decomposed in terms of spherical harmonics and +some choice of radial basis functions in order to be compactly represented in +vector form.

+

A single AniSOAP vector represents the environment of a single central ellipsoid. +A system of such particles can then be represented, for example, as a matrix of +AniSOAP vectors.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/index.html b/docs/build/html/index.html new file mode 100644 index 0000000..bdd4a6d --- /dev/null +++ b/docs/build/html/index.html @@ -0,0 +1,154 @@ + + + + + + + + + Welcome to AniSOAP’s documentation! — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Welcome to AniSOAP’s documentation!

+

AniSOAP is a Python library for creating descriptors of chemical systems +suitable for machine learning use. This project aims to extend the popular Smooth Overlap of Atomic Positions (SOAP) +descriptors to coarse-grained systems consisting of aspherical particles +with anisotropic interactions.

+
+

Note

+

This project is under active development.

+
+
+

Note

+

AniSOAP documentation is a work in progress; please contact us with questions +not yet addressed here.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/installation.html b/docs/build/html/installation.html new file mode 100644 index 0000000..22345f8 --- /dev/null +++ b/docs/build/html/installation.html @@ -0,0 +1,159 @@ + + + + + + + + + Installation — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Installation

+
+

Dependencies

+

Before installing AniSOAP, please make sure you have the following installed (We recommend using an environment manager like conda):

+ +
+
+

Installing AniSOAP

+

Navigate to the directory where you would like the AniSOAP package to be located, then copy and paste the +following into your shell:

+
git clone https://github.com/cersonsky-lab/AniSOAP
+
+
+

Then navigate to the AniSOAP directory with:

+
cd AniSOAP
+
+
+

Now use pip to install the library:

+
pip install .
+
+
+
+
+

Testing

+

AniSOAP is still under active development, so you may want to run some tests to ensure that your installation is working properly. From the main directory you can run the internal tests with:

+
pytest tests/.
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv new file mode 100644 index 0000000..783fb4f Binary files /dev/null and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/py-modindex.html b/docs/build/html/py-modindex.html new file mode 100644 index 0000000..e0c3407 --- /dev/null +++ b/docs/build/html/py-modindex.html @@ -0,0 +1,169 @@ + + + + + + + + Python Module Index — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ a +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ a
+ anisoap +
    + anisoap.representations.ellipsoidal_density_projection +
    + anisoap.representations.radial_basis +
    + anisoap.utils.cyclic_list +
    + anisoap.utils.metatensor_utils +
    + anisoap.utils.moment_generator +
    + anisoap.utils.monomial_iterator +
    + anisoap.utils.shortcuts +
    + anisoap.utils.spherical_to_cartesian +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/search.html b/docs/build/html/search.html new file mode 100644 index 0000000..b678034 --- /dev/null +++ b/docs/build/html/search.html @@ -0,0 +1,129 @@ + + + + + + + + Search — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js new file mode 100644 index 0000000..5b07fc8 --- /dev/null +++ b/docs/build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"API Reference": [[0, null]], "Computation times": [[4, null], [8, null]], "Contents:": [[6, null]], "Dependencies": [[7, "dependencies"]], "Example 1: Creating AniSOAP vectors from ellipsoidal frames.": [[1, null]], "Example 2: Machine-learning benzene energies.": [[2, null]], "Examples": [[3, null]], "First Steps": [[5, "first-steps"]], "Getting Started": [[5, null]], "Installation": [[7, null]], "Installing AniSOAP": [[7, "installing-anisoap"]], "Introduction": [[5, "introduction"]], "Key Concepts": [[5, "key-concepts"]], "Representations": [[0, "module-anisoap.representations.ellipsoidal_density_projection"]], "Testing": [[7, "testing"]], "Usage": [[9, null]], "Utilities": [[0, "module-anisoap.utils.cyclic_list"]], "Welcome to AniSOAP\u2019s documentation!": [[6, null]]}, "docnames": ["api", "auto_examples/example01_invariances_of_powerspectrum_test", "auto_examples/example02_learn_benzene", "auto_examples/index", "auto_examples/sg_execution_times", "getting_started", "index", "installation", "sg_execution_times", "usage"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["api.rst", "auto_examples/example01_invariances_of_powerspectrum_test.rst", "auto_examples/example02_learn_benzene.rst", "auto_examples/index.rst", "auto_examples/sg_execution_times.rst", "getting_started.rst", "index.rst", "installation.rst", "sg_execution_times.rst", "usage.rst"], "indexentries": {}, "objects": {"anisoap.representations": [[0, 0, 0, "-", "ellipsoidal_density_projection"], [0, 0, 0, "-", "radial_basis"]], "anisoap.representations.ellipsoidal_density_projection": [[0, 1, 1, "", "EllipsoidalDensityProjection"], [0, 4, 1, "", "contract_pairwise_feat"], [0, 4, 1, "", "pairwise_ellip_expansion"]], "anisoap.representations.ellipsoidal_density_projection.EllipsoidalDensityProjection": [[0, 2, 1, "", "feature_gradients"], [0, 2, 1, "", "features"], [0, 3, 1, "", "power_spectrum"], [0, 3, 1, "", "transform"]], "anisoap.representations.radial_basis": [[0, 1, 1, "", "GTORadialBasis"], [0, 1, 1, "", "MonomialBasis"], [0, 4, 1, "", "gto_overlap"], [0, 4, 1, "", "gto_prefactor"], [0, 4, 1, "", "gto_square_norm"], [0, 4, 1, "", "inverse_matrix_sqrt"], [0, 4, 1, "", "monomial_overlap"], [0, 4, 1, "", "monomial_prefactor"], [0, 4, 1, "", "monomial_square_norm"]], "anisoap.representations.radial_basis.GTORadialBasis": [[0, 3, 1, "", "calc_overlap_matrix"], [0, 3, 1, "", "get_basis"], [0, 3, 1, "", "get_num_radial_functions"], [0, 3, 1, "", "orthonormalize_basis"], [0, 3, 1, "", "plot_basis"]], "anisoap.representations.radial_basis.MonomialBasis": [[0, 3, 1, "", "calc_overlap_matrix"], [0, 3, 1, "", "get_basis"], [0, 3, 1, "", "get_num_radial_functions"], [0, 3, 1, "", "orthonormalize_basis"], [0, 3, 1, "", "plot_basis"]], "anisoap.utils": [[0, 0, 0, "-", "cyclic_list"], [0, 0, 0, "-", "metatensor_utils"], [0, 0, 0, "-", "moment_generator"], [0, 0, 0, "-", "monomial_iterator"], [0, 0, 0, "-", "shortcuts"], [0, 0, 0, "-", "spherical_to_cartesian"]], "anisoap.utils.cyclic_list": [[0, 1, 1, "", "CGRCacheList"]], "anisoap.utils.cyclic_list.CGRCacheList": [[0, 3, 1, "", "clear_cache"], [0, 3, 1, "", "get_val"], [0, 3, 1, "", "insert"], [0, 3, 1, "", "keys"]], "anisoap.utils.metatensor_utils": [[0, 4, 1, "", "cg_combine"], [0, 4, 1, "", "standardize_keys"]], "anisoap.utils.moment_generator": [[0, 4, 1, "", "compute_moments_diagonal_inefficient_implementation"], [0, 4, 1, "", "compute_moments_inefficient_implementation"], [0, 4, 1, "", "compute_moments_single_variable"]], "anisoap.utils.monomial_iterator": [[0, 1, 1, "", "TrivariateMonomialIndices"]], "anisoap.utils.monomial_iterator.TrivariateMonomialIndices": [[0, 3, 1, "", "find_idx"]], "anisoap.utils.spherical_to_cartesian": [[0, 4, 1, "", "prefact_minus1"], [0, 4, 1, "", "prefact_minus2"], [0, 4, 1, "", "spherical_to_cartesian"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "method", "Python method"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute", "3": "py:method", "4": "py:function"}, "terms": {"": [0, 1, 5], "0": [0, 1, 2, 4, 7, 8], "00": [4, 8], "000": [4, 8], "00000000e": [], "0005455594781168515": [], "001": [0, 2], "002": [], "00it": [], "01": [], "01it": [], "02": [], "02415869": 1, "02878644": 1, "02it": [], "03": [], "03290243": 1, "034": [], "03it": [], "04": [], "04it": [], "05": [], "05715855": 1, "05it": [], "06": [4, 8], "06913808e": [], "06it": [], "07": [], "07507814": 1, "07it": [], "08": 0, "08446388": 1, "08971953": 1, "08it": [], "09": [], "09it": [], "0x15e1c85b0": [], "1": [0, 2, 3, 4, 7, 8], "10": [1, 2, 7], "100": [0, 2], "10001": [], "10026": [], "10051": [], "1006": [], "10076": [], "10101": [], "10126": [], "10151": [], "10176": [], "10201": [], "10226": [], "10251": [], "10276": [], "10301": [], "1031": [], "10326": [], "10351": [], "10376": [], "10400": [], "10425": [], "10443": [], "10450": [], "10475": [], "10500": [], "10525": [], "10550": [], "1056": [], "10575": [], "10600": [], "10625": [], "10650": [], "10675": [], "10700": [], "10725": [], "10750": [], "10775": [], "10800": [], "1081": [], "10825": [], "10850": [], "10875": [], "10900": [], "10925": [], "10950": [], "10975": [], "10it": [], "11": [], "11000": [], "11025": [], "11050": [], "1106": [], "11075": [], "11100": [], "11110": [], "11125": [], "11150": [], "11175": [], "11200": [], "11225": [], "11250": [], "11275": [], "11300": [], "1131": [], "11325": [], "11350": [], "11375": [], "11400": [], "11425": [], "11450": [], "11475": [], "11500": [], "11525": [], "11550": [], "1156": [], "11575": [], "11600": [], "11625": [], "11650": [], "11675": [], "11700": [], "11725": [], "11750": [], "11775": [], "11800": [], "1181": [], "11825": [], "11850": [], "11875": [], "119": [], "11900": [], "11925": [], "11950": [], "11975": [], "11it": [], "12": [], "12000": [], "12025": [], "12050": [], "1206": [], "12075": [], "12100": [], "12122": [], "12125": [], "12150": [], "12175": [], "12200": [], "12225": [], "12250": [], "12275": [], "12300": [], "1231": [], "12325": [], "12350": [], "12375": [], "12400": [], "12425": [], "12450": [], "12475": [], "12500": [], "12501": [], "12525": [], "12550": [], "1256": [], "12575": [], "12576": [], "12600": [], "12625": [], "12650": [], "12675": [], "12700": [], "12725": [], "12750": [], "12775": [], "12800": [], "12807": [], "1281": [], "12825": [], "12850": [], "12875": [], "12883789e": [], "12900": [], "12905": [], "12925": [], "12950": [], "12975": [], "12it": [], "13": 7, "13000": [], "13025": [], "1305": [], "13050": [], "13075": [], "13100": [], "13125": [], "13150": [], "13175": [], "13200": [], "13225": [], "13250": [], "13275": [], "1329": [], "13300": [], "13325": [], "1333": [], "13350": [], "13375": [], "13400": [], "13425": [], "13450": [], "1347": [], "13475": [], "13500": [], "13525": [], "1353": [], "13550": [], "13575": [], "13600": [], "13625": [], "13650": [], "13652": [], "1367": [], "13675": [], "13700": [], "13725": [], "13750": [], "1377": [], "13775": [], "13800": [], "13825": [], "13850": [], "1387": [], "13875": [], "1388": [], "13900": [], "1391": [], "13925": [], "1393": [], "13950": [], "13975": [], "13it": [], "14": [], "14000": [], "1402": [], "14025": [], "14050": [], "14075": [], "14100": [], "14125": [], "14150": [], "14175": [], "14200": [], "14225": [], "14250": [], "1427": [], "14275": [], "143": [], "14300": [], "14325": [], "14350": [], "14375": [], "14400": [], "14425": [], "14450": [], "14475": [], "14500": [], "1452": [], "14525": [], "1454": [], "14550": [], "14575": [], "14600": [], "14625": [], "14650": [], "14675": [], "14700": [], "14725": [], "1474": [], "14750": [], "1477": [], "14775": [], "14800": [], "14825": [], "14850": [], "14875": [], "1488": [], "14900": [], "14925": [], "14950": [], "1496": [], "14975": [], "1499": [], "14it": [], "15": [], "15000": [], "1501": [], "1502": [], "15025": [], "15050": [], "15075": [], "15100": [], "15125": [], "15150": [], "15175": [], "15200": [], "15225": [], "15250": [], "1527": [], "15275": [], "15300": [], "15325": [], "15349": [], "15374": [], "15399": [], "15424": [], "15449": [], "1546": [], "1547": [], "15474": [], "1548": [], "15499": [], "1552": [], "15524": [], "15549": [], "15574": [], "15599": [], "1562": [], "15624": [], "15649": [], "15674": [], "15699": [], "1571": [], "15724": [], "15749": [], "1577": [], "15774": [], "15799": [], "15824": [], "15848211e": [], "15849": [], "15874": [], "15899": [], "15924": [], "15949": [], "15965019": 1, "15974": [], "15999": [], "15it": [], "16": [], "1602": [], "16024": [], "16049": [], "16074": [], "16099": [], "16124": [], "16149": [], "16174": [], "16199": [], "16224": [], "16249": [], "1627": [], "16274": [], "16299": [], "16324": [], "16349": [], "16374": [], "16399": [], "16424": [], "16449": [], "16474": [], "16499": [], "165": [], "1652": [], "16524": [], "16549": [], "16574": [], "16599": [], "16624": [], "16649": [], "16674": [], "16699": [], "167": [], "16724": [], "16749": [], "16755_10030": 0, "1677": [], "16774": [], "16799": [], "16824": [], "16849": [], "16874": [], "16899": [], "169": [], "16924": [], "16946": [], "16949": [], "16974": [], "16999": [], "16it": [], "17": [], "1702": [], "17024": [], "17049": [], "17074": [], "17079529": 1, "17099": [], "17124": [], "17149": [], "17174": [], "17199": [], "172": [], "17224": [], "17249": [], "1726": [], "17274": [], "17299": [], "173": 1, "17324": [], "17349": [], "17374": [], "17399": [], "17424": [], "17449": [], "17474": [], "17499": [], "1750": [], "17524": [], "17549": [], "17574": [], "17599": [], "176": [], "17624": [], "17649": [], "17674": [], "17699": [], "17724": [], "1774": [], "17749": [], "17774": [], "17799": [], "17824": [], "17849": [], "17874": [], "17886": [], "17899": [], "17924": [], "17949": [], "17974": [], "1798": [], "17999": [], "17it": [], "18": 7, "18024": [], "18049": [], "18074": [], "18099": [], "18124": [], "18149": [], "18172": [], "18174": [], "18196": [], "18199": [], "1822": [], "18224": [], "18249": [], "18274": [], "18299": [], "18324": [], "18349": [], "18355": [], "18374": [], "18399": [], "18424": [], "18449": [], "1846": [], "18474": [], "18499": [], "18524": [], "18549": [], "18574": [], "18599": [], "18624": [], "18649": [], "18674": [], "18699": [], "187": [], "1870": [], "18724": [], "18749": [], "18774": [], "18799": [], "18816": [], "18824": [], "18849": [], "18874": [], "18899": [], "18924": [], "18949": [], "1895": [], "18974": [], "18999": [], "18it": [], "19": [], "19024": [], "19049": [], "19074": [], "19099": [], "191": [], "19124": [], "19149": [], "19174": [], "19195": [], "19199": [], "1920": [], "19224": [], "19249": [], "19274": [], "19299": [], "19324": [], "19349": [], "19374": [], "19399": [], "19424": [], "19449": [], "1945": [], "19474": [], "19499": [], "19524": [], "19549": [], "19574": [], "19599": [], "19624": [], "19649": [], "19674": [], "19699": [], "1970": [], "19724": [], "19749": [], "19774": [], "19799": [], "19824": [], "19849": [], "19865": [], "19874": [], "19899": [], "19924": [], "1994": [], "19949": [], "19974": [], "19999": [], "19it": [], "1e": [0, 1, 2], "1st": 3, "2": [0, 1, 3, 4, 8], "20": 2, "20024": [], "20049": [], "20074": [], "20099": [], "20124": [], "20149": [], "20174": [], "2019": [], "20199": [], "20224": [], "20249": [], "20274": [], "20299": [], "20324": [], "20349": [], "20374": [], "20399": [], "20424": [], "2044": [], "20449": [], "20466222": 1, "20474": [], "20499": [], "20524": [], "20549": [], "20574": [], "20599": [], "20624": [], "20649": [], "20674": [], "2069": [], "20699": [], "207": [], "20724": [], "20749": [], "20774": [], "20799": [], "20824": [], "20849": [], "20874": [], "20899": [], "20924": [], "2094": [], "20949": [], "20974": [], "20999": [], "20it": [], "21": [], "21024": [], "21049": [], "21074": [], "21099": [], "21124": [], "21149": [], "21173": [], "2119": [], "21197": [], "21221": [], "21245": [], "21269": [], "21293": [], "21317": [], "213207": 1, "21342": [], "21367": [], "21392": [], "21417": [], "2144": [], "21442": [], "21467": [], "21492": [], "215": [], "21517": [], "21542": [], "21567": [], "21592": [], "21617": [], "21642": [], "21667": [], "2169": [], "21692": [], "21717": [], "21742": [], "21767": [], "21792": [], "21817": [], "21842": [], "21867": [], "21892": [], "21917": [], "2194": [], "21942": [], "21967": [], "21992": [], "21it": [], "22": [], "22017": [], "22042": [], "22067": [], "22092": [], "22117": [], "22142": [], "22167": [], "2219": [], "22192": [], "22217": [], "22242": [], "22267": [], "22292": [], "223": [], "22317": [], "22342": [], "22367": [], "22392": [], "224": [], "22417": [], "2244": [], "22442": [], "22467": [], "22492": [], "22517": [], "22542": [], "22567": [], "22592": [], "22617": [], "22642": [], "22667": [], "2269": [], "22692": [], "22717": [], "22742": [], "22767": [], "22792": [], "228": [], "22817": [], "22842": [], "22867": [], "22892": [], "22917": [], "2294": [], "22942": [], "22967": [], "22992": [], "22it": [], "23": [], "230": [], "23017": [], "23042": [], "23067": [], "23092": [], "231": [], "23117": [], "23142": [], "23167": [], "2319": [], "23192": [], "232": [], "23217": [], "23242": [], "23267": [], "23292": [], "233": [], "23317": [], "23342": [], "23367": [], "23392": [], "234": [], "23417": [], "2344": [], "23442": [], "23467": [], "23492": [], "235": [], "23517": [], "23542": [], "23567": [], "23592": [], "236": [], "23617": [], "23642": [], "23667": [], "2369": [], "23692": [], "237": [], "23717": [], "23742": [], "23767": [], "23792": [], "238": [], "23817": [], "23842": [], "23867": [], "23892": [], "239": [], "23917": [], "2394": [], "23942": [], "23967": [], "23992": [], "23it": [], "24": [], "240": [], "24017": [], "24042": [], "24067": [], "2407": [], "24092": [], "241": [], "24117": [], "24142": [], "24167": [], "2419": [], "24192": [], "242": [], "24217": [], "24242": [], "24267": [], "24292": [], "243": [], "24317": [], "24342": [], "24367": [], "24392": [], "244": [], "24417": [], "2444": [], "24442": [], "24467": [], "24492": [], "24517": [], "24542": [], "24567": [], "24592": [], "24617": [], "24642": [], "24667": [], "2469": [], "24692": [], "24717": [], "24742": [], "24767": [], "24792": [], "24817": [], "24842": [], "24867": [], "24892": [], "24917": [], "2494": [], "24942": [], "24967": [], "24992": [], "24it": [], "25": [], "25017": [], "25042": [], "25067": [], "25092": [], "25117": [], "25142": [], "25167": [], "2519": [], "25192": [], "25217": [], "25242": [], "25267": [], "25292": [], "25317": [], "25342": [], "25367": [], "25392": [], "25417": [], "2544": [], "25442": [], "25467": [], "25492": [], "25517": [], "25542": [], "25567": [], "25592": [], "25617": [], "25642": [], "25667": [], "2569": [], "25692": [], "25717": [], "25742": [], "25767": [], "25792": [], "25817": [], "25842": [], "25867": [], "25892": [], "25917": [], "2594": [], "25942": [], "25967": [], "25992": [], "25it": [], "26": [], "26017": [], "26042": [], "26050794": 1, "26067": [], "26092": [], "26117": [], "26142": [], "26167": [], "2619": [], "26192": [], "26217": [], "26242": [], "26267": [], "26292": [], "263": [], "26317": [], "26342": [], "26367": [], "26392": [], "26417": [], "2644": [], "26442": [], "26467": [], "26492": [], "26500539": 1, "26517": [], "26542": [], "26567": [], "26592": [], "26617": [], "26642": [], "26667": [], "2669": [], "26692": [], "26717": [], "26742": [], "26767": [], "26792": [], "26817": [], "26842": [], "26867": [], "26892": [], "26917": [], "2694": [], "26942": [], "26967": [], "26992": [], "26it": [], "27": [], "27017": [], "27042": [], "27067": [], "27092": [], "27117": [], "27142": [], "27167": [], "2719": [], "27192": [], "27217": [], "27242": [], "27267": [], "27292": [], "27317": [], "27342": [], "27355258": 1, "27367": [], "27392": [], "27417": [], "27427499e": [], "2744": [], "27442": [], "27467": [], "27492": [], "27517": [], "27542": [], "27567": [], "27592": [], "27617": [], "27642": [], "27667": [], "2769": [], "27692": [], "27717": [], "27742": [], "27767": [], "27792": [], "27817": [], "27842": [], "27867": [], "27892": [], "27917": [], "2794": [], "27942": [], "27967": [], "27992": [], "27it": [], "28": [], "28017": [], "28042": [], "28067": [], "28092": [], "28117": [], "28133240e": [], "28142": [], "28167": [], "2819": [], "28192": [], "28217": [], "28242": [], "28267": [], "28292": [], "28317": [], "28342": [], "28367": [], "28392": [], "28417": [], "2844": [], "28442": [], "28467": [], "28492": [], "28517": [], "28542": [], "28567": [], "28592": [], "28617": [], "28642": [], "28667": [], "2869": [], "28692": [], "28717": [], "28742": [], "28767": [], "28792": [], "288": [], "28817": [], "28842": [], "28867": [], "28892": [], "28917": [], "2894": [], "28942": [], "28967": [], "28992": [], "28it": [], "29": [], "29017": [], "29042": [], "29067": [], "29092": [], "29117": [], "29142": [], "29167": [], "2919": [], "29192": [], "29217": [], "29242": [], "29267": [], "29292": [], "29317": [], "29342": [], "29367": [], "29392": [], "29417": [], "2944": [], "29442": [], "29467": [], "29492": [], "29517": [], "29542": [], "29567": [], "29592": [], "29617": [], "29642": [], "29667": [], "2969": [], "29692": [], "29717": [], "29742": [], "29767": [], "29792": [], "29817": [], "29842": [], "29867": [], "29892": [], "29917": [], "2994": [], "29942": [], "29967": [], "29992": [], "29it": [], "2d": 0, "2l": 0, "2n": 0, "2n_": 0, "2nd": 3, "2nmax": 0, "3": [0, 1, 2, 7], "30": [], "30017": [], "30042": [], "30067": [], "30092": [], "30117": [], "30142": [], "30167": [], "3019": [], "30192": [], "30217": [], "30242": [], "30267": [], "30292": [], "30317": [], "30342": [], "30367": [], "30392": [], "30417": [], "3044": [], "30442": [], "30467": [], "30492": [], "30517": [], "30542": [], "30567": [], "30592": [], "30617": [], "30642": [], "30667": [], "3069": [], "30692": [], "30717": [], "30742": [], "30767": [], "30792": [], "30817": [], "30842": [], "30867": [], "30892": [], "30917": [], "3094": [], "30942": [], "30967": [], "30992": [], "30it": [], "31": [], "31017": [], "31042": [], "31067": [], "31092": [], "31117": [], "31142": [], "31167": [], "3119": [], "31192": [], "31217": [], "31242": [], "31267": [], "31292": [], "313": [], "31317": [], "31342": [], "31367": [], "31392": [], "31417": [], "3144": [], "31442": [], "31467": [], "31492": [], "31517": [], "31542": [], "31567": [], "31592": [], "31617": [], "31642": [], "31667": [], "3169": [], "31692": [], "31717": [], "31742": [], "31767": [], "31792": [], "31817": [], "31842": [], "31867": [], "31892": [], "31917": [], "3194": [], "31942": [], "31967": [], "31992": [], "31it": [], "32": 0, "32017": [], "32042": [], "32067": [], "32092": [], "32117": [], "32142": [], "32167": [], "3219": [], "32192": [], "32217": [], "32242": [], "32267": [], "32292": [], "32317": [], "32342": [], "32367": [], "32392": [], "32417": [], "3244": [], "32442": [], "32467": [], "32492": [], "32517": [], "32542": [], "32567": [], "32592": [], "32617": [], "32642": [], "32667": [], "3269": [], "32692": [], "32717": [], "32742": [], "32767": [], "32792": [], "32817": [], "32842": [], "32867": [], "32892": [], "32917": [], "3294": [], "32942": [], "32967": [], "32992": [], "32it": [], "33": [], "33017": [], "33042": [], "33067": [], "33092": [], "33117": [], "33142": [], "33167": [], "3319": [], "33192": [], "33217": [], "33242": [], "33267": [], "33292": [], "33317": [], "33342": [], "33367": [], "33392": [], "33417": [], "3344": [], "33442": [], "33467": [], "33492": [], "33517": [], "33542": [], "33567": [], "33572147e": [], "33592": [], "33617": [], "33642": [], "33667": [], "3369": [], "33692": [], "33717": [], "33742": [], "33767": [], "33792": [], "338": [], "33817": [], "33842": [], "33867": [], "33892": [], "33917": [], "3394": [], "33942": [], "33967": [], "33992": [], "33it": [], "34": [], "34017": [], "34042": [], "34067": [], "34092": [], "34117": [], "34142": [], "34167": [], "3419": [], "34192": [], "34217": [], "34242": [], "34267": [], "34292": [], "34317": [], "34342": [], "34367": [], "34392": [], "34417": [], "3444": [], "34442": [], "34467": [], "34492": [], "34517": [], "34542": [], "34567": [], "34592": [], "34617": [], "34642": [], "34667": [], "3469": [], "34692": [], "34717": [], "34742": [], "34767": [], "34792": [], "34817": [], "34842": [], "34867": [], "34892": [], "34917": [], "3493": [], "34942": [], "34967": [], "34992": [], "34it": [], "35": [], "35017": [], "35042": [], "35067": [], "35092": [], "35117": [], "35142": [], "35167": [], "3517": [], "35192": [], "35217": [], "35242": [], "35267": [], "35292": [], "35317": [], "35342": [], "35367": [], "35392": [], "3541": [], "35417": [], "35442": [], "35467": [], "35492": [], "35517": [], "35542": [], "35567": [], "35592": [], "35616": [], "3564": [], "35640": [], "3565": [], "35664": [], "35688": [], "35712": [], "35736": [], "35760": [], "35784": [], "35808": [], "35833": [], "35858": [], "35883": [], "3589": [], "35908": [], "35933": [], "35958": [], "35981829e": [], "35983": [], "35it": [], "36": [], "36008": [], "36033": [], "36058": [], "36083": [], "36108": [], "3613": [], "36133": [], "36158": [], "36183": [], "36208": [], "36233": [], "36258": [], "36283": [], "363": [], "36308": [], "36333": [], "36358": [], "3637": [], "36383": [], "36408": [], "36433": [], "36458": [], "36483": [], "36508": [], "36533": [], "36558": [], "36583": [], "36608": [], "3661": [], "36633": [], "36658": [], "36683": [], "36708": [], "36733": [], "36758": [], "36783": [], "36808": [], "36833": [], "36858": [], "3686": [], "36883": [], "36908": [], "36933": [], "36958": [], "36983": [], "36it": [], "37": [], "37008": [], "37033": [], "37058": [], "37083": [], "37108": [], "3711": [], "37133": [], "37158": [], "37183": [], "37208": [], "37233": [], "37258": [], "37283": [], "37308": [], "37333": [], "37358": [], "3736": [], "37383": [], "37408": [], "37433": [], "37458": [], "37483": [], "37508": [], "37533": [], "37558": [], "37583": [], "37608": [], "3761": [], "37633": [], "37658": [], "37683": [], "37708": [], "37733": [], "37758": [], "37783": [], "37808": [], "37833": [], "37858": [], "3786": [], "37883": [], "37908": [], "37933": [], "37958": [], "37983": [], "37it": [], "38": [], "38008": [], "38033": [], "38058": [], "38083": [], "38108": [], "3811": [], "38133": [], "38158": [], "38183": [], "38208": [], "38233": [], "38258": [], "38283": [], "38308": [], "38333": [], "38358": [], "3836": [], "38383": [], "38408": [], "3841": [], "38433": [], "38458": [], "38483": [], "38508": [], "38533": [], "38558": [], "38583": [], "38608": [], "3861": [], "38633": [], "38658": [], "38683": [], "38708": [], "38733": [], "38758": [], "38783": [], "388": [], "38808": [], "38833": [], "38858": [], "3886": [], "38883": [], "38908": [], "38933": [], "38958": [], "38983": [], "38it": [], "39": [], "39008": [], "39033": [], "39058": [], "39083": [], "39108": [], "3911": [], "39133": [], "39158": [], "39183": [], "39208": [], "39233": [], "39258": [], "39283": [], "39308": [], "39333": [], "39358": [], "3936": [], "39383": [], "39408": [], "39433": [], "39458": [], "39483": [], "39508": [], "39533": [], "39558": [], "39583": [], "39608": [], "3961": [], "39633": [], "39658": [], "39683": [], "39708": [], "39733": [], "39758": [], "39783": [], "39808": [], "39833": [], "39858": [], "3986": [], "39883": [], "39908": [], "39933": [], "39958": [], "39983": [], "39it": [], "3d": 0, "3f": 2, "4": [0, 1, 2, 7], "40": [], "40008": [], "40033": [], "40058": [], "40083": [], "40108": [], "4011": [], "40133": [], "40158": [], "40183": [], "40208": [], "40233": [], "40258": [], "40283": [], "40308": [], "40333": [], "4035": [], "40358": [], "40383": [], "40408": [], "40433": [], "40458": [], "40483": [], "40508": [], "40514029": 1, "40533": [], "40558": [], "40583": [], "4059": [], "40608": [], "40633": [], "40658": [], "40683": [], "40708": [], "40733": [], "40758": [], "40783": [], "40808": [], "40833": [], "4084": [], "40858": [], "40883": [], "40908": [], "40933": [], "40958": [], "40983": [], "40it": [], "41": [], "41008": [], "41033": [], "41058": [], "41083": [], "4109": [], "41108": [], "41133": [], "41158": [], "41183": [], "41208": [], "41233": [], "41258": [], "41283": [], "413": [], "41308": [], "41333": [], "4134": [], "41358": [], "41383": [], "41408": [], "41433": [], "41458": [], "41483": [], "41508": [], "41533": [], "41558": [], "41583": [], "4159": [], "41608": [], "41633": [], "41658": [], "41683": [], "41708": [], "41733": [], "41758": [], "41783": [], "41808": [], "41833": [], "4184": [], "41858": [], "41883": [], "41908": [], "41933": [], "41958": [], "41983": [], "41it": [], "42": [], "42008": [], "42033": [], "42058": [], "42083": [], "4209": [], "42108": [], "42133": [], "42158": [], "42183": [], "42208": [], "42233": [], "42258": [], "42283": [], "42308": [], "42333": [], "4234": [], "42358": [], "42383": [], "42408": [], "42433": [], "42458": [], "42483": [], "42508": [], "42533": [], "42558": [], "42583": [], "4259": [], "42608": [], "42633": [], "42658": [], "42683": [], "42708": [], "42733": [], "42758": [], "42783": [], "42808": [], "42833": [], "4284": [], "42858": [], "42883": [], "42908": [], "42933": [], "42958": [], "42983": [], "42it": [], "43": [], "43008": [], "43033": [], "43058": [], "43083": [], "4309": [], "43108": [], "43133": [], "43158": [], "43183": [], "43208": [], "43233": [], "43258": [], "43283": [], "43308": [], "43333": [], "4334": [], "43358": [], "43383": [], "43408": [], "43433": [], "43458": [], "43483": [], "43508": [], "43533": [], "43558": [], "43583": [], "4359": [], "43608": [], "43633": [], "43658": [], "43683": [], "43708": [], "43733": [], "43758": [], "43783": [], "438": [], "43808": [], "43833": [], "4384": [], "43844989e": [], "43858": [], "43883": [], "43908": [], "43933": [], "43958": [], "43983": [], "43it": [], "44": [], "44008": [], "44033": [], "44058": [], "44083": [], "4409": [], "44108": [], "44133": [], "44158": [], "4417325": 1, "44183": [], "44208": [], "44233": [], "44258": [], "44283": [], "44307": [], "44331": [], "4434": [], "44355": [], "44379": [], "44403": [], "44427": [], "44452": [], "44477": [], "44502": [], "44527": [], "44552": [], "44576": [], "4459": [], "44600": [], "44625": [], "44650": [], "44675": [], "44700": [], "44725": [], "44750": [], "44775": [], "44800": [], "44825": [], "4484": [], "44850": [], "44875": [], "44900": [], "44925": [], "44950": [], "44975": [], "44it": [], "45": [], "45000": [], "45025": [], "45050": [], "45075": [], "4509": [], "45100": [], "45125": [], "45150": [], "45175": [], "45200": [], "45225": [], "45250": [], "45275": [], "45300": [], "45325": [], "4534": [], "45350": [], "45375": [], "45400": [], "45425": [], "45450": [], "45475": [], "45500": [], "45525": [], "45550": [], "45559478e": [], "45575": [], "4559": [], "45600": [], "45625": [], "45650": [], "4567": [], "45675": [], "45700": [], "45725": [], "45750": [], "45775": [], "45800": [], "45825": [], "4584": [], "45850": [], "45875": [], "45900": [], "45925": [], "45950": [], "45975": [], "45it": [], "46": [], "46000": [], "46025": [], "46050": [], "46075": [], "4609": [], "46100": [], "46125": [], "46150": [], "46175": [], "46200": [], "46225": [], "46250": [], "46275": [], "463": [], "46300": [], "46325": [], "4634": [], "46350": [], "46375": [], "46400": [], "46425": [], "46450": [], "46475": [], "46500": [], "46525": [], "46550": [], "46575": [], "4659": [], "46600": [], "46625": [], "46650": [], "46675": [], "46700": [], "46725": [], "46750": [], "46775": [], "46800": [], "46825": [], "4684": [], "46850": [], "46875": [], "46900": [], "46925": [], "46950": [], "46975": [], "46it": [], "47": [], "47000": [], "47025": [], "47050": [], "47075": [], "4709": [], "47100": [], "47125": [], "47150": [], "47175": [], "47200": [], "47225": [], "47250": [], "47275": [], "47300": [], "47325": [], "4734": [], "47350": [], "47375": [], "474": 2, "47400": [], "47425": [], "47450": [], "47475": [], "47500": [], "47525": [], "47550": [], "47575": [], "4759": [], "47600": [], "47625": [], "47650": [], "47675": [], "47700": [], "47725": [], "47750": [], "47775": [], "47800": [], "47825": [], "4784": [], "47850": [], "47875": [], "47900": [], "47925": [], "47950": [], "47975": [], "47it": [], "48": [], "48000": [], "48025": [], "48050": [], "48075": [], "4809": [], "48100": [], "48125": [], "48150": [], "48175": [], "48200": [], "48225": [], "48250": [], "48275": [], "48300": [], "48325": [], "4834": [], "48350": [], "48375": [], "48400": [], "48425": [], "48450": [], "48475": [], "48500": [], "48525": [], "48550": [], "48575": [], "4859": [], "48600": [], "48625": [], "48650": [], "48675": [], "48700": [], "48725": [], "48750": [], "48775": [], "488": [], "48800": [], "48825": [], "4884": [], "48850": [], "48875": [], "48900": [], "48925": [], "48950": [], "48975": [], "48it": [], "49": [], "490": [], "49000": [], "49025": [], "49050": [], "49075": [], "4909": [], "49100": [], "49125": [], "49150": [], "49175": [], "49200": [], "49225": [], "49250": [], "49275": [], "49300": [], "49325": [], "4934": [], "49350": [], "49375": [], "49400": [], "49425": [], "49450": [], "49475": [], "49500": [], "49525": [], "49550": [], "49575": [], "4959": [], "49600": [], "49625": [], "49650": [], "49675": [], "49700": [], "49725": [], "49750": [], "49775": [], "49800": [], "49825": [], "4984": [], "49850": [], "49875": [], "49900": [], "49925": [], "49950": [], "49975": [], "49it": [], "5": [0, 1, 2], "50": [], "50000": [], "50025": [], "50050": [], "50075": [], "5009": [], "50100": [], "50125": [], "50150": [], "50175": [], "50200": [], "50225": [], "50249": [], "50273": [], "50297": [], "50321": [], "5034": [], "50345": [], "50369": [], "50393": [], "50417": [], "50442": [], "50466": [], "50490": [], "50514": [], "50539": [], "50564": [], "50589": [], "5059": [], "50614": [], "50639": [], "50664": [], "50689": [], "50714": [], "50739": [], "50764": [], "50789": [], "50814": [], "50839": [], "5084": [], "50864": [], "50889": [], "50914": [], "50939": [], "50964": [], "50989": [], "50it": [], "51": [], "51014": [], "51039": [], "51064": [], "51089": [], "5109": [], "51114": [], "51139": [], "51164": [], "51189": [], "51214": [], "51239": [], "51264": [], "51289": [], "513": [], "51314": [], "51339": [], "5134": [], "51364": [], "51389": [], "51414": [], "51439": [], "51464": [], "51489": [], "51514": [], "51539": [], "51564": [], "51589": [], "5159": [], "51614": [], "51639": [], "51664": [], "51689": [], "51714": [], "51739": [], "51764": [], "51789": [], "51814": [], "51839": [], "5184": [], "51864": [], "51889": [], "51914": [], "51939": [], "51964": [], "51989": [], "51it": [], "52": [], "52014": [], "52039": [], "52064": [], "52089": [], "5209": [], "52114": [], "52139": [], "52164": [], "52189": [], "52214": [], "52239": [], "52264": [], "52289": [], "52314": [], "52339": [], "5234": [], "52364": [], "52389": [], "52414": [], "52439": [], "52464": [], "52489": [], "52514": [], "52539": [], "52564": [], "52589": [], "5259": [], "52614": [], "52639": [], "52664": [], "52689": [], "52714": [], "52739": [], "52764": [], "52789": [], "52814": [], "52839": [], "5284": [], "52864": [], "52889": [], "529": [], "52914": [], "52939": [], "52964": [], "52989": [], "52it": [], "53": [], "53014": [], "53039": [], "53064": [], "53089": [], "5309": [], "53114": [], "53139": [], "53164": [], "53189": [], "53214": [], "53239": [], "53264": [], "53289": [], "53314": [], "53339": [], "5334": [], "53364": [], "53389": [], "534": [], "53414": [], "53439": [], "53464": [], "53489": [], "53514": [], "53539": [], "53564": [], "53589": [], "5359": [], "53614": [], "53639": [], "5366": [], "53664": [], "53689": [], "53714": [], "53739": [], "53764": [], "53789": [], "538": [], "53814": [], "53839": [], "5384": [], "53864": [], "53889": [], "53914": [], "53939": [], "53964": [], "53989": [], "53it": [], "54": [], "540": [], "54014": [], "54039": [], "54064": [], "54089": [], "5409": [], "54114": [], "54139": [], "54164": [], "54189": [], "54214": [], "54239": [], "54264": [], "54289": [], "54314": [], "54339": [], "5434": [], "54364": [], "54389": [], "54414": [], "54439": [], "54464": [], "54489": [], "545": [], "54514": [], "54539": [], "54564": [], "54589": [], "5459": [], "54614": [], "54639": [], "54664": [], "54689": [], "54714": [], "54739": [], "54764": [], "54789": [], "548": [], "54814": [], "54839": [], "5484": [], "54864": [], "54889": [], "54914": [], "54939": [], "54964": [], "54989": [], "54it": [], "55": [], "55014": [], "55039": [], "55064": [], "55089": [], "5509": [], "551": [], "55114": [], "55139": [], "55164": [], "55189": [], "55214": [], "55239": [], "55264": [], "55289": [], "55314": [], "55339": [], "5534": [], "55364": [], "55380868": 1, "55389": [], "554": [1, 2], "55414": [], "55439": [], "55464": [], "55489": [], "55514": [], "55539": [], "55564": [], "55589": [], "5559": [], "55614": [], "55639": [], "55664": [], "55689": [], "55714": [], "55739": [], "55764": [], "55789": [], "55814": [], "55839": [], "5584": [], "55864": [], "55889": [], "55914": [], "55939": [], "55964": [], "55989": [], "55it": [], "56": [], "56014": [], "56039": [], "56064": [], "56089": [], "5609": [], "56114": [], "56139": [], "56164": [], "56189": [], "562": [], "56214": [], "56239": [], "56264": [], "56289": [], "56314": [], "56339": [], "5634": [], "56364": [], "56377054": 1, "56389": [], "56414": [], "56439": [], "56464": [], "56489": [], "56514": [], "56539": [], "56564": [], "56589": [], "5659": [], "56614": [], "56639": [], "56664": [], "56689": [], "56714": [], "56739": [], "56764": [], "56789": [], "56814": [], "56839": [], "5684": [], "56864": [], "56889": [], "56914": [], "56939": [], "56964": [], "56989": [], "56it": [], "57": [], "57014": [], "57039": [], "57064": [], "57089": [], "5709": [], "57114": [], "57139": [], "57164": [], "57189": [], "57214": [], "57239": [], "57264": [], "57289": [], "57314": [], "57339": [], "5734": [], "57364": [], "57389": [], "57414": [], "57439": [], "57464": [], "57489": [], "57514": [], "57539": [], "57564": [], "57589": [], "5759": [], "57614": [], "57639": [], "57664": [], "57689": [], "57714": [], "57739": [], "57747976": 1, "57764": [], "57789": [], "57814": [], "57839": [], "5784": [], "57864": [], "57889": [], "57914": [], "57939": [], "57964": [], "57989": [], "57it": [], "58": [], "58014": [], "58039": [], "58064": [], "5808": [], "58089": [], "5809": [], "58114": [], "58139": [], "58164": [], "58189": [], "58214": [], "58239": [], "58264": [], "58289": [], "58314": [], "58339": [], "5834": [], "58364": [], "58389": [], "58414": [], "58439": [], "58464": [], "58489": [], "58514": [], "58539": [], "58564": [], "58589": [], "5859": [], "586": [], "58614": [], "58639": [], "58664": [], "58689": [], "58714": [], "58739": [], "58764": [], "58789": [], "58814": [], "58839": [], "5884": [], "58864": [], "58889": [], "58914": [], "58939": [], "58964": [], "58989": [], "58it": [], "59": [], "59014": [], "59039": [], "59064": [], "59089": [], "5909": [], "59114": [], "59139": [], "59164": [], "59189": [], "59214": [], "59239": [], "59264": [], "59289": [], "59314": [], "59339": [], "5934": [], "59364": [], "59389": [], "59414": [], "59439": [], "59464": [], "59489": [], "59514": [], "59539": [], "59564": [], "59589": [], "5959": [], "59614": [], "59639": [], "59664": [], "59689": [], "59714": [], "59739": [], "59764": [], "59789": [], "59814": [], "59839": [], "5984": [], "59864": [], "59889": [], "59914": [], "59939": [], "59964": [], "59989": [], "59it": [], "6": [1, 2], "60": [], "60014": [], "60039": [], "60064": [], "60089": [], "6009": [], "60114": [], "60139": [], "60164": [], "60189": [], "60214": [], "60239": [], "60264": [], "60289": [], "60314": [], "60339": [], "6034": [], "60364": [], "60389": [], "60414": [], "60439": [], "60464": [], "60489": [], "60514": [], "60539": [], "60564": [], "60589": [], "6059": [], "60614": [], "60639": [], "60664": [], "60689": [], "60714": [], "60739": [], "60764": [], "60789": [], "60814": [], "60839": [], "6084": [], "60864": [], "60889": [], "60914": [], "60939": [], "60964": [], "60989": [], "60it": [], "61": [], "610": [], "61014": [], "61039": [], "61064": [], "61089": [], "6109": [], "61114": [], "61139": [], "61164": [], "61189": [], "61214": [], "61232694": 1, "61239": [], "61264": [], "61289": [], "61314": [], "61339": [], "6134": [], "61364": [], "61389": [], "614": [], "61414": [], "6143": [], "61439": [], "61464": [], "61489": [], "61514": [], "61539": [], "61564": [], "61589": [], "6159": [], "61614": [], "61639": [], "61664": [], "61689": [], "61714": [], "61739": [], "61764": [], "61789": [], "61814": [], "61839": [], "6184": [], "61864": [], "61889": [], "61914": [], "61939": [], "61964": [], "61989": [], "61it": [], "62": [], "62014": [], "62039": [], "62064": [], "62089": [], "6209": [], "62114": [], "62139": [], "62164": [], "62189": [], "62214": [], "62239": [], "62264": [], "62289": [], "62314": [], "62339": [], "6234": [], "62364": [], "62377674e": [], "62389": [], "62414": [], "62439": [], "62464": [], "62489": [], "62514": [], "62539": [], "62564": [], "62589": [], "6259": [], "62614": [], "62639": [], "62664": [], "62689": [], "62714": [], "62739": [], "62764": [], "62789": [], "62814": [], "62839": [], "6284": [], "62864": [], "62889": [], "62914": [], "62939": [], "62964": [], "62989": [], "62it": [], "63": [], "63014": [], "63039": [], "63064": [], "63089": [], "6309": [], "63114": [], "63139": [], "63164": [], "63189": [], "63214": [], "63239": [], "63264": [], "63289": [], "63314": [], "63339": [], "6334": [], "63364": [], "63389": [], "634": [], "63414": [], "63439": [], "63464": [], "63489": [], "63514": [], "63539": [], "63564": [], "63589": [], "6359": [], "63614": [], "63639": [], "63664": [], "63665090e": [], "63689": [], "63714": [], "63739": [], "63764": [], "63789": [], "63814": [], "63839": [], "6384": [], "63864": [], "63889": [], "63914": [], "63939": [], "63964": [], "63989": [], "63it": [], "64": [], "64014": [], "64039": [], "64064": [], "64089": [], "6409": [], "64114": [], "64139": [], "64164": [], "64189": [], "64214": [], "64239": [], "64264": [], "64289": [], "64314": [], "64339": [], "6434": [], "64364": [], "64389": [], "64414": [], "64439": [], "64464": [], "64489": [], "64514": [], "64539": [], "64564": [], "64589": [], "6459": [], "64614": [], "64639": [], "64664": [], "64689": [], "64713": [], "64737": [], "64761": [], "64785": [], "64809": [], "64833": [], "6484": [], "64857": [], "64881": [], "64906": [], "64931": [], "64956": [], "64981": [], "64it": [], "65": [], "65006": [], "65031": [], "65056": [], "6508": [], "65081": [], "65106": [], "65131": [], "65156": [], "65181": [], "65206": [], "65231": [], "65256": [], "65281": [], "65306": [], "6532": [], "65331": [], "65356": [], "65381": [], "65406": [], "65431": [], "65456": [], "65481": [], "65506": [], "65531": [], "65556": [], "6556": [], "65581": [], "65606": [], "65631": [], "65656": [], "65681": [], "65706": [], "65731": [], "65756": [], "65781": [], "658": [], "6580": [], "65806": [], "65831": [], "65856": [], "65881": [], "65906": [], "65931": [], "65956": [], "65981": [], "65it": [], "66": [], "66006": [], "66031": [], "6604": [], "66056": [], "66081": [], "66106": [], "66131": [], "66156": [], "66181": [], "66206": [], "66231": [], "66256": [], "6628": [], "66281": [], "66306": [], "66331": [], "66356": [], "66381": [], "66406": [], "66431": [], "66456": [], "66481": [], "66506": [], "6652": [], "66531": [], "66556": [], "66581": [], "66606": [], "66631": [], "66656": [], "66681": [], "66706": [], "66731": [], "66756": [], "6676": [], "66781": [], "66806": [], "66831": [], "66856": [], "66881": [], "66906": [], "66931": [], "66956": [], "66981": [], "66it": [], "67": [], "67006": [], "6701": [], "67031": [], "67056": [], "67081": [], "67106": [], "67131": [], "67156": [], "67170996": 1, "67181": [], "67206": [], "67231": [], "67256": [], "6726": [], "67281": [], "67306": [], "67331": [], "67356": [], "67381": [], "67406": [], "67431": [], "67456": [], "67481": [], "67506": [], "6751": [], "67531": [], "67556": [], "67581": [], "67606": [], "67631": [], "67656": [], "67681": [], "67706": [], "67731": [], "67756": [], "6776": [], "6777": [], "67781": [], "67806": [], "67831": [], "67856": [], "67881": [], "67906": [], "67931": [], "67956": [], "67981": [], "67it": [], "68": [], "68006": [], "6801": [], "68031": [], "68056": [], "68081": [], "68106": [], "68131": [], "68156": [], "68181": [], "682": [], "68206": [], "68231": [], "68256": [], "6826": [], "68281": [], "683": [], "68306": [], "68331": [], "68356": [], "68381": [], "68406": [], "68431": [], "68456": [], "68481": [], "68506": [], "6851": [], "68531": [], "68556": [], "68581": [], "68606": [], "68631": [], "68656": [], "68681": [], "68705": [], "68729": [], "68754": [], "6876": [], "68778": [], "68803": [], "68828": [], "68853": [], "68878": [], "68903": [], "68928": [], "68953": [], "68978": [], "68it": [], "69": [], "69003": [], "6901": [], "69028": [], "69053": [], "69078": [], "69103": [], "69128": [], "69153": [], "69178": [], "69203": [], "69228": [], "69253": [], "6926": [], "69278": [], "69303": [], "69328": [], "69353": [], "69378": [], "69403": [], "69428": [], "69453": [], "69478": [], "69503": [], "6951": [], "69528": [], "69552": [], "69577": [], "69602": [], "69627": [], "69652": [], "69677": [], "69702": [], "69727": [], "69752": [], "6976": [], "69777": [], "69802": [], "69827": [], "69852": [], "69877": [], "69902": [], "69927": [], "69952": [], "69977": [], "69it": [], "7": [1, 2], "70": [], "70002": [], "7001": [], "70027": [], "70052": [], "70077": [], "70102": [], "70127": [], "70152": [], "70177": [], "70202": [], "70227": [], "70252": [], "7026": [], "70277": [], "70302": [], "70327": [], "70352": [], "70377": [], "70402": [], "70427": [], "70452": [], "70477": [], "70502": [], "7051": [], "70522314": 1, "70527": [], "70552": [], "70577": [], "70602": [], "70627": [], "70652": [], "70677": [], "707": 1, "70702": [], "70727": [], "70752": [], "7076": [], "70777": [], "70802": [], "70827": [], "70852": [], "70877": [], "70902": [], "70927": [], "70952": [], "70977": [], "70it": [], "71": [], "71002": [], "7101": [], "71027": [], "71052": [], "71077": [], "71102": [], "71127": [], "71152": [], "71177": [], "71202": [], "71227": [], "71252": [], "7126": [], "71277": [], "71302": [], "71327": [], "71352": [], "71377": [], "71402": [], "71412501": 1, "71427": [], "71452": [], "71477": [], "71502": [], "7151": [], "71527": [], "71552": [], "71577": [], "71602": [], "71627": [], "71652": [], "71677": [], "71702": [], "71727": [], "71752": [], "7176": [], "71777": [], "71802": [], "71827": [], "71852": [], "71877": [], "71902": [], "71927": [], "71950039": 1, "71952": [], "71977": [], "71it": [], "72": [], "72002": [], "7201": [], "72027": [], "72052": [], "72077": [], "72102": [], "72127": [], "72152": [], "72177": [], "72202": [], "72227": [], "72252": [], "7226": [], "72277": [], "72302": [], "72327": [], "72352": [], "72377": [], "72402": [], "72427": [], "72452": [], "72477": [], "72502": [], "7251": [], "72527": [], "72552": [], "72577": [], "72602": [], "72627": [], "72652": [], "72677": [], "72702": [], "72727": [], "72752": [], "7276": [], "72777": [], "72802": [], "72827": [], "72852": [], "72877": [], "72902": [], "72927": [], "72952": [], "72977": [], "72it": [], "73": [], "73002": [], "7301": [], "73027": [], "73052": [], "73077": [], "73102": [], "73127": [], "73143792": 1, "73152": [], "73177": [], "732": [], "73202": [], "73227": [], "73252": [], "7326": [], "73277": [], "73302": [], "73327": [], "73352": [], "73377": [], "73402": [], "73427": [], "73452": [], "73477": [], "73502": [], "7351": [], "73527": [], "73552": [], "73577": [], "73602": [], "73627": [], "73652": [], "73677": [], "73702": [], "73727": [], "73752": [], "7376": [], "73777": [], "73802": [], "73827": [], "73852": [], "73877": [], "73902": [], "73927": [], "73952": [], "73977": [], "73it": [], "74": [], "74002": [], "7401": [], "74027": [], "74052": [], "74077": [], "74102": [], "74127": [], "74152": [], "74177": [], "74202": [], "74227": [], "74252": [], "7426": [], "74277": [], "74302": [], "74327": [], "74352": [], "74377": [], "74402": [], "74427": [], "74452": [], "74477": [], "74502": [], "7451": [], "74527": [], "74552": [], "74577": [], "74602": [], "74627": [], "74652": [], "74677": [], "74702": [], "74727": [], "74752": [], "7476": [], "74777": [], "74802": [], "74827": [], "74852": [], "74877": [], "74902": [], "74924": [], "74it": [], "75": [], "7501": [], "7526": [], "7551": [], "757": [], "7576": [], "75it": [], "76": [], "7601": [], "7626": [], "7651": [], "7676": [], "76it": [], "77": [], "7701": [], "7726": [], "7751": [], "7776": [], "77it": [], "78": [], "7801": [], "781": [], "7826": [], "7851": [], "7876": [], "78it": [], "79": [], "7901": [], "7926": [], "79269019e": [], "79385889": 1, "7951": [], "7976": [], "79it": [], "8": [1, 2], "80": [], "8001": [], "8026": [], "8051": [], "806": [], "8076": [], "80it": [], "81": [], "8101": [], "8126": [], "8151": [], "8176": [], "81it": [], "82": [], "8201": [], "8226": [], "8251": [], "8276": [], "82it": [], "83": [], "8301": [], "831": [], "8326": [], "83293024e": [], "83298071e": [], "8351": [], "8376": [], "83it": [], "84": [], "8401": [], "8426": [], "8451": [], "84759970e": [], "8476": [], "84it": [], "85": [], "8501": [], "8526": [], "8551": [], "856": [], "8576": [], "85866790e": [], "85it": [], "86": [], "8601": [], "86203436": 1, "8626": [], "8651": [], "866": [2, 4, 8], "8676": [], "86it": [], "87": [], "8701": [], "8726": [], "8751": [], "8776": [], "87it": [], "88": [], "8801": [], "881": 2, "8826": [], "8851": [], "8876": [], "88789961": 1, "888": [], "88it": [], "89": [], "8901": [], "8926": [], "89484241": 1, "8951": [], "8976": [], "89it": [], "9": [2, 7], "90": [], "9001": [], "9026": [], "9051": [], "906": [], "9076": [], "909": 2, "90it": [], "91": [], "9101": [], "9126": [], "915": [], "9151": [], "9176": [], "91it": [], "92": [], "9201": [], "9226": [], "9251": [], "9276": [], "92it": [], "93": [], "9301": [], "931": [], "9326": [], "9351": [], "9376": [], "93980442": 1, "93it": [], "94": [], "9401": [], "9426": [], "94322073": 1, "9451": [], "9476": [], "94it": [], "95": [], "9501": [], "95192796e": [], "9526": [], "9551": [], "956": [], "9576": [], "95it": [], "96": [], "9601": [], "9626": [], "9651": [], "9676": [], "96it": [], "97": [], "9701": [], "9726": [], "9751": [], "97635144e": [], "9776": [], "9780444594365": 0, "97it": [], "98": [], "9801": [], "981": [], "9826": [], "9851": [], "9876": [], "98it": [], "99": [], "9901": [], "9926": [], "9951": [], "9976": [], "99it": [], "A": [0, 5], "ASE": [7, 9], "BE": 0, "By": 0, "For": [0, 5], "If": 0, "In": [0, 1, 2, 5], "It": [0, 3, 5], "NOT": 0, "On": [], "The": [0, 1, 2, 3], "Then": 7, "These": 0, "To": 0, "_area": 0, "_cg": 0, "_function": 0, "_ins_index": 0, "_l": 0, "_norm": 0, "_of": 0, "_per": 0, "_radial": 0, "_radialbasi": 0, "_validate_data": 2, "a1": 2, "a2": 2, "a3": 2, "abil": 5, "abov": 0, "accept": 0, "access": 0, "account": 0, "accru": [], "across": 0, "activ": [6, 7], "actual": 0, "add": 1, "addit": 0, "address": 6, "advanc": 0, "afram": 2, "after": 0, "aggreg": 0, "aim": 6, "aka": [5, 7], "algorithm": 0, "alin62": [1, 2], "all": [0, 1, 2, 3, 8], "allclos": 1, "allow": 0, "alpha": 2, "alpha_": 2, "also": 3, "alwai": 0, "amount": 1, "an": [0, 3, 7], "analysi": 0, "analyt": 0, "angular": 0, "ani": 0, "anisoap": [0, 2, 3, 4, 5, 8, 9], "anisoap_hyp": [1, 2], "anisotrop": 6, "anlm": 0, "api": [2, 6], "appear": 0, "appli": 0, "appropri": 0, "ar": [0, 1, 2, 3, 5], "arang": 2, "arbitrari": 1, "around": 0, "arrai": [0, 1, 2], "array_lik": 0, "as_quat": 1, "ase": [0, 1, 2, 3, 5], "aspher": 6, "assum": [0, 1, 2], "atol": 1, "atom": [0, 1, 2, 3, 5, 6, 7], "atom_fram": 2, "atomist": 1, "attach": 1, "attribut": 0, "auto": 1, "auto_exampl": 4, "auto_examples_jupyt": 3, "auto_examples_python": 3, "automat": 0, "ax": 0, "bar": 0, "base": [0, 1, 2], "baseestim": 2, "basi": [0, 5], "basis_rcond": [0, 1, 2], "basis_tol": [0, 1, 2], "becaus": 0, "becom": 2, "been": 0, "befor": [0, 5, 7], "being": [0, 3, 5], "below": [0, 2], "benzen": [1, 3, 4, 8], "between": 0, "bin": 2, "bit": 0, "bitwis": 0, "block": 0, "bodi": 5, "booksit": 0, "bool": 0, "both": 0, "bound": 0, "boundari": 1, "braket": 0, "c_diamet": [0, 1, 2], "c_q": [0, 1, 2], "cach": 0, "calc_overlap_matrix": 0, "calcul": [0, 1, 2], "call": 0, "can": [0, 1, 3, 5, 7], "cannot": [0, 1], "cartesian": 0, "case": [0, 1], "cd": 7, "cell": 1, "center": 0, "central": [0, 5], "cersonski": 7, "cg": 0, "cg_combin": [0, 2], "cgrcachelist": 0, "channel": 0, "check": 0, "chemic": 6, "chief": 5, "choic": 5, "choos": 1, "class": 0, "clear_cach": 0, "clebsch": 0, "clebsch_gordan": 0, "clebschgordanr": [0, 2], "clock": 0, "clone": 7, "coars": [1, 3, 6], "code": [0, 1, 2, 3], "coeffici": 0, "collect": 3, "column": 2, "column_wis": 2, "com": [0, 7], "combin": 0, "compactli": 5, "compon": 0, "comput": [0, 2], "compute_gradi": 0, "compute_moments_diagonal_inefficient_implement": 0, "compute_moments_inefficient_implement": 0, "compute_moments_single_vari": 0, "concept": 6, "conceptu": 0, "conda": 7, "condit": 1, "consid": [0, 5], "consist": [0, 6], "constant": 0, "constructor": 1, "contact": 6, "contain": [0, 1, 2], "contract": [], "contract_pairwise_feat": 0, "contribut": 0, "convert": [1, 2], "copi": [0, 7], "correspond": 0, "cost": 0, "coupl": 0, "covari": 0, "creat": [3, 4, 5, 6, 8], "crystal": 3, "current": [0, 3], "custom": 0, "cut": 0, "cutoff": 0, "cutoff_radiu": [0, 1, 2], "cv": 2, "cyclic_list": 0, "d": 0, "data": [0, 1, 2], "dataset": 0, "decompos": 5, "decomposit": 2, "default": 0, "defin": 0, "deg": 0, "degre": 0, "demonstr": [1, 2, 3], "densiti": [0, 5], "depend": [0, 5, 6], "deprec": [0, 2], "descriptor": [0, 6], "desir": 0, "determin": 0, "develop": [2, 3, 6, 7], "diagon": 0, "diamet": [], "dict": 0, "dictionari": 1, "did": 1, "differ": [0, 5], "dilat": 0, "dim": 0, "dimens": [0, 1], "dimension": 0, "directori": 7, "distinct": 0, "distribut": 0, "dive": 5, "divid": 0, "do": [0, 2], "document": [1, 2], "doe": 0, "doubl": 0, "download": [0, 1, 2, 3], "dr": 0, "dx": 0, "dy": 0, "dz": 0, "e": [0, 1], "each": [0, 1, 5], "eff": 0, "effect": 0, "effici": 0, "eigenvalu": 0, "either": 0, "element": 0, "ellipsoid": [0, 2, 3, 4, 5, 8], "ellipsoid_length": 0, "ellipsoidal_density_project": [0, 1, 2], "ellipsoidaldensityproject": [0, 1, 2], "elsevi": 0, "empti": 0, "en": 0, "end": [0, 1, 2], "energi": [3, 4, 8], "energy_pa": 2, "ensur": [0, 7], "entri": 0, "enumer": 0, "env": 2, "environ": [5, 7], "equal": 0, "equat": 0, "equivari": 0, "ev": 2, "evalu": 0, "everi": 0, "exact": 0, "exampl": [0, 4, 5, 6, 8], "example01_invariances_of_powerspectrum_test": [1, 4, 8], "example02_learn_benzen": [2, 4, 8], "execut": [4, 8], "exist": 0, "exp": 0, "expans": 0, "expon": 0, "express": 0, "extend": 6, "f": [0, 1, 2], "factor": 0, "fals": [0, 2], "familiar": 5, "featom": [5, 7], "featur": 0, "feature_gradi": 0, "feature_nam": 0, "features_gradi": 0, "field": 5, "figsiz": 2, "figur": 2, "file": [1, 2, 4, 8], "find": 0, "find_idx": 0, "first": [0, 1, 6], "first_atom": 0, "fit": 2, "fit_intercept": 2, "fix": 0, "flag": 0, "float": 0, "focus": 0, "follow": 7, "form": [0, 5], "format": [1, 2], "found": 0, "frac": 0, "frame": [0, 2, 3, 4, 8], "frame1": 1, "frame2": 1, "frame_to_global_atom_idx": 0, "frames_rot": 1, "frames_transl": 1, "from": [0, 2, 3, 4, 7, 8], "from_quat": 1, "front": 0, "full": [0, 1, 2], "fulli": 0, "function": [0, 2, 5], "futur": 0, "futurewarn": 2, "galleri": [1, 2, 3, 8], "gamma": 0, "gaussian": [0, 5], "gener": [0, 1, 2, 3], "geometr": 5, "get": [0, 6], "get_basi": 0, "get_num_radial_funct": 0, "get_posit": 1, "get_val": 0, "git": 7, "github": 7, "given": 0, "global": 0, "global_factor": 0, "global_reconstruction_error": 2, "go": [1, 2], "gordan": 0, "gradient": 0, "grain": [1, 3, 6], "gram": 0, "gre": 2, "gto": [0, 1, 2], "gto_overlap": 0, "gto_prefactor": 0, "gto_square_norm": 0, "gtoradialbasi": 0, "ha": 0, "hand": 0, "harmon": [0, 5], "have": [0, 7], "heavili": 9, "help": 5, "henc": 0, "here": [0, 1, 2, 3, 6], "higher": 7, "hist": 2, "how": [1, 2, 3], "html": [], "http": [0, 7], "hyper": 1, "hyperparamet": 0, "i": [0, 1, 2, 3, 5, 6, 7], "i_test": 2, "i_train": 2, "ideal": 2, "idx": 0, "ij": 0, "immedi": 0, "implement": 0, "import": [1, 2], "increas": 0, "index": 0, "indexerror": 0, "indic": 0, "info": 2, "inform": [1, 5], "infti": 0, "initi": 0, "inner": 0, "input": [0, 2], "insert": 0, "instal": 6, "instanc": 0, "instanti": 0, "instead": [0, 2], "instruct": 0, "int": 0, "int_": 0, "int_0": 0, "integ": 0, "integr": 0, "interact": [5, 6], "intern": 7, "interoper": 9, "interpret": 0, "interv": 0, "introduct": 6, "intuit": 0, "invari": [1, 3], "invers": 0, "inverse_matrix_sqrt": 0, "inverse_sqrt_matrix": 0, "inverse_transform": 2, "inversion_sigma": 0, "involv": 0, "io": [1, 2], "ipynb": [1, 2], "iter": 0, "itertool": [], "its": [0, 5], "itself": 0, "j": 0, "jupyt": [1, 2, 3], "just": 1, "keep": 0, "kei": [0, 6], "kwarg": 0, "l": 0, "l_": 0, "l_max": 0, "lab": 7, "label": 0, "langl": 0, "last": 0, "later": 1, "lcut": 0, "lead": 0, "learn": [3, 4, 6, 8], "learnabl": 5, "least": 0, "left": 0, "legend": [1, 2], "len": [1, 2], "length": 0, "less": 0, "lexicograph": 0, "lib": 2, "librari": [6, 7], "like": [0, 7], "line": 0, "line2d": [], "linear": [2, 3], "linear_model": 2, "link": 0, "linspac": [], "list": [0, 1], "lm": 0, "lmax": [0, 1, 2], "load": [1, 2], "local": 5, "locat": 7, "lodwin": 0, "logspac": 2, "loop": 0, "lowdin": 0, "lower": 0, "lr": 2, "lvert": 0, "m": 0, "machin": [3, 4, 5, 6, 8], "made": [0, 1], "mai": [0, 3, 5, 7], "main": 7, "make": [0, 7], "manag": 7, "mani": 5, "match": 0, "mathbf": 0, "mathemat": 0, "matplotlib": [1, 2], "matric": 0, "matrix": [0, 5], "matter": 0, "max": [0, 2], "max_angular": [0, 1, 2], "max_radi": [0, 1, 2], "maxdeg": 0, "maximum": 0, "mb": [4, 8], "mean": 0, "mean_over_sampl": 0, "mem": [4, 8], "memori": 0, "merg": 0, "mesh": 0, "metatensor": [0, 2, 5, 7, 9], "metatensor_util": 0, "method": 0, "metric": 2, "mimic": 0, "min": 2, "miniconda3": 2, "minim": 3, "minut": [1, 2], "mode": [1, 2], "model": [0, 1, 2], "model_select": 2, "modifi": 0, "molecul": 1, "moment": 0, "moment_gener": 0, "monomi": 0, "monomial_iter": 0, "monomial_overlap": 0, "monomial_prefactor": 0, "monomial_square_norm": 0, "monomialbasi": 0, "monomni": 0, "more": [0, 3], "most": 0, "much": 0, "multipli": 0, "multivari": [0, 5], "must": 0, "mvg": 5, "mvg_nu2": 0, "myiter": 0, "n": [0, 5], "n0": 0, "n1": 0, "n2": 0, "n_": 0, "n_0": 0, "n_1": 0, "n_2": 0, "n_featur": 0, "n_r": 0, "n_sampl": 0, "name": 0, "navig": 7, "nbviewer": [], "ndarrai": 0, "nearbi": 5, "need": 0, "neighbor": 0, "neighbor_list": 0, "neighbor_speci": 0, "neighborlist": 0, "new": [0, 1], "nmax": [0, 1, 2], "none": 0, "norm": 0, "normal": 0, "note": [0, 2], "notebook": [1, 2, 3, 8], "now": [0, 7], "np": [0, 1, 2], "nu": 0, "num_atom": 0, "num_compon": 0, "num_n": 0, "num_radial_funct": 0, "num_sampl": 0, "number": [0, 1], "number_of_radial_functions_per_l": 0, "numpi": [0, 1, 2, 7], "object": [0, 1, 3], "obtain": 0, "old": 1, "onc": 0, "one": 0, "ones": [1, 2], "onli": 0, "oper": 0, "option": 0, "order": [0, 5], "order_nu": 0, "org": 0, "orient": [0, 1], "origin": 0, "orthonorm": 0, "orthonormalize_basi": 0, "other": 0, "other_keys_match": 0, "otherwis": 0, "our": 0, "outer": 0, "output": 0, "over": 0, "overlap": [0, 5, 6], "overrid": 0, "packag": [2, 5, 7], "page": 0, "page_replacement_algorithm": 0, "pair": 0, "pair_ellip_feat": 0, "pair_ellip_feat_feat": 0, "pairwis": 0, "pairwise_ellip_expans": 0, "paramet": 0, "parent": 0, "pariti": 2, "part": 2, "particl": [1, 5, 6], "pass": [0, 1], "past": 7, "pbc": [0, 1], "pca": 2, "pdf": 0, "per": [0, 2], "perform": [0, 2], "period": 1, "phi_i": 0, "phi_j": 0, "phi_m": 0, "phi_n": 0, "pi": 0, "pickl": 2, "pip": 7, "place": 0, "pleas": [6, 7], "plot": [0, 1, 2], "plot_basi": 0, "plt": [1, 2], "point": 0, "polynomi": 0, "popular": 6, "port": 0, "posit": [0, 1, 6], "possibl": 0, "postion": 1, "potenti": 5, "power": [0, 1], "power_spectrum": [0, 1, 2], "power_spectrum_rot": 1, "power_spectrum_transl": 1, "precomput": 0, "predict": 2, "prefact_minus1": 0, "prefact_minus2": 0, "prefactor": 0, "prepar": 2, "preprocess": [1, 2], "present": 0, "preserv": 5, "princip": 0, "principal_compon": 0, "print": [1, 2], "privat": 0, "probabl": 0, "proceed": 0, "process": 0, "product": 0, "progress": [0, 6], "project": [0, 6], "proper": 0, "properli": 7, "properti": 0, "prove": 3, "provid": 0, "public": 2, "py": [1, 2, 4, 8], "pyplot": [1, 2], "pytest": 7, "python": [0, 1, 2, 3, 6, 7], "python3": 2, "q_rotat": 1, "quaternion": [0, 1, 2], "question": [0, 6], "r": [0, 1, 2], "r_": 0, "r_cut": 0, "radial": [0, 5], "radial_basi": 0, "radial_basis_nam": [0, 1, 2], "radial_gaussian_width": [0, 1, 2], "radialbasi": 0, "radiu": 0, "rais": 0, "random": 1, "rang": 0, "rangl": 0, "rascalin": [2, 5, 7], "rc": 2, "rcond": 0, "reach": 0, "read": [1, 2], "realiti": 1, "reccommend": 7, "recent": 0, "reciproc": 0, "recommend": 7, "reconstruct": 0, "recurs": 0, "reduc": 0, "refer": 6, "regress": [2, 3], "regular": 2, "relat": 0, "remov": 2, "render": [], "repeat": 0, "replac": 0, "repres": [1, 5], "represent": [1, 2, 5, 6], "requir": [0, 2], "rerun": [], "research": [1, 2], "reset": 0, "reshap": 2, "respect": 0, "result": 0, "retain": 0, "return": 0, "rho_": 0, "rho_i": 0, "ridgecv": 2, "ridgecvifittedridgecv": [], "right": 0, "root": 0, "rotat": [0, 1, 3], "rotation_kei": [0, 1, 2], "rotation_matric": 0, "rotation_typ": [0, 1, 2], "rtol": 1, "run": [1, 2, 7], "rust": [0, 7], "rust_moment": 0, "rustup": 7, "rvert": 0, "s_": 0, "sacrif": 0, "same": [0, 1], "sampl": 0, "save": 1, "scalar_first": 1, "scale": 0, "scatter": 2, "scheme": 0, "scikit": 2, "scipi": [1, 7], "score": 2, "script": [1, 2], "second": [0, 1, 2], "second_atom": 0, "see": 0, "seen": 0, "self": 0, "semiax": 2, "set": 0, "set_posit": 1, "shape": 0, "shell": 7, "should": [0, 1], "show": [0, 1, 2], "show_progress": 0, "shuffl": 2, "side": 0, "sigma": 0, "sigma_": 0, "sigma_m": 0, "sigma_n": 0, "signific": 0, "similarli": 5, "simpl": 0, "simpli": 0, "simplic": 0, "simul": 7, "sinc": 0, "singl": [0, 5], "site": 2, "size": 0, "sklearn": 2, "skmatter": [1, 2], "slice": 0, "smooth": [5, 6], "so": [0, 7], "soap": [5, 6], "soappowerspectrum": 2, "solid": 0, "solut": 0, "some": [0, 1, 5, 7], "someth": 0, "sort": 0, "sourc": [1, 2, 3], "spars": 0, "spatial": 1, "speci": 0, "special": 0, "specif": 0, "specifi": [0, 1], "spectrum": [0, 1], "speed": 0, "sph_to_cart": 0, "spheric": [0, 5], "spherical_harmonics_l": 0, "spherical_to_cartesian": 0, "sphinx": [1, 2, 3], "sphinx_gallery_thumbnail_numb": 2, "split": 2, "sqrt": 0, "squar": 0, "square_norm_area": 0, "stai": 3, "standard": [0, 2], "standardflexiblescal": [1, 2], "standardize_kei": [0, 2], "start": 6, "step": [0, 6], "still": 7, "store": [0, 1], "string": 0, "subclass": 0, "subtract": 0, "subtract_center_contribut": [0, 2], "suitabl": 6, "sum": 0, "sum_": 0, "sum_over_sampl": 0, "suppos": 0, "sure": 7, "sy": [], "symbol": 1, "symmetr": 0, "system": [0, 5, 6], "t": [0, 1], "t_": 0, "take": 0, "taken": 0, "techniqu": 0, "tensor": 0, "tensorblock": [], "tensormap": 0, "term": [0, 5], "test": [2, 6], "text": 0, "th": 0, "thei": 1, "theori": 0, "therefor": 0, "thi": [0, 1, 2, 6], "thing": 0, "third": 0, "those": 0, "three": 0, "through": 3, "time": [1, 2], "tol": 0, "toler": 0, "total": [1, 2, 4, 8], "tqdm": 1, "train": 2, "train_siz": 2, "train_test_split": 2, "transform": [0, 1, 2], "translat": [1, 3], "translation_vector": 1, "treat": 5, "trivari": 0, "trivariatemonomialindic": 0, "true": [0, 1, 2], "trust": [], "try": [], "tune": 3, "tupl": 0, "turn": 2, "tutori": 3, "two": [0, 1], "type": 0, "types_1": 0, "types_2": 0, "types_cent": 0, "u": 6, "unabl": [], "unaggreg": 0, "under": [0, 6, 7], "underli": [0, 1], "unnorm": 0, "until": 0, "unus": 0, "up": [0, 1], "us": [0, 1, 2, 3, 6, 7], "usag": 6, "user": [1, 2], "userwarn": [1, 2], "util": [2, 5, 6], "valid": 2, "validate_data": 2, "valu": 0, "variabl": 0, "varianc": 0, "vector": [0, 2, 3, 4, 5, 8], "vectori": 0, "version": 0, "via": 0, "w": [1, 2], "wai": 5, "want": [0, 7], "warn": [1, 2], "wast": 0, "we": [0, 1, 2, 5, 7], "when": 0, "where": [0, 7], "whether": 0, "which": [0, 1], "while": 0, "whose": 0, "width": 0, "wiki": 0, "wikipedia": 0, "wish": 0, "without": 0, "work": [0, 5, 6, 7], "world": [], "would": [1, 7], "wrap": 0, "write": 1, "written": 0, "x": [0, 1, 2], "x_": 0, "x_a": 0, "x_anisoap": [], "x_anisoap_raw": 2, "x_anisoap_scalar": [], "x_asoap_raw": 0, "x_b": 0, "x_test": 2, "x_test_scal": 2, "x_train": 2, "x_train_scal": 2, "xlabel": 2, "xx": 1, "xxx": 1, "xyz": [1, 2], "y": [0, 1, 2], "y_": 0, "y_scalar": [], "y_test": 2, "y_test_scal": 2, "y_train": 2, "y_train_scal": 2, "yet": 6, "yield": 0, "ylabel": 2, "you": [0, 1, 7], "your": 7, "yourself": 5, "z": [0, 1, 2], "zero": 0, "zip": [1, 2, 3]}, "titles": ["API Reference", "Example 1: Creating AniSOAP vectors from ellipsoidal frames.", "Example 2: Machine-learning benzene energies.", "Examples", "Computation times", "Getting Started", "Welcome to AniSOAP\u2019s documentation!", "Installation", "Computation times", "Usage"], "titleterms": {"": 6, "1": 1, "2": 2, "anisoap": [1, 6, 7], "api": 0, "benzen": 2, "comput": [4, 8], "concept": 5, "content": 6, "creat": 1, "depend": 7, "document": 6, "ellipsoid": 1, "energi": 2, "exampl": [1, 2, 3], "first": 5, "frame": 1, "from": 1, "get": 5, "hello": [], "instal": 7, "introduct": 5, "kei": 5, "learn": 2, "machin": 2, "print": [], "refer": 0, "represent": 0, "section": [], "start": 5, "step": 5, "test": 7, "time": [4, 8], "usag": 9, "util": 0, "vector": 1, "welcom": 6}}) \ No newline at end of file diff --git a/docs/build/html/usage.html b/docs/build/html/usage.html new file mode 100644 index 0000000..23aa054 --- /dev/null +++ b/docs/build/html/usage.html @@ -0,0 +1,120 @@ + + + + + + + + + Usage — AniSOAP 0.0.1 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Usage

+

AniSOAP interoperates heavily with ASE and +Metatensor.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 68e0911..7abd6e0 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,6 +1,9 @@ # sphinx dependencies Sphinx==7.2.6 sphinx-rtd-theme==2.0.0 +sphinx-gallery # convert python files into nice documentation +sphinx-tabs # tabs for code examples (one tab per language) + --find-links https://download.pytorch.org/whl/torch_stable.html torch==1.11.0+cpu diff --git a/docs/source/api.rst b/docs/source/api.rst index bcc56fc..9d37fdc 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -14,6 +14,10 @@ Representations Utilities --------- +.. automodule:: anisoap.utils.cyclic_list + :members: + :show-inheritance: + :inherited-members: .. automodule:: anisoap.utils.metatensor_utils :members: :show-inheritance: @@ -26,11 +30,11 @@ Utilities :members: :show-inheritance: :inherited-members: -.. automodule:: anisoap.utils.spherical_to_cartesian +.. automodule:: anisoap.utils.shortcuts :members: :show-inheritance: :inherited-members: -.. automodule:: anisoap.utils.shortcuts +.. automodule:: anisoap.utils.spherical_to_cartesian :members: :show-inheritance: :inherited-members: diff --git a/docs/source/auto_examples/auto_examples_jupyter.zip b/docs/source/auto_examples/auto_examples_jupyter.zip new file mode 100644 index 0000000..d5dded7 Binary files /dev/null and b/docs/source/auto_examples/auto_examples_jupyter.zip differ diff --git a/docs/source/auto_examples/auto_examples_python.zip b/docs/source/auto_examples/auto_examples_python.zip new file mode 100644 index 0000000..05173d7 Binary files /dev/null and b/docs/source/auto_examples/auto_examples_python.zip differ diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.codeobj.json b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.codeobj.json new file mode 100644 index 0000000..8a14c6b --- /dev/null +++ b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.codeobj.json @@ -0,0 +1,511 @@ +{ + "AniSOAP_HYPERS": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "Atoms": [ + { + "is_class": true, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": true, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + } + ], + "EllipsoidalDensityProjection": [ + { + "is_class": true, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": true, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": true, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + } + ], + "R.as_quat": [ + { + "is_class": false, + "is_explicit": false, + "module": "_cython_3_0_11", + "module_short": "_cython_3_0_11", + "name": "cython_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "scipy.spatial.transform.Rotation", + "module_short": "scipy.spatial.transform.Rotation", + "name": "as_quat" + } + ], + "R.from_quat": [ + { + "is_class": true, + "is_explicit": false, + "module": "scipy.spatial.transform._rotation", + "module_short": "scipy.spatial.transform", + "name": "Rotation.from_quat" + }, + { + "is_class": true, + "is_explicit": false, + "module": "scipy.spatial.transform", + "module_short": "scipy.spatial.transform", + "name": "Rotation.from_quat" + }, + { + "is_class": true, + "is_explicit": false, + "module": "scipy.spatial", + "module_short": "scipy.spatial", + "name": "Rotation.from_quat" + }, + { + "is_class": true, + "is_explicit": false, + "module": "scipy", + "module_short": "scipy", + "name": "Rotation.from_quat" + }, + { + "is_class": false, + "is_explicit": false, + "module": "scipy.spatial.transform.Rotation", + "module_short": "scipy.spatial.transform.Rotation", + "name": "from_quat" + } + ], + "calculator": [ + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection" + } + ], + "calculator.power_spectrum": [ + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection.power_spectrum" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection.power_spectrum" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection.power_spectrum" + } + ], + "frame": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + } + ], + "frame.arrays": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "frame.get_positions": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms.get_positions" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms.get_positions" + } + ], + "frame.set_positions": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms.set_positions" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms.set_positions" + } + ], + "frame1": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + } + ], + "frame1.arrays": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "frame2": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + } + ], + "frame2.arrays": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "frames": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "frames_rotation": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "frames_translation": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "lmax": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "nmax": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "np.allclose": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "allclose" + } + ], + "np.array": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "array" + } + ], + "np.ones": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ones" + } + ], + "plt.legend": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "legend" + } + ], + "plt.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "plot" + } + ], + "plt.show": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "show" + } + ], + "power_spectrum": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "power_spectrum.T": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "power_spectrum_rotation": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "power_spectrum_translated": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "q_rotation": [ + { + "is_class": false, + "is_explicit": false, + "module": "scipy.spatial.transform._rotation", + "module_short": "scipy.spatial.transform", + "name": "Rotation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "scipy.spatial.transform", + "module_short": "scipy.spatial.transform", + "name": "Rotation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "scipy.spatial", + "module_short": "scipy.spatial", + "name": "Rotation" + }, + { + "is_class": false, + "is_explicit": false, + "module": "scipy", + "module_short": "scipy", + "name": "Rotation" + } + ], + "quaternion": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "read": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase.io", + "module_short": "ase.io", + "name": "read" + } + ], + "translation_vector": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ] +} \ No newline at end of file diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.ipynb b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.ipynb new file mode 100644 index 0000000..d8184af --- /dev/null +++ b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.ipynb @@ -0,0 +1,176 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Example 1: Creating AniSOAP vectors from ellipsoidal frames.\nThis example demonstrates:\n\n1. How to read ellipsoidal frames from ``.xyz`` file.\n2. How to convert ellipsoidal frames to AniSOAP vectors.\n3. How to create ellipsoidal frames with ``ase.Atoms``.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from ase.io import read\nfrom ase import Atoms\n\nimport numpy as np\n\nfrom scipy.spatial.transform import Rotation as R\nfrom tqdm.auto import tqdm\nfrom skmatter.preprocessing import StandardFlexibleScaler\n\nfrom anisoap.representations.ellipsoidal_density_projection import (\n EllipsoidalDensityProjection,\n)\n\nimport matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read the first two frames of ellipsoids.xyz, which represent coarse-grained benzene molecules.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "frames = read(\"ellipsoids.xyz\", \"0:2\")\nframes_translation = read(\"ellipsoids.xyz\", \"0:2\")\nframes_rotation = read(\"ellipsoids.xyz\", \"0:2\")\n\nprint(f\"{len(frames)=}\") # a list of atoms objects\nprint(f\"{frames[0].arrays=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, the xyz file did not store ellipsoid dimension information. \n\nWe will add this information here.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "for frame in frames:\n frame.arrays[\"c_diameter[1]\"] = np.ones(len(frame)) * 3.\n frame.arrays[\"c_diameter[2]\"] = np.ones(len(frame)) * 3.\n frame.arrays[\"c_diameter[3]\"] = np.ones(len(frame)) * 1.\n\nprint(f\"{frames[0].arrays=}\")\nprint(f\"{frames[1].arrays=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Specify the hypers to create AniSOAP vector.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lmax = 5\nnmax = 3\n\nAniSOAP_HYPERS = {\n \"max_angular\": lmax,\n \"max_radial\": nmax,\n \"radial_basis_name\": \"gto\",\n \"rotation_type\": \"quaternion\",\n \"rotation_key\": \"c_q\",\n \"cutoff_radius\": 7.0,\n \"radial_gaussian_width\": 1.5,\n \"basis_rcond\": 1e-8,\n \"basis_tol\": 1e-4,\n}\ncalculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the AniSOAP vector (i.e. the power spectrum).\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "power_spectrum = calculator.power_spectrum(frames)\nplt.plot(power_spectrum.T)\nplt.legend([\"frame[0] power spectrum\", \"frame[1] power spectrum\"])\nplt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we will demonstrate translation invariance.\n\nTranslation vector is used to demonstrate the power spectrum of ellipsoidal representations are invariant of translation in positions.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(\"Old Positions:\", frames[0].get_positions(), frames[1].get_positions())\ntranslation_vector = np.array([2.0, 2.0, 2.0])\nfor frame in frames:\n frame.set_positions(frame.get_positions() + translation_vector)\nprint(\"New Positions:\", frames[0].get_positions(), frames[1].get_positions())\npower_spectrum_translated = calculator.power_spectrum(frames)\nprint(f\"{np.allclose(power_spectrum, power_spectrum_translated)=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we demonstrate rotational invariance, rotating all ellipsoids by the same amount.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(\"Old Orientations:\", frames[0].arrays[\"c_q\"], frames[1].arrays[\"c_q\"])\n\nquaternion = [1, 2, 0, -3] # random rotation\nq_rotation = R.from_quat(quaternion, scalar_first=True) \nfor frame in frames:\n frame.arrays[\"c_q\"] = R.as_quat(\n q_rotation * R.from_quat(frame.arrays[\"c_q\"], scalar_first=True),\n scalar_first=True,\n )\nprint(\"New Orientations:\", frames[0].arrays[\"c_q\"], frames[1].arrays[\"c_q\"])\n\npower_spectrum_rotation = calculator.power_spectrum(frames)\nprint(f\"{np.allclose(power_spectrum, power_spectrum_rotation, rtol=1e-2, atol=1e-2)=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's how to create ellipsoidal frames. In this example:\n\n* Each frame contains 2-3 ellipsoids, with periodic boundary conditions.\n* The quaternions(``c_q``) and particle dimensions(``c_diameter[i]``) cannot be passed into the Atoms constructor.\n* They are attached as data in the Atoms.arrays dictionary.\n* I just made up arbitrary postions and orientations. Quaternions should be in (w,x,y,z) format.\n* In reality you would choose positions and orientations based on some underlying atomistic model.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "frame1 = Atoms(symbols='XX', \n positions=np.array([[0., 0., 0.], [2.5, 3., 2.]]),\n cell=np.array([5., 5., 5.,]), \n pbc=True)\nframe1.arrays[\"c_q\"] = np.array([[0., 1., 0., 0.], [0., 0., 1., 0]])\nframe1.arrays[\"c_diameter[1]\"] = np.array([3., 3.])\nframe1.arrays[\"c_diameter[2]\"] = np.array([3., 3.])\nframe1.arrays[\"c_diameter[3]\"] = np.array([1., 1.])\n\nframe2 = Atoms(symbols='XXX', \n positions = np.array([[0., 1., 2.], [2., 3., 4.], [5., 5., 1.]]),\n cell=[10., 10., 10.,], \n pbc=True)\nframe2.arrays[\"c_q\"] = np.array([[0., 1., 0., 0.], [0., 0., 1., 0], [0., 0., 0.707, 0.707]])\nframe2.arrays[\"c_diameter[1]\"] = np.array([3., 3., 3.])\nframe2.arrays[\"c_diameter[2]\"] = np.array([3., 3., 3.])\nframe2.arrays[\"c_diameter[3]\"] = np.array([1., 1., 1.])\n\nframes = [frame1, frame2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can then use ``ase.io.write()``/``ase.io.read()`` to save/load these frames for later use.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py new file mode 100644 index 0000000..ab6e354 --- /dev/null +++ b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py @@ -0,0 +1,150 @@ +# %% +""" +Example 1: Creating AniSOAP vectors from ellipsoidal frames. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to create ellipsoidal frames with ``ase.Atoms``. +""" + +from ase.io import read +from ase import Atoms + +import numpy as np + +from scipy.spatial.transform import Rotation as R +from tqdm.auto import tqdm +from skmatter.preprocessing import StandardFlexibleScaler + +from anisoap.representations.ellipsoidal_density_projection import ( + EllipsoidalDensityProjection, +) + +import matplotlib.pyplot as plt + + +# %% +# Read the first two frames of ellipsoids.xyz, which represent coarse-grained benzene molecules. + +frames = read("ellipsoids.xyz", "0:2") +frames_translation = read("ellipsoids.xyz", "0:2") +frames_rotation = read("ellipsoids.xyz", "0:2") + +print(f"{len(frames)=}") # a list of atoms objects +print(f"{frames[0].arrays=}") + +# %% +# In this case, the xyz file did not store ellipsoid dimension information. +# +# We will add this information here. + +for frame in frames: + frame.arrays["c_diameter[1]"] = np.ones(len(frame)) * 3.0 + frame.arrays["c_diameter[2]"] = np.ones(len(frame)) * 3.0 + frame.arrays["c_diameter[3]"] = np.ones(len(frame)) * 1.0 + +print(f"{frames[0].arrays=}") +print(f"{frames[1].arrays=}") + +# %% +# Specify the hypers to create AniSOAP vector. + +lmax = 5 +nmax = 3 + +AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-4, +} +calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + +# %% +# Create the AniSOAP vector (i.e. the power spectrum). +power_spectrum = calculator.power_spectrum(frames) +plt.plot(power_spectrum.T) +plt.legend(["frame[0] power spectrum", "frame[1] power spectrum"]) +plt.show() + +# %% +# Here we will demonstrate translation invariance. +# +# Translation vector is used to demonstrate the power spectrum of ellipsoidal representations are invariant of translation in positions. +print("Old Positions:", frames[0].get_positions(), frames[1].get_positions()) +translation_vector = np.array([2.0, 2.0, 2.0]) +for frame in frames: + frame.set_positions(frame.get_positions() + translation_vector) +print("New Positions:", frames[0].get_positions(), frames[1].get_positions()) +power_spectrum_translated = calculator.power_spectrum(frames) +print(f"{np.allclose(power_spectrum, power_spectrum_translated)=}") + +# %% +# Here, we demonstrate rotational invariance, rotating all ellipsoids by the same amount. +print("Old Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + +quaternion = [1, 2, 0, -3] # random rotation +q_rotation = R.from_quat(quaternion, scalar_first=True) +for frame in frames: + frame.arrays["c_q"] = R.as_quat( + q_rotation * R.from_quat(frame.arrays["c_q"], scalar_first=True), + scalar_first=True, + ) +print("New Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + +power_spectrum_rotation = calculator.power_spectrum(frames) +print(f"{np.allclose(power_spectrum, power_spectrum_rotation, rtol=1e-2, atol=1e-2)=}") + +# %% +# Here's how to create ellipsoidal frames. In this example: +# +# * Each frame contains 2-3 ellipsoids, with periodic boundary conditions. +# * The quaternions(``c_q``) and particle dimensions(``c_diameter[i]``) cannot be passed into the Atoms constructor. +# * They are attached as data in the Atoms.arrays dictionary. +# * I just made up arbitrary postions and orientations. Quaternions should be in (w,x,y,z) format. +# * In reality you would choose positions and orientations based on some underlying atomistic model. +frame1 = Atoms( + symbols="XX", + positions=np.array([[0.0, 0.0, 0.0], [2.5, 3.0, 2.0]]), + cell=np.array( + [ + 5.0, + 5.0, + 5.0, + ] + ), + pbc=True, +) +frame1.arrays["c_q"] = np.array([[0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0]]) +frame1.arrays["c_diameter[1]"] = np.array([3.0, 3.0]) +frame1.arrays["c_diameter[2]"] = np.array([3.0, 3.0]) +frame1.arrays["c_diameter[3]"] = np.array([1.0, 1.0]) + +frame2 = Atoms( + symbols="XXX", + positions=np.array([[0.0, 1.0, 2.0], [2.0, 3.0, 4.0], [5.0, 5.0, 1.0]]), + cell=[ + 10.0, + 10.0, + 10.0, + ], + pbc=True, +) +frame2.arrays["c_q"] = np.array( + [[0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0], [0.0, 0.0, 0.707, 0.707]] +) +frame2.arrays["c_diameter[1]"] = np.array([3.0, 3.0, 3.0]) +frame2.arrays["c_diameter[2]"] = np.array([3.0, 3.0, 3.0]) +frame2.arrays["c_diameter[3]"] = np.array([1.0, 1.0, 1.0]) + +frames = [frame1, frame2] + +# %% +# You can then use ``ase.io.write()``/``ase.io.read()`` to save/load these frames for later use. diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py.md5 b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py.md5 new file mode 100644 index 0000000..ca36936 --- /dev/null +++ b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.py.md5 @@ -0,0 +1 @@ +2f8297811bae0807c43d0f61504a702b \ No newline at end of file diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.rst b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.rst new file mode 100644 index 0000000..bf7b17a --- /dev/null +++ b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.rst @@ -0,0 +1,337 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/example01_invariances_of_powerspectrum_test.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_example01_invariances_of_powerspectrum_test.py: + + +Example 1: Creating AniSOAP vectors from ellipsoidal frames. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to create ellipsoidal frames with ``ase.Atoms``. + +.. GENERATED FROM PYTHON SOURCE LINES 11-29 + +.. code-block:: Python + + + from ase.io import read + from ase import Atoms + + import numpy as np + + from scipy.spatial.transform import Rotation as R + from tqdm.auto import tqdm + from skmatter.preprocessing import StandardFlexibleScaler + + from anisoap.representations.ellipsoidal_density_projection import ( + EllipsoidalDensityProjection, + ) + + import matplotlib.pyplot as plt + + + + + + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 30-31 + +Read the first two frames of ellipsoids.xyz, which represent coarse-grained benzene molecules. + +.. GENERATED FROM PYTHON SOURCE LINES 31-39 + +.. code-block:: Python + + + frames = read("ellipsoids.xyz", "0:2") + frames_translation = read("ellipsoids.xyz", "0:2") + frames_rotation = read("ellipsoids.xyz", "0:2") + + print(f"{len(frames)=}") # a list of atoms objects + print(f"{frames[0].arrays=}") + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + len(frames)=2 + frames[0].arrays={'numbers': array([0, 0]), 'positions': array([[-0. , -0. , 3.27355258], + [ 2.86203436, 4.88789961, 6.73143792]]), 'c_q': array([[ 0.15965019, 0.67170996, -0.07507814, 0.71950039], + [-0.213207 , -0.03290243, 0.26500539, 0.93980442]])} + + + + +.. GENERATED FROM PYTHON SOURCE LINES 40-43 + +In this case, the xyz file did not store ellipsoid dimension information. + +We will add this information here. + +.. GENERATED FROM PYTHON SOURCE LINES 43-52 + +.. code-block:: Python + + + for frame in frames: + frame.arrays["c_diameter[1]"] = np.ones(len(frame)) * 3. + frame.arrays["c_diameter[2]"] = np.ones(len(frame)) * 3. + frame.arrays["c_diameter[3]"] = np.ones(len(frame)) * 1. + + print(f"{frames[0].arrays=}") + print(f"{frames[1].arrays=}") + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + frames[0].arrays={'numbers': array([0, 0]), 'positions': array([[-0. , -0. , 3.27355258], + [ 2.86203436, 4.88789961, 6.73143792]]), 'c_q': array([[ 0.15965019, 0.67170996, -0.07507814, 0.71950039], + [-0.213207 , -0.03290243, 0.26500539, 0.93980442]]), 'c_diameter[1]': array([3., 3.]), 'c_diameter[2]': array([3., 3.]), 'c_diameter[3]': array([1., 1.])} + frames[1].arrays={'numbers': array([0]), 'positions': array([[1.05715855, 3.61232694, 6.89484241]]), 'c_q': array([[ 0.79385889, 0.57747976, -0.17079529, 0.08446388]]), 'c_diameter[1]': array([3.]), 'c_diameter[2]': array([3.]), 'c_diameter[3]': array([1.])} + + + + +.. GENERATED FROM PYTHON SOURCE LINES 53-54 + +Specify the hypers to create AniSOAP vector. + +.. GENERATED FROM PYTHON SOURCE LINES 54-71 + +.. code-block:: Python + + + lmax = 5 + nmax = 3 + + AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-4, + } + calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + /Users/alin62/Documents/Research/anisoap/anisoap/representations/ellipsoidal_density_projection.py:554: UserWarning: In quaternion mode, quaternions are assumed to be in (w,x,y,z) format. + warnings.warn( + + + + +.. GENERATED FROM PYTHON SOURCE LINES 72-73 + +Create the AniSOAP vector (i.e. the power spectrum). + +.. GENERATED FROM PYTHON SOURCE LINES 73-78 + +.. code-block:: Python + + power_spectrum = calculator.power_spectrum(frames) + plt.plot(power_spectrum.T) + plt.legend(["frame[0] power spectrum", "frame[1] power spectrum"]) + plt.show() + + + + +.. image-sg:: /auto_examples/images/sphx_glr_example01_invariances_of_powerspectrum_test_001.png + :alt: example01 invariances of powerspectrum test + :srcset: /auto_examples/images/sphx_glr_example01_invariances_of_powerspectrum_test_001.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 79-82 + +Here we will demonstrate translation invariance. + +Translation vector is used to demonstrate the power spectrum of ellipsoidal representations are invariant of translation in positions. + +.. GENERATED FROM PYTHON SOURCE LINES 82-90 + +.. code-block:: Python + + print("Old Positions:", frames[0].get_positions(), frames[1].get_positions()) + translation_vector = np.array([2.0, 2.0, 2.0]) + for frame in frames: + frame.set_positions(frame.get_positions() + translation_vector) + print("New Positions:", frames[0].get_positions(), frames[1].get_positions()) + power_spectrum_translated = calculator.power_spectrum(frames) + print(f"{np.allclose(power_spectrum, power_spectrum_translated)=}") + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + Old Positions: [[-0. -0. 3.27355258] + [ 2.86203436 4.88789961 6.73143792]] [[1.05715855 3.61232694 6.89484241]] + New Positions: [[2. 2. 5.27355258] + [4.86203436 6.88789961 8.73143792]] [[3.05715855 5.61232694 8.89484241]] + np.allclose(power_spectrum, power_spectrum_translated)=True + + + + +.. GENERATED FROM PYTHON SOURCE LINES 91-92 + +Here, we demonstrate rotational invariance, rotating all ellipsoids by the same amount. + +.. GENERATED FROM PYTHON SOURCE LINES 92-106 + +.. code-block:: Python + + print("Old Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + + quaternion = [1, 2, 0, -3] # random rotation + q_rotation = R.from_quat(quaternion, scalar_first=True) + for frame in frames: + frame.arrays["c_q"] = R.as_quat( + q_rotation * R.from_quat(frame.arrays["c_q"], scalar_first=True), + scalar_first=True, + ) + print("New Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + + power_spectrum_rotation = calculator.power_spectrum(frames) + print(f"{np.allclose(power_spectrum, power_spectrum_rotation, rtol=1e-2, atol=1e-2)=}") + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + Old Orientations: [[ 0.15965019 0.67170996 -0.07507814 0.71950039] + [-0.213207 -0.03290243 0.26500539 0.93980442]] [[ 0.79385889 0.57747976 -0.17079529 0.08446388]] + New Orientations: [[ 0.26050794 0.20466222 -0.94322073 0.02415869] + [ 0.71412501 0.08971953 -0.40514029 0.56377054]] [[-0.02878644 0.4417325 -0.55380868 -0.70522314]] + np.allclose(power_spectrum, power_spectrum_rotation, rtol=1e-2, atol=1e-2)=True + + + + +.. GENERATED FROM PYTHON SOURCE LINES 107-114 + +Here's how to create ellipsoidal frames. In this example: + +* Each frame contains 2-3 ellipsoids, with periodic boundary conditions. +* The quaternions(``c_q``) and particle dimensions(``c_diameter[i]``) cannot be passed into the Atoms constructor. +* They are attached as data in the Atoms.arrays dictionary. +* I just made up arbitrary postions and orientations. Quaternions should be in (w,x,y,z) format. +* In reality you would choose positions and orientations based on some underlying atomistic model. + +.. GENERATED FROM PYTHON SOURCE LINES 114-134 + +.. code-block:: Python + + frame1 = Atoms(symbols='XX', + positions=np.array([[0., 0., 0.], [2.5, 3., 2.]]), + cell=np.array([5., 5., 5.,]), + pbc=True) + frame1.arrays["c_q"] = np.array([[0., 1., 0., 0.], [0., 0., 1., 0]]) + frame1.arrays["c_diameter[1]"] = np.array([3., 3.]) + frame1.arrays["c_diameter[2]"] = np.array([3., 3.]) + frame1.arrays["c_diameter[3]"] = np.array([1., 1.]) + + frame2 = Atoms(symbols='XXX', + positions = np.array([[0., 1., 2.], [2., 3., 4.], [5., 5., 1.]]), + cell=[10., 10., 10.,], + pbc=True) + frame2.arrays["c_q"] = np.array([[0., 1., 0., 0.], [0., 0., 1., 0], [0., 0., 0.707, 0.707]]) + frame2.arrays["c_diameter[1]"] = np.array([3., 3., 3.]) + frame2.arrays["c_diameter[2]"] = np.array([3., 3., 3.]) + frame2.arrays["c_diameter[3]"] = np.array([1., 1., 1.]) + + frames = [frame1, frame2] + + + + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 135-135 + +You can then use ``ase.io.write()``/``ase.io.read()`` to save/load these frames for later use. + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (0 minutes 0.173 seconds) + + +.. _sphx_glr_download_auto_examples_example01_invariances_of_powerspectrum_test.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: example01_invariances_of_powerspectrum_test.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: example01_invariances_of_powerspectrum_test.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: example01_invariances_of_powerspectrum_test.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.zip b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.zip new file mode 100644 index 0000000..7cafa9f Binary files /dev/null and b/docs/source/auto_examples/example01_invariances_of_powerspectrum_test.zip differ diff --git a/docs/source/auto_examples/example02_learn_benzene.codeobj.json b/docs/source/auto_examples/example02_learn_benzene.codeobj.json new file mode 100644 index 0000000..9c4ca84 --- /dev/null +++ b/docs/source/auto_examples/example02_learn_benzene.codeobj.json @@ -0,0 +1,2051 @@ +{ + "AniSOAP_HYPERS": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "EllipsoidalDensityProjection": [ + { + "is_class": true, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": true, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": true, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + } + ], + "RidgeCV": [ + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model", + "name": "RidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "MultiOutputMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "MultiOutputMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "RegressorMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RegressorMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model._ridge", + "name": "_BaseRidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "_BaseRidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_BaseRidgeCV" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model._base", + "module_short": "sklearn.linear_model._base", + "name": "LinearModel" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "LinearModel" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "LinearModel" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV" + } + ], + "StandardFlexibleScaler": [ + { + "is_class": true, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": true, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": true, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester" + }, + { + "is_class": true, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + } + ], + "a1": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + } + ], + "a2": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + } + ], + "a3": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "float" + } + ], + "atom_frames": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "calculator": [ + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection" + } + ], + "calculator.power_spectrum": [ + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations.ellipsoidal_density_projection", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection.power_spectrum" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap.representations", + "module_short": "anisoap.representations", + "name": "EllipsoidalDensityProjection.power_spectrum" + }, + { + "is_class": false, + "is_explicit": false, + "module": "anisoap", + "module_short": "anisoap", + "name": "EllipsoidalDensityProjection.power_spectrum" + } + ], + "energies": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "frame": [ + { + "is_class": false, + "is_explicit": false, + "module": "ase.atoms", + "module_short": "ase", + "name": "Atoms" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase", + "module_short": "ase", + "name": "Atoms" + } + ], + "frame.arrays": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "dict" + } + ], + "frames": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "list" + } + ], + "i_test": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "i_train": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "lmax": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "lr": [ + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model", + "name": "RidgeCV" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RidgeCV" + } + ], + "lr.alpha_": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "float64" + } + ], + "lr.fit": [ + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "MultiOutputMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "MultiOutputMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "RegressorMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RegressorMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model._ridge", + "name": "_BaseRidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "_BaseRidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_BaseRidgeCV.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._base", + "module_short": "sklearn.linear_model._base", + "name": "LinearModel.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "LinearModel.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "LinearModel.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.fit" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.fit" + } + ], + "lr.predict": [ + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "MultiOutputMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "MultiOutputMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "RegressorMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RegressorMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model._ridge", + "name": "_BaseRidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "_BaseRidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_BaseRidgeCV.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._base", + "module_short": "sklearn.linear_model._base", + "name": "LinearModel.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "LinearModel.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "LinearModel.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.predict" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.predict" + } + ], + "lr.score": [ + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "RidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "MultiOutputMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "MultiOutputMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "RegressorMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "RegressorMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._ridge", + "module_short": "sklearn.linear_model._ridge", + "name": "_BaseRidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "_BaseRidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_BaseRidgeCV.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model._base", + "module_short": "sklearn.linear_model._base", + "name": "LinearModel.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.linear_model", + "module_short": "sklearn.linear_model", + "name": "LinearModel.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "LinearModel.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.score" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.score" + } + ], + "nmax": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "int" + } + ], + "np.arange": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "arange" + } + ], + "np.array": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "builtin_function_or_method" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "array" + } + ], + "np.logspace": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "logspace" + } + ], + "np.max": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "max" + } + ], + "np.min": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "min" + } + ], + "np.ones": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ones" + } + ], + "np.reshape": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "_ArrayFunctionDispatcher" + }, + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "reshape" + } + ], + "plt.figure": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "figure" + } + ], + "plt.hist": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "hist" + } + ], + "plt.legend": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "legend" + } + ], + "plt.plot": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "plot" + } + ], + "plt.scatter": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "scatter" + } + ], + "plt.show": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "show" + } + ], + "plt.xlabel": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "xlabel" + } + ], + "plt.ylabel": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "matplotlib.pyplot", + "module_short": "matplotlib.pyplot", + "name": "ylabel" + } + ], + "read": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "ase.io", + "module_short": "ase.io", + "name": "read" + } + ], + "train_test_split": [ + { + "is_class": false, + "is_explicit": false, + "module": "builtins", + "module_short": "builtins", + "name": "function" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.model_selection", + "module_short": "sklearn.model_selection", + "name": "train_test_split" + } + ], + "x_anisoap_raw": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "x_test": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "x_test_scaler": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler" + } + ], + "x_test_scaler.transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.transform" + } + ], + "x_train": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "x_train_scaler": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler" + } + ], + "x_train_scaler.transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.transform" + } + ], + "y_test": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "y_test_scaler": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler" + } + ], + "y_test_scaler.inverse_transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.inverse_transform" + } + ], + "y_test_scaler.transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.transform" + } + ], + "y_train": [ + { + "is_class": false, + "is_explicit": false, + "module": "numpy", + "module_short": "numpy", + "name": "ndarray" + } + ], + "y_train_scaler": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler" + } + ], + "y_train_scaler.inverse_transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.inverse_transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.inverse_transform" + } + ], + "y_train_scaler.transform": [ + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing._data", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter.preprocessing", + "module_short": "skmatter.preprocessing", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "skmatter", + "module_short": "skmatter", + "name": "StandardFlexibleScaler.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "TransformerMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.base", + "module_short": "sklearn.base", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "BaseEstimator.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._set_output", + "module_short": "sklearn.utils._set_output", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_SetOutputMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._estimator_html_repr", + "module_short": "sklearn.utils._estimator_html_repr", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_HTMLDocumentationLinkMixin.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils._metadata_requests", + "module_short": "sklearn.utils._metadata_requests", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn.utils", + "module_short": "sklearn.utils", + "name": "_MetadataRequester.transform" + }, + { + "is_class": false, + "is_explicit": false, + "module": "sklearn", + "module_short": "sklearn", + "name": "_MetadataRequester.transform" + } + ] +} \ No newline at end of file diff --git a/docs/source/auto_examples/example02_learn_benzene.ipynb b/docs/source/auto_examples/example02_learn_benzene.ipynb new file mode 100644 index 0000000..d5b75e4 --- /dev/null +++ b/docs/source/auto_examples/example02_learn_benzene.ipynb @@ -0,0 +1,133 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Example 2: Machine-learning benzene energies.\nThis example demonstrates:\n\n1. How to read ellipsoidal frames from ``.xyz`` file.\n2. How to convert ellipsoidal frames to AniSOAP vectors.\n3. How to use these frames in machine learning models.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import metatensor\nimport numpy as np\nfrom anisoap.representations import EllipsoidalDensityProjection\nfrom anisoap.utils import ClebschGordanReal, cg_combine, standardize_keys\nfrom ase.io import read\nfrom matplotlib import pyplot as plt\nfrom matplotlib import rc\nfrom rascaline import SoapPowerSpectrum\nfrom sklearn.decomposition import PCA\nfrom skmatter.metrics import global_reconstruction_error as GRE\nfrom sklearn.model_selection import train_test_split\nfrom skmatter.preprocessing import StandardFlexibleScaler\nimport pickle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read the frames\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lmax = 9\nnmax = 6\n\natom_frames = read(\"benzenes.xyz\", \":\") # all atom frames, containing benzene energies\nframes = read(\"ellipsoids.xyz\", \":\") # ellipsoid frames\nenergies = np.array([aframe.info[\"energy_pa\"] for aframe in atom_frames])\nenergies = np.reshape(energies, (-1, 1)) # Turn energies into column vector, required for sklearn\nplt.hist(energies, bins=100)\nplt.xlabel(\"Loaded Energies, eV\")\nplt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Computing the AniSOAP Vectors\n\n* The ideal semiaxes for the ellipsoid are (4, 4, 0.5)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a1, a2, a3 = 4., 4., 0.5\nfor frame in frames:\n frame.arrays[\"c_diameter[1]\"] = a1 * np.ones(len(frame))\n frame.arrays[\"c_diameter[2]\"] = a2 * np.ones(len(frame))\n frame.arrays[\"c_diameter[3]\"] = a3 * np.ones(len(frame))\n\nAniSOAP_HYPERS = {\n \"max_angular\": lmax,\n \"max_radial\": nmax,\n \"radial_basis_name\": \"gto\",\n \"subtract_center_contribution\": True,\n \"rotation_type\": \"quaternion\",\n \"rotation_key\": \"c_q\",\n \"cutoff_radius\": 7.0,\n \"radial_gaussian_width\": 1.5,\n \"basis_rcond\": 1e-8,\n \"basis_tol\": 1e-3,\n}\n\ncalculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS)\n\nx_anisoap_raw = calculator.power_spectrum(frames)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we do standard preparation of the data for machine learning.\n\n* Perform a train test split and standardization.\n* Note: Warnings below are from StandardFlexibleScaler.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n\ni_train, i_test = train_test_split(np.arange(len(frames)), train_size=0.9, shuffle=True)\nx_train_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_train])\nx_train = x_train_scaler.transform(x_anisoap_raw[i_train])\ny_train_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_train])\ny_train = y_train_scaler.transform(energies[i_train])\n\nx_test_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_test])\nx_test = x_test_scaler.transform(x_anisoap_raw[i_test])\ny_test_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_test])\ny_test = y_test_scaler.transform(energies[i_test])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Input into a regularized linear regression machine learning model\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from sklearn.linear_model import RidgeCV\n\nlr = RidgeCV(cv=5, alphas=np.logspace(-8, 2, 20), fit_intercept=True)\nlr.fit(x_train, y_train)\nprint(f\"{lr.alpha_=:.3f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Model performance and Parity Plot\nsphinx_gallery_thumbnail_number = 2\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.figure(figsize=(8, 8))\nplt.scatter(y_train_scaler.inverse_transform(y_train), \n y_train_scaler.inverse_transform(lr.predict(x_train).reshape(-1,1)),\n alpha=0.5)\n\nplt.scatter(y_test_scaler.inverse_transform(y_test), \n y_test_scaler.inverse_transform(lr.predict(x_test).reshape(-1,1)),\n alpha=0.5)\n\nplt.plot([np.min(energies), np.max(energies)], [np.min(energies), np.max(energies)], \"r--\")\nplt.xlabel(\"Per-atom Energies (eV)\")\nplt.ylabel(\"AniSOAP Predicted Per-atom Energies (eV)\")\nplt.legend([\"Train\", \"Test\", \"y=x\"])\n\nprint(f\"Train R^2: {lr.score(x_train, y_train):.3f}\")\nprint(f\"Test R^2: {lr.score(x_test, y_test):.3f}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/source/auto_examples/example02_learn_benzene.py b/docs/source/auto_examples/example02_learn_benzene.py new file mode 100644 index 0000000..c592ef6 --- /dev/null +++ b/docs/source/auto_examples/example02_learn_benzene.py @@ -0,0 +1,123 @@ +# %% +""" +Example 2: Machine-learning benzene energies. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to use these frames in machine learning models. +""" + +import metatensor +import numpy as np +from anisoap.representations import EllipsoidalDensityProjection +from anisoap.utils import ClebschGordanReal, cg_combine, standardize_keys +from ase.io import read +from matplotlib import pyplot as plt +from matplotlib import rc +from rascaline import SoapPowerSpectrum +from sklearn.decomposition import PCA +from skmatter.metrics import global_reconstruction_error as GRE +from sklearn.model_selection import train_test_split +from skmatter.preprocessing import StandardFlexibleScaler +import pickle + +# %% +# Read the frames + +lmax = 9 +nmax = 6 + +atom_frames = read("benzenes.xyz", ":") # all atom frames, containing benzene energies +frames = read("ellipsoids.xyz", ":") # ellipsoid frames +energies = np.array([aframe.info["energy_pa"] for aframe in atom_frames]) +energies = np.reshape( + energies, (-1, 1) +) # Turn energies into column vector, required for sklearn +plt.hist(energies, bins=100) +plt.xlabel("Loaded Energies, eV") +plt.show() + + +# %% +# Computing the AniSOAP Vectors +# +# * The ideal semiaxes for the ellipsoid are (4, 4, 0.5) + +a1, a2, a3 = 4.0, 4.0, 0.5 +for frame in frames: + frame.arrays["c_diameter[1]"] = a1 * np.ones(len(frame)) + frame.arrays["c_diameter[2]"] = a2 * np.ones(len(frame)) + frame.arrays["c_diameter[3]"] = a3 * np.ones(len(frame)) + +AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "subtract_center_contribution": True, + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-3, +} + +calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + +x_anisoap_raw = calculator.power_spectrum(frames) + +# %% +# Here, we do standard preparation of the data for machine learning. +# +# * Perform a train test split and standardization. +# * Note: Warnings below are from StandardFlexibleScaler. + +from sklearn.model_selection import train_test_split + +i_train, i_test = train_test_split(np.arange(len(frames)), train_size=0.9, shuffle=True) +x_train_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_train]) +x_train = x_train_scaler.transform(x_anisoap_raw[i_train]) +y_train_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_train]) +y_train = y_train_scaler.transform(energies[i_train]) + +x_test_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_test]) +x_test = x_test_scaler.transform(x_anisoap_raw[i_test]) +y_test_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_test]) +y_test = y_test_scaler.transform(energies[i_test]) + +# %% +# Input into a regularized linear regression machine learning model + +from sklearn.linear_model import RidgeCV + +lr = RidgeCV(cv=5, alphas=np.logspace(-8, 2, 20), fit_intercept=True) +lr.fit(x_train, y_train) +print(f"{lr.alpha_=:.3f}") + +# %% +# Model performance and Parity Plot +# sphinx_gallery_thumbnail_number = 2 +plt.figure(figsize=(8, 8)) +plt.scatter( + y_train_scaler.inverse_transform(y_train), + y_train_scaler.inverse_transform(lr.predict(x_train).reshape(-1, 1)), + alpha=0.5, +) + +plt.scatter( + y_test_scaler.inverse_transform(y_test), + y_test_scaler.inverse_transform(lr.predict(x_test).reshape(-1, 1)), + alpha=0.5, +) + +plt.plot( + [np.min(energies), np.max(energies)], [np.min(energies), np.max(energies)], "r--" +) +plt.xlabel("Per-atom Energies (eV)") +plt.ylabel("AniSOAP Predicted Per-atom Energies (eV)") +plt.legend(["Train", "Test", "y=x"]) + +print(f"Train R^2: {lr.score(x_train, y_train):.3f}") +print(f"Test R^2: {lr.score(x_test, y_test):.3f}") diff --git a/docs/source/auto_examples/example02_learn_benzene.py.md5 b/docs/source/auto_examples/example02_learn_benzene.py.md5 new file mode 100644 index 0000000..78228b8 --- /dev/null +++ b/docs/source/auto_examples/example02_learn_benzene.py.md5 @@ -0,0 +1 @@ +297016b0c6afb0d83845a7544de20de3 \ No newline at end of file diff --git a/docs/source/auto_examples/example02_learn_benzene.rst b/docs/source/auto_examples/example02_learn_benzene.rst new file mode 100644 index 0000000..fa4787a --- /dev/null +++ b/docs/source/auto_examples/example02_learn_benzene.rst @@ -0,0 +1,290 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "auto_examples/example02_learn_benzene.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code. + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_auto_examples_example02_learn_benzene.py: + + +Example 2: Machine-learning benzene energies. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to use these frames in machine learning models. + +.. GENERATED FROM PYTHON SOURCE LINES 11-26 + +.. code-block:: Python + + + import metatensor + import numpy as np + from anisoap.representations import EllipsoidalDensityProjection + from anisoap.utils import ClebschGordanReal, cg_combine, standardize_keys + from ase.io import read + from matplotlib import pyplot as plt + from matplotlib import rc + from rascaline import SoapPowerSpectrum + from sklearn.decomposition import PCA + from skmatter.metrics import global_reconstruction_error as GRE + from sklearn.model_selection import train_test_split + from skmatter.preprocessing import StandardFlexibleScaler + import pickle + + + + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 27-28 + +Read the frames + +.. GENERATED FROM PYTHON SOURCE LINES 28-41 + +.. code-block:: Python + + + lmax = 9 + nmax = 6 + + atom_frames = read("benzenes.xyz", ":") # all atom frames, containing benzene energies + frames = read("ellipsoids.xyz", ":") # ellipsoid frames + energies = np.array([aframe.info["energy_pa"] for aframe in atom_frames]) + energies = np.reshape(energies, (-1, 1)) # Turn energies into column vector, required for sklearn + plt.hist(energies, bins=100) + plt.xlabel("Loaded Energies, eV") + plt.show() + + + + + +.. image-sg:: /auto_examples/images/sphx_glr_example02_learn_benzene_001.png + :alt: example02 learn benzene + :srcset: /auto_examples/images/sphx_glr_example02_learn_benzene_001.png + :class: sphx-glr-single-img + + + + + +.. GENERATED FROM PYTHON SOURCE LINES 42-45 + +Computing the AniSOAP Vectors + +* The ideal semiaxes for the ellipsoid are (4, 4, 0.5) + +.. GENERATED FROM PYTHON SOURCE LINES 45-69 + +.. code-block:: Python + + + a1, a2, a3 = 4., 4., 0.5 + for frame in frames: + frame.arrays["c_diameter[1]"] = a1 * np.ones(len(frame)) + frame.arrays["c_diameter[2]"] = a2 * np.ones(len(frame)) + frame.arrays["c_diameter[3]"] = a3 * np.ones(len(frame)) + + AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "subtract_center_contribution": True, + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-3, + } + + calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + + x_anisoap_raw = calculator.power_spectrum(frames) + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + /Users/alin62/Documents/Research/anisoap/anisoap/representations/ellipsoidal_density_projection.py:554: UserWarning: In quaternion mode, quaternions are assumed to be in (w,x,y,z) format. + warnings.warn( + + + + +.. GENERATED FROM PYTHON SOURCE LINES 70-74 + +Here, we do standard preparation of the data for machine learning. + +* Perform a train test split and standardization. +* Note: Warnings below are from StandardFlexibleScaler. + +.. GENERATED FROM PYTHON SOURCE LINES 74-88 + +.. code-block:: Python + + + from sklearn.model_selection import train_test_split + + i_train, i_test = train_test_split(np.arange(len(frames)), train_size=0.9, shuffle=True) + x_train_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_train]) + x_train = x_train_scaler.transform(x_anisoap_raw[i_train]) + y_train_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_train]) + y_train = y_train_scaler.transform(energies[i_train]) + + x_test_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_test]) + x_test = x_test_scaler.transform(x_anisoap_raw[i_test]) + y_test_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_test]) + y_test = y_test_scaler.transform(energies[i_test]) + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + /Users/alin62/miniconda3/envs/anisoap/lib/python3.10/site-packages/sklearn/base.py:474: FutureWarning: `BaseEstimator._validate_data` is deprecated in 1.6 and will be removed in 1.7. Use `sklearn.utils.validation.validate_data` instead. This function becomes public and is part of the scikit-learn developer API. + warnings.warn( + + + + +.. GENERATED FROM PYTHON SOURCE LINES 89-90 + +Input into a regularized linear regression machine learning model + +.. GENERATED FROM PYTHON SOURCE LINES 90-97 + +.. code-block:: Python + + + from sklearn.linear_model import RidgeCV + + lr = RidgeCV(cv=5, alphas=np.logspace(-8, 2, 20), fit_intercept=True) + lr.fit(x_train, y_train) + print(f"{lr.alpha_=:.3f}") + + + + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + lr.alpha_=0.001 + + + + +.. GENERATED FROM PYTHON SOURCE LINES 98-100 + +Model performance and Parity Plot +sphinx_gallery_thumbnail_number = 2 + +.. GENERATED FROM PYTHON SOURCE LINES 100-116 + +.. code-block:: Python + + plt.figure(figsize=(8, 8)) + plt.scatter(y_train_scaler.inverse_transform(y_train), + y_train_scaler.inverse_transform(lr.predict(x_train).reshape(-1,1)), + alpha=0.5) + + plt.scatter(y_test_scaler.inverse_transform(y_test), + y_test_scaler.inverse_transform(lr.predict(x_test).reshape(-1,1)), + alpha=0.5) + + plt.plot([np.min(energies), np.max(energies)], [np.min(energies), np.max(energies)], "r--") + plt.xlabel("Per-atom Energies (eV)") + plt.ylabel("AniSOAP Predicted Per-atom Energies (eV)") + plt.legend(["Train", "Test", "y=x"]) + + print(f"Train R^2: {lr.score(x_train, y_train):.3f}") + print(f"Test R^2: {lr.score(x_test, y_test):.3f}") + + + +.. image-sg:: /auto_examples/images/sphx_glr_example02_learn_benzene_002.png + :alt: example02 learn benzene + :srcset: /auto_examples/images/sphx_glr_example02_learn_benzene_002.png + :class: sphx-glr-single-img + + +.. rst-class:: sphx-glr-script-out + + .. code-block:: none + + Train R^2: 0.909 + Test R^2: 0.881 + + + + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** (6 minutes 0.866 seconds) + + +.. _sphx_glr_download_auto_examples_example02_learn_benzene.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: example02_learn_benzene.ipynb ` + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: example02_learn_benzene.py ` + + .. container:: sphx-glr-download sphx-glr-download-zip + + :download:`Download zipped: example02_learn_benzene.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/source/auto_examples/example02_learn_benzene.zip b/docs/source/auto_examples/example02_learn_benzene.zip new file mode 100644 index 0000000..cd2b028 Binary files /dev/null and b/docs/source/auto_examples/example02_learn_benzene.zip differ diff --git a/docs/source/auto_examples/index.rst b/docs/source/auto_examples/index.rst new file mode 100644 index 0000000..d7a3389 --- /dev/null +++ b/docs/source/auto_examples/index.rst @@ -0,0 +1,89 @@ +:orphan: + +Examples +======== + +Here is a collection of examples that may prove useful. + +The 1st example is a minimal example demonstrating how to create an AniSOAP vector from an ase.Atoms object. It also demonstrates the rotational and translational invariance. + +The 2nd example is an example demonstrating how AniSOAP can be used to coarse-grain benzene and learn benzene crystal energies through linear regression. + +.. Note:: + + More tutorials are currently being developed. Stay tuned! + + + +.. raw:: html + +
+ +.. thumbnail-parent-div-open + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_example01_invariances_of_powerspectrum_test_thumb.png + :alt: + + :ref:`sphx_glr_auto_examples_example01_invariances_of_powerspectrum_test.py` + +.. raw:: html + +
Example 1: Creating AniSOAP vectors from ellipsoidal frames.
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /auto_examples/images/thumb/sphx_glr_example02_learn_benzene_thumb.png + :alt: + + :ref:`sphx_glr_auto_examples_example02_learn_benzene.py` + +.. raw:: html + +
Example 2: Machine-learning benzene energies.
+
+ + +.. thumbnail-parent-div-close + +.. raw:: html + +
+ + +.. toctree:: + :hidden: + + /auto_examples/example01_invariances_of_powerspectrum_test + /auto_examples/example02_learn_benzene + + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-gallery + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download all examples in Python source code: auto_examples_python.zip ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download all examples in Jupyter notebooks: auto_examples_jupyter.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/source/auto_examples/sg_execution_times.rst b/docs/source/auto_examples/sg_execution_times.rst new file mode 100644 index 0000000..e7d709b --- /dev/null +++ b/docs/source/auto_examples/sg_execution_times.rst @@ -0,0 +1,40 @@ + +:orphan: + +.. _sphx_glr_auto_examples_sg_execution_times: + + +Computation times +================= +**06:00.866** total execution time for 2 files **from auto_examples**: + +.. container:: + + .. raw:: html + + + + + + + + .. list-table:: + :header-rows: 1 + :class: table table-striped sg-datatable + + * - Example + - Time + - Mem (MB) + * - :ref:`sphx_glr_auto_examples_example02_learn_benzene.py` (``example02_learn_benzene.py``) + - 06:00.866 + - 0.0 + * - :ref:`sphx_glr_auto_examples_example01_invariances_of_powerspectrum_test.py` (``example01_invariances_of_powerspectrum_test.py``) + - 00:00.000 + - 0.0 diff --git a/docs/source/conf.py b/docs/source/conf.py index 6213f5f..d9d505b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,8 +25,19 @@ "sphinx.ext.napoleon", "sphinx.ext.mathjax", "sphinx.ext.coverage", + "sphinx_tabs.tabs", + "sphinx_gallery.gen_gallery", ] +sphinx_gallery_conf = { + "examples_dirs": "../../notebooks/", # path to your example scripts + "gallery_dirs": "auto_examples", # path to where to save gallery generated output + "filename_pattern": "/*", + "ignore_pattern": r"__init__\.py", + "example_extensions": {".py"}, + "within_subsection_order": "ExampleTitleSortKey", +} + sys.path.insert(0, os.path.abspath("../../")) templates_path = ["_templates"] diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index b0976cc..a5af607 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -4,14 +4,28 @@ Getting Started Introduction ------------ -Todo +AniSOAP is a package for creating machine-learnable representations of systems +of particles in a way that preserves geometrical information. AniSOAP works +similarly to SOAP (Smooth Overlap of Atomic Potentials) in many ways, with the +chief difference being AniSOAP's ability to represent ellipsoidal particles. First Steps ----------- -AniSOAP depends extensively on the packages `rascaline -`_ -and `metatensor `_. +AniSOAP depends on and utilizes the packages `featomic (aka rascaline) +`_, `metatensor `_, +and `ase `_. It may be helpful to familiarize yourself with these packages before diving into AniSOAP. +Key Concepts +------------ +In the AniSOAP representation, particles are treated as multivariate Gaussians (MVGs). +For each particle, we can consider its n-body interactions with nearby particles. +Each local density field is then decomposed in terms of spherical harmonics and +some choice of radial basis functions in order to be compactly represented in +vector form. + +A single AniSOAP vector represents the environment of a single central ellipsoid. +A system of such particles can then be represented, for example, as a matrix of +AniSOAP vectors. diff --git a/docs/source/index.rst b/docs/source/index.rst index 5a69110..2a6dd39 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,8 +3,9 @@ Welcome to AniSOAP's documentation! =================================== **AniSOAP** is a Python library for creating descriptors of chemical systems -suitable for machine learning use. This project aims to extend SOAP -descriptors by computing anisotrophy extensions. +suitable for machine learning use. This project aims to extend the popular Smooth Overlap of Atomic Positions (SOAP) +descriptors to coarse-grained systems consisting of aspherical particles +with anisotropic interactions. .. note:: @@ -21,7 +22,7 @@ descriptors by computing anisotrophy extensions. installation getting_started - tutorials + auto_examples/index usage api diff --git a/docs/source/installation.rst b/docs/source/installation.rst index f054f92..95f4b5a 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -5,14 +5,14 @@ Installation Dependencies ------------ -Before installing AniSOAP, please make sure you have the following installed\: +Before installing AniSOAP, please make sure you have the following installed (We recommend using an environment manager like `conda `_): -* `Python: 3.6 or higher `_ +* `Python: 3.9 or 3.10 `_ * `numPy: 1.13 or higher `_ * `sciPy: 1.4.0 or higher `_ * `Atomic Simulation Environment (ASE): 3.18 or higher `_ -* `Metatensor `_ -* `Rascaline `_ +* `Metatensor `_ +* `Featomic (aka Rascaline) `_ * `Rust -- We reccommend using 'rustup `_ diff --git a/docs/source/sg_execution_times.rst b/docs/source/sg_execution_times.rst new file mode 100644 index 0000000..13132f3 --- /dev/null +++ b/docs/source/sg_execution_times.rst @@ -0,0 +1,40 @@ + +:orphan: + +.. _sphx_glr_sg_execution_times: + + +Computation times +================= +**06:00.866** total execution time for 2 files **from all galleries**: + +.. container:: + + .. raw:: html + + + + + + + + .. list-table:: + :header-rows: 1 + :class: table table-striped sg-datatable + + * - Example + - Time + - Mem (MB) + * - :ref:`sphx_glr_auto_examples_example02_learn_benzene.py` (``../../notebooks/example02_learn_benzene.py``) + - 06:00.866 + - 0.0 + * - :ref:`sphx_glr_auto_examples_example01_invariances_of_powerspectrum_test.py` (``../../notebooks/example01_invariances_of_powerspectrum_test.py``) + - 00:00.000 + - 0.0 diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst deleted file mode 100644 index fde3cf7..0000000 --- a/docs/source/tutorials.rst +++ /dev/null @@ -1,8 +0,0 @@ -Tutorials -========= - -Here is a collection of tutorials that may prove useful, including some interactive Jupyter Notebooks. - -.. Note:: - - More tutorials are currently being developed. Stay tuned! diff --git a/docs/source/usage.rst b/docs/source/usage.rst index 6f3336c..e3eebd9 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -1,4 +1,5 @@ Usage ===== -Check back soon! +AniSOAP interoperates heavily with `ASE `_ and +`Metatensor `_. diff --git a/notebooks/GALLERY_HEADER.rst b/notebooks/GALLERY_HEADER.rst new file mode 100644 index 0000000..276acfb --- /dev/null +++ b/notebooks/GALLERY_HEADER.rst @@ -0,0 +1,12 @@ +Examples +======== + +Here is a collection of examples that may prove useful. + +The 1st example is a minimal example demonstrating how to create an AniSOAP vector from an ase.Atoms object. It also demonstrates the rotational and translational invariance. + +The 2nd example is an example demonstrating how AniSOAP can be used to coarse-grain benzene and learn benzene crystal energies through linear regression. + +.. Note:: + + More tutorials are currently being developed. Stay tuned! diff --git a/notebooks/invariances_example/ellipsoids.xyz b/notebooks/ellipsoids.xyz similarity index 100% rename from notebooks/invariances_example/ellipsoids.xyz rename to notebooks/ellipsoids.xyz diff --git a/notebooks/example01_invariances_of_powerspectrum_test.py b/notebooks/example01_invariances_of_powerspectrum_test.py new file mode 100644 index 0000000..ab6e354 --- /dev/null +++ b/notebooks/example01_invariances_of_powerspectrum_test.py @@ -0,0 +1,150 @@ +# %% +""" +Example 1: Creating AniSOAP vectors from ellipsoidal frames. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to create ellipsoidal frames with ``ase.Atoms``. +""" + +from ase.io import read +from ase import Atoms + +import numpy as np + +from scipy.spatial.transform import Rotation as R +from tqdm.auto import tqdm +from skmatter.preprocessing import StandardFlexibleScaler + +from anisoap.representations.ellipsoidal_density_projection import ( + EllipsoidalDensityProjection, +) + +import matplotlib.pyplot as plt + + +# %% +# Read the first two frames of ellipsoids.xyz, which represent coarse-grained benzene molecules. + +frames = read("ellipsoids.xyz", "0:2") +frames_translation = read("ellipsoids.xyz", "0:2") +frames_rotation = read("ellipsoids.xyz", "0:2") + +print(f"{len(frames)=}") # a list of atoms objects +print(f"{frames[0].arrays=}") + +# %% +# In this case, the xyz file did not store ellipsoid dimension information. +# +# We will add this information here. + +for frame in frames: + frame.arrays["c_diameter[1]"] = np.ones(len(frame)) * 3.0 + frame.arrays["c_diameter[2]"] = np.ones(len(frame)) * 3.0 + frame.arrays["c_diameter[3]"] = np.ones(len(frame)) * 1.0 + +print(f"{frames[0].arrays=}") +print(f"{frames[1].arrays=}") + +# %% +# Specify the hypers to create AniSOAP vector. + +lmax = 5 +nmax = 3 + +AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-4, +} +calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + +# %% +# Create the AniSOAP vector (i.e. the power spectrum). +power_spectrum = calculator.power_spectrum(frames) +plt.plot(power_spectrum.T) +plt.legend(["frame[0] power spectrum", "frame[1] power spectrum"]) +plt.show() + +# %% +# Here we will demonstrate translation invariance. +# +# Translation vector is used to demonstrate the power spectrum of ellipsoidal representations are invariant of translation in positions. +print("Old Positions:", frames[0].get_positions(), frames[1].get_positions()) +translation_vector = np.array([2.0, 2.0, 2.0]) +for frame in frames: + frame.set_positions(frame.get_positions() + translation_vector) +print("New Positions:", frames[0].get_positions(), frames[1].get_positions()) +power_spectrum_translated = calculator.power_spectrum(frames) +print(f"{np.allclose(power_spectrum, power_spectrum_translated)=}") + +# %% +# Here, we demonstrate rotational invariance, rotating all ellipsoids by the same amount. +print("Old Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + +quaternion = [1, 2, 0, -3] # random rotation +q_rotation = R.from_quat(quaternion, scalar_first=True) +for frame in frames: + frame.arrays["c_q"] = R.as_quat( + q_rotation * R.from_quat(frame.arrays["c_q"], scalar_first=True), + scalar_first=True, + ) +print("New Orientations:", frames[0].arrays["c_q"], frames[1].arrays["c_q"]) + +power_spectrum_rotation = calculator.power_spectrum(frames) +print(f"{np.allclose(power_spectrum, power_spectrum_rotation, rtol=1e-2, atol=1e-2)=}") + +# %% +# Here's how to create ellipsoidal frames. In this example: +# +# * Each frame contains 2-3 ellipsoids, with periodic boundary conditions. +# * The quaternions(``c_q``) and particle dimensions(``c_diameter[i]``) cannot be passed into the Atoms constructor. +# * They are attached as data in the Atoms.arrays dictionary. +# * I just made up arbitrary postions and orientations. Quaternions should be in (w,x,y,z) format. +# * In reality you would choose positions and orientations based on some underlying atomistic model. +frame1 = Atoms( + symbols="XX", + positions=np.array([[0.0, 0.0, 0.0], [2.5, 3.0, 2.0]]), + cell=np.array( + [ + 5.0, + 5.0, + 5.0, + ] + ), + pbc=True, +) +frame1.arrays["c_q"] = np.array([[0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0]]) +frame1.arrays["c_diameter[1]"] = np.array([3.0, 3.0]) +frame1.arrays["c_diameter[2]"] = np.array([3.0, 3.0]) +frame1.arrays["c_diameter[3]"] = np.array([1.0, 1.0]) + +frame2 = Atoms( + symbols="XXX", + positions=np.array([[0.0, 1.0, 2.0], [2.0, 3.0, 4.0], [5.0, 5.0, 1.0]]), + cell=[ + 10.0, + 10.0, + 10.0, + ], + pbc=True, +) +frame2.arrays["c_q"] = np.array( + [[0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0], [0.0, 0.0, 0.707, 0.707]] +) +frame2.arrays["c_diameter[1]"] = np.array([3.0, 3.0, 3.0]) +frame2.arrays["c_diameter[2]"] = np.array([3.0, 3.0, 3.0]) +frame2.arrays["c_diameter[3]"] = np.array([1.0, 1.0, 1.0]) + +frames = [frame1, frame2] + +# %% +# You can then use ``ase.io.write()``/``ase.io.read()`` to save/load these frames for later use. diff --git a/notebooks/example02_learn_benzene.py b/notebooks/example02_learn_benzene.py new file mode 100644 index 0000000..c592ef6 --- /dev/null +++ b/notebooks/example02_learn_benzene.py @@ -0,0 +1,123 @@ +# %% +""" +Example 2: Machine-learning benzene energies. +============================================================ +This example demonstrates: + +1. How to read ellipsoidal frames from ``.xyz`` file. +2. How to convert ellipsoidal frames to AniSOAP vectors. +3. How to use these frames in machine learning models. +""" + +import metatensor +import numpy as np +from anisoap.representations import EllipsoidalDensityProjection +from anisoap.utils import ClebschGordanReal, cg_combine, standardize_keys +from ase.io import read +from matplotlib import pyplot as plt +from matplotlib import rc +from rascaline import SoapPowerSpectrum +from sklearn.decomposition import PCA +from skmatter.metrics import global_reconstruction_error as GRE +from sklearn.model_selection import train_test_split +from skmatter.preprocessing import StandardFlexibleScaler +import pickle + +# %% +# Read the frames + +lmax = 9 +nmax = 6 + +atom_frames = read("benzenes.xyz", ":") # all atom frames, containing benzene energies +frames = read("ellipsoids.xyz", ":") # ellipsoid frames +energies = np.array([aframe.info["energy_pa"] for aframe in atom_frames]) +energies = np.reshape( + energies, (-1, 1) +) # Turn energies into column vector, required for sklearn +plt.hist(energies, bins=100) +plt.xlabel("Loaded Energies, eV") +plt.show() + + +# %% +# Computing the AniSOAP Vectors +# +# * The ideal semiaxes for the ellipsoid are (4, 4, 0.5) + +a1, a2, a3 = 4.0, 4.0, 0.5 +for frame in frames: + frame.arrays["c_diameter[1]"] = a1 * np.ones(len(frame)) + frame.arrays["c_diameter[2]"] = a2 * np.ones(len(frame)) + frame.arrays["c_diameter[3]"] = a3 * np.ones(len(frame)) + +AniSOAP_HYPERS = { + "max_angular": lmax, + "max_radial": nmax, + "radial_basis_name": "gto", + "subtract_center_contribution": True, + "rotation_type": "quaternion", + "rotation_key": "c_q", + "cutoff_radius": 7.0, + "radial_gaussian_width": 1.5, + "basis_rcond": 1e-8, + "basis_tol": 1e-3, +} + +calculator = EllipsoidalDensityProjection(**AniSOAP_HYPERS) + +x_anisoap_raw = calculator.power_spectrum(frames) + +# %% +# Here, we do standard preparation of the data for machine learning. +# +# * Perform a train test split and standardization. +# * Note: Warnings below are from StandardFlexibleScaler. + +from sklearn.model_selection import train_test_split + +i_train, i_test = train_test_split(np.arange(len(frames)), train_size=0.9, shuffle=True) +x_train_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_train]) +x_train = x_train_scaler.transform(x_anisoap_raw[i_train]) +y_train_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_train]) +y_train = y_train_scaler.transform(energies[i_train]) + +x_test_scaler = StandardFlexibleScaler(column_wise=False).fit(x_anisoap_raw[i_test]) +x_test = x_test_scaler.transform(x_anisoap_raw[i_test]) +y_test_scaler = StandardFlexibleScaler(column_wise=True).fit(energies[i_test]) +y_test = y_test_scaler.transform(energies[i_test]) + +# %% +# Input into a regularized linear regression machine learning model + +from sklearn.linear_model import RidgeCV + +lr = RidgeCV(cv=5, alphas=np.logspace(-8, 2, 20), fit_intercept=True) +lr.fit(x_train, y_train) +print(f"{lr.alpha_=:.3f}") + +# %% +# Model performance and Parity Plot +# sphinx_gallery_thumbnail_number = 2 +plt.figure(figsize=(8, 8)) +plt.scatter( + y_train_scaler.inverse_transform(y_train), + y_train_scaler.inverse_transform(lr.predict(x_train).reshape(-1, 1)), + alpha=0.5, +) + +plt.scatter( + y_test_scaler.inverse_transform(y_test), + y_test_scaler.inverse_transform(lr.predict(x_test).reshape(-1, 1)), + alpha=0.5, +) + +plt.plot( + [np.min(energies), np.max(energies)], [np.min(energies), np.max(energies)], "r--" +) +plt.xlabel("Per-atom Energies (eV)") +plt.ylabel("AniSOAP Predicted Per-atom Energies (eV)") +plt.legend(["Train", "Test", "y=x"]) + +print(f"Train R^2: {lr.score(x_train, y_train):.3f}") +print(f"Test R^2: {lr.score(x_test, y_test):.3f}") diff --git a/paper/paper.bib b/paper/paper.bib new file mode 100644 index 0000000..8f600a9 --- /dev/null +++ b/paper/paper.bib @@ -0,0 +1,261 @@ + +@article{bartok_representing_2013, + title = {On representing chemical environments}, + volume = {87}, + issn = {1098-0121, 1550-235X}, + url = {https://link.aps.org/doi/10.1103/PhysRevB.87.184115}, + doi = {10.1103/PhysRevB.87.184115}, + number = {18}, + urldate = {2023-07-21}, + journal = {Physical Review B}, + author = {Bartók, Albert P. and Kondor, Risi and Csányi, Gábor}, + month = may, + year = {2013}, + pages = {184115}, + file = {Full Text PDF:/Users/alin62/Zotero/storage/FD3Z6FDS/Bartók et al. - 2013 - On representing chemical environments.pdf:application/pdf}, +} + +@article{behler_atom-centered_2011, + title = {Atom-centered symmetry functions for constructing high-dimensional neural network potentials}, + volume = {134}, + issn = {0021-9606}, + url = {https://doi.org/10.1063/1.3553717}, + doi = {10.1063/1.3553717}, + abstract = {Neural networks offer an unbiased and numerically very accurate approach to represent high-dimensional ab initio potential-energy surfaces. Once constructed, neural network potentials can provide the energies and forces many orders of magnitude faster than electronic structure calculations, and thus enable molecular dynamics simulations of large systems. However, Cartesian coordinates are not a good choice to represent the atomic positions, and a transformation to symmetry functions is required. Using simple benchmark systems, the properties of several types of symmetry functions suitable for the construction of high-dimensional neural network potential-energy surfaces are discussed in detail. The symmetry functions are general and can be applied to all types of systems such as molecules, crystalline and amorphous solids, and liquids.}, + number = {7}, + urldate = {2023-07-21}, + journal = {The Journal of Chemical Physics}, + author = {Behler, Jörg}, + month = feb, + year = {2011}, + pages = {074106}, + file = {Full Text PDF:/Users/alin62/Zotero/storage/WTSPCG7Q/Behler - 2011 - Atom-centered symmetry functions for constructing .pdf:application/pdf;Snapshot:/Users/alin62/Zotero/storage/ELXWYAEY/Atom-centered-symmetry-functions-for-constructing.html:text/html}, +} + +@article{musil_physics-inspired_2021, + title = {Physics-{Inspired} {Structural} {Representations} for {Molecules} and {Materials}}, + volume = {121}, + issn = {0009-2665}, + url = {https://doi.org/10.1021/acs.chemrev.1c00021}, + doi = {10.1021/acs.chemrev.1c00021}, + abstract = {The first step in the construction of a regression model or a data-driven analysis, aiming to predict or elucidate the relationship between the atomic-scale structure of matter and its properties, involves transforming the Cartesian coordinates of the atoms into a suitable representation. The development of atomic-scale representations has played, and continues to play, a central role in the success of machine-learning methods for chemistry and materials science. This review summarizes the current understanding of the nature and characteristics of the most commonly used structural and chemical descriptions of atomistic structures, highlighting the deep underlying connections between different frameworks and the ideas that lead to computationally efficient and universally applicable models. It emphasizes the link between properties, structures, their physical chemistry, and their mathematical description, provides examples of recent applications to a diverse set of chemical and materials science problems, and outlines the open questions and the most promising research directions in the field.}, + number = {16}, + urldate = {2022-10-19}, + journal = {Chemical Reviews}, + author = {Musil, Felix and Grisafi, Andrea and Bartók, Albert P. and Ortner, Christoph and Csányi, Gábor and Ceriotti, Michele}, + month = aug, + year = {2021}, + note = {Publisher: American Chemical Society}, + pages = {9759--9815}, + file = {ACS Full Text Snapshot:/Users/alin62/Zotero/storage/DSL2B3B4/acs.chemrev.html:text/html;Full Text PDF:/Users/alin62/Zotero/storage/TKK2LGST/Musil et al. - 2021 - Physics-Inspired Structural Representations for Mo.pdf:application/pdf}, +} + +@article{behler_generalized_2007, + title = {Generalized {Neural}-{Network} {Representation} of {High}-{Dimensional} {Potential}-{Energy} {Surfaces}}, + volume = {98}, + copyright = {http://link.aps.org/licenses/aps-default-license}, + issn = {0031-9007, 1079-7114}, + url = {https://link.aps.org/doi/10.1103/PhysRevLett.98.146401}, + doi = {10.1103/PhysRevLett.98.146401}, + language = {en}, + number = {14}, + urldate = {2024-08-14}, + journal = {Physical Review Letters}, + author = {Behler, Jörg and Parrinello, Michele}, + month = apr, + year = {2007}, + pages = {146401}, +} + +@article{lin_expanding_2024, + title = {Expanding density-correlation machine learning representations for anisotropic coarse-grained particles}, + volume = {161}, + issn = {0021-9606, 1089-7690}, + url = {https://pubs.aip.org/jcp/article/161/7/074112/3308992/Expanding-density-correlation-machine-learning}, + doi = {10.1063/5.0210910}, + abstract = {Physics-based, atom-centered machine learning (ML) representations have been instrumental to the effective integration of ML within the atomistic simulation community. Many of these representations build off the idea of atoms as having spherical, or isotropic, interactions. In many communities, there is often a need to represent groups of atoms, either to increase the computational efficiency of simulation via coarse-graining or to understand molecular influences on system behavior. In such cases, atom-centered representations will have limited utility, as groups of atoms may not be well-approximated as spheres. In this work, we extend the popular Smooth Overlap of Atomic Positions (SOAP) ML representation for systems consisting of non-spherical anisotropic particles or clusters of atoms. We show the power of this anisotropic extension of SOAP, which we deem AniSOAP, in accurately characterizing liquid crystal systems and predicting the energetics of Gay–Berne ellipsoids and coarse-grained benzene crystals. With our study of these prototypical anisotropic systems, we derive fundamental insights on how molecular shape influences mesoscale behavior and explain how to reincorporate important atom–atom interactions typically not captured by coarse-grained models. Moving forward, we propose AniSOAP as a flexible, unified framework for coarse-graining in complex, multiscale simulation.}, + language = {en}, + number = {7}, + urldate = {2024-09-24}, + journal = {The Journal of Chemical Physics}, + author = {Lin, Arthur and Huguenin-Dumittan, Kevin K. and Cho, Yong-Cheol and Nigam, Jigyasa and Cersonsky, Rose K.}, + month = aug, + year = {2024}, + pages = {074112}, + file = {Lin et al. - 2024 - Expanding density-correlation machine learning rep.pdf:/Users/alin62/Zotero/storage/HFIZ8QCS/Lin et al. - 2024 - Expanding density-correlation machine learning rep.pdf:application/pdf}, +} + +@misc{guillaume_fraux_metatensor_2024, + type = {Documentation}, + title = {Metatensor}, + url = {https://docs.metatensor.org/latest/index.html}, + urldate = {2024-09-23}, + journal = {Metatensor Documentation}, + author = {{Guillaume Fraux} and {Davide Tisi} and {Philip Loche} and {Joseph W. Abbott} and {Jigyasa Nigam} and {Chiheb Ben Mahmoud}}, + year = {2024}, +} + +@article{drautz_atomic_2019, + title = {Atomic cluster expansion for accurate and transferable interatomic potentials}, + volume = {99}, + issn = {2469-9950, 2469-9969}, + url = {https://link.aps.org/doi/10.1103/PhysRevB.99.014104}, + doi = {10.1103/PhysRevB.99.014104}, + language = {en}, + number = {1}, + urldate = {2024-09-24}, + journal = {Physical Review B}, + author = {Drautz, Ralf}, + month = jan, + year = {2019}, + pages = {014104}, +} + +@article{hjorth_larsen_atomic_2017, + title = {The atomic simulation environment—a {Python} library for working with atoms}, + volume = {29}, + issn = {0953-8984, 1361-648X}, + url = {https://iopscience.iop.org/article/10.1088/1361-648X/aa680e}, + doi = {10.1088/1361-648X/aa680e}, + number = {27}, + urldate = {2024-09-24}, + journal = {Journal of Physics: Condensed Matter}, + author = {Hjorth Larsen, Ask and Jørgen Mortensen, Jens and Blomqvist, Jakob and Castelli, Ivano E and Christensen, Rune and Dułak, Marcin and Friis, Jesper and Groves, Michael N and Hammer, Bjørk and Hargus, Cory and Hermes, Eric D and Jennings, Paul C and Bjerre Jensen, Peter and Kermode, James and Kitchin, John R and Leonhard Kolsbjerg, Esben and Kubal, Joseph and Kaasbjerg, Kristen and Lysgaard, Steen and Bergmann Maronsson, Jón and Maxson, Tristan and Olsen, Thomas and Pastewka, Lars and Peterson, Andrew and Rostgaard, Carsten and Schiøtz, Jakob and Schütt, Ole and Strange, Mikkel and Thygesen, Kristian S and Vegge, Tejs and Vilhelmsen, Lasse and Walter, Michael and Zeng, Zhenhua and Jacobsen, Karsten W}, + month = jul, + year = {2017}, + pages = {273002}, + file = {Full Text:/Users/alin62/Zotero/storage/L54WV5BX/Hjorth Larsen et al. - 2017 - The atomic simulation environment—a Python library.pdf:application/pdf}, +} + +@article{cersonsky_data-driven_2023, + title = {A data-driven interpretation of the stability of organic molecular crystals}, + volume = {14}, + issn = {2041-6520, 2041-6539}, + url = {https://xlink.rsc.org/?DOI=D2SC06198H}, + doi = {10.1039/D2SC06198H}, + abstract = {Due to the subtle balance of molecular interactions, predicting the stability of molecular crystals is a non-trivial scientific problem. Physically-motivated machine learning models can not only “rediscover” the maxims of crystal engineering, but also guide crystal design. + , + Due to the subtle balance of intermolecular interactions that govern structure–property relations, predicting the stability of crystal structures formed from molecular building blocks is a highly non-trivial scientific problem. A particularly active and fruitful approach involves classifying the different combinations of interacting chemical moieties, as understanding the relative energetics of different interactions enables the design of molecular crystals and fine-tuning of their stabilities. While this is usually performed based on the empirical observation of the most commonly encountered motifs in known crystal structures, we propose to apply a combination of supervised and unsupervised machine-learning techniques to automate the construction of an extensive library of molecular building blocks. We introduce a structural descriptor tailored to the prediction of the binding (lattice) energy and apply it to a curated dataset of organic crystals, exploiting its atom-centered nature to obtain a data-driven assessment of the contribution of different chemical groups to the lattice energy of the crystal. We then interpret this library using a low-dimensional representation of the structure–energy landscape and discuss selected examples of the insights into crystal engineering that can be extracted from this analysis, providing a complete database to guide the design of molecular materials.}, + language = {en}, + number = {5}, + urldate = {2024-09-24}, + journal = {Chemical Science}, + author = {Cersonsky, Rose K. and Pakhnova, Maria and Engel, Edgar A. and Ceriotti, Michele}, + year = {2023}, + pages = {1272--1285}, + file = {Full Text:/Users/alin62/Zotero/storage/EZ7PDXQ2/Cersonsky et al. - 2023 - A data-driven interpretation of the stability of o.pdf:application/pdf}, +} + +@article{de_comparing_2016, + title = {Comparing molecules and solids across structural and alchemical space}, + volume = {18}, + issn = {1463-9076, 1463-9084}, + url = {https://xlink.rsc.org/?DOI=C6CP00415F}, + doi = {10.1039/C6CP00415F}, + abstract = {A general procedure to compare molecules and materials powers insightful representations of energy landscapes and precise machine-learning predictions of properties. + , + + Evaluating the (dis)similarity of crystalline, disordered and molecular compounds is a critical step in the development of algorithms to navigate automatically the configuration space of complex materials. For instance, a structural similarity metric is crucial for classifying structures, searching chemical space for better compounds and materials, and driving the next generation of machine-learning techniques for predicting the stability and properties of molecules and materials. In the last few years several strategies have been designed to compare atomic coordination environments. In particular, the smooth overlap of atomic positions (SOAPs) has emerged as an elegant framework to obtain translation, rotation and permutation-invariant descriptors of groups of atoms, underlying the development of various classes of machine-learned inter-atomic potentials. Here we discuss how one can combine such local descriptors using a regularized entropy match (REMatch) approach to describe the similarity of both whole molecular and bulk periodic structures, introducing powerful metrics that enable the navigation of alchemical and structural complexities within a unified framework. Furthermore, using this kernel and a ridge regression method we can predict atomization energies for a database of small organic molecules with a mean absolute error below 1 kcal mol + −1 + , reaching an important milestone in the application of machine-learning techniques for the evaluation of molecular properties.}, + language = {en}, + number = {20}, + urldate = {2024-09-24}, + journal = {Physical Chemistry Chemical Physics}, + author = {De, Sandip and Bartók, Albert P. and Csányi, Gábor and Ceriotti, Michele}, + year = {2016}, + pages = {13754--13769}, + file = {Accepted Version:/Users/alin62/Zotero/storage/LWLJXCKR/De et al. - 2016 - Comparing molecules and solids across structural a.pdf:application/pdf}, +} + +@article{nguyen_systematic_2022, + title = {Systematic bottom-up molecular coarse-graining via force and torque matching using anisotropic particles}, + volume = {156}, + issn = {0021-9606, 1089-7690}, + url = {https://pubs.aip.org/jcp/article/156/18/184118/2841230/Systematic-bottom-up-molecular-coarse-graining-via}, + doi = {10.1063/5.0085006}, + abstract = {We derive a systematic and general method for parameterizing coarse-grained molecular models consisting of anisotropic particles from fine-grained (e.g., all-atom) models for condensed-phase molecular dynamics simulations. The method, which we call anisotropic force-matching coarse-graining (AFM-CG), is based on rigorous statistical mechanical principles, enforcing consistency between the coarse-grained and fine-grained phase-space distributions to derive equations for the coarse-grained forces, torques, masses, and moments of inertia in terms of properties of a condensed-phase fine-grained system. We verify the accuracy and efficiency of the method by coarse-graining liquid-state systems of two different anisotropic organic molecules, benzene and perylene, and show that the parameterized coarse-grained models more accurately describe properties of these systems than previous anisotropic coarse-grained models parameterized using other methods that do not account for finite-temperature and many-body effects on the condensed-phase coarse-grained interactions. The AFM-CG method will be useful for developing accurate and efficient dynamical simulation models of condensed-phase systems of molecules consisting of large, rigid, anisotropic fragments, such as liquid crystals, organic semiconductors, and nucleic acids.}, + language = {en}, + number = {18}, + urldate = {2024-08-14}, + journal = {The Journal of Chemical Physics}, + author = {Nguyen, Huong T. L. and Huang, David M.}, + month = may, + year = {2022}, + pages = {184118}, + file = {Full Text:/Users/alin62/Zotero/storage/F6RQNJMS/Nguyen and Huang - 2022 - Systematic bottom-up molecular coarse-graining via.pdf:application/pdf}, +} + +@article{durumeric_machine_2023, + title = {Machine learned coarse-grained protein force-fields: {Are} we there yet?}, + volume = {79}, + issn = {0959440X}, + shorttitle = {Machine learned coarse-grained protein force-fields}, + url = {https://linkinghub.elsevier.com/retrieve/pii/S0959440X23000076}, + doi = {10.1016/j.sbi.2023.102533}, + language = {en}, + urldate = {2024-07-15}, + journal = {Current Opinion in Structural Biology}, + author = {Durumeric, Aleksander E.P. and Charron, Nicholas E. and Templeton, Clark and Musil, Félix and Bonneau, Klara and Pasos-Trejo, Aldo S. and Chen, Yaoyi and Kelkar, Atharva and Noé, Frank and Clementi, Cecilia}, + month = apr, + year = {2023}, + keywords = {machine-learning, reading-list, review}, + pages = {102533}, + file = {Durumeric et al. - 2023 - Machine learned coarse-grained protein force-field.pdf:/Users/alin62/Zotero/storage/8UH5DUHM/Durumeric et al. - 2023 - Machine learned coarse-grained protein force-field.pdf:application/pdf}, +} + +@article{majewski_machine_2023, + title = {Machine learning coarse-grained potentials of protein thermodynamics}, + volume = {14}, + issn = {2041-1723}, + url = {https://www.nature.com/articles/s41467-023-41343-1}, + doi = {10.1038/s41467-023-41343-1}, + abstract = {Abstract + A generalized understanding of protein dynamics is an unsolved scientific problem, the solution of which is critical to the interpretation of the structure-function relationships that govern essential biological processes. Here, we approach this problem by constructing coarse-grained molecular potentials based on artificial neural networks and grounded in statistical mechanics. For training, we build a unique dataset of unbiased all-atom molecular dynamics simulations of approximately 9 ms for twelve different proteins with multiple secondary structure arrangements. The coarse-grained models are capable of accelerating the dynamics by more than three orders of magnitude while preserving the thermodynamics of the systems. Coarse-grained simulations identify relevant structural states in the ensemble with comparable energetics to the all-atom systems. Furthermore, we show that a single coarse-grained potential can integrate all twelve proteins and can capture experimental structural features of mutated proteins. These results indicate that machine learning coarse-grained potentials could provide a feasible approach to simulate and understand protein dynamics.}, + language = {en}, + number = {1}, + urldate = {2024-01-09}, + journal = {Nature Communications}, + author = {Majewski, Maciej and Pérez, Adrià and Thölke, Philipp and Doerr, Stefan and Charron, Nicholas E. and Giorgino, Toni and Husic, Brooke E. and Clementi, Cecilia and Noé, Frank and De Fabritiis, Gianni}, + month = sep, + year = {2023}, + pages = {5739}, + file = {Full Text:/Users/alin62/Zotero/storage/FXEXX4XN/Majewski et al. - 2023 - Machine learning coarse-grained potentials of prot.pdf:application/pdf}, +} + +@article{wang_machine_2019, + title = {Machine {Learning} of {Coarse}-{Grained} {Molecular} {Dynamics} {Force} {Fields}}, + volume = {5}, + copyright = {http://pubs.acs.org/page/policy/authorchoice\_termsofuse.html}, + issn = {2374-7943, 2374-7951}, + url = {https://pubs.acs.org/doi/10.1021/acscentsci.8b00913}, + doi = {10.1021/acscentsci.8b00913}, + language = {en}, + number = {5}, + urldate = {2024-07-30}, + journal = {ACS Central Science}, + author = {Wang, Jiang and Olsson, Simon and Wehmeyer, Christoph and Pérez, Adrià and Charron, Nicholas E. and De Fabritiis, Gianni and Noé, Frank and Clementi, Cecilia}, + month = may, + year = {2019}, + keywords = {machine-learning, optimal-representation, reading-list}, + pages = {755--767}, + file = {wang-et-al-2019-machine-learning-of-coarse-grained-molecular-dynamics-force-fields.pdf:/Users/alin62/Zotero/storage/C7LKQDWU/wang-et-al-2019-machine-learning-of-coarse-grained-molecular-dynamics-force-fields.pdf:application/pdf}, +} + +@article{wilson_anisotropic_2023, + title = {Anisotropic molecular coarse-graining by force and torque matching with neural networks}, + volume = {159}, + issn = {0021-9606, 1089-7690}, + url = {https://pubs.aip.org/jcp/article/159/2/024110/2901764/Anisotropic-molecular-coarse-graining-by-force-and}, + doi = {10.1063/5.0143724}, + abstract = {We develop a machine-learning method for coarse-graining condensed-phase molecular systems using anisotropic particles. The method extends currently available high-dimensional neural network potentials by addressing molecular anisotropy. We demonstrate the flexibility of the method by parametrizing single-site coarse-grained models of a rigid small molecule (benzene) and a semi-flexible organic semiconductor (sexithiophene), attaining structural accuracy close to the all-atom models for both molecules at a considerably lower computational expense. The machine-learning method of constructing the coarse-grained potential is shown to be straightforward and sufficiently robust to capture anisotropic interactions and many-body effects. The method is validated through its ability to reproduce the structural properties of the small molecule’s liquid phase and the phase transitions of the semi-flexible molecule over a wide temperature range.}, + language = {en}, + number = {2}, + urldate = {2024-09-24}, + journal = {The Journal of Chemical Physics}, + author = {Wilson, Marltan O. and Huang, David M.}, + month = jul, + year = {2023}, + pages = {024110}, + file = {Full Text:/Users/alin62/Zotero/storage/PP7I2X9X/Wilson and Huang - 2023 - Anisotropic molecular coarse-graining by force and.pdf:application/pdf}, +} diff --git a/paper/paper.md b/paper/paper.md new file mode 100644 index 0000000..b47ac9f --- /dev/null +++ b/paper/paper.md @@ -0,0 +1,160 @@ +--- +title: 'AniSOAP: Machine Learning Representations ' +tags: + - Python + - machine learning + - molecular simulation +# authors: +# - name: Adrian M. Price-Whelan +# orcid: 0000-0000-0000-0000 +# equal-contrib: true +# affiliation: "1, 2" # (Multiple affiliations must be quoted) +# - name: Author Without ORCID +# equal-contrib: true # (This is how you can denote equal contributions between multiple authors) +# affiliation: 2 +# - name: Author with no affiliation +# corresponding: true # (This is how to denote the corresponding author) +# affiliation: 3 +# - given-names: Ludwig +# dropping-particle: van +# surname: Beethoven +# affiliation: 3 +# affiliations: +# - name: Lyman Spitzer, Jr. Fellow, Princeton University, USA +# index: 1 +# - name: Institution Name, Country +# index: 2 +# - name: Independent Researcher, Country +# index: 3 +authors: + - name: Arthur Yan Lin + orcid: 0000-0000-0000-0000 + affiliation: 1 + - name: Lucas Ortengren + orcid: 0000-0000-0000-0000 + affiliation: 1 + - name: Seonwoo Hwang + orcid: 0000-0000-0000-0000 + affiliation: 1 + - name: Yong-Cheol Cho + orcid: 0000-0000-0000-0000 + affiliation: 1 + - name: Jigyasa Nigam + orcid: 0000-0000-0000-0000 + affiliation: 2 + - name: Rose K. Cersonsky + orcid: 0000-0000-0000-0000 + affiliation: 1 +affiliations: + - name: Department of Chemical and Biological Engineering, University of Wisconsin-Madison, USA + index: 1 + - name: Laboratory of Computational Science and Modeling, École Polytechnique Fédérale de Lausanne, Switzerland + index: 2 + - name: Department of Computer Science and Engineering, University of Wisconsin-Madison, USA + index: 3 + +date: 31 August 2024 +bibliography: paper.bib + +# Optional fields if submitting to a AAS journal too, see this blog post: +# https://blog.joss.theoj.org/2018/12/a-new-collaboration-with-aas-publishing +aas-doi: 10.3847/xxxxx <- update this with the DOI from AAS once you know it. +aas-journal: Astrophysical Journal <- The name of the AAS journal. +--- + +# Summary + +`AniSOAP` is a package that creates Machine Learning (ML) representations of non-spherical particle configurations; these representations can then be used in ML-driven simulations and analyses. This generalization of existing spherical ML representations therefore aims to bridge the gap between two scientific communities: The machine-learned atomistic simulation community, whose primary concern is obtaining fast and (quantum) accurate descriptions of the complex interactions occuring between (spherical) atoms, and the coarse-grained and colloid modeling community, whose primary concern is understanding emergent behavior of macroscopic particles with (plausibly) complex geometries. `AniSOAP` provide a common framework to answer scientific questions at the intersection of these two fields. + +# Statement of need + +Machine learning (ML) has greatly advanced atomistic molecular dynamics (MD), enabling 1. Quick and quantum-accurate MD simulations, and 2. Robust techniques to analyze simulation results. Key to these advancements are the increasingly sophisticated strategies used to *featurize* atomistic environments to sensitively differentiate different configurations; this has enabled supervised, semisupervised, and unsupervised studies across a wide variety of chemical spaces[@behler_atom-centered_2011; @bartok_representing_2013; @de_comparing_2016; @cersonsky_data-driven_2023] (more citations?). However, these techniques are often limited to atomistic resolution, as coarse-grained entities (``particles'' or groups of atoms) are not spherical and thus cannot be fully resolved with many atom-inspired ML representations. In these contexts, where molecules or particles have complex, anisotropic geometry, it is important to resolve the orientation-dependence of their interactions with neighboring particles. + +In this software, we present the implementation of AniSOAP, an anisotropic generalization of the popular Smooth Overlap of Atomic Positions (SOAP) featurization[@bartok_representing_2013]. The power of SOAP, like other atomistic featurizations, lies in the incorporation of relevant physical information and symmetries, creating numerically efficient, symmetrized, and high-body order ``fingerprints'' that are commonly used in creating complex interaction potentials and machine-learning-enabled analyses. AniSOAP extends SOAP by additionally enabling information about the particle geometry and orientation within its featurization. Hence, AniSOAP can be used as a geometrically accurate, high body-order coarse-grained (CG) featurization of molecular and macromolecular systems. As a generalization of SOAP, AniSOAP retains full compatibility with SOAP, and the two representations can be used together to represent molecules at multiple resolutions. + +This technology is motivated by the need to reduce computational complexity in molecular studies, either from a performance-based standpoint (despite high-performance capabilities, many systems cannot be simulated with all-atom resolution in reasonable times) or from a conceptual standpoint, as we may not always want to analyze the behavior of _atoms_, but superatomic entities, such as functional groups. +While CG has made enormous strides in accelerating simulation and analysis, it's important to note that most CG techniques still reduce macromolecules to a set of spherical beads. This is often adequate for dilute simulations, where the anisotropy of a group of atoms may not play a big role in determining system behavior. However, in concentrated or highly condensed systems (e.g., liquid crystals, glasses, molecular crystals), molecular anisotropy often plays a huge role in determining system behavior, and coarse-graining entities can lose a significant amount of information on the interactions within the system. Still, physically-grounded and tractable simulation of shaped particles is a long-standing challenge. The flexibility of the AniSOAP representation coupled with learning algorithms may help address these challenges, as we can build anisotropic potentials off of high-quality, first-principles data. + +By incorporating anisotropy, AniSOAP extends the advances of atomistic machine learning to coarse-grained and mesoscale systems. With the flexibility of machine learning algorithms and anchored by the concepts underlying the feature-rich SOAP representation, AniSOAP provides a promising conduit for providing data-driven insights to many chemical systems at different length and time-scales. + +# What is an AniSOAP vector? +An AniSOAP vector is a series of numbers that represents a system of ellipsoidal particles, which in the most general case, consists of $\geq 1$ particles with different positions, shapes, orientations, and species identifications. Essentially, this is very similar to other point-cloud representations used in atomistic machine learning, like SOAP[@bartok_representing_2013] or ACE[@drautz_atomic_2019], except for the fact that AniSOAP vectors incorporate additional geometric information. + +The AniSOAP vector captures $n$-body correlations between different particles, which means that it encodes information about a central particle and its interactions with $(n-1)$ of its neighbors. In the majority of cases, we take $n=3$, which we call "the power spectrum", which encodes information about each particle, and the distance and subtended angle from the central particle to each possible pair of two neighboring particles within a cutoff radius. Ocassionally, we take $n=2$, called "the radial spectrum" which only captures all pairwise interactions up to a cutoff radius. + +The radial spectra is built by expanding local atom density fields in terms of radial basis functions and spherical harmonics -- this construction ensures that the values are translationally, rotationally, and permutationally invariant. To obtain higher body order, we take higher order correlations of these radial spectra. These entries are stored in a multidimensional array using the `TensorMap` format in the package `metatensor`[@guillaume_fraux_metatensor_2024]; this multidimensional array is usually flattened into a 1-dimensional representation to be used in ML algorithms. These vectors are information-rich, and can be used in various machine learning models. Traditionally, the power spectrum is used as an input to shallower machine learning models, like gaussian processes or kernel/linear regresssion, to learn system energies and forces. The AniSOAP vector can also be used as an order parameter to describe phase transitions. Specific use-cases of AniSOAP can be seen in our paper here[@lin_expanding_2024]. + +# What does the AniSOAP package do to take a configuration and construct the representation? +The AniSOAP package currently takes in as input a list of frames in the `Atomic Simulation Environment` package[@hjorth_larsen_atomic_2017]. Each frame contains the particles' positions, dimensions, and orientations. If using periodic boundary conditions, the frame also needs the dimensions of the unit cell. Additional information about each frame can also be stored (e.g. the system energy) and used as a target for supervised ML. Note that while ASE terminology calls each particle an "atom", in the case of AniSOAP, the ellipsoidal bodies are often used to describe groups of atoms. + +With this information, one can construct an `EllipsoidalDensityProjection` object, whose main functionality is to calculate the expansion coefficients of the density field in each frame. One can take Clebsch-Gordan products of these expansion coefficients to create higher body-order descriptors. We provide all the functionality required for these processes, and an example of constructing an arbitrarily high body-order descriptor is shown in an example. We also provide the convenience method `power_spectrum` and `radial_spectrum` to calculate the 3-body and 2-body descriptors of each frame. + + + +# Conclusion and future developments +AniSOAP is a powerful featurization that can be used for supervised and unsupervised analyses of molecular systems. AniSOAP is under active development and we envision it being used in a wide variety of contexts. Below, we outline two AniSOAP development goals. + +Our first goal is to directly use the wide variety of ML driven techniques used in the atomistic simulation community to derive physical insights on the molecular level. In particular, one major use case of AniSOAP is to derive Machine-Learned Inter-_Particle_ Potentials (MLIPPs), which requires learning both energies and forces. While forces can be learned directly, it is preferable to obtain froces by taking gradients of learned energies as it enforces conservation of energy. We are currently working on efficient implementations of AniSOAP gradients to enable MD simulations. + +We are also interested in unifying the theory of MLIPPs with the vast theory and developments of bottom-up coarse-graining. While bottom-up coarse-graining has recently benefited from significantly neural network potentials[@wang_machine_2019; @majewski_machine_2023; @wilson_anisotropic_2023], such techniques typically have large data requirements due to the neural network architecture, which require more training data than shallower models, and the inherently low signal-to-noise of the training set due to high mapping degeneracy in coarse-grained models[@durumeric_machine_2023]. AniSOAP may remedy this data-barrier on two different fronts: AniSOAP based potentials tend to be shallow (linear/kernel regression), and the geometric accuracy of AniSOAP particles will significantly decrease the mapping degeneracy. We hope that these benefits can be tied with existing theoretical frameworks on anisotropic coarse-graining[@nguyen_systematic_2022] to create robust, interpretable, and practical tools to perform accurate molecular coarse-grained simulations. + +# References + + + + + + +