diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..a07e6b0ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +target/ +**/*.rs.bk +Cargo.lock + +.tox/ +build/ +dist/ +*.egg-info +__pycache__/ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_redirect.html b/_redirect.html new file mode 100644 index 000000000..4f607eaeb --- /dev/null +++ b/_redirect.html @@ -0,0 +1,9 @@ + + +
+ + + + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..e22946da0 --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/latest/.buildinfo b/latest/.buildinfo new file mode 100644 index 000000000..2768a09a3 --- /dev/null +++ b/latest/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 8b6cf372667946410ccdc2de10046502 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/latest/.doctrees/devdoc/explanations/architecture.doctree b/latest/.doctrees/devdoc/explanations/architecture.doctree new file mode 100644 index 000000000..01c49eb6c Binary files /dev/null and b/latest/.doctrees/devdoc/explanations/architecture.doctree differ diff --git a/latest/.doctrees/devdoc/explanations/index.doctree b/latest/.doctrees/devdoc/explanations/index.doctree new file mode 100644 index 000000000..d6c5ffe83 Binary files /dev/null and b/latest/.doctrees/devdoc/explanations/index.doctree differ diff --git a/latest/.doctrees/devdoc/explanations/interfaces.doctree b/latest/.doctrees/devdoc/explanations/interfaces.doctree new file mode 100644 index 000000000..bba32335e Binary files /dev/null and b/latest/.doctrees/devdoc/explanations/interfaces.doctree differ diff --git a/latest/.doctrees/devdoc/explanations/radial-integral.doctree b/latest/.doctrees/devdoc/explanations/radial-integral.doctree new file mode 100644 index 000000000..95c232cd1 Binary files /dev/null and b/latest/.doctrees/devdoc/explanations/radial-integral.doctree differ diff --git a/latest/.doctrees/devdoc/get-started.doctree b/latest/.doctrees/devdoc/get-started.doctree new file mode 100644 index 000000000..7a50b32db Binary files /dev/null and b/latest/.doctrees/devdoc/get-started.doctree differ diff --git a/latest/.doctrees/devdoc/how-to/index.doctree b/latest/.doctrees/devdoc/how-to/index.doctree new file mode 100644 index 000000000..92fbd8cb1 Binary files /dev/null and b/latest/.doctrees/devdoc/how-to/index.doctree differ diff --git a/latest/.doctrees/devdoc/how-to/new-calculator.doctree b/latest/.doctrees/devdoc/how-to/new-calculator.doctree new file mode 100644 index 000000000..4f4893c21 Binary files /dev/null and b/latest/.doctrees/devdoc/how-to/new-calculator.doctree differ diff --git a/latest/.doctrees/devdoc/how-to/profiling.doctree b/latest/.doctrees/devdoc/how-to/profiling.doctree new file mode 100644 index 000000000..362fe0eb6 Binary files /dev/null and b/latest/.doctrees/devdoc/how-to/profiling.doctree differ diff --git a/latest/.doctrees/devdoc/index.doctree b/latest/.doctrees/devdoc/index.doctree new file mode 100644 index 000000000..e961f3287 Binary files /dev/null and b/latest/.doctrees/devdoc/index.doctree differ diff --git a/latest/.doctrees/environment.pickle b/latest/.doctrees/environment.pickle new file mode 100644 index 000000000..dcce5c8a3 Binary files /dev/null and b/latest/.doctrees/environment.pickle differ diff --git a/latest/.doctrees/examples/compute-soap.doctree b/latest/.doctrees/examples/compute-soap.doctree new file mode 100644 index 000000000..f665231c0 Binary files /dev/null and b/latest/.doctrees/examples/compute-soap.doctree differ diff --git a/latest/.doctrees/examples/first-calculation.doctree b/latest/.doctrees/examples/first-calculation.doctree new file mode 100644 index 000000000..13764970d Binary files /dev/null and b/latest/.doctrees/examples/first-calculation.doctree differ diff --git a/latest/.doctrees/examples/index.doctree b/latest/.doctrees/examples/index.doctree new file mode 100644 index 000000000..7b4196ac3 Binary files /dev/null and b/latest/.doctrees/examples/index.doctree differ diff --git a/latest/.doctrees/examples/keys-selection.doctree b/latest/.doctrees/examples/keys-selection.doctree new file mode 100644 index 000000000..212d73b81 Binary files /dev/null and b/latest/.doctrees/examples/keys-selection.doctree differ diff --git a/latest/.doctrees/examples/long-range-descriptor.doctree b/latest/.doctrees/examples/long-range-descriptor.doctree new file mode 100644 index 000000000..8bb5ef021 Binary files /dev/null and b/latest/.doctrees/examples/long-range-descriptor.doctree differ diff --git a/latest/.doctrees/examples/profiling.doctree b/latest/.doctrees/examples/profiling.doctree new file mode 100644 index 000000000..d223ed484 Binary files /dev/null and b/latest/.doctrees/examples/profiling.doctree differ diff --git a/latest/.doctrees/examples/property-selection.doctree b/latest/.doctrees/examples/property-selection.doctree new file mode 100644 index 000000000..afcf5d758 Binary files /dev/null and b/latest/.doctrees/examples/property-selection.doctree differ diff --git a/latest/.doctrees/examples/sample-selection.doctree b/latest/.doctrees/examples/sample-selection.doctree new file mode 100644 index 000000000..bdef04ddd Binary files /dev/null and b/latest/.doctrees/examples/sample-selection.doctree differ diff --git a/latest/.doctrees/examples/sg_execution_times.doctree b/latest/.doctrees/examples/sg_execution_times.doctree new file mode 100644 index 000000000..b306999d8 Binary files /dev/null and b/latest/.doctrees/examples/sg_execution_times.doctree differ diff --git a/latest/.doctrees/examples/splined-radial-integral.doctree b/latest/.doctrees/examples/splined-radial-integral.doctree new file mode 100644 index 000000000..7fcf9facc Binary files /dev/null and b/latest/.doctrees/examples/splined-radial-integral.doctree differ diff --git a/latest/.doctrees/explanations/concepts.doctree b/latest/.doctrees/explanations/concepts.doctree new file mode 100644 index 000000000..136dabb7a Binary files /dev/null and b/latest/.doctrees/explanations/concepts.doctree differ diff --git a/latest/.doctrees/explanations/index.doctree b/latest/.doctrees/explanations/index.doctree new file mode 100644 index 000000000..b8992b032 Binary files /dev/null and b/latest/.doctrees/explanations/index.doctree differ diff --git a/latest/.doctrees/explanations/rotation_adapted.doctree b/latest/.doctrees/explanations/rotation_adapted.doctree new file mode 100644 index 000000000..a5dbf7e49 Binary files /dev/null and b/latest/.doctrees/explanations/rotation_adapted.doctree differ diff --git a/latest/.doctrees/explanations/soap.doctree b/latest/.doctrees/explanations/soap.doctree new file mode 100644 index 000000000..69e683181 Binary files /dev/null and b/latest/.doctrees/explanations/soap.doctree differ diff --git a/latest/.doctrees/get-started/featomic.doctree b/latest/.doctrees/get-started/featomic.doctree new file mode 100644 index 000000000..49240b7bf Binary files /dev/null and b/latest/.doctrees/get-started/featomic.doctree differ diff --git a/latest/.doctrees/get-started/index.doctree b/latest/.doctrees/get-started/index.doctree new file mode 100644 index 000000000..218ca7777 Binary files /dev/null and b/latest/.doctrees/get-started/index.doctree differ diff --git a/latest/.doctrees/get-started/installation.doctree b/latest/.doctrees/get-started/installation.doctree new file mode 100644 index 000000000..22791f4ab Binary files /dev/null and b/latest/.doctrees/get-started/installation.doctree differ diff --git a/latest/.doctrees/get-started/tutorials.doctree b/latest/.doctrees/get-started/tutorials.doctree new file mode 100644 index 000000000..6db9deb75 Binary files /dev/null and b/latest/.doctrees/get-started/tutorials.doctree differ diff --git a/latest/.doctrees/how-to/computing-soap.doctree b/latest/.doctrees/how-to/computing-soap.doctree new file mode 100644 index 000000000..d2d03d631 Binary files /dev/null and b/latest/.doctrees/how-to/computing-soap.doctree differ diff --git a/latest/.doctrees/how-to/index.doctree b/latest/.doctrees/how-to/index.doctree new file mode 100644 index 000000000..85537edb8 Binary files /dev/null and b/latest/.doctrees/how-to/index.doctree differ diff --git a/latest/.doctrees/how-to/keys-selection.doctree b/latest/.doctrees/how-to/keys-selection.doctree new file mode 100644 index 000000000..aa4adc35b Binary files /dev/null and b/latest/.doctrees/how-to/keys-selection.doctree differ diff --git a/latest/.doctrees/how-to/long-range.doctree b/latest/.doctrees/how-to/long-range.doctree new file mode 100644 index 000000000..136ca4139 Binary files /dev/null and b/latest/.doctrees/how-to/long-range.doctree differ diff --git a/latest/.doctrees/how-to/property-selection.doctree b/latest/.doctrees/how-to/property-selection.doctree new file mode 100644 index 000000000..458618753 Binary files /dev/null and b/latest/.doctrees/how-to/property-selection.doctree differ diff --git a/latest/.doctrees/how-to/sample-selection.doctree b/latest/.doctrees/how-to/sample-selection.doctree new file mode 100644 index 000000000..f8b95f4af Binary files /dev/null and b/latest/.doctrees/how-to/sample-selection.doctree differ diff --git a/latest/.doctrees/how-to/splined-radial-integral.doctree b/latest/.doctrees/how-to/splined-radial-integral.doctree new file mode 100644 index 000000000..d3db53d19 Binary files /dev/null and b/latest/.doctrees/how-to/splined-radial-integral.doctree differ diff --git a/latest/.doctrees/index.doctree b/latest/.doctrees/index.doctree new file mode 100644 index 000000000..c1df8ba93 Binary files /dev/null and b/latest/.doctrees/index.doctree differ diff --git a/latest/.doctrees/references/api/c/calculators.doctree b/latest/.doctrees/references/api/c/calculators.doctree new file mode 100644 index 000000000..8d1d022b9 Binary files /dev/null and b/latest/.doctrees/references/api/c/calculators.doctree differ diff --git a/latest/.doctrees/references/api/c/index.doctree b/latest/.doctrees/references/api/c/index.doctree new file mode 100644 index 000000000..57718171c Binary files /dev/null and b/latest/.doctrees/references/api/c/index.doctree differ diff --git a/latest/.doctrees/references/api/c/misc.doctree b/latest/.doctrees/references/api/c/misc.doctree new file mode 100644 index 000000000..aeae65a55 Binary files /dev/null and b/latest/.doctrees/references/api/c/misc.doctree differ diff --git a/latest/.doctrees/references/api/c/systems.doctree b/latest/.doctrees/references/api/c/systems.doctree new file mode 100644 index 000000000..374005dc0 Binary files /dev/null and b/latest/.doctrees/references/api/c/systems.doctree differ diff --git a/latest/.doctrees/references/api/cxx/calculators.doctree b/latest/.doctrees/references/api/cxx/calculators.doctree new file mode 100644 index 000000000..45e40bc13 Binary files /dev/null and b/latest/.doctrees/references/api/cxx/calculators.doctree differ diff --git a/latest/.doctrees/references/api/cxx/index.doctree b/latest/.doctrees/references/api/cxx/index.doctree new file mode 100644 index 000000000..646bef263 Binary files /dev/null and b/latest/.doctrees/references/api/cxx/index.doctree differ diff --git a/latest/.doctrees/references/api/cxx/misc.doctree b/latest/.doctrees/references/api/cxx/misc.doctree new file mode 100644 index 000000000..3e1ced095 Binary files /dev/null and b/latest/.doctrees/references/api/cxx/misc.doctree differ diff --git a/latest/.doctrees/references/api/cxx/systems.doctree b/latest/.doctrees/references/api/cxx/systems.doctree new file mode 100644 index 000000000..25c4a971e Binary files /dev/null and b/latest/.doctrees/references/api/cxx/systems.doctree differ diff --git a/latest/.doctrees/references/api/index.doctree b/latest/.doctrees/references/api/index.doctree new file mode 100644 index 000000000..fe7706de6 Binary files /dev/null and b/latest/.doctrees/references/api/index.doctree differ diff --git a/latest/.doctrees/references/api/python/basis.doctree b/latest/.doctrees/references/api/python/basis.doctree new file mode 100644 index 000000000..22f441f52 Binary files /dev/null and b/latest/.doctrees/references/api/python/basis.doctree differ diff --git a/latest/.doctrees/references/api/python/calculators.doctree b/latest/.doctrees/references/api/python/calculators.doctree new file mode 100644 index 000000000..532e89865 Binary files /dev/null and b/latest/.doctrees/references/api/python/calculators.doctree differ diff --git a/latest/.doctrees/references/api/python/cutoff.doctree b/latest/.doctrees/references/api/python/cutoff.doctree new file mode 100644 index 000000000..ae0c26078 Binary files /dev/null and b/latest/.doctrees/references/api/python/cutoff.doctree differ diff --git a/latest/.doctrees/references/api/python/density.doctree b/latest/.doctrees/references/api/python/density.doctree new file mode 100644 index 000000000..ade6641cf Binary files /dev/null and b/latest/.doctrees/references/api/python/density.doctree differ diff --git a/latest/.doctrees/references/api/python/index.doctree b/latest/.doctrees/references/api/python/index.doctree new file mode 100644 index 000000000..b80697480 Binary files /dev/null and b/latest/.doctrees/references/api/python/index.doctree differ diff --git a/latest/.doctrees/references/api/python/misc.doctree b/latest/.doctrees/references/api/python/misc.doctree new file mode 100644 index 000000000..415275a60 Binary files /dev/null and b/latest/.doctrees/references/api/python/misc.doctree differ diff --git a/latest/.doctrees/references/api/python/splines.doctree b/latest/.doctrees/references/api/python/splines.doctree new file mode 100644 index 000000000..bec277542 Binary files /dev/null and b/latest/.doctrees/references/api/python/splines.doctree differ diff --git a/latest/.doctrees/references/api/python/systems.doctree b/latest/.doctrees/references/api/python/systems.doctree new file mode 100644 index 000000000..59eebd459 Binary files /dev/null and b/latest/.doctrees/references/api/python/systems.doctree differ diff --git a/latest/.doctrees/references/api/python/utils/clebsch-gordan.doctree b/latest/.doctrees/references/api/python/utils/clebsch-gordan.doctree new file mode 100644 index 000000000..0752b52cd Binary files /dev/null and b/latest/.doctrees/references/api/python/utils/clebsch-gordan.doctree differ diff --git a/latest/.doctrees/references/api/python/utils/index.doctree b/latest/.doctrees/references/api/python/utils/index.doctree new file mode 100644 index 000000000..11f81dd57 Binary files /dev/null and b/latest/.doctrees/references/api/python/utils/index.doctree differ diff --git a/latest/.doctrees/references/api/python/utils/power-spectrum.doctree b/latest/.doctrees/references/api/python/utils/power-spectrum.doctree new file mode 100644 index 000000000..96e6310d6 Binary files /dev/null and b/latest/.doctrees/references/api/python/utils/power-spectrum.doctree differ diff --git a/latest/.doctrees/references/api/rust.doctree b/latest/.doctrees/references/api/rust.doctree new file mode 100644 index 000000000..635c4f116 Binary files /dev/null and b/latest/.doctrees/references/api/rust.doctree differ diff --git a/latest/.doctrees/references/api/torch/calculators.doctree b/latest/.doctrees/references/api/torch/calculators.doctree new file mode 100644 index 000000000..5028ea85b Binary files /dev/null and b/latest/.doctrees/references/api/torch/calculators.doctree differ diff --git a/latest/.doctrees/references/api/torch/cxx/calculators.doctree b/latest/.doctrees/references/api/torch/cxx/calculators.doctree new file mode 100644 index 000000000..6277d2e4d Binary files /dev/null and b/latest/.doctrees/references/api/torch/cxx/calculators.doctree differ diff --git a/latest/.doctrees/references/api/torch/cxx/index.doctree b/latest/.doctrees/references/api/torch/cxx/index.doctree new file mode 100644 index 000000000..b7aacb4f2 Binary files /dev/null and b/latest/.doctrees/references/api/torch/cxx/index.doctree differ diff --git a/latest/.doctrees/references/api/torch/index.doctree b/latest/.doctrees/references/api/torch/index.doctree new file mode 100644 index 000000000..abcfe11ad Binary files /dev/null and b/latest/.doctrees/references/api/torch/index.doctree differ diff --git a/latest/.doctrees/references/api/torch/systems.doctree b/latest/.doctrees/references/api/torch/systems.doctree new file mode 100644 index 000000000..80e748d87 Binary files /dev/null and b/latest/.doctrees/references/api/torch/systems.doctree differ diff --git a/latest/.doctrees/references/api/torch/utils/clebsch-gordan.doctree b/latest/.doctrees/references/api/torch/utils/clebsch-gordan.doctree new file mode 100644 index 000000000..81c2a4ffb Binary files /dev/null and b/latest/.doctrees/references/api/torch/utils/clebsch-gordan.doctree differ diff --git a/latest/.doctrees/references/api/torch/utils/index.doctree b/latest/.doctrees/references/api/torch/utils/index.doctree new file mode 100644 index 000000000..5cdd94bb3 Binary files /dev/null and b/latest/.doctrees/references/api/torch/utils/index.doctree differ diff --git a/latest/.doctrees/references/api/torch/utils/power-spectrum.doctree b/latest/.doctrees/references/api/torch/utils/power-spectrum.doctree new file mode 100644 index 000000000..84040267b Binary files /dev/null and b/latest/.doctrees/references/api/torch/utils/power-spectrum.doctree differ diff --git a/latest/.doctrees/references/calculators/atomic-composition.doctree b/latest/.doctrees/references/calculators/atomic-composition.doctree new file mode 100644 index 000000000..aec52d18a Binary files /dev/null and b/latest/.doctrees/references/calculators/atomic-composition.doctree differ diff --git a/latest/.doctrees/references/calculators/index.doctree b/latest/.doctrees/references/calculators/index.doctree new file mode 100644 index 000000000..b4908232a Binary files /dev/null and b/latest/.doctrees/references/calculators/index.doctree differ diff --git a/latest/.doctrees/references/calculators/lode-spherical-expansion.doctree b/latest/.doctrees/references/calculators/lode-spherical-expansion.doctree new file mode 100644 index 000000000..76e9804e4 Binary files /dev/null and b/latest/.doctrees/references/calculators/lode-spherical-expansion.doctree differ diff --git a/latest/.doctrees/references/calculators/neighbor-list.doctree b/latest/.doctrees/references/calculators/neighbor-list.doctree new file mode 100644 index 000000000..6d2f90bea Binary files /dev/null and b/latest/.doctrees/references/calculators/neighbor-list.doctree differ diff --git a/latest/.doctrees/references/calculators/soap-power-spectrum.doctree b/latest/.doctrees/references/calculators/soap-power-spectrum.doctree new file mode 100644 index 000000000..9eee9ec8b Binary files /dev/null and b/latest/.doctrees/references/calculators/soap-power-spectrum.doctree differ diff --git a/latest/.doctrees/references/calculators/soap-radial-spectrum.doctree b/latest/.doctrees/references/calculators/soap-radial-spectrum.doctree new file mode 100644 index 000000000..8021c22f8 Binary files /dev/null and b/latest/.doctrees/references/calculators/soap-radial-spectrum.doctree differ diff --git a/latest/.doctrees/references/calculators/sorted-distances.doctree b/latest/.doctrees/references/calculators/sorted-distances.doctree new file mode 100644 index 000000000..1201c59fa Binary files /dev/null and b/latest/.doctrees/references/calculators/sorted-distances.doctree differ diff --git a/latest/.doctrees/references/calculators/spherical-expansion-by-pair.doctree b/latest/.doctrees/references/calculators/spherical-expansion-by-pair.doctree new file mode 100644 index 000000000..50753b82d Binary files /dev/null and b/latest/.doctrees/references/calculators/spherical-expansion-by-pair.doctree differ diff --git a/latest/.doctrees/references/calculators/spherical-expansion.doctree b/latest/.doctrees/references/calculators/spherical-expansion.doctree new file mode 100644 index 000000000..c0cd9ac40 Binary files /dev/null and b/latest/.doctrees/references/calculators/spherical-expansion.doctree differ diff --git a/latest/.doctrees/references/index.doctree b/latest/.doctrees/references/index.doctree new file mode 100644 index 000000000..dadce8391 Binary files /dev/null and b/latest/.doctrees/references/index.doctree differ diff --git a/latest/_downloads/081634a43959105f7f41a7682e76d405/property-selection.ipynb b/latest/_downloads/081634a43959105f7f41a7682e76d405/property-selection.ipynb new file mode 100644 index 000000000..b412db67f --- /dev/null +++ b/latest/_downloads/081634a43959105f7f41a7682e76d405/property-selection.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Property Selection\n\n.. start-body\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import chemfiles\nimport numpy as np\nfrom metatensor import Labels, MetatensorError, TensorBlock, TensorMap\nfrom skmatter.feature_selection import FPS\n\nfrom featomic import SoapPowerSpectrum" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we load the dataset with chemfiles\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "with chemfiles.Trajectory(\"dataset.xyz\") as trajectory:\n frames = [f for f in trajectory]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and define the hyper parameters of the representation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "HYPER_PARAMETERS = {\n \"cutoff\": {\n \"radius\": 5.0,\n \"smoothing\": {\"type\": \"ShiftedCosine\", \"width\": 0.5},\n },\n \"density\": {\n \"type\": \"Gaussian\",\n \"width\": 0.3,\n },\n \"basis\": {\n \"type\": \"TensorProduct\",\n \"max_angular\": 4,\n \"radial\": {\"type\": \"Gto\", \"max_radial\": 6},\n },\n}\n\ncalculator = SoapPowerSpectrum(**HYPER_PARAMETERS)\n\ndescriptor = calculator.compute(frames)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The selections for feature can be a set of ``Labels``, in which case the names\nof the labels must be a subset of the names of the properties produced by the\ncalculator. You can see the default set of names with:\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(\"property names:\", descriptor.property_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use a subset of these names to define a selection. In this case, only\nproperties matching the labels in this selection will be used by featomic\n(here, only properties with ``l = 0`` will be used)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "selection = Labels(\n names=[\"l\"],\n values=np.array([[0]]),\n)\nselected_descriptor = calculator.compute(frames, selected_properties=selection)\n\nselected_descriptor = selected_descriptor.keys_to_samples(\"center_type\")\nselected_descriptor = selected_descriptor.keys_to_properties(\n [\"neighbor_1_type\", \"neighbor_2_type\"]\n)\n\nproperties = selected_descriptor.block().properties" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We expect to get `[0]` as the list of `l` properties\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(f\"we have the following angular components: {np.unique(properties['l'])}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The previous selection method uses the same selection for all blocks. If you\ncan to use different selection for different blocks, you should use a\n``TensorMap`` to create your selection\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "selected_descriptor = calculator.compute(frames, selected_properties=selection)\ndescriptor_for_comparison = calculator.compute(\n frames, selected_properties=selected_descriptor\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The descriptor had 180 properties stored in the first block, the\nselected_descriptor had 36. So ``descriptor_for_comparison`` will also have 36\nproperties.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(\"shape of first block initially:\", descriptor.block(0).values.shape)\nprint(\"shape of first block of reference:\", selected_descriptor.block(0).values.shape)\nprint(\n \"shape of first block after selection:\",\n descriptor_for_comparison.block(0).values.shape,\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``TensorMap`` format allows us to select different features within each\nblock, and then construct a general matrix of features. We can select the most\nsignificant features using FPS, which selects features based on the distance\nbetween them. The following code snippet selects the 10 most important\nfeatures in each block, then constructs a TensorMap containing this selection,\nand calculates the final matrix of features for it.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def fps_feature_selection(descriptor, n_to_select):\n \"\"\"\n Select ``n_to_select`` features block by block in the ``descriptor``, using\n Farthest Point Sampling to do the selection; and return a ``TensorMap`` with\n the right structure to be used as properties selection with featomic calculators\n \"\"\"\n blocks = []\n for block in descriptor:\n # create a separate FPS selector for each block\n fps = FPS(n_to_select=n_to_select)\n mask = fps.fit(block.values).get_support()\n selected_properties = Labels(\n names=block.properties.names,\n values=block.properties.values[mask],\n )\n # The only important data here is the properties, so we create empty\n # sets of samples and components.\n blocks.append(\n TensorBlock(\n values=np.empty((1, len(selected_properties))),\n samples=Labels.single(),\n components=[],\n properties=selected_properties,\n )\n )\n\n return TensorMap(descriptor.keys, blocks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can then apply this function to subselect according to the data contained\nin a descriptor\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "selection = fps_feature_selection(descriptor, n_to_select=10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and use the selection with featomic, potentially running the calculation on a\ndifferent set of systems\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "selected_descriptor = calculator.compute(frames, selected_properties=selection)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that in this case it is no longer possible to have a single feature\nmatrix, because each block will have its own properties.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "try:\n selected_descriptor.keys_to_samples(\"center_type\")\nexcept MetatensorError as err:\n print(err)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ".. end-body\n\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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/latest/_downloads/157269325187c1e5cc5b17bff969fe70/profiling.py b/latest/_downloads/157269325187c1e5cc5b17bff969fe70/profiling.py new file mode 100644 index 000000000..9253a32cb --- /dev/null +++ b/latest/_downloads/157269325187c1e5cc5b17bff969fe70/profiling.py @@ -0,0 +1,65 @@ +""" +Profiling calculation +===================== + +.. start-body +""" + +import chemfiles + +import featomic +from featomic import SoapPowerSpectrum + + +def compute_soap(path): + """Compute SOAP power spectrum. + + This is the same code as the 'compute-soap' example + """ + with chemfiles.Trajectory(path) as trajectory: + frames = [f for f in trajectory] + + HYPER_PARAMETERS = { + "cutoff": { + "radius": 5.0, + "smoothing": {"type": "ShiftedCosine", "width": 0.5}, + }, + "density": { + "type": "Gaussian", + "width": 0.3, + }, + "basis": { + "type": "TensorProduct", + "max_angular": 4, + "radial": {"type": "Gto", "max_radial": 6}, + }, + } + + calculator = SoapPowerSpectrum(**HYPER_PARAMETERS) + descriptor = calculator.compute(frames, gradients=["positions"]) + descriptor = descriptor.keys_to_samples("center_type") + descriptor = descriptor.keys_to_properties(["neighbor_1_type", "neighbor_2_type"]) + + return descriptor + + +# %% +# +# Run the calculation with profiling enabled. + +with featomic.Profiler() as profiler: + descriptor = compute_soap("dataset.xyz") +# %% +# +# Display the recorded profiling data as table. + +print(profiler.as_short_table()) + +# %% +# +# You can also save this data as json for future usage +print(profiler.as_json()) + +# %% +# +# .. end-body diff --git a/latest/_downloads/1dcd7388f9219fe5f08cc17fa4fa2d0d/property-selection.py b/latest/_downloads/1dcd7388f9219fe5f08cc17fa4fa2d0d/property-selection.py new file mode 100644 index 000000000..e50407f31 --- /dev/null +++ b/latest/_downloads/1dcd7388f9219fe5f08cc17fa4fa2d0d/property-selection.py @@ -0,0 +1,168 @@ +""" +Property Selection +================== + +.. start-body +""" + +import chemfiles +import numpy as np +from metatensor import Labels, MetatensorError, TensorBlock, TensorMap +from skmatter.feature_selection import FPS + +from featomic import SoapPowerSpectrum + + +# %% +# +# First we load the dataset with chemfiles + +with chemfiles.Trajectory("dataset.xyz") as trajectory: + frames = [f for f in trajectory] + +# %% +# +# and define the hyper parameters of the representation + +HYPER_PARAMETERS = { + "cutoff": { + "radius": 5.0, + "smoothing": {"type": "ShiftedCosine", "width": 0.5}, + }, + "density": { + "type": "Gaussian", + "width": 0.3, + }, + "basis": { + "type": "TensorProduct", + "max_angular": 4, + "radial": {"type": "Gto", "max_radial": 6}, + }, +} + +calculator = SoapPowerSpectrum(**HYPER_PARAMETERS) + +descriptor = calculator.compute(frames) + +# %% +# +# The selections for feature can be a set of ``Labels``, in which case the names +# of the labels must be a subset of the names of the properties produced by the +# calculator. You can see the default set of names with: + +print("property names:", descriptor.property_names) + +# %% +# +# We can use a subset of these names to define a selection. In this case, only +# properties matching the labels in this selection will be used by featomic +# (here, only properties with ``l = 0`` will be used) + +selection = Labels( + names=["l"], + values=np.array([[0]]), +) +selected_descriptor = calculator.compute(frames, selected_properties=selection) + +selected_descriptor = selected_descriptor.keys_to_samples("center_type") +selected_descriptor = selected_descriptor.keys_to_properties( + ["neighbor_1_type", "neighbor_2_type"] +) + +properties = selected_descriptor.block().properties + +# %% +# +# We expect to get `[0]` as the list of `l` properties + +print(f"we have the following angular components: {np.unique(properties['l'])}") + +# %% +# +# The previous selection method uses the same selection for all blocks. If you +# can to use different selection for different blocks, you should use a +# ``TensorMap`` to create your selection + +selected_descriptor = calculator.compute(frames, selected_properties=selection) +descriptor_for_comparison = calculator.compute( + frames, selected_properties=selected_descriptor +) + +# %% +# +# The descriptor had 180 properties stored in the first block, the +# selected_descriptor had 36. So ``descriptor_for_comparison`` will also have 36 +# properties. +print("shape of first block initially:", descriptor.block(0).values.shape) +print("shape of first block of reference:", selected_descriptor.block(0).values.shape) +print( + "shape of first block after selection:", + descriptor_for_comparison.block(0).values.shape, +) + +# %% +# +# The ``TensorMap`` format allows us to select different features within each +# block, and then construct a general matrix of features. We can select the most +# significant features using FPS, which selects features based on the distance +# between them. The following code snippet selects the 10 most important +# features in each block, then constructs a TensorMap containing this selection, +# and calculates the final matrix of features for it. + + +def fps_feature_selection(descriptor, n_to_select): + """ + Select ``n_to_select`` features block by block in the ``descriptor``, using + Farthest Point Sampling to do the selection; and return a ``TensorMap`` with + the right structure to be used as properties selection with featomic calculators + """ + blocks = [] + for block in descriptor: + # create a separate FPS selector for each block + fps = FPS(n_to_select=n_to_select) + mask = fps.fit(block.values).get_support() + selected_properties = Labels( + names=block.properties.names, + values=block.properties.values[mask], + ) + # The only important data here is the properties, so we create empty + # sets of samples and components. + blocks.append( + TensorBlock( + values=np.empty((1, len(selected_properties))), + samples=Labels.single(), + components=[], + properties=selected_properties, + ) + ) + + return TensorMap(descriptor.keys, blocks) + + +# %% +# +# We can then apply this function to subselect according to the data contained +# in a descriptor + +selection = fps_feature_selection(descriptor, n_to_select=10) + +# %% +# +# and use the selection with featomic, potentially running the calculation on a +# different set of systems + +selected_descriptor = calculator.compute(frames, selected_properties=selection) + +# %% +# +# Note that in this case it is no longer possible to have a single feature +# matrix, because each block will have its own properties. + +try: + selected_descriptor.keys_to_samples("center_type") +except MetatensorError as err: + print(err) + +# %% +# +# .. end-body diff --git a/latest/_downloads/1fca5afa28681412baa1843c260225ba/sample-selection.py b/latest/_downloads/1fca5afa28681412baa1843c260225ba/sample-selection.py new file mode 100644 index 000000000..6f5226aad --- /dev/null +++ b/latest/_downloads/1fca5afa28681412baa1843c260225ba/sample-selection.py @@ -0,0 +1,142 @@ +""" +Sample Selection +================ + +.. start-body +""" + +import chemfiles +import numpy as np +from metatensor import Labels + +from featomic import SoapPowerSpectrum + + +# %% +# +# First we load the dataset with chemfiles + +with chemfiles.Trajectory("dataset.xyz") as trajectory: + frames = [f for f in trajectory] + +# %% +# +# and define the hyper parameters of the representation + +HYPER_PARAMETERS = { + "cutoff": { + "radius": 5.0, + "smoothing": {"type": "ShiftedCosine", "width": 0.5}, + }, + "density": { + "type": "Gaussian", + "width": 0.3, + }, + "basis": { + "type": "TensorProduct", + "max_angular": 4, + "radial": {"type": "Gto", "max_radial": 6}, + }, +} + +calculator = SoapPowerSpectrum(**HYPER_PARAMETERS) + +descriptor = calculator.compute(frames) + +# %% +# +# The selections for sample can be a set of ``Labels``, in which case the names +# of the labels must be a subset of the names of the samples produced by the +# calculator. You can see the default set of names with: + +print("sample names:", descriptor.sample_names) + +# %% +# +# We can use a subset of these names to define a selection. In this case, only +# samples matching the labels in this selection will be used by featomic (here, +# only atoms from system 0, 2, and 3) + +selection = Labels( + names=["system"], + values=np.array([[0], [2], [3]]), +) + +descriptor_selected = calculator.compute(frames, selected_samples=selection) + +descriptor_selected = descriptor_selected.keys_to_samples("center_type") +descriptor_selected = descriptor_selected.keys_to_properties( + ["neighbor_1_type", "neighbor_2_type"] +) + +samples = descriptor_selected.block().samples + +# %% +# +# The first block should have ``[0, 2, 3]`` as ``samples["system"]`` + +print(f"we have the following systems: {np.unique(samples['system'])}") + +# %% +# +# If we want to select not only based on the system indexes but also atomic +# indexes, we can do the following (here we select atom 0 in the first system +# and atom 1 in the third system): + +selection = Labels( + names=["system", "atom"], + values=np.array([[0, 0], [2, 1]]), +) + +descriptor_selected = calculator.compute(frames, selected_samples=selection) +descriptor_selected = descriptor_selected.keys_to_samples("center_type") +descriptor_selected = descriptor_selected.keys_to_properties( + ["neighbor_1_type", "neighbor_2_type"] +) + +# %% +# +# The values will have 2 rows, since we have two samples: + +print( + "shape of first block of descriptor:", + descriptor_selected.block(0).values.shape, +) + +# %% +# +# The previous selection method uses the same selection for all blocks. If you +# can to use different selection for different blocks, you should use a +# `TensorMap` to create your selection + +descriptor = calculator.compute(frames) +descriptor_selected = calculator.compute(frames, selected_samples=selection) + +# %% +# +# notice how we are passing a TensorMap as the ``selected_samples`` argument: + +print(type(descriptor_selected)) +descriptor_for_comparison = calculator.compute( + frames, selected_samples=descriptor_selected +) + +# %% +# +# The descriptor had 420 samples stored in the first block, +# the ``descriptor_selected`` had 0. So ``descriptor_for_comparison`` +# will also have 0 samples. + +print("shape of first block initially:", descriptor.block(0).values.shape) +print( + "shape of first block of reference:", + descriptor_selected.block(0).values.shape, +) +print( + "shape of first block after selection:", + descriptor_for_comparison.block(0).values.shape, +) + +# %% +# +# .. end-body diff --git a/latest/_downloads/2ec60c786c8a5f204193e244b399a9a4/profiling.zip b/latest/_downloads/2ec60c786c8a5f204193e244b399a9a4/profiling.zip new file mode 100644 index 000000000..7105cea9b Binary files /dev/null and b/latest/_downloads/2ec60c786c8a5f204193e244b399a9a4/profiling.zip differ diff --git a/latest/_downloads/33cbf89244c381c85dfb98b83889ff69/first-calculation.ipynb b/latest/_downloads/33cbf89244c381c85dfb98b83889ff69/first-calculation.ipynb new file mode 100644 index 000000000..a6ea5a0cc --- /dev/null +++ b/latest/_downloads/33cbf89244c381c85dfb98b83889ff69/first-calculation.ipynb @@ -0,0 +1,399 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n\n# First descriptor computation\n\nThis is an introduction to the featomic interface using a molecular crystals\ndataset using the Python interface. If you are interested in another\nprogramming language we recommend you first follow this tutorial and afterward\ntake a look at the how-to guide on `userdoc-how-to-computing-soap`.\n\n## The dataset\n\nThe atomic configurations used in our documentation are a small subset of the\n[ShiftML2 dataset](https://pubs.acs.org/doi/pdf/10.1021/acs.jpcc.2c03854)\ncontaining molecular crystals. There are four crystals - one with each of the\nelements [hydrogen, carbon], [hydrogen, carbon, nitrogen, oxygen], [hydrogen,\ncarbon, nitrogen], or [hydrogen, carbon, oxygen]. Each crystal has 10 structures,\nalso denoted by frames, attributed to it. The first frame of each crystal structure\nis the geometry-optimized frame. The following 9 frames contain atoms that are\nslightly displaced from the geometry-optimized frame. You can obtain the dataset\nfrom our :download:`website <../../static/dataset.xyz>`.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will start by importing all the required packages: the classic numpy;\nchemfiles to load data, and featomic to compute representations. Afterward\nwe will load the dataset using chemfiles.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import chemfiles\nimport numpy as np\n\nfrom featomic import SphericalExpansion\n\n\nwith chemfiles.Trajectory(\"dataset.xyz\") as trajectory:\n frames = [f for f in trajectory]\n\nprint(f\"The dataset contains {len(frames)} frames.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will not explain here how to use chemfiles in detail, as we only use a few\nfunctions. Briefly, :class:`chemfiles.Trajectory` loads structure data in a\nformat featomic can use. If you want to learn more about the possibilities\ntake a look at the [chemfiles documentation](https://chemfiles.org).\n\nLet us now take a look at the first frame of the dataset.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "frame0 = frames[0]\n\nprint(frame0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With ``frame0.atoms`` we get a list of the atoms that make up frame zero.\nThe ``name`` attribute gives us the name of the specified atom.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "elements, counts = np.unique([atom.name for atom in frame0.atoms], return_counts=True)\n\nprint(\n f\"The first frame contains \"\n f\"{counts[0]} {elements[0]}-atoms, \"\n f\"{counts[1]} {elements[1]}-atoms, \"\n f\"{counts[2]} {elements[2]}-atoms and \"\n f\"{counts[3]} {elements[3]}-atoms.\"\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Calculate a descriptor\n\nWe will now calculate an atomic descriptor for this structure using the SOAP\nspherical expansion as introduced by [Bart\u00f3k, Kondor, and Cs\u00e1nyi](http://dx.doi.org/10.1103/PhysRevB.87.184115).\n\nTo do so we define below a set of parameters telling featomic how the\nspherical expansion should be calculated. These parameters are also called\nhyper parameters since they are parameters of the representation, in\nopposition to parameters of machine learning models. Hyper parameters are a\ncrucial part of calculating descriptors. Poorly selected hyper parameters will\nlead to a poor description of your dataset as discussed in the [literature](https://arxiv.org/abs/1502.02127).\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cutoff = {\n \"radius\": 4.5,\n \"smoothing\": {\"type\": \"ShiftedCosine\", \"width\": 0.5},\n}\n\ndensity = {\n \"type\": \"Gaussian\",\n \"width\": 0.3,\n \"radial_scaling\": {\n \"type\": \"Willatt2018\",\n \"scale\": 2.0,\n \"rate\": 1.0,\n \"exponent\": 4,\n },\n}\n\nbasis = {\n \"type\": \"TensorProduct\",\n \"max_angular\": 5,\n \"radial\": {\"type\": \"Gto\", \"max_radial\": 8},\n}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After we set the hyper parameters we initialize a\n:class:`featomic.calculators.SphericalExpansion` object with hyper parameters\ndefined above and run the\n:py:func:`featomic.calculators.CalculatorBase.compute()` method.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "calculator = SphericalExpansion(cutoff=cutoff, density=density, basis=basis)\ndescriptor0 = calculator.compute(frame0)\nprint(type(descriptor0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The descriptor format is a :class:`metatensor.TensorMap` object. Metatensor is\nlike numpy for storing representations of atomistic ML data. Extensive details\non the metatensor are covered in the [corresponding documentation](https://lab-cosmo.github.io/metatensor/).\n\nWe will now have a look at how the data is stored inside\n:class:`metatensor.TensorMap` objects.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(descriptor0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The :class:`metatensor.TensorMap` is structured in several instances of an\n:class:`metatensor.TensorBlock`. To distinguish the block each block is associated\nwith a unique key. For the current example, we have one block for each angular channel\nlabeled by ``o3_lambda``, the central atom type ``center_type`` and\nneighbor atom type labeled by ``neighbor_type``. Different atomic types are\nrepresented using their atomic number, e.g. 1 for hydrogen, 6 for carbon, etc. To\nsummarize, this descriptor contains 112 blocks covering all combinations of the\nangular channels of the central and neighbor atom types in our dataset.\n\nLet us take a look at the second block (at index 1) in detail. This block contains the\ndescriptor for the $l=1$ angular channel for hydrogen-hydrogen pairs.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "block = descriptor0.block(1)\nprint(descriptor0.keys[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The descriptor values\n\nThe values of the representation are stored as an array. Each entry in this\narray also has associated unique metadata as each block. For the spherical\nexpansion calculator used in this tutorial the values have three dimensions\nwhich we can verify from the ``.shape`` attribute.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.values.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The descriptor values\n\nThe first dimension is denoted by the `samples`, the intermediate dimension by\n`components`, and the last dimension by `properties`. The \"sample dimension\"\nhas a length of eight because we have eight hydrogen atoms in the first frame.\nWe can reveal more detailed metadata information about the sample-dimension\nprinting of the :py:attr:`metatensor.TensorBlock.samples` attribute of the\nblock\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.samples)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The result is an :class:`metatensor.TensorMap` instance. It contains in total\neight tuples each with two values. The tuple values are named as follows\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.samples.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Meaning that the first entry of each tuple indicates the _structure_, which is\n0 for all because we only computed the representation of a single frame. The\nsecond entry of each tuple refers to the index of the _center_ atom.\n\nWe can do a similar investigation for the second dimension: the\n:py:attr:`metatensor.TensorBlock.components`.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.components)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, the components are associated with the angular channels of the\nrepresentation. The size of ``o3_mu`` is $2l + 1$, where\n$l$ is the current ``o3_lambda`` of the block. Here, its\ndimension is three because we are looking at the ``o3_lambda=1``\nblock. You may have noticed that the return value of the last call is a\n:class:`list` of :class:`metatensor.Labels` and not a single ``Labels``\ninstance. The reason is that a block can have several component dimensions as\nwe will see below for the gradients.\n\nThe last value represents the number of radial channels. For the\n:py:attr:`metatensor.TensorBlock.properties` dimension we find an object\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.properties)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "containing a tuple of only one value ranging from 0 to 8. The name of this entry is\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.properties.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and denoting the radial channels. The range results from our choice of\n``max_radial = 9`` in the hyper parameters above.\n\nAfter looking at the metadata we can investigate the actual data of the\nrepresentation in more details\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(block.values[0, 0, :])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By using ``[0, 0, :]`` we selected the first hydrogen and the first ``m``\nchannel. As you the output shows the values are floating point numbers between\n``-1.0`` and ``1.0``. Values in this range are reasonable and can be directly\nused as input for a machine learning algorithm.\n\nFeatomic is also able to process more than one structure within one function\ncall. You can process a whole dataset with\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "descriptor_full = calculator.compute(frames)\n\nblock_full = descriptor_full.block(0)\nprint(block_full.values.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, the 0th block of the :class:`metatensor.TensorMap` contains not eight but\n420 entries in the first dimensions. This reflects the fact that in total we\nhave 420 hydrogen atoms in the whole dataset.\n\nIf you want to use another calculator instead of\n:class:`featomic.calculators.SphericalExpansion` shown here check out the\n`userdoc-references` section.\n\n## Computing gradients\n\nAdditionally, featomic is also able to calculate gradients on top of the\nvalues. Gradients are useful for constructing an ML potential and running\nsimulations. For example ``gradients`` of the representation with respect to\natomic positions can be calculated by setting the ``gradients`` parameter of\nthe :py:func:`featomic.calculators.CalculatorBase.compute()` method to\n``[\"positions\"]``.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "descriptor_gradients = calculator.compute(frame0, gradients=[\"positions\"])\n\nblock_gradients = descriptor_gradients.block(0)\ngradient_position = block_gradients.gradient(\"positions\")\n\nprint(gradient_position.values.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The calculated descriptor contains the values and in each block the associated\nposition gradients as an :class:`metatensor.block.Gradient` instance. The\nactual values are stored in the ``data`` attribute. Similar to the features\nthe gradient data also has associated metadata. But, compared to the values\nwere we found three dimensions, and gradients have four. Again the first is\ncalled `samples` and the `properties`. The dimensions between the sample and\nproperty dimensions are denoted by `components`.\n\nLooking at the shape in more detail we find that we have 52 samples, which is\nmuch more compared to features where we only have eight samples. This arises\nfrom the fact that we calculate the position gradient for each pair in the\nstructure. For our selected block these are all hydrogen-hydrogen pairs.\nNaively one would come up with ``8 * 8 = 64`` samples, but featomic already\nignores pairs that are outside of the cutoff radius. Their position gradient\nis always zero. The :attr:`metatensor.block.Gradient.samples` attribute shows\nthis in detail.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(gradient_position.samples)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we have a tuple of three with the names\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(gradient_position.samples.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above output of the Labels instance for example the `(2, 0, 17)` entry\nis missing indicating that this pair is outside of the cutoff.\n\nNow looking at the :attr:`metatensor.block.Gradient.components`\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(gradient_position.components)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "we find two of them. Besides the `o3_mu` component that is also present in the\nfeatures position gradients also have a component indicating the direction of the\ngradient vector.\n\nFinally, the :attr:`metatensor.block.Gradient.properties` dimension is the same as for\nthe values\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(gradient_position.properties)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Featomic can also calculate gradients with respect to the strain (i.e. the virial).\nFor this, you have to add ``\"strain\"`` to the list parsed to the ``gradients``\nparameter of the :py:func:`featomic.calculators.CalculatorBase.compute()` method.\nStrain gradients/virial are useful when computing the stress and the pressure.\n\nIf you want to know about the effect of changing hypers take a look at the next\ntutorial. If you want to solve an explicit problem our `userdoc-how-to` might\nhelp you.\n\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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/latest/_downloads/36d886e596f0b08a8c0e4ccbd309a891/long-range-descriptor.py b/latest/_downloads/36d886e596f0b08a8c0e4ccbd309a891/long-range-descriptor.py new file mode 100644 index 000000000..a31191746 --- /dev/null +++ b/latest/_downloads/36d886e596f0b08a8c0e4ccbd309a891/long-range-descriptor.py @@ -0,0 +1,391 @@ +""" +.. _userdoc-tutorials-long-range-descriptor: + +Long-range only LODE descriptor +=============================== + +.. start-body + +We start the example by loading the required packages +""" + +# %% + +import ase +import ase.visualize.plot +import matplotlib.pyplot as plt +import numpy as np +from ase.build import molecule +from metatensor import LabelsEntry, TensorMap + +import featomic +from featomic import LodeSphericalExpansion, SphericalExpansion + + +# %% +# +# **Single water molecule (short range) system** +# +# Our first test system is a single water molecule with a :math:`15\,\mathrm{Å}` +# vacuum layer around it. + + +atoms = molecule("H2O", vacuum=15, pbc=True) + +# %% +# We choose a ``cutoff`` for the projection of the spherical expansion and the +# neighbor search of the real space spherical expansion. + +cutoff = 3 + +# %% +# We can use ase's visualization tools to plot the system and draw a gray circle to +# indicate the ``cutoff`` radius. + +fig, ax = plt.subplots() + +ase.visualize.plot.plot_atoms(atoms) + +cutoff_circle = plt.Circle( + xy=atoms[0].position[:2], + radius=cutoff, + color="gray", + ls="dashed", + fill=False, +) +ax.add_patch(cutoff_circle) + +ax.set_xlabel("Å") +ax.set_ylabel("Å") + +fig.show() + + +# %% +# +# As you can see, for a single water molecule, the ``cutoff`` includes all atoms of +# the system. The combination of the test system and the ``cutoff`` aims to +# demonstrate that the full atomic fingerprint is contained within the ``cutoff``. +# By later subtracting the short-range density from the LODE density, we will observe +# that the difference between them is almost zero, indicating that a single water +# molecule is a short-range system. + + +# %% +# +# For the density, we choose a smeared power law as used in LODE, which does not decay +# exponentially like a :py:class:`GaussianSmall residual values may stems from the contribution of the periodic images. You\n can verify and reduce those contributions by either increasing the cell and/or\n increase the ``potential_exponent``.