diff --git a/.gitignore b/.gitignore index 39421ce87..9e4be271b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ *~ .vagrant -notebooks/.ipynb_checkpoints notebooks/*.png notebooks/*.svg notebooks/*.pdf @@ -8,4 +7,7 @@ notebooks/*.pdb notebooks/*.ndx tmp doc/build -doc/source/.ipynb_checkpoints +**/.ipynb_checkpoints +**/.vscode +.vscode +**/.DS_Store \ No newline at end of file diff --git a/doc/examples/README.rst b/doc/examples/README.rst new file mode 100644 index 000000000..2fc2c67eb --- /dev/null +++ b/doc/examples/README.rst @@ -0,0 +1,6 @@ + +======== +Examples +======== + +Here are some examples. \ No newline at end of file diff --git a/doc/examples/analysis/pca.ipynb b/doc/examples/analysis/pca.ipynb new file mode 100644 index 000000000..8ef60060d --- /dev/null +++ b/doc/examples/analysis/pca.ipynb @@ -0,0 +1,344 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Principal Component Analysis in MDAnalysis\n", + "\n", + "2019\n", + "\n", + "Author: [Lily Wang](http://minium.com.au) [(@lilyminium)](https://github.com/lilyminium)\n", + "\n", + "Inspired by the MDAnalysis PCA tutorial by [Kathleen Clark](https://becksteinlab.physics.asu.edu/people/75/kathleen-clark) [(@kaceyreidy)](https://github.com/kaceyreidy)\n", + "\n", + "In this tutorial we:\n", + "\n", + "* use PCA to analyse and visualise large macromolecular conformational changes in the enzyme adenylate kinase (AdK)\n", + "* use PCA to compare the conformational differences between ???" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Background" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Principal component analysis (PCA) is a statistical technique that decomposes a system of observations into linearly uncorrelated variables called **principal components**. These components are ordered so that the first principal component accounts for the largest variance in the data, and each following component accounts for less and less variance. PCA is often applied to molecular dynamics trajectories to extract the large-scale conformational motions or \"essential dynamics\" of a protein. The frame-by-frame conformational fluctuation can be considered a linear combination of the essential dynamics yielded by the PCA.\n", + "\n", + "In MDAnalysis, the method is as follows:\n", + "\n", + "1. Optionally align each frame in your trajectory to the first frame.\n", + "2. Construct a 3N x 3N covariance for the N atoms in your trajectory. Optionally, you can provide a mean; otherwise the covariance is to the averaged structure over the trajectory.\n", + "3. Diagonalise the covariance matrix. The eigenvectors are the principal components, and their eigenvalues are the associated variance.\n", + "4. Sort the eigenvalues so that the principal components are ordered by variance.\n", + "\n", + "
\n", + " \n", + "**Note**\n", + " \n", + "It should be noted that principal component analysis algorithms are deterministic, but the solutions are not unique. For example, you could easily change the sign of an eigenvector without altering the PCA. Different algorithms are likely to produce different answers, due to variations in implementation. `MDAnalysis` is likely to return different solutions to, say, `cpptraj`. \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Large conformational changes in adenylate kinase" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In MDAnalysis, analysis modules usually need to be imported explicitly. The `pca` module contains the `PCA` class that we will use for analysis. We also import the AdK files from the MDAnalysis test suite." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "3996de84aab74b3aa903e977a8ac80b7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "_ColormakerRegistry()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import MDAnalysis as mda\n", + "import MDAnalysis.analysis.pca as pca\n", + "from MDAnalysisTests.datafiles import PSF, DCD\n", + "\n", + "import nglview as nv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As usual, we start off by creating a universe." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "u = mda.Universe(PSF, DCD)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unlike other analyses, `pc.PCA` can only be applied to `Universe`s. The default `PCA` arguments are:\n", + "\n", + "```python\n", + "my_pca = pca.PCA(u, select='all', align=False, mean=None, n_components=None)\n", + "```\n", + "\n", + "By default (`align=False`), your trajectory will not be aligned to any structure. If you set `align=True`, every frame will be aligned to the first frame of your trajectory, based on the atoms in your `select` string. \n", + "\n", + "As PCA is usually used to extract large-scale conformational motions, we select only the backbone atoms here." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pc = pca.PCA(u, select=\"backbone\", align=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once you set up the class, you can run the analysis with `.run(start=None, stop=None, step=None, verbose=None)`. These allow you to specify the frames to compute the analysis over. The default arguments compute over every frame." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pc.run(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The principal components are accessible in `.p_components`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2565, 2565)\n" + ] + }, + { + "data": { + "text/plain": [ + "array([ 0.02725098, 0.00156086, 0.00816821, ..., -0.01783826,\n", + " 0.04746114, 0.04257271])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(pc.p_components.shape)\n", + "pc.p_components[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The variance of each principal component is in `.variance`. For example, to get the variance explained by the first principal component:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "281443.5086197605" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pc.variance[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This variance is somewhat meaningless by itself. It is much more intuitive to consider the variance of a principal component as a percentage of the total variance in the data. MDAnalysis also tracks the percentage cumulative variance in `.cumulated_variance`. As shown below, the first principal component contains 98.7% the total trajectory variance. The first three components combined account for 99.9% of the total variance." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.9873464381554058\n", + "0.999419901112709\n" + ] + } + ], + "source": [ + "print(pc.cumulated_variance[0])\n", + "print(pc.cumulated_variance[3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The average structure is also saved as an `AtomGroup` in `.mean_atoms`." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[16.297781 6.8397956 -7.622989 ]\n", + " [14.900139 7.062459 -7.235277 ]\n", + " [14.185768 5.8268375 -6.879689 ]\n", + " ...\n", + " [13.035071 15.354209 -3.8042812]\n", + " [13.695147 15.725297 -4.988666 ]\n", + " [12.63667 15.566869 -6.1185045]]\n" + ] + } + ], + "source": [ + "print(pc.mean_atoms.positions)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a33209712ed34b32b969c1f8258aed91", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "NGLWidget()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mean_structure = mda.Merge(pc.mean_atoms)\n", + "nv.show_mdanalysis(mean_structure)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (mdanalysis)", + "language": "python", + "name": "mdanalysis" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/source/_static/.DS_Store b/doc/source/_static/.DS_Store new file mode 100644 index 000000000..a1d2192ce Binary files /dev/null and b/doc/source/_static/.DS_Store differ diff --git a/doc/source/_static/custom.css b/doc/source/_static/custom.css index cd04a426b..5fbb18515 100644 --- a/doc/source/_static/custom.css +++ b/doc/source/_static/custom.css @@ -5,8 +5,7 @@ /* MDAnalysis gray: #808080 */ /* MDAnalysis white: #FFFFFF */ /* MDAnalysis black: #000000 */ - -@import url('readable.css'); +/* Darker orange: e76900 */ /* -- page layout --------------------------------------------------------- */ @@ -19,27 +18,57 @@ div.body { color: #000000; } +div.sphinxsidebar a { + color: #808080; +} + div.sphinxsidebar a:hover { color: #FF9200; } +div.sphinxsidebar a:visited { + color: #808080; +} + div.sphinxsidebar p { color: #808080; } +div.wy-menu-vertical span.caption-text { + color: #FF9200; +} + +/* li.current ul { + background: #fbd29b; +} */ + + +/* div.sphinxsidebar a { + color: #808080; +} + +div.sphinxsidebar a:hover { + color: #FF9200; +} + +div.wy-menu-vertical a:visited { + color: #808080; +} + */ + /* -- body styles --------------------------------------------------------- */ -a { +div.rst-content a { color: #FF9200; text-decoration: none; } -a:visited { - color: #FF9200; +div.rst-content a:visited { + color: #e76900; } -a:hover { +div.rst-content a:hover { color: #FF9200; text-decoration: underline; } @@ -49,6 +78,10 @@ pre, tt, code { font-family: Menlo, Monaco, 'Courier New', monospace } +/* For the backtick tags */ +/* code > span.pre { + color: #e76900; +} */ div.body h1 { font-weight: bolder; @@ -75,4 +108,36 @@ div.admonition { div.admonition p.admonition-title { font-size: 100%; font-weight: bolder; +} + +div.admonition.warning { + background: #ffdeb3; +} + +div.admonition.warning > p.admonition-title { + background: #FF9200; +} + +div.admonition.note { + background: #e6e6e6; /* RTD menu light grey */ +} + +div.admonition.note > p.admonition-title { + background: #808080; +} + +/* -- notebook styles --------------------------------------------------------- */ +.rst-content div[class^="highlight"] pre { + white-space: pre-wrap; +} + +/* -- gallery styles ---------------------------------------------------------- */ +div.sphx-glr-download a { + border: 1px solid #fff; + background: #808080; +} + +div.sphx-glr-download a:hover { + border: 1px solid #fff; + background: #000; } \ No newline at end of file diff --git a/doc/source/_static/logos/user_guide.png b/doc/source/_static/logos/user_guide.png new file mode 100644 index 000000000..5d82c3cfd Binary files /dev/null and b/doc/source/_static/logos/user_guide.png differ diff --git a/doc/source/_static/logos/user_guide.psd b/doc/source/_static/logos/user_guide.psd new file mode 100644 index 000000000..428781843 Binary files /dev/null and b/doc/source/_static/logos/user_guide.psd differ diff --git a/doc/source/auto_examples/index.rst b/doc/source/auto_examples/index.rst new file mode 100644 index 000000000..74cd10b92 --- /dev/null +++ b/doc/source/auto_examples/index.rst @@ -0,0 +1,24 @@ +:orphan: + + + +.. _sphx_glr_auto_examples: + + +======== +Examples +======== + +Here are some examples. + +.. raw:: html + +
+ + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/doc/source/conf.py b/doc/source/conf.py index fe119d756..54d3689d5 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -13,7 +13,8 @@ # import os # import sys # sys.path.insert(0, os.path.abspath('.')) - +import sphinx_rtd_theme +import sphinx_gallery # -- Project information ----------------------------------------------------- @@ -35,7 +36,9 @@ 'sphinx.ext.viewcode', 'sphinx.ext.githubpages', 'sphinx_sitemap', - 'nbsphinx' + 'nbsphinx', + 'sphinx_rtd_theme', + 'sphinx_gallery.gen_gallery' ] mathjax_path = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML' @@ -46,15 +49,33 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.ipynb_checkpoints'] + +sphinx_gallery_conf = { + 'example_dirs': ['../examples'], # source files + 'gallery_dirs': ['auto_examples'], # where files are built + 'filename_pattern': '/plot_', # filenames to execute, accepts regex + 'ignore_pattern': r'__init__\.py', # filenames to not execute/parse/add, accepts regex + 'download_all_examples': False, + + # 'binder': { + # 'org': 'MDAnalysis', + # 'repo': 'UserGuide', + # 'branch': 'master' + # 'binderhub_url': 'full URL of binderhub deployment', + # 'dependencies': './binder/requirements.txt', + # 'use_jupyter_lab': False + # } +} # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' +# html_theme_path = ['_themes', ] # styles/fonts to match http://mdanalysis.org (see public/css) # @@ -78,41 +99,32 @@ extra_nav_links['@mdanalysis'] = 'https://twitter.com/mdanalysis' html_theme_options = { - 'logo' : "logos/mdanalysistutorial-logo-200x150.png", - 'github_user': 'MDAnalysis', - 'github_repo': 'mdanalysis', - 'github_button': False, - # 'github_type': 'star', - 'github_banner': True, - 'show_related': True, - 'fixed_sidebar': False, - 'sidebar_includehidden': True, - 'sidebar_collapse': True, - # style - 'link': color['orange'], - 'link_hover': color['orange'], - 'gray_1': color['gray'], - 'narrow_sidebar_bg': color['gray'], - 'narrow_sidebar_fg': color['white'], - # typography - 'font_family': "'PT Sans', Helvetica, Arial, 'sans-serif'", - 'head_font_family': "", - 'code_font_family': "Menlo, Monaco, 'Courier New', monospace", - 'caption_font_size': "smaller", - # external links - 'extra_nav_links': extra_nav_links, + 'canonical_url': '', + 'logo_only': True, + 'display_version': True, + 'prev_next_buttons_location': 'bottom', + 'style_external_links': False, + 'style_nav_header_background': 'white', #'#e76900', # dark orange + # Toc options + 'collapse_navigation': True, + 'sticky_navigation': True, + 'navigation_depth': 5, + 'includehidden': True, + 'titles_only': False, } # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. html_favicon = "_static/logos/mdanalysis-logo.ico" +html_logo = '_static/logos/user_guide.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +html_css_files = ['custom.css']#, 'readable.css'] # Custom sidebar templates, maps document names to template names. # alabaster sidebars diff --git a/doc/source/data_structures.rst b/doc/source/data_structures.rst index cbd96bba8..e89f41fb5 100644 --- a/doc/source/data_structures.rst +++ b/doc/source/data_structures.rst @@ -52,6 +52,23 @@ AtomGroup AtomGroup instances can be easily created (e.g., from an AtomGroup.select_atoms() selection or simply by slicing). +-------------------- +Indexing and slicing +-------------------- +blah blah + +----------- +Set methods +----------- +blah + +---------------- +Geometry methods +---------------- + + +UpdatingAtomGroup +==================== ResidueGroup and SegmentGroup @@ -63,10 +80,3 @@ Residue or a Segment (typically a whole molecule or all of the solvent) also exist as containers, as well as groups of these units ( ResidueGroup, SegmentGroup). - - - -Topology -==================== - -MDA Topology =/= 'force field' topology. Connectivity only. See ParmEd etc for other stuff. \ No newline at end of file diff --git a/doc/source/faq.rst b/doc/source/faq.rst new file mode 100644 index 000000000..8ac35ab63 --- /dev/null +++ b/doc/source/faq.rst @@ -0,0 +1,30 @@ +.. -*- coding: utf-8 -*- + +========================== +Frequently asked questions +========================== + + +Trajectories +========================== + +Why do the atom positions change over trajectories? +--------------------------------------------------- + +A fundamental concept in MDAnalysis is that at any one time, +only one time frame of the trajectory is being accessed. The +:code:`trajectory` attribute of a :code:`Universe` is actually (usually) a file reader. +Think of the trajectory as a function :math:`X(t)` of the frame index :math:`t` +that makes the data from this specific frame available. This structure is important +because it allows MDAnalysis to work with trajectory files too large to fit +into the computer's memory. + +The Timestep data structure :code:`my_universe.trajectory.ts` holds frame information. +You also see the Timestep when you iterate through a trajectory: + +.. code-block:: python + + for ts in my_universe.trajectory: + print(ts.frame, ts.time) + +This prints the frame index (starting with 0) and the time for all frames. \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index 86cd6dcae..2bd271c35 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -12,9 +12,16 @@ Link to gallery. .. toctree:: :maxdepth: 1 - :caption: Contents: + :caption: Getting started installation quickstart + faq + auto_examples/index + +.. toctree:: + :maxdepth: 1 + :caption: User guide + data_structures formats/formats diff --git a/doc/source/quickstart.ipynb b/doc/source/quickstart.ipynb index fa3447b39..169f92189 100644 --- a/doc/source/quickstart.ipynb +++ b/doc/source/quickstart.ipynb @@ -4,27 +4,1616 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Quickstart" + "# Quick start guide" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This guide is designed as a basic introduction to MDAnalysis to get you up and running. You can see more complex tasks in our [Example gallery](placeholder). This page outlines how to:\n", + "\n", + "* [load a molecular dynamics structure or trajectory](#Loading-a-structure-or-trajectory)\n", + "* [work with AtomGroups, a central data structure in MDAnalysis](#Working-with-groups-of-atoms)\n", + "* [work with a trajectory](#Working-with-trajectories)\n", + "* [write out coordinates](#Writing-out-coordinates)\n", + "\n", + "* [use the analysis algorithms in MDAnalysis](#Analysis)\n", + "* [correct and automated citation of MDAnalysis and algorithms](#References)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "0.19.2\n" + ] + } + ], + "source": [ + "import MDAnalysis as mda\n", + "from MDAnalysis.tests.datafiles import PSF, DCD, GRO, XTC\n", + "\n", + "print(mda.Universe(PSF, DCD))\n", + "print(mda.__version__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This tutorial assumes that you already have MDAnalysis installed. Running the cell above should give:\n", + "\n", + "```console\n", + "\n", + "0.19.2\n", + "```\n", + "If you get an error message, you need to install MDAnalysis. If your version is under `0.18.0`, you need to upgrade MDAnalysis. [Instructions for both are here.](installation.rst) After installing, restart this notebook." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overview" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis is a Python package that provides tools to access and analyse data in molecular dynamics trajectories. Several key data structures form the backbone of MDAnalysis.\n", + "\n", + "* A molecular system consists of particles. A particle is represented as an `Atom` object, even if it is a coarse-grained bead. \n", + "* `Atom`s are grouped into [AtomGroup](data_structures.rst#atomgroups)s. The `AtomGroup` is probably the most important class in MDAnalysis, as almost everything can be accessed through it. See [Working with atoms](#Working-with-groups-of-atoms) below. \n", + "* A `Universe` contains all the particles in a molecular system in an `AtomGroup` accessible at the `.atoms` attribute, and combines it with a trajectory at `.trajectory`. \n", + "\n", + "A fundamental concept in MDAnalysis is that at any one time, \n", + "only one time frame of the trajectory is being accessed. The \n", + "`trajectory` attribute of a `Universe` is usually a file reader. \n", + "Think of the trajectory as a function $X(t)$ of the frame index $t$ \n", + "that only makes the data from this specific frame available. This structure is important \n", + "because it allows MDAnalysis to work with trajectory files too large to fit \n", + "into the computer's memory. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading a structure or trajectory" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Working with MDAnalysis typically starts with loading data into a `Universe`, the central data structure in MDAnalysis. \n", + "\n", + "
\n", + "\n", + "**See also**\n", + "\n", + "The [user guide](data_structures.rst#universes) has a complete explanation of ways to create and manipulate a `Universe`.\n", + "
\n", + "\n", + "\n", + "The first arguments for creating a `Universe` are topology and trajectory files.\n", + "\n", + "* A **topology file** is always required for loading data into a Universe. A topology file lists atoms, residues, and their connectivity. MDAnalysis accepts the PSF, PDB, CRD, and GRO formats.\n", + "\n", + "* A topology file can then be followed by **any number of trajectory files**. A trajectory file contains a list of coordinates in the order defined in the topology. If no trajectory files are given, then only a structure is loaded. If multiple trajectory files are given, the trajectories are concatenated in the given order. MDAnalysis accepts single frames (e.g. PDB, CRD, GRO) and timeseries data (e.g. DCD, XTC, TRR, XYZ). " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "False\n" + ] + } + ], + "source": [ + "psf = mda.Universe(PSF)\n", + "print(psf)\n", + "print(hasattr(psf, 'trajectory'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As PSF files don't contain any coordinate information and no trajectory file has been loaded, the `structure_only` universe does not contain a trajectory. If the topology file does contain coordinate information, a trajectory of 1 frame is created." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "1\n" + ] + } + ], + "source": [ + "gro = mda.Universe(GRO)\n", + "print(gro)\n", + "print(len(gro.trajectory))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the remainder of this guide we will work with the universe `u`, created below. This is a simulation where the enzyme adenylate kinase samples a transition from a closed to an open conformation [(Beckstein *et al.*, 2009)](https://doi.org/10.1016/j.jmb.2009.09.009)." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "98\n" + ] + } + ], + "source": [ + "u = mda.Universe(PSF, DCD)\n", + "print(u)\n", + "print(len(u.trajectory))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**Note**\n", + "\n", + "The MDAnalysis test suite is packaged with a bunch of test files and trajectories, which are named after their file format. We are using these files throughout this guide for convenience. To analyse your own files, simply replace the `PSF` and `DCD` above with paths to your own files. For example:\n", + "\n", + "```python\n", + "structure_only = mda.Universe(\"my_pdb_file.pdb\")\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Working with groups of atoms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most analysis requires creating and working with an `AtomGroup`, a collection of `Atom`s. For convenience, you can also work with chemically meaningful groups of `Atoms` such as a `Residue` or a `Segment`. These come with analogous containers to `AtomGroup`: `ResidueGroup` and `SegmentGroup`. For instance, the `.residues` attribute of a `Universe` returns a `ResidueGroup`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ", , , ..., , , ]>\n" + ] + } + ], + "source": [ + "print(u.residues)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Selecting atoms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The easiest way to access the particles of your `Universe` is with the `atoms` attribute:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u.atoms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This returns an `AtomGroup`, which can be thought of as a list of `Atom` objects. Most analysis involves working with groups of atoms in `AtomGroup`s. `AtomGroup`s can easily be created by slicing another `AtomGroup`. For example, the below slice returns the last five atoms." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ", , , , ]>\n" + ] + } + ], + "source": [ + "last_five = u.atoms[-5:]\n", + "print(last_five)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis supports fancy indexing: passing an array or list of indices to get a new AtomGroup with the atoms at those indices in the old AtomGroup." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ", , , , , ]>\n" + ] + } + ], + "source": [ + "print(last_five[[0, 3, -1, 1, 3, 0]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis has also implemented a [powerful atom selection language](selections.rst) that is similar to existing languages in VMD, PyMol, and other packages. This is available with the `.select_atoms()` function of an `AtomGroup` or `Universe` instance:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ", , , ..., , , ]>\n" + ] + } + ], + "source": [ + "print(u.select_atoms('resname ASP or resname GLU'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Numerical ranges can be written as `first-last` or `first:last` where the range is **inclusive**. Note that in slicing, the `last` index is not included." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "51\n", + "50\n" + ] + } + ], + "source": [ + "print(u.select_atoms('resid 50-100').n_residues)\n", + "print(u.residues[50:100].n_residues)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Selections can also be combined with boolean operators, and allow wildcards. \n", + "\n", + "For example, the command below selects the $C_{\\alpha}$ atoms of glutamic acid and histidine in the first 100 residues of the protein. Glutamic acid is typically named \"GLU\", but histidine can be named \"HIS\", \"HSD\", or \"HSE\" depending on its protonation state and the force field used." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u.select_atoms(\"(resname GLU or resname HS*) and name CA and (resid 1:100)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**Note**\n", + "\n", + "An `AtomGroup` created from a selection is sorted and duplicate elements are removed. This is not true for an `AtomGroup` produced by slicing. Thus, slicing can be used when the order of atoms is crucial.\n", + "
\n", + "\n", + "
\n", + "\n", + "**See also**\n", + "\n", + "The [user guide](selections.rst) has a complete rundown of creating AtomGroups through indexing, selection language, and set methods.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Getting atom information from AtomGroups" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An `AtomGroup` can tell you information about the atoms inside it with a number of convenient attributes." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['N' 'HT1' 'HT2' 'HT3' 'CA' 'HA' 'CB' 'HB1' 'HB2' 'CG' 'HG1' 'HG2' 'SD'\n", + " 'CE' 'HE1' 'HE2' 'HE3' 'C' 'O' 'N']\n" + ] + } + ], + "source": [ + "print(u.atoms[:20].names)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.008 1.008 1.008 12.011 1.008 1.008 12.011 1.008 1.008 1.008\n", + " 12.011 15.999 14.007 1.008 12.011 1.008 12.011 1.008 12.011 1.008]\n" + ] + } + ], + "source": [ + "print(u.atoms[50:70].masses)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It also knows which residues and segments the atoms belong to. The `.residues` and `.segments` return a `ResidueGroup` and `SegmentGroup`, respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ", ]>\n", + "]>\n" + ] + } + ], + "source": [ + "print(u.atoms[:20].residues)\n", + "print(u.atoms[-20:].segments)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that there are no duplicates in the `ResidueGroup` and `SegmentGroup` above. To get residue attributes atom-wise, you can access them directly through `AtomGroup`." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET'\n", + " 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'MET' 'ARG']\n" + ] + } + ], + "source": [ + "print(u.atoms[:20].resnames)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can group atoms together by topology attributes.\n", + "\n", + "For example, to group atoms with the same residue name and mass together:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lily/anaconda3/envs/mdanalysis/lib/python3.7/site-packages/MDAnalysis/lib/util.py:1747: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n", + " if isinstance(v, collections.MutableMapping):\n" + ] + }, + { + "data": { + "text/plain": [ + "{('ARG', 'N'): ,\n", + " ('ASP', 'C'): ,\n", + " ('ASP', 'N'): ,\n", + " ('LYS', 'N'): ,\n", + " ('ALA', 'C'): ,\n", + " ('ALA', 'HN'): ,\n", + " ('ASN', 'O'): ,\n", + " ('GLN', 'C'): ,\n", + " ('THR', 'N'): ,\n", + " ('ILE', 'C'): ,\n", + " ('GLU', 'N'): ,\n", + " ('LEU', 'N'): }" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "near_met = u.select_atoms('not resname MET and (around 2 resname MET)')\n", + "near_met.groupby(['resnames', 'names'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**See also**\n", + "\n", + "A complete list of topology attributes can be found [in the user guide.](placeholder)\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### AtomGroup positions and methods" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `.positions` attribute is probably the most important information you can get from an `AtomGroup`: a `numpy.ndarray` of coordinates, with the shape (n_atoms, 3)." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[11.664622 8.393473 -8.983231 ]\n", + " [11.414839 5.4344215 -6.5134845 ]\n", + " [ 8.959755 5.612923 -3.6132305 ]\n", + " [ 8.290068 3.075991 -0.79665166]\n", + " [ 5.011126 3.7638984 1.130355 ]]\n", + "(5, 3)\n" + ] + } + ], + "source": [ + "ca = u.select_atoms('resid 1-5 and name CA')\n", + "print(ca.positions)\n", + "print(ca.positions.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A number of other quantities have been defined for an AtomGroup, including:\n", + "\n", + "* `.center_of_mass()`\n", + "* `.center_of_geometry()`\n", + "* `.total_mass()`\n", + "* `.total_charge()`\n", + "* `.radius_of_gyration()`\n", + "* `.bsphere()` (the bounding sphere of the selection)\n", + "\n", + "See the [user guide](data_structures.rst#atomgroups) for a complete list and description of AtomGroup methods." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 9.06808195 5.25614133 -3.75524844]\n" + ] + } + ], + "source": [ + "print(ca.center_of_mass())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**Note**\n", + "\n", + "The `.center_of_mass()` function, like many of the analysis modules in MDAnalysis, relies on having accurate mass properties available. **Particle masses may not always be available or accurate!**\n", + "\n", + "Currently, MDAnalysis assigns masses to particles based on their element or 'atom type', which is guessed from the particle name. If MDAnalysis guesses incorrectly (e.g. a calcium atom called CA is treated as a $C_{\\alpha}$), the mass of that atom will be inaccurate. If MDAnalysis has no idea what the particle is (e.g. coarse-grained beads), it will raise a warning, and give that particle a mass of 0. \n", + "\n", + "To be certain that MDAnalysis is using the correct masses, you can set them manually.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis can also create topology geometries such as bonds, angles, dihedral angles, and improper angles from an `AtomGroup`. This `AtomGroup` has a special requirement: only the atoms involved in the geometry can be in the group. For example, an `AtomGroup` used to create a bond can only have 2 atoms in it; an `AtomGroup` used to create a dihedral or improper angle must have 4 atoms." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['N' 'HT1' 'HT2']\n" + ] + } + ], + "source": [ + "nhh = u.atoms[:3]\n", + "print(nhh.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After a topology object such as an angle is created, the value of the angle (in degrees) can be calculated based on the positions of the atoms." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "37.99234750892497\n" + ] + } + ], + "source": [ + "angle_nhh = nhh.angle\n", + "print(angle_nhh.value())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the order of the atoms matters for angles, dihedrals, and impropers. The value returned for an angle is the angle between first and third atom, with the apex at the second. Fancy indexing is one way to get an ordered AtomGroup.\n", + "```\n", + " 3\n", + " /\n", + " /\n", + "2------1\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['HT1' 'N' 'HT2']\n" + ] + } + ], + "source": [ + "hnh = u.atoms[[1, 0, 2]]\n", + "print(hnh.names)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "106.20364651944931\n" + ] + } + ], + "source": [ + "angle_hnh = hnh.angle\n", + "print(angle_hnh.value())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Working with trajectories" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The trajectory of a Universe contains the changing coordinate information. The number of frames in a trajectory is its length:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "98\n" + ] + } + ], + "source": [ + "print(len(u.trajectory))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The standard way to assess the information of each frame in a trajectory is to iterate over it. When the timestep changes, the universe only contains information associated with that timestep." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 24, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Frame: 0, Time: 1 ps, Rgyr: 16.669 A\n", + "Frame: 1, Time: 2 ps, Rgyr: 16.6732 A\n", + "Frame: 2, Time: 3 ps, Rgyr: 16.7315 A\n", + "Frame: 3, Time: 4 ps, Rgyr: 16.7223 A\n", + "Frame: 4, Time: 5 ps, Rgyr: 16.744 A\n", + "Frame: 5, Time: 6 ps, Rgyr: 16.7185 A\n", + "Frame: 6, Time: 7 ps, Rgyr: 16.7741 A\n", + "Frame: 7, Time: 8 ps, Rgyr: 16.7764 A\n", + "Frame: 8, Time: 9 ps, Rgyr: 16.7894 A\n", + "Frame: 9, Time: 10 ps, Rgyr: 16.8289 A\n", + "Frame: 10, Time: 11 ps, Rgyr: 16.8521 A\n", + "Frame: 11, Time: 12 ps, Rgyr: 16.8549 A\n", + "Frame: 12, Time: 13 ps, Rgyr: 16.8723 A\n", + "Frame: 13, Time: 14 ps, Rgyr: 16.9108 A\n", + "Frame: 14, Time: 15 ps, Rgyr: 16.9494 A\n", + "Frame: 15, Time: 16 ps, Rgyr: 16.981 A\n", + "Frame: 16, Time: 17 ps, Rgyr: 17.0033 A\n", + "Frame: 17, Time: 18 ps, Rgyr: 17.0196 A\n", + "Frame: 18, Time: 19 ps, Rgyr: 17.0784 A\n", + "Frame: 19, Time: 20 ps, Rgyr: 17.1265 A\n" + ] + } + ], + "source": [ + "for ts in u.trajectory[:20]:\n", + " time = u.trajectory.time\n", + " rgyr = u.atoms.radius_of_gyration()\n", + " print(\"Frame: {:3d}, Time: {:4.0f} ps, Rgyr: {:g} A\".format(ts.frame, time, rgyr))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After iteration, the trajectory 'resets' back to the first frame." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "print(u.trajectory.frame)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can set the timestep of the trajectory with the frame index:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10\n" + ] + } + ], + "source": [ + "print(u.trajectory[10].frame)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This persists until the timestep is next changed." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Frame: 10, Time: 11 ps, Rgyr: 16.8521 A\n" + ] + } + ], + "source": [ + "frame = u.trajectory.frame\n", + "time = u.trajectory.time\n", + "rgyr = u.atoms.radius_of_gyration()\n", + "print(\"Frame: {:3d}, Time: {:4.0f} ps, Rgyr: {:g} A\".format(frame, time, rgyr))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Generally, trajectory analysis first collects frame-wise data in a list." + ] + }, + { + "cell_type": "code", + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ - "import MDAnalysis as mda" + "rgyr = []\n", + "time = []\n", + "protein = u.select_atoms(\"protein\")\n", + "for ts in u.trajectory:\n", + " time.append(u.trajectory.time)\n", + " rgyr.append(protein.radius_of_gyration())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can then be converted into other data structures, such as a numpy array or a pandas DataFrame. It can be plotted (as below), or used for further analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Radius of gyration (A)
Time (ps)
1.016.669018
2.016.673217
3.016.731454
4.016.722283
5.016.743961
\n", + "
" + ], + "text/plain": [ + " Radius of gyration (A)\n", + "Time (ps) \n", + "1.0 16.669018\n", + "2.0 16.673217\n", + "3.0 16.731454\n", + "4.0 16.722283\n", + "5.0 16.743961" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "rgyr_df = pd.DataFrame(rgyr, columns=['Radius of gyration (A)'], index=time)\n", + "rgyr_df.index.name = 'Time (ps)'\n", + "\n", + "rgyr_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "\n", + "rgyr_df.plot(title='Radius of gyration')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dynamic selection" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As seen above, coordinates change while iterating over the trajectory. Therefore, properties calculated from the coordinates, such as the radius of gyration, also change. \n", + "\n", + "Selections are often defined on static properties that do not change when moving through a trajectory. Above, the static selection is all the atoms that are in a protein. You can define the selection once and then recalculate the property of interest for each frame of the trajectory.\n", + "\n", + "However, some selections contain distance-dependent queries (such as `around` or `point`, [see selection keywords for more details](selections.rst)). In this case, the selection should be updated for each time step using a dynamic selection by setting the keyword `updating=True`. This command gives an `UpdatingAtomGroup` rather than a static `AtomGroup`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dynamic = u.select_atoms('around 2 resname ALA', updating=True)\n", + "print(type(dynamic))\n", + "dynamic" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "static = u.select_atoms('around 2 resname ALA')\n", + "print(type(static))\n", + "static" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When you call the next frame of the universe, the atoms in the dynamic selection are updated, whereas the atoms in the static selection remain the same." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u.trajectory.next()\n", + "dynamic" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "static" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Writing out coordinates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis supports writing data out into a range of file formats, including both single frame formats (e.g. PDB, GRO) and trajectory writers (e.g. XTC, DCD, and multi-frame PDB files)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Single frame" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most straightforward way to write to a file that can only hold a single frame is to use the `write()` method of any `AtomGroup`. MDAnalysis uses the file extension to determine the output file format. For instance, to only write out the $C_{\\alpha}$ atoms to a file in GRO format:\n", + "\n", + "```python\n", + "ca = u.select_atoms('name CA')\n", + "ca.write('calphas.gro')\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Trajectories" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The standard way to write out trajectories is to:\n", + "\n", + "1. Open a trajectory `Writer` and specify how many atoms a frame will contain\n", + "2. Iterate through the trajectory and write coordinates frame-by-frame with `Writer.write()`\n", + "3. If you do not use the context manager and the `with` statement below, you then need to close the trajectory with `.close()`.\n", + "\n", + "For instance, to write out the $C_{\\alpha}$ atoms to a trajectory in the XTC format:\n", + "\n", + "```python\n", + "ca = u.select_atoms('name CA')\n", + "with mda.Writer('calphas.xtc', ca.n_atoms) as w:\n", + " for ts in u.trajectory:\n", + " w.write(ca)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Analysis" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis comes with a diverse set of analysis modules, and the building blocks to implement your own.\n", + "\n", + "The majority of these follow a common interface:\n", + "\n", + "1. Initialise the analysis with a `Universe` and other required parameters.\n", + "2. Run the analysis with `.run()`. Optional arguments are the `start` frame index, `stop` frame index, `step` size, and toggling `verbose`. The default is to run analysis on the whole trajectory.\n", + "3. Results are stored within the class.\n", + "4. Often, a function is available to operate on single frames.\n", + "\n", + "**However, not all analysis uses this model. It is important to check the documentation for each analysis.** You can also see examples in the [Example gallery](placeholder).\n", + "\n", + "Below, simple RMSD analysis is shown. The `rms` module follows the interface above." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### RMSD" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not all sub-modules of MDAnalysis are imported with `import MDAnalysis`. Most analysis modules have to be imported explicitly. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from MDAnalysis.analysis import rms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MDAnalysis provides a `rmsd()` function for calculating the RMSD between two numpy arrays of coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6.852774844656239" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bb = u.select_atoms('backbone')\n", + "\n", + "u.trajectory[0] # first frame\n", + "first = bb.positions\n", + "\n", + "u.trajectory[-1] #last frame\n", + "last = bb.positions\n", + "\n", + "rms.rmsd(first, last)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An `RMSD` class is also provided to operate on trajectories. \n", + "\n", + "Below, the `RMSD` class is created. \n", + "* The first argument is the `AtomGroup` or `Universe` for which the RMSD is calculated. \n", + "* As a reference `AtomGroup` or `Universe` is not given as the second argument, the default is to align to the current frame of the first argument. Here it is set to the first frame. \n", + "* We choose to align the trajectory over the backbone atoms, and then compute the RMSD for the backbone atoms (`select`). \n", + "* Then, without re-aligning the trajectory, the RMSD is also computed (`groupselections`) for the $C_{\\alpha}$ atoms (`name CA`) and every protein atom (`protein`).\n", + "\n", + "The RMSD is computed when we call `.run()`." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u.trajectory[0] # set to first frame\n", + "rmsd_analysis = rms.RMSD(u, select='backbone', groupselections=['name CA', 'protein'])\n", + "rmsd_analysis.run(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The results are stored in the `.rmsd` attribute. This is an array with the shape (n_frames, 2 + n_selections)." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(98, 5)\n" + ] + } + ], + "source": [ + "print(rmsd_analysis.rmsd.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can interpret this as an array with 98 rows and 5 columns. Each row is the RMSD associated with a frame in the trajectory. The columns are as follows:\n", + "\n", + "1. Frame number\n", + "2. Time (ps)\n", + "3. RMSD (backbone)\n", + "4. RMSD (C-alpha)\n", + "5. RMSD (protein)\n", + "\n", + "We can turn this into a `pandas` DataFrame and plot the results." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BackboneC-alphasProtein
Time (ps)
1.06.391203e-074.263638e-085.443850e-08
2.04.636592e-014.235205e-016.934167e-01
3.06.419340e-015.939111e-018.748416e-01
4.07.743983e-017.371346e-011.052780e+00
5.08.588600e-018.279498e-011.154986e+00
\n", + "
" + ], + "text/plain": [ + " Backbone C-alphas Protein\n", + "Time (ps) \n", + "1.0 6.391203e-07 4.263638e-08 5.443850e-08\n", + "2.0 4.636592e-01 4.235205e-01 6.934167e-01\n", + "3.0 6.419340e-01 5.939111e-01 8.748416e-01\n", + "4.0 7.743983e-01 7.371346e-01 1.052780e+00\n", + "5.0 8.588600e-01 8.279498e-01 1.154986e+00" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "rmsd_df = pd.DataFrame(rmsd_analysis.rmsd[:, 2:],\n", + " columns=['Backbone', 'C-alphas', 'Protein'],\n", + " index=rmsd_analysis.rmsd[:, 1])\n", + "rmsd_df.index.name = 'Time (ps)'\n", + "rmsd_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "rmsd_df.plot(title='RMSD')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**See also**\n", + "\n", + "See the [analysis documentation](analysis.rst) for more information.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When using MDAnalysis in published work, please cite both these papers:\n", + "\n", + "* N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein. MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. *J. Comput. Chem.* **32** (2011), 2319–2327. doi:[10.1002/jcc.21787](http://dx.doi.org/10.1002/jcc.21787)\n", + "\n", + "* R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N.\n", + " Melo, S. L. Seyler, D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney,\n", + " and O. Beckstein. [MDAnalysis: A Python package for the rapid analysis of\n", + " molecular dynamics simulations](http://conference.scipy.org/proceedings/scipy2016/oliver_beckstein.html). In S. Benthall and S. Rostrup, editors,\n", + " *Proceedings of the 15th Python in Science Conference*, pages 98-105,\n", + " Austin, TX, 2016. SciPy. doi:[10.25080/Majora-629e541a-00e](https://doi.org/10.25080/Majora-629e541a-00e)\n", + " \n", + "MDAnalysis includes many algorithms and modules that should also be individually cited. For example, if you use the `MDAnalysis.analysis.rms` or `MDAnalysis.analysis.align` modules, please cite:\n", + "\n", + "* Douglas L. Theobald. Rapid calculation of RMSD using a\n", + " quaternion-based characteristic polynomial. *Acta Crystallographica A*\n", + " **61** (2005), 478-480.\n", + "* Pu Liu, Dmitris K. Agrafiotis, and Douglas L. Theobald. Fast\n", + " determination of the optimal rotational matrix for macromolecular\n", + " superpositions. *J. Comput. Chem.* **31** (2010), 1561–1563.\n", + " \n", + "The primary sources of each module will be in their documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Automatic citations with duecredit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Citations can be also be automatically generated using `duecredit`. [Complete installation and usage instructions can be found in the user guide](placeholder), but it is simple to generate a list of citations for your python script `my_script.py`.\n", + "\n", + "```console\n", + "$ python -m duecredit my_script.py\n", + "```\n", + "\n", + "This extracts citations into a hidden file, which can then be exported to different formats. For example, to display them as BibTeX, use the command:\n", + "\n", + "```console\n", + "$ duecredit summary --format=bibtex\n", + "```" + ] } ], "metadata": { + "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python (mdanalysis)", "language": "python", @@ -42,6 +1631,10 @@ "pygments_lexer": "ipython3", "version": "3.7.3" }, + "nbsphinx-toctree": { + "maxdepth": 2, + "numbered": true + }, "toc": { "base_numbering": 1, "nav_menu": {}, diff --git a/environment.yml b/environment.yml index f324ce5c2..e00c49080 100644 --- a/environment.yml +++ b/environment.yml @@ -6,4 +6,8 @@ dependencies: - jupyter_contrib_nbextensions - nglview - pip: - - mdanalysis \ No newline at end of file + - mdanalysis + - mdanalysistests + - sphinx_rtd_theme + - nbsphinx + - sphinx-gallery \ No newline at end of file