{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "BioPandas\n", "\n", "Authors: \n", "- Sebastian Raschka \n", "- Arian Jamasb \n", "\n", "License: BSD 3 clause \n", "Project Website: http://rasbt.github.io/biopandas/ \n", "Code Repository: https://github.com/rasbt/biopandas " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Last updated: 2022-05-12\n", "\n", "pandas : 1.4.0\n", "biopandas: 0.4.0\n", "\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -d -u -p pandas,biopandas" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "\n", "pd.set_option('display.width', 600)\n", "pd.set_option('display.max_columns', 8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Working with mmCIF Structures in DataFrames" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading mmCIF Files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several ways to load a mmCIF structure into a `PandasMmcif` object.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1 -- Loading an mmCIF file from the Protein Data Bank\n", "\n", "MmCIF files can be directly fetched from The Protein Data Bank at [http://www.rcsb.org](http://www.rcsb.org) via its unique 4-letter after initializing a new [`PandasMmcif`](../api_subpackages/biopandas.mmcif) object and calling the `fetch_mmcif` method:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "# Initialize a new PandasMmcif object\n", "# and fetch the mmCIF file from rcsb.org\n", "pmmcif = PandasMmcif().fetch_mmcif('3eiy')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2 -- Loading an mmCIF file from the AlphaFold Structure Database\n", "\n", "\n", "(*New in version 0.4.0*)\n", "\n", "PDB files can be directly fetched from The AlphaFold Structure Database at [https://alphafold.ebi.ac.uk/](https://alphafold.ebi.ac.uk/) via its unique [UniProt](https://www.uniprot.org/) Identifier after initializing a new [`PandasPdb`](../api/biopandas.pdb#pandaspdb) object and calling the [`fetch_af2`](../api/biopandas.pdb#pandaspdbfetch_pdb) method:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "# Initialize a new PandasPdb object\n", "# and fetch the PDB file from alphafold.ebi.ac.uk\n", "ppdb = PandasMmcif().fetch_mmcif(uniprot_id='Q5VSL9', source='alphafold2-v2')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3 a) -- Loading a mmCIF structure from a local file\n", "\n", "Alternatively, we can load mmCIF files from local directories as regular mmCIF files using `read_mmcif`:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.read_mmcif('./data/3eiy.cif')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif](https://raw.githubusercontent.com/rasbt/biopandas/main/docs/tutorials/data/3eiy.cif)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3 b) -- Loading a mmCIF structure from a local gzipped mmCIF file\n", "\n", "Or, we can load them from gzip archives like so (note that the file must end with a '.gz' suffix in order to be recognized as a gzip file):" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.read_mmcif('./data/3eiy.cif.gz')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif.gz](https://github.com/rasbt/biopandas/blob/main/docs/tutorials/data/3eiy.cif.gz?raw=true)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After the file was succesfully loaded, we have access to the following attributes:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mmCIF Code: 3eiy\n", "mmCIF Header Line: \n", "\n", "Raw mmCIF file contents:\n", "\n", "data_3EIY\n", "# \n", "_entry.id 3EIY \n", "# \n", "_audit_conform.dict_name mmcif_pdbx.dic \n", "_audit_conform.dict_version 5.281 \n", "_audit_conform.dict_location http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic \n", "# \n", "loop_\n", "_database_2.database_id \n", "_database_2.database_code \n", "PDB 3EIY \n", "RCSB RCSB049380 \n", "WWPDB D_1000049380 \n", "# \n", "loop_\n", "_pdbx_database_related.db_name \n", "_pdbx_database_related.db_id \n", "_pdbx_database_related.details \n", "_pdbx_database_related.content_type \n", "TargetDB BupsA.00023.a . unspecified \n", "PDB 3d63 \n", ";The same protein, \"open\" conformation, apo form, in space group P21212\n", ";\n", "unspecified \n", "PDB 3EIZ . unspecified \n", "PDB 3EJ0 . unspecified \n", "PDB 3EJ2 . \n", "...\n" ] } ], "source": [ "print('mmCIF Code: %s' % pmmcif.code)\n", "print('mmCIF Header Line: %s' % pmmcif.header)\n", "print('\\nRaw mmCIF file contents:\\n\\n%s\\n...' % pmmcif.pdb_text[:1000])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most interesting / useful attribute is the `PandasMmcif.df` DataFrame dictionary though, which gives us access to the mmCIF files as pandas DataFrames. Let's print the first 3 lines from the `ATOM` coordinate section to see how it looks like:" ] }, { "cell_type": "code", "execution_count": 8, "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", " \n", " \n", " \n", " \n", " \n", " \n", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
0ATOM1NN...SERAN1
1ATOM2CCA...SERACA1
2ATOM3CC...SERAC1
\n", "

3 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "0 ATOM 1 N N ... SER A N 1\n", "1 ATOM 2 C CA ... SER A CA 1\n", "2 ATOM 3 C C ... SER A C 1\n", "\n", "[3 rows x 21 columns]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['ATOM'].head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But more on that in the next section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4 -- Loading a mmCIF file from a Python List" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mmcif files can also be loaded into a `PandasMmcif` object from a Python list:" ] }, { "cell_type": "code", "execution_count": 9, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
0ATOM1NN...SERAN1
1ATOM2CCA...SERACA1
2ATOM3CC...SERAC1
3ATOM4OO...SERAO1
4ATOM5CCB...SERACB1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "0 ATOM 1 N N ... SER A N 1\n", "1 ATOM 2 C CA ... SER A CA 1\n", "2 ATOM 3 C C ... SER A C 1\n", "3 ATOM 4 O O ... SER A O 1\n", "4 ATOM 5 C CB ... SER A CB 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "with open('./data/3eiy.cif', 'r') as f:\n", " three_eiy = f.read()\n", "\n", "pmmcif2 = PandasMmcif()\n", "pmmcif2.read_mmcif_from_list(three_eiy)\n", "\n", "pmmcif2.df['ATOM'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Looking at mmCIF files in DataFrames" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "mmCIF files are parsed according to the [mmCIF file format description](https://mmcif.wwpdb.org). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more information, we recommend the helpful [Beginner’s Guide to PDB Structures and the PDBx/mmCIF Format](https://pdb101.rcsb.org/learn/guide-to-understanding-pdb-data/beginner’s-guide-to-pdb-structures-and-the-pdbx-mmcif-format) guide." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After loading a PDB file from rcsb.org or our local drive, the [`PandasPdb.df`](../api/biopandas.pdb/#pandaspdbdf) attribute should contain the following 3 DataFrame objects:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['ATOM', 'HETATM', 'ANISOU'])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "\n", "pmmcif = PandasMmcif()\n", "pmmcif.read_mmcif('./data/3eiy.cif')\n", "pmmcif.df.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif](https://raw.githubusercontent.com/rasbt/biopandas/main/docs/tutorials/data/3eiy.cif)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 'ATOM': contains the entries from the ATOM coordinate section\n", "- 'HETATM': ... entries from the \"HETATM\" coordinate section \n", "- 'ANISOU': ... entries from the \"ANISOU\" coordinate section " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The columns for `'ATOM'` DataFrame are as follows:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['group_PDB', 'id', 'type_symbol', 'label_atom_id', 'label_alt_id', 'label_comp_id', 'label_asym_id', 'label_entity_id', 'label_seq_id', 'pdbx_PDB_ins_code', 'Cartn_x', 'Cartn_y', 'Cartn_z', 'occupancy', 'B_iso_or_equiv', 'pdbx_formal_charge', 'auth_seq_id', 'auth_comp_id', 'auth_asym_id', 'auth_atom_id', 'pdbx_PDB_model_num'], dtype='object')" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['ATOM'].columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **'group_PDB'**:\n", "The group of atoms to which the atom site belongs. This data\n", " item is provided for compatibility with the original Protein\n", " Data Bank format, and only for that purpose.\n", "- **'id'**: The value of _atom_site.id must uniquely identify a record in the\n", " ATOM_SITE list. Note that this item need not be a number; it can be any unique\n", " identifier.\n", "- **'type_symbol'**: The code used to identify the atom species (singular or plural)\n", " representing this atom type. Normally this code is the element\n", " symbol. The code may be composed of any character except\n", " an underscore with the additional proviso that digits designate\n", " an oxidation state and must be followed by a + or - character.\n", "- **'label_atom_id'**: An atom name identifier, e.g., N, CA, C, O, ...\n", "- **'label_alt_id'**: A place holder to indicate alternate conformation. The alternate conformation\n", " can be an entire polymer chain, or several residues or\n", " partial residue (several atoms within one residue). If\n", " an atom is provided in more than one position, then a\n", " non-blank alternate location indicator must be used for\n", " each of the atomic positions.\n", "- **'label_comp_id'**: For protein polymer entities, this is the three-letter code for\n", " the amino acid. For nucleic acid polymer entities, this is the one-letter code\n", " for the base.\n", "- **'label_asym_id'**: A value that uniquely identifies a record in\n", " the STRUCT_ASYM list.\n", "- **'label_entity_id'**: A value that uniquely identifies a record in\n", " the ENTITY list.\n", "- **'label_seq_id'**: A value that uniquely identifies a record in\n", " the ENTITY_POLY_SEQ list.\n", "- **'pdbx_PDB_ins_code'**: PDB insertion code.\n", "- **'Cartn_x'**: The x atom-site coordinate in angstroms\n", "- **'Cartn_y'**: The y atom-site coordinate in angstroms\n", "- **'Cartn_z'**: The z atom-site coordinate in angstroms\n", "- **'occupancy'**: The fraction of the atom type present at this site.\n", " The sum of the occupancies of all the atom types at this site\n", " may not significantly exceed 1.0 unless it is a dummy site.\n", "- **'B_iso_or_equiv'**: Isotropic atomic displacement parameter, or equivalent isotropic\n", " atomic displacement parameter, B_eq, calculated from the\n", " anisotropic displacement parameters. \n", "- **'pdbx_formal_charge'**: The net integer charge assigned to this atom. This is the\n", " formal charge assignment normally found in chemical diagrams.\n", "- **'auth_seq_id'**: An alternative identifier for _atom_site.label_seq_id that\n", " may be provided by an author in order to match the identification\n", " used in the publication that describes the structure.\n", "- **'auth_comp_id'**: An alternative identifier for _atom_site.label_comp_id that\n", " may be provided by an author in order to match the identification\n", " used in the publication that describes the structure.\n", "- **'auth_asym_id'**: An alternative identifier for _atom_site.label_asym_id that\n", " may be provided by an author in order to match the identification\n", " used in the publication that describes the structure.\n", "- **'auth_atom_id'**: An alternative identifier for _atom_site.label_atom_id that\n", " may be provided by an author in order to match the identification\n", " used in the publication that describes the structure.\n", "- **'pdbx_PDB_model_num'**: PDB model number." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The columns of the 'HETATM' DataFrame are indentical to the 'ATOM' DataFrame that we've seen earlier:" ] }, { "cell_type": "code", "execution_count": 12, "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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
1330HETATM1331KK...KAK1
1331HETATM1332NANA...NAANA1
\n", "

2 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "1330 HETATM 1331 K K ... K A K 1\n", "1331 HETATM 1332 NA NA ... NA A NA 1\n", "\n", "[2 rows x 21 columns]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['HETATM'].head(2)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set(pmmcif.df['HETATM'].columns) == set(pmmcif.df['ATOM'].columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, there are a few naming differences in the ANISOU columns, for instance, the `'ATOM'` and `'HETATM'` DataFrames feature the following columns that are not contained in ANISOU:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'B_iso_or_equiv',\n", " 'Cartn_x',\n", " 'Cartn_y',\n", " 'Cartn_z',\n", " 'auth_asym_id',\n", " 'auth_atom_id',\n", " 'auth_comp_id',\n", " 'auth_seq_id',\n", " 'group_PDB',\n", " 'label_alt_id',\n", " 'label_asym_id',\n", " 'label_atom_id',\n", " 'label_comp_id',\n", " 'label_entity_id',\n", " 'label_seq_id',\n", " 'occupancy',\n", " 'pdbx_PDB_model_num',\n", " 'pdbx_formal_charge'}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set(pmmcif.df['ATOM'].columns) - set(pmmcif.df['ANISOU'].columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vice versa, ANISOU contains the following columns that are not in the `'ATOM'` and `'HETATM'` DataFrames:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'U[1][1]',\n", " 'U[1][2]',\n", " 'U[1][3]',\n", " 'U[2][2]',\n", " 'U[2][3]',\n", " 'U[3][3]',\n", " 'pdbx_auth_asym_id',\n", " 'pdbx_auth_atom_id',\n", " 'pdbx_auth_comp_id',\n", " 'pdbx_auth_seq_id',\n", " 'pdbx_label_alt_id',\n", " 'pdbx_label_asym_id',\n", " 'pdbx_label_atom_id',\n", " 'pdbx_label_comp_id',\n", " 'pdbx_label_seq_id'}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set(pmmcif.df['ANISOU'].columns) - set(pmmcif.df['ATOM'].columns) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "BioPandas tries to stay to the original column names as close as possible, and for more details, we recommend checking the original descriptions:\n", "\n", "- [ATOM/HETATM](https://mmcif.wwpdb.org/docs/pdb_to_pdbx_correspondences.html#ATOMP)\n", "- [ANISOU](https://mmcif.wwpdb.org/docs/pdb_to_pdbx_correspondences.html#ANISOU)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Working with mmCIF DataFrames" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the previous sections, we've seen how to load mmCIF structures into DataFrames, and how to access them. Now, let's talk about manipulating mmCIF files in DataFrames." ] }, { "cell_type": "code", "execution_count": 16, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
0ATOM1NN...SERAN1
1ATOM2CCA...SERACA1
2ATOM3CC...SERAC1
3ATOM4OO...SERAO1
4ATOM5CCB...SERACB1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "0 ATOM 1 N N ... SER A N 1\n", "1 ATOM 2 C CA ... SER A CA 1\n", "2 ATOM 3 C C ... SER A C 1\n", "3 ATOM 4 O O ... SER A O 1\n", "4 ATOM 5 C CB ... SER A CB 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from biopandas.mmcif import PandasMmcif\n", "pmmcif = PandasMmcif()\n", "pmmcif.read_mmcif('./data/3eiy.cif.gz')\n", "pmmcif.df['ATOM'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif.gz](https://github.com/rasbt/biopandas/blob/main/docs/tutorials/data/3eiy.cif.gz?raw=true)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Okay, there's actually not *that* much to say ... \n", "Once we have our mmCIF file in the DataFrame format, we have the whole convenience of [pandas](http://pandas.pydata.org) right there at our fingertips." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, let's get all Proline residues:" ] }, { "cell_type": "code", "execution_count": 17, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
38ATOM39NN...PROAN1
39ATOM40CCA...PROACA1
40ATOM41CC...PROAC1
41ATOM42OO...PROAO1
42ATOM43CCB...PROACB1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "38 ATOM 39 N N ... PRO A N 1\n", "39 ATOM 40 C CA ... PRO A CA 1\n", "40 ATOM 41 C C ... PRO A C 1\n", "41 ATOM 42 O O ... PRO A O 1\n", "42 ATOM 43 C CB ... PRO A CB 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['ATOM'][pmmcif.df['ATOM']['auth_comp_id'] == 'PRO'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or main chain atoms:" ] }, { "cell_type": "code", "execution_count": 18, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
1ATOM2CCA...SERACA1
7ATOM8CCA...PHEACA1
18ATOM19CCA...SERACA1
24ATOM25CCA...ASNACA1
32ATOM33CCA...VALACA1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "1 ATOM 2 C CA ... SER A CA 1\n", "7 ATOM 8 C CA ... PHE A CA 1\n", "18 ATOM 19 C CA ... SER A CA 1\n", "24 ATOM 25 C CA ... ASN A CA 1\n", "32 ATOM 33 C CA ... VAL A CA 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['ATOM'][pmmcif.df['ATOM']['label_atom_id'] == 'CA'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's also easy to strip our coordinate section from hydrogen atoms if there are any ..." ] }, { "cell_type": "code", "execution_count": 19, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
0ATOM1NN...SERAN1
1ATOM2CCA...SERACA1
2ATOM3CC...SERAC1
3ATOM4OO...SERAO1
4ATOM5CCB...SERACB1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "0 ATOM 1 N N ... SER A N 1\n", "1 ATOM 2 C CA ... SER A CA 1\n", "2 ATOM 3 C C ... SER A C 1\n", "3 ATOM 4 O O ... SER A O 1\n", "4 ATOM 5 C CB ... SER A CB 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pmmcif.df['ATOM'][pmmcif.df['ATOM']['type_symbol'] != 'H'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or, let's compute the average temperature factor of our protein main chain:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Average B-Factor [Main Chain]: 1.00\n" ] } ], "source": [ "mainchain = pmmcif.df['ATOM'][(pmmcif.df['ATOM']['label_atom_id'] == 'C') | \n", " (pmmcif.df['ATOM']['label_atom_id'] == 'O') | \n", " (pmmcif.df['ATOM']['label_atom_id'] == 'N') | \n", " (pmmcif.df['ATOM']['label_atom_id'] == 'CA')]\n", "\n", "bfact_mc_avg = mainchain['occupancy'].mean()\n", "print('Average B-Factor [Main Chain]: %.2f' % bfact_mc_avg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we are using pandas under the hood, which in turns uses matplotlib under the hood, we can produce quick summary plots of our mmCIF structures relatively conveniently:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "\n", "pmmcif = PandasMmcif().read_mmcif('./data/3eiy.cif.gz')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif.gz](https://github.com/rasbt/biopandas/blob/main/docs/tutorials/data/3eiy.cif.gz?raw=true)]" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "from matplotlib import style\n", "style.use('ggplot')" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEaCAYAAAAL7cBuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAqOklEQVR4nO3df1xUdb4/8NcMoCCz4PyAEMQMwZDS5RqkUEbFrO2Wl0us2gPDAkmvYrurlCt328RdtdhVJH9Q7t2rlnUfN71bYD+86mNCsaJdphTDnxuuv1iQXzOBKAjDfL5/KOcLcZARYWZwXs/Hg8eDc+acM+83A/PifM6ZcxRCCAEiIqIfUDq6ACIick4MCCIiksWAICIiWQwIIiKSxYAgIiJZDAgiIpLFgKB+W7lyJUJDQwdl2wcPHoRCoUBlZaXs9EB7++234e7uPijb7o+LFy8iPj4e3t7eUCgUji6HXBQDgrpJTU2FQqGAQqGAu7s7NBoNYmJi8Lvf/Q4mk6nbsi+//DL++te/2rzt0NBQrFy50qZlY2NjUV1djcDAwFspv0+VlZVQKBQ4ePBgt/nPPPMM/vnPfw7oc92O1157DbW1tSgrK0N1dbXsMp2h2fk1bNgwhISE4De/+Q0sFstNt3/u3Llu63Z+hYeHD0j9t/Jak/Nynn+ZyGlMmzYNu3btgtVqhdlsxt/+9jf88Y9/xJYtW1BcXIzx48cDAFQqFVQq1YA/f1tbG4YNG4aAgIAB33ZvvLy84OXlZbfn68t3332HBx98EGFhYX0ue/jwYYwaNQrXrl1DaWkp0tPT4eXlhVdffbXPdXfv3o0HH3xQmnamvSgAsFqtEELAzc3N0aW4JkHUxfPPPy/i4+N7zG9sbBQhISHisccek+ZlZ2eLcePGSdMXL14USUlJQqvVCk9PT3HPPfeIP/7xj0IIIeLi4gSAbl9nz54VBw4cEADEJ598Ih566CExfPhwsWnTJmn+xYsXhRBCmv7oo49EdHS0GD58uIiIiBD79++Xnv+H63Ryc3MT27dvF0KIHjXcfffdQgghtm/fLtzc3Lqt9+mnn4rJkyeLYcOGCT8/P7Fo0SLR3Nzc42f1pz/9SYwZM0b86Ec/EgkJCaK2tvamP+OmpiaxYMECodPpxPDhw8UDDzwg9u3bJz3+wxqff/552e301m9SUpJISEi4aQ1nz54VAMTnn3/e47F//OMf4umnnxajRo0SXl5e4v777xc7duzosdzmzZvFhAkTpJ/Pz3/+cyFE76+1EEJ89dVXYtq0acLT01OMHDlSJCcni5qaGmmbnb9T77//vrj33nuFm5ubKC8vF8eOHRPTp08Xvr6+YsSIESI8PFy2JhpYHGIim/j4+GDRokU4ePAg6urqZJfJyMhAY2MjDAYDTp48ia1bt2L06NEAgA8//BBjx47FSy+9hOrqalRXVyM4OFha96WXXsKvf/1rnDx5EomJib3WkZmZiRUrVuDIkSOYOnUqEhISbmlo6PDhwwCADz74ANXV1TAajbLLffvtt0hISMAjjzyCsrIyvPPOO/jkk0+wcOHCbssZjUYcOHAAn376Kfbu3YuysjK8/PLLN61h3rx52LdvH9577z0cOXIEDz30EGbMmIFTp04BAKqrqxETE4M5c+aguroaGzZssLm/o0eP4ssvv0RsbKzN6/xQc3Mz4uPjsXfvXpSXl2PBggVIS0vDgQMHpGWys7OxfPlyZGRkoLy8HHv37kVkZCSA3l/rS5cuYfr06Rg9ejRKS0vx8ccf49ixY/j5z3/e7fmrqqrw5ptv4u2338aJEydw9913Izk5GVqtFiUlJSgvL8f69euhVqv73SPZyNEJRc6ltz0IIYT4v//7PwFA/O1vfxNC9NyDmDRpksjOzu512+PGjevxeOd/wT/8b7C3PYj/+q//kpZpb28XY8aMEa+88orsOp267kFcvHhRABAHDhzotswP9yBSUlJEdHR0t2UKCwuFQqEQ586dE0Jc/1npdDrR2toqLfP666+LgICAXn8G3333nQAgPv30027z/+Vf/kWkpaVJ03FxcSI9Pb3X7XTtd8SIEcLb21sMGzZMABDPPPOMsFgsN123cw/Cy8tLeHt7S19df75dJSQkiBdeeEEIIURzc7Pw9PQUa9eu7XX7cq/1b3/7WxEUFCSuXbsmzSsrKxMARHFxsRDi+u+UQqEQ58+f77auj4+P9BqS/XAPgmwmblzXsbezapYsWYLXXnsNU6ZMwfLly3Ho0CGbt911HPxmYmJipO/d3d3x4IMP4sSJEzY/j62OHz+ORx55pNu8uLg4CCG6Pd+ECRMwfPhwaTooKAg1NTW9brdz3R9u+5FHHsHx48f7Veu+fftQVlaGo0ePorCwEN988w3S09OlxzuPFalUKvzsZz/rtu727dtRVlYmfc2aNQtXr15FVlYW7rvvPmg0GqhUKuzZswfnz58HcP1n09raiunTp99SncePH8fUqVMxbNgwad6Pf/xj+Pr6duv9rrvuwpgxY7qt+/LLL+OFF17Ao48+ipUrV0p7gjS4nOuIFDm1Y8eOQaFQICQkRPbxtLQ0/PSnP8XevXtx4MAB/OxnP8PTTz+N9957r89te3t796sm0eVixEqlsse8jo4OWK3Wfm27tyDsOr/rm13nY6IfF0gWQvT7dNaxY8dKQ3nh4eG4evUq5syZg1dffRXjxo1DWVmZtOwPD8QHBQX1OFV58eLF2L17N3JzcxEeHg5vb2+89NJLaGxs7LZcf+q15Wcq97vw6quv4tlnn8XevXtRVFSE1157Db/+9a+xevXqW66BbMc9CLJJU1MT3nrrLcTHx0Or1fa63KhRo5CWloYdO3Zg69at+O///m80NTUBuP5m2tHRcVt1dD2t1mKxwGg0YsKECQAAf39/ANfHsDuVlZV1e8PufEPvq4777rsPxcXF3eYVFxdDoVAgIiKi3/Xfd999ANBj7+rzzz+XHrtdnWcitbS0ALh+ymnnV1BQUJ/rHzp0CM8++yyeeeYZ/PjHP0ZISAj+/ve/S49HRETA09MT+/bt63Ubcq/1fffdh6+++gptbW3SvKNHj6KxsdGm3kNCQpCRkYG//OUv+P3vf4+33nqrz3Xo9jAgqIe2tjZcunQJ1dXVOHHiBLZt24YHH3wQ165du+kf5Ysvvog9e/bgzJkzOH78OD788EMEBwfjRz/6EQDgnnvuwZdffokLFy6gvr6+X//Z5+TkYM+ePTh58iQWLVqEmpoaLFq0CMD1N8K7774bK1euxKlTp/DFF19g6dKl3f471el0UKlU2L9/Py5dugSz2Sz7PMuWLcPhw4eRmZmJU6dOYe/evfjFL36BZ599tsfwx60YN24cZs2ahYyMDOzbtw+nTp3Cr371Kxw7dgzLli3r1zbr6upw6dIlVFZWoqioCCtXrkR4eHi/P9Nw7733Yvfu3SgtLcWJEyewYMGCbqGrUqnw0ksvYeXKlcjPz8ff//53HD16FK+//rq0jNxr/eKLL6KpqQmpqak4duwYvvjiC8ydOxcPP/wwpk2b1ms9zc3NWLx4MYqKinD27FkcOXIEe/fuva2gJhs58PgHOaHnn39eOjXRzc1NjBw5UkyZMkX87ne/EyaTqduyPzxInZGRIcLCwoSnp6fQaDTiySefFMeOHZMeNxqNYvLkycLT07PHaa4/PLDc20Hq3bt3S6eeTpgwQezdu7fben/961+l55g0aZI4dOhQt4PUQgjxzjvviLFjxwp3d3ebT3PV6XRi4cKFsqe5dvXuu++Kvv6sGhsbpdNchw0b1uM0VyFu7SB155dSqRRBQUFi7ty50oH03tzsNNcLFy6I6dOnixEjRoiAgACxYsUKMW/ePBEXFyctY7VaxRtvvCHGjx8vPDw8hL+/v5g5c6b0uNxrLUT301x9fX17Pc21q5aWFpGcnCzGjh0rhg8fLvz8/MTs2bPFhQsXbtoj3T6FELyjHBER9cQhJiIiksWAICIiWQwIIiKSxYAgIiJZDAgiIpJ1R32Suuu52s5Mp9Ohvr7e0WU4jCv378q9A+zfGfu/2T1XuAdBRESyGBBERCSLAUFERLIYEEREJIsBQUREshgQREQkiwFBRESyGBBERCSLAUFERLLuqE9SD0Ud8xMc8rxuf/7IIc9LREMH9yCIiEiWXfcgrFYrsrKyoNFokJWVhebmZuTl5aGurg5+fn5YunQpVCoVAKCgoABFRUVQKpVIS0tDZGSkPUslInJ5dt2D2LNnD4KCgqTpwsJCTJw4ERs3bsTEiRNRWFgIAKisrERJSQnWr1+PV155BVu3bu3XDe6JiKj/7BYQDQ0NOHz4MOLj46V5RqMRcXFxAIC4uDgYjUZpfmxsLDw8PODv74+AgABUVFTYq1QiIoIdh5jefvttpKSkoKWlRZrX2NgItVoNAFCr1WhqagIAmEwmhIWFSctpNBqYTKYe2zQYDDAYDACAnJwc6HS6wWxhwLi7u0u11jioBkf+rLr272pcuXeA/Q+1/u0SEN988w18fX0REhKC48eP97m8EMKm7er1euj1emna2a6z3htnuCa8I5/fGfp3FFfuHWD/ztj/ze4HYZeAOH36NL7++mscOXIEbW1taGlpwcaNG+Hr6wuz2Qy1Wg2z2QwfHx8AgFarRUNDg7S+yWSCRqOxR6lERHSDXY5BzJkzB1u2bEF+fj6WLFmC+++/H7/85S8RFRWF4uJiAEBxcTGio6MBAFFRUSgpKUF7eztqa2tRXV2N0NBQe5RKREQ3OPSDcomJicjLy0NRURF0Oh0yMzMBAMHBwYiJiUFmZiaUSiXS09OhVPIjG0RE9qQQtg74DwFD8Z7UrvhJamcch7UXV+4dYP/O2D/vSU1ERLeMAUFERLIYEEREJIsBQUREshgQREQkiwFBRESyGBBERCSLAUFERLIYEEREJIsBQUREshgQREQkiwFBRESyGBBERCSLAUFERLIYEEREJIsBQUREsuxyR7m2tjZkZ2fDYrGgo6MDU6dOxezZs7Fr1y589tln0r2ok5OTMXnyZABAQUEBioqKoFQqkZaWhsjISHuUSkREN9glIDw8PJCdnQ1PT09YLBasWLFCesN/6qmnkJDQ/a5qlZWVKCkpwfr162E2m7Fq1Sps2LCBtx0lIrIju7zjKhQKeHp6AgA6OjrQ0dEBhULR6/JGoxGxsbHw8PCAv78/AgICUFFRYY9SiYjoBrvsQQCA1WrF8uXLcenSJTzxxBMICwvDkSNHsG/fPhw6dAghISF47rnnoFKpYDKZEBYWJq2r0WhgMpl6bNNgMMBgMAAAcnJyoNPp7NXObXF3d5dqrXFQDY78WXXt39W4cu8A+x9q/dstIJRKJdauXYsrV65g3bp1uHDhAqZPn46ZM2cCAHbu3IkdO3YgIyMDQgibtqnX66HX66VpZ7sZeG+c4cbljnx+Z+jfUVy5d4D9O2P/gYGBvT5m90F9b29vREREoKysDCNHjoRSqYRSqUR8fDzOnDkDANBqtWhoaJDWMZlM0Gg09i6ViMil2SUgmpqacOXKFQDXz2gqLy9HUFAQzGaztExpaSmCg4MBAFFRUSgpKUF7eztqa2tRXV2N0NBQe5RKREQ32GWIyWw2Iz8/H1arFUIIxMTE4IEHHsCmTZtw7tw5KBQK+Pn5YcGCBQCA4OBgxMTEIDMzE0qlEunp6TyDiYjIzhTC1gH/IaCqqsrRJdik6zhkx/yEPpYeHG5//sghzws45zisvbhy7wD7d8b+b3YMwm4Hqcm5OCqYAAAFJY57biKyGcdtiIhIFgOCiIhkMSCIiEgWA4KIiGQxIIiISBYDgoiIZDEgiIhIFgOCiIhkMSCIiEgWA4KIiGQxIIiISBYDgoiIZDEgiIhIFgOCiIhkMSCIiEiWXe4H0dbWhuzsbFgsFnR0dGDq1KmYPXs2mpubkZeXh7q6Ovj5+WHp0qVQqVQAgIKCAhQVFUGpVCItLQ2RkZH2KJWIiG6wS0B4eHggOzsbnp6esFgsWLFiBSIjI1FaWoqJEyciMTERhYWFKCwsREpKCiorK1FSUoL169fDbDZj1apV2LBhA287SkRkR3Z5x1UoFPD09AQAdHR0oKOjAwqFAkajEXFxcQCAuLg4GI1GAIDRaERsbCw8PDzg7++PgIAAVFRU2KNUIiK6wW63HLVarVi+fDkuXbqEJ554AmFhYWhsbIRarQYAqNVqNDU1AQBMJhPCwsKkdTUaDUwmk71KJSIi2DEglEol1q5diytXrmDdunW4cOFCr8sKIWzapsFggMFgAADk5ORAp9MNSK2Dzd3dXaq1xsG1OELX/l2NK/cOsP+h1r/dAqKTt7c3IiIiUFZWBl9fX5jNZqjVapjNZvj4+AAAtFotGhoapHVMJhM0Gk2Pben1euj1emm6vr5+8BsYADqdbsjUOhgsFovL9u/qrz37d77+AwMDe33MLscgmpqacOXKFQDXz2gqLy9HUFAQoqKiUFxcDAAoLi5GdHQ0ACAqKgolJSVob29HbW0tqqurERoaao9SiYjoBrvsQZjNZuTn58NqtUIIgZiYGDzwwAMYP3488vLyUFRUBJ1Oh8zMTABAcHAwYmJikJmZCaVSifT0dJ7BRERkZwph64D/EFBVVeXoEmzSdTezY36Cg6uxv7sKSpxuN9tenHGIwZ7Yv/P17/AhJiIiGnoYEEREJIsBQUREshgQREQkiwFBRESyGBBERCSLAUFERLIYEEREJIsBQUREshgQREQkiwFBRESyGBBERCSLAUFERLIYEEREJIsBQUREshgQREQkiwFBRESy7HLL0fr6euTn5+P777+HQqGAXq/Hk08+iV27duGzzz6Dj48PACA5ORmTJ08GABQUFKCoqAhKpRJpaWmIjIy0R6lERHSDXQLCzc0Nc+fORUhICFpaWpCVlYVJkyYBAJ566ikkJHS/7WZlZSVKSkqwfv16mM1mrFq1Chs2bOB9qYmI7Mgu77hqtRohISEAAC8vLwQFBcFkMvW6vNFoRGxsLDw8PODv74+AgABUVFTYo1QiIrrBLnsQXdXW1uLs2bMIDQ3FqVOnsG/fPhw6dAghISF47rnnoFKpYDKZEBYWJq2j0WhkA8VgMMBgMAAAcnJyoNPp7NbH7XB3d5dqrXFwLY7QtX9X48q9A+x/qPVv14BobW1Fbm4uUlNTMWLECEyfPh0zZ84EAOzcuRM7duxARkYGhBA2bU+v10Ov10vT9fX1g1L3QNPpdEOm1sFgsVhctn9Xf+3Zv/P1HxgY2OtjdhvUt1gsyM3NxbRp0zBlyhQAwMiRI6FUKqFUKhEfH48zZ84AALRaLRoaGqR1TSYTNBqNvUolIiLcQkB89NFHsvM/+eSTPtcVQmDLli0ICgrCjBkzpPlms1n6vrS0FMHBwQCAqKgolJSUoL29HbW1taiurkZoaKitpRIR0QCweYjpgw8+6HG2Uef8rm/6ck6fPo1Dhw5hzJgxWLZsGYDrp7R++eWXOHfuHBQKBfz8/LBgwQIAQHBwMGJiYpCZmQmlUon09HSewUREZGd9BsSxY8cAAFarVfq+U01NDby8vPp8kvDwcOzatavH/M7PPMhJSkpCUlJSn9smIqLB0WdAvPXWWwCAtrY26XsAUCgUGDlyJObNmzd41RERkcP0GRD5+fkAgM2bN+PFF18c9IKIiMg52HwMoms4WK3Wbo/x+AAR0Z3H5oD4xz/+ga1bt+LChQtoa2vr9tjOnTsHvDAiInIsmwMiPz8fDzzwABYtWoThw4cPZk1EROQEbA6I+vp6JCcnQ6FQDGY9RETkJGw+eBAdHY2jR48OZi1EROREbN6DaG9vx7p16xAeHo6RI0d2e4xnNxER3XlsDojRo0dj9OjRg1kLERE5EZsDYtasWYNZBxERORmbA+KHl9no6v777x+QYoiIyHnYHBBdL7MBAE1NTbBYLNBqtdi8efOAF0ZERI51S5+D6MpqteKDDz6w6WJ9REQ09PT7GhlKpRJJSUnYvXv3QNZDRERO4rYuovTtt9/yOkxERHcom4eYFi1a1G26ra0NbW1teOGFFwa8KCIicjybA+IXv/hFt+nhw4dj1KhRGDFiRJ/r1tfXIz8/H99//z0UCgX0ej2efPJJNDc3Iy8vD3V1dfDz88PSpUuhUqkAAAUFBSgqKoJSqURaWhoiIyNvrTMiIrotNgdEREQEgOsHpxsbG+Hr62vz8JKbmxvmzp2LkJAQtLS0ICsrC5MmTcLBgwcxceJEJCYmorCwEIWFhUhJSUFlZSVKSkqwfv16mM1mrFq1Chs2bOBwFhGRHdn8jtvS0oLNmzcjJSUFCxcuREpKCjZv3oyrV6/2ua5arUZISAgAwMvLC0FBQTCZTDAajYiLiwMAxMXFwWg0AgCMRiNiY2Ph4eEBf39/BAQEoKKioj/9ERFRP9m8B7Ft2za0trZi3bp18PPzQ11dHd5//31s27btlq7FVFtbi7NnzyI0NBSNjY1Qq9UArodIU1MTAMBkMiEsLExaR6PRwGQy9diWwWCAwWAAAOTk5ECn09lchyO5u7tLtdY4uBZH6Nq/q3Hl3gH2P9T6tzkgysrKsHnzZuleEIGBgcjIyOhxbOJmWltbkZubi9TU1JseuxBC2LQ9vV4PvV4vTdfX19tciyPpdLohU+tgsFgsLtu/q7/27N/5+g8MDOz1MZuHmIYNGyb9h9+pqakJ7u62ZYzFYkFubi6mTZuGKVOmAAB8fX1hNpsBAGazGT4+PgAArVaLhoYGaV2TyQSNRmNrqURENABsDojHH38cq1evxv79+3HkyBHs378fa9asQXx8fJ/rCiGwZcsWBAUFYcaMGdL8qKgoFBcXAwCKi4sRHR0tzS8pKUF7eztqa2tRXV2N0NDQW+2NiIhug81DTElJSdBoNPjiiy+k/+j/7d/+DY8//nif654+fRqHDh3CmDFjsGzZMgBAcnIyEhMTkZeXh6KiIuh0OmRmZgIAgoODERMTg8zMTCiVSqSnp/MMJiIiO1MIGwf8t23bhoceegj33nuvNO/06dP46quvkJqaOlj13ZKqqipHl2CTruOQHfMTHFyN/d1VUOJ047D24oxj0PbE/p2v/wE5BvHll19i3Lhx3eaFhITgiy++6H9lRETktGwOCIVCAavV2m2e1Wq1+YwjIiIaWmwOiPDwcLz//vtSSFitVvzv//4vwsPDB604IiJyHJsPUqelpSEnJwf//u//Lo2jqdVqLF++fDDrIyIiB7E5ILRaLf7whz+goqICDQ0N0Gq1CA0N5dlFRER3KJsDArh+k6Dx48cPVi1ERORE+O8/ERHJYkAQEZEsBgQREcliQBARkSwGBBERyWJAEBGRLAYEERHJYkAQEZEsBgQREcliQBARkaxbutRGf7355ps4fPgwfH19kZubCwDYtWsXPvvsM+k+1MnJyZg8eTIAoKCgAEVFRVAqlUhLS0NkZKQ9yiQioi7sEhCPPvoofvrTnyI/P7/b/KeeegoJCd3vqFZZWYmSkhKsX78eZrMZq1atwoYNG3hRQCIiO7PLu25ERARUKpVNyxqNRsTGxsLDwwP+/v4ICAhARUXFIFdIREQ/ZJc9iN7s27cPhw4dQkhICJ577jmoVCqYTCaEhYVJy2g0GphMJtn1DQYDDAYDACAnJwc6nc4udd8ud3d3qdYaB9fiCF37dzWu3DvA/oda/w4LiOnTp2PmzJkAgJ07d2LHjh3IyMi4pVuY6vV66PV6adrZbgbeG2e8cbk9WSwWl+3f1V979u98/QcGBvb6mMMG9keOHAmlUgmlUon4+HicOXMGwPUbEzU0NEjLmUwmaDQaR5VJROSyHBYQZrNZ+r60tBTBwcEAgKioKJSUlKC9vR21tbWorq5GaGioo8okInJZdhlieuONN3DixAlcvnwZCxcuxOzZs3H8+HGcO3cOCoUCfn5+WLBgAQAgODgYMTExyMzMhFKpRHp6Os9gIiJyALsExJIlS3rMe/zxx3tdPikpCUlJSYNYERER9YX/mhMRkSyHnubqTDrmJ/S90ABxxVNbiWjo4R4EERHJYkAQEZEsBgQREcniMQiyu5qnYx3yvG5//sghz0s0VHEPgoiIZDEgiIhIFgOCiIhkMSCIiEgWA4KIiGQxIIiISBYDgoiIZDEgiIhIFgOCiIhkMSCIiEiWXS618eabb+Lw4cPw9fVFbm4uAKC5uRl5eXmoq6uDn58fli5dCpVKBQAoKChAUVERlEol0tLSEBkZaY8yiYioC7vsQTz66KP4zW9+021eYWEhJk6ciI0bN2LixIkoLCwEAFRWVqKkpATr16/HK6+8gq1bt8JqtdqjTCIi6sIuARERESHtHXQyGo2Ii4sDAMTFxcFoNErzY2Nj4eHhAX9/fwQEBKCiosIeZRIRURcOu5prY2Mj1Go1AECtVqOpqQkAYDKZEBYWJi2n0WhgMplkt2EwGGAwGAAAOTk50Ol0/a6Hd3m7893O78dAcXd3d4o6HIX9D63+ne5y30IIm5fV6/XQ6/XSdH19/WCURHcIR11mHPj/lxrX6XQu/XvK/p2v/8DAwF4fc9hZTL6+vjCbzQAAs9kMHx8fAIBWq0VDQ4O0nMlkgkajcUiNRESuzGEBERUVheLiYgBAcXExoqOjpfklJSVob29HbW0tqqurERoa6qgyiYhcll2GmN544w2cOHECly9fxsKFCzF79mwkJiYiLy8PRUVF0Ol0yMzMBAAEBwcjJiYGmZmZUCqVSE9Ph1LJj2sQEdmbQtzKoL+Tq6qq6ve6HfMTBrASou4cdQzCkb/Xcrd4dcYxeHtyxv5vdgzC6Q5SE92JOt+oebYcDSUcuyEiIlkMCCIiksWAICIiWQwIIiKSxYAgIiJZDAgiIpLFgCAiIlkMCCIiksWAICIiWQwIIiKSxYAgIiJZDAgiIpLFgCAiIlkMCCIiksWAICIiWQ6/H8TixYvh6ekJpVIJNzc35OTkoLm5GXl5eairq4Ofnx+WLl0KlUrl6FKJiFyKwwMCALKzs+Hj4yNNFxYWYuLEiUhMTERhYSEKCwuRkpLiwAqJiFyPUw4xGY1GxMXFAQDi4uJgNBodXBERketxij2INWvWAAB+8pOfQK/Xo7GxEWq1GgCgVqvR1NTkyPKIiFySwwNi1apV0Gg0aGxsxOrVq296A+0fMhgMMBgMAICcnBzodLp+18F7BRMNLLm/R3d399v6Ox3qhlr/Dg8IjUYDAPD19UV0dDQqKirg6+sLs9kMtVoNs9nc7fhEV3q9Hnq9Xpqur6+3S81E1De5v0edTufSf6fO2P/N/il36DGI1tZWtLS0SN9/++23GDNmDKKiolBcXAwAKC4uRnR0tCPLJCJySQ7dg2hsbMS6desAAB0dHXj44YcRGRmJcePGIS8vD0VFRdDpdMjMzHRkmURELkkhhBCOLmKgVFVV9XvdjvkJA1gJEbn9+aMe85xxiMWenLF/px1iIiIi58WAICIiWQwIIiKSxYAgIiJZDAgiIpLFgCAiIlkMCCIikuXwS20Q0Z1J7rNF9rjmmdznL6h/uAdBRESyGBBERCSLAUFERLIYEEREJIsBQUREshgQREQkiwFBRESy+DkIIrqjOOreLnfi5y+4B0FERLKceg+irKwM27dvh9VqRXx8PBITEx1dEhGRy3DagLBardi6dSt++9vfQqvV4j/+4z8QFRWF0aNHO7o0IqIebBnaGqxLjQzW8JbTDjFVVFQgICAAd911F9zd3REbGwuj0ejosoiIXIbT7kGYTCZotVppWqvV4rvvvuu2jMFggMFgAADk5OTc9Obbffr06/6vS0R0B3LaPQghRI95CoWi27Rer0dOTg5ycnLsVdaAyMrKcnQJDuXK/bty7wD7H2r9O21AaLVaNDQ0SNMNDQ1Qq9UOrIiIyLU4bUCMGzcO1dXVqK2thcViQUlJCaKiohxdFhGRy3DaYxBubm6YN28e1qxZA6vVisceewzBwcGOLmtA6PV6R5fgUK7cvyv3DrD/oda/QsgN9hMRkctz2iEmIiJyLAYEERHJctpjEHeC+vp65Ofn4/vvv4dCoYBer8eTTz6J5uZm5OXloa6uDn5+fli6dClUKpWjyx1wbW1tyM7OhsViQUdHB6ZOnYrZs2e7TP/A9SsCZGVlQaPRICsry6V6X7x4MTw9PaFUKuHm5oacnByX6v/KlSvYsmULLl68CIVCgUWLFiEwMHBI9c9jEIPIbDbDbDYjJCQELS0tyMrKwrJly3Dw4EGoVCokJiaisLAQzc3NSElJcXS5A04IgWvXrsHT0xMWiwUrVqxAamoqSktLXaJ/APjkk09w5swZ6fV/7733XKb3xYsX4/XXX4ePj480z5X637x5MyZMmID4+HhYLBZcu3YNBQUFQ6p/DjENIrVajZCQEACAl5cXgoKCYDKZYDQaERcXBwCIi4u7Yy8holAo4OnpCQDo6OhAR0cHFAqFy/Tf0NCAw4cPIz4+XprnKr33xlX6v3r1Kk6ePInHH38cAODu7g5vb+8h1z+HmOyktrYWZ8+eRWhoKBobG6UP/anVajQ1NTm4usFjtVqxfPlyXLp0CU888QTCwsJcpv+3334bKSkpaGlpkea5Su+d1qxZAwD4yU9+Ar1e7zL919bWwsfHB2+++SbOnz+PkJAQpKamDrn+GRB20NraitzcXKSmpmLEiBGOLseulEol1q5diytXrmDdunW4cOGCo0uyi2+++Qa+vr4ICQnB8ePHHV2OQ6xatQoajQaNjY1YvXr17V0rbYjp6OjA2bNnMW/ePISFhWH79u0oLCx0dFm3jAExyCwWC3JzczFt2jRMmTIFAODr6wuz2Qy1Wg2z2dxtjPZO5e3tjYiICJSVlblE/6dPn8bXX3+NI0eOoK2tDS0tLdi4caNL9N5Jo9EAuP77Hh0djYqKCpfpX6vVQqvVIiwsDAAwdepUFBYWDrn+eQxiEAkhsGXLFgQFBWHGjBnS/KioKBQXFwMAiouLER0d7agSB1VTUxOuXLkC4PoZTeXl5QgKCnKJ/ufMmYMtW7YgPz8fS5Yswf33349f/vKXLtE7cH2vuXNorbW1Fd9++y3GjBnjMv2PHDkSWq0WVVVVAIDy8nKMHj16yPXPs5gG0alTp7BixQqMGTNGuhJtcnIywsLCkJeXh/r6euh0OmRmZjr1qW79df78eeTn58NqtUIIgZiYGMycOROXL192if47HT9+HB9//DGysrJcpveamhqsW7cOwPXhlocffhhJSUku0z8AnDt3Dlu2bIHFYoG/vz8yMjIghBhS/TMgiIhIFoeYiIhIFgOCiIhkMSCIiEgWA4KIiGQxIIiISBYDgqif9u/fj/nz52Pu3Lm4fPmyo8shGnD8JDXRDYsXL8b3338PpVIJd3d3jB8/HvPnz4dOp+uxrMViwTvvvIM1a9Zg7Nixt/W8s2fPxsaNGxEQEHBb2yEaaNyDIOpi+fLlePfdd/GnP/0Jvr6+2LZtm+xyjY2NaG9vd/h90js6Ohz6/HRn4x4EkYxhw4Zh6tSpeOedd3o8VlVVheXLlwMAUlNTERoaiuzsbGzfvh2lpaW4evUqAgICkJqaigkTJgC4flXbwsJCHDhwAI2NjRg1ahSWLVuGTZs2AQCWLVsGAFi0aBFiY2NhMBiwe/duNDc3Izw8HPPnz5eubTR79mzMmzcPe/bsQUdHB/Lz8+3xIyFXJIhICCFERkaGOHr0qBBCiNbWVrFp0yaxadMm2WVramrErFmzhMVikeYVFxeLpqYmYbFYxEcffSReeOEFce3aNSGEELt37xaZmZnin//8p7BareLs2bOiqalJCCHErFmzRHV1tbSd8vJyMW/ePHHmzBnR1tYmtm7dKlasWCE9PmvWLPH73/9eXL58Wdo+0WDgHgRRF2vXroWbmxtaW1vh6+uLV155xeZ1H3nkEen7f/3Xf8WHH36IqqoqjB07Fp999hlSUlKkS17f7LjF559/jscee0y62dScOXOQlpaG2tpa+Pv7AwCefvppp76GD90ZGBBEXSxbtgyTJk2C1WqF0WhEdnY21q5di6VLl0rLvPvuu7LrfvzxxygqKoLJZIJCoUBLS4t0dlNDQwPuuusum2owm8245557pGlPT0+oVCqYTCYpILRabX9bJLIZA4JIhlKpxJQpU/Cf//mfqKio6DUUOp08eRK7d+/GihUrMHr0aCiVSqSlpUHcuBamVqtFTU0NxowZ0+dzq9Vq1NfXS9Otra1obm6WjkEAkK4OTDSYeBYTkQwhBIxGI65cuYKgoKA+l29paYGbmxt8fHxgtVrxl7/8BVevXpUej4+Px86dO1FdXQ0hBM6fPy/tXfj6+qKmpkZa9uGHH8aBAwdw7tw5tLe343/+538QGhoq7T0Q2Qv3IIi6+MMf/gClUgmFQgE/Pz8sXrzYplNZIyMjERkZiV/96lcYPnw4nnrqqW6fn5gxYwba29uxevVqXL58GUFBQXj55ZcBALNmzUJ+fj7a2tqwYMECxMbG4plnnkFubi6am5tx7733YsmSJYPVMlGveD8IIiKSxSEmIiKSxYAgIiJZDAgiIpLFgCAiIlkMCCIiksWAICIiWQwIIiKSxYAgIiJZ/w+rFgxuGTreRgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pmmcif.df['ATOM']['B_iso_or_equiv'].plot(kind='hist')\n", "plt.title('Distribution of B-Factors')\n", "plt.xlabel('B-factor')\n", "plt.ylabel('count')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEaCAYAAAD+E0veAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABxGUlEQVR4nO2dd5gTVffHv3eS3WyvWcoC0ot0FFRUWBSwoqI/CyoCiqggomAByws2dBERRJCiAhZeXxEFxC6CWLAsIFKlyVKkLNvYXpK5vz8mM5mZzCSTniz38zz7bDL1zGTmnnvKPZdQSikYDAaDwQDAhVsABoPBYEQOTCkwGAwGQ4IpBQaDwWBIMKXAYDAYDAmmFBgMBoMhwZQCg8FgMCSYUmCEnQEDBuDee+8NtxhuefbZZ9GuXbtwi+EThBB88MEH4RbDMK1atcKLL77odptRo0Zh0KBBfp8rPz8fhBD8/PPPEXGcSIApBT8ZNWoUCCHSX2pqKvr27Ysvv/zS477PPvusYl/xLzc312+5fv75ZxBCkJ+f7/ex/OXkyZOIi4tDkyZNUF9fH25x3HLs2DEQQvDDDz+E/NxbtmyByWTCeeedF9DjnjhxAjfffHNAj+mJbt26wWQyYfv27V7vm5eXh4kTJwZEjl9//RU33XQTGjdujLi4OLRt2xbDhw/H1q1bA3J8kRYtWuDEiRO48MILA3rccMCUQgDo168fTpw4gRMnTuC3337Deeedh6FDh+LgwYMe923VqpW0r/j30EMPhUBq49TV1fm1/5IlS3DttdciMzMTa9asCZBUDY9FixZh7NixyM/Px+bNmwN23CZNmiAuLi5gx/PEpk2bUFBQgNGjR2Px4sVe75+VlYXExES/5Vi6dCn69euHmJgYLF++HHv27MFHH32EVq1a4eGHH/b7+HJMJhOaNGmCmJiYgB43LFCGX4wcOZIOHDhQsaysrIwCoJ9++qnbfadNm0bbtm2ruW758uX0ggsuoCkpKTQzM5Nec801dO/evYptTp06RUeNGkUbNWpELRYL7dChA33nnXfooUOHKADFX05ODqWUUp7n6cyZM2nr1q1pTEwMbdOmDZ09e7biuC1btqRPP/00HTt2LM3IyKC9e/emlFL61ltv0U6dOlGLxUIzMjJov3796NGjR91eo91up61ataJr1qyhM2bMoIMHD3bZJicnh44ePVr6XldXRydPnkyzs7NpTEwMPffcc+ny5csV+wCg8+fPp8OHD6dJSUm0efPmdMaMGYptCgsL6c0330wTEhJoo0aN6DPPPENHjBjh8nupjyv/a9myJaXU+VutXr2aduzYkSYkJNABAwbQAwcOKPbfvHkzHTx4ME1MTKRWq5XeeOONND8/3+09olR4ZpKSkuhff/1Fx44dS8eMGaMp29y5c+mtt95KExISaIsWLejHH39MS0tL6R133EGTkpJo69at6cqVK132e//99726d2VlZfS+++6jVquVWiwWev7559NvvvnG43VQSumIESPoxIkT6e+//05TU1NpZWWlYn19fT197rnnaJs2bWhsbCzNzs6m48ePl9a3bNmSvvDCC9L34uJi6ZobNWpEn376aY+/47///kstFgu9//77NdcXFxdTSqn0rnz00Ud0yJAhND4+nrZu3Zq+9957iu3nzJlDe/ToQRMTE2njxo3pbbfdRo8fPy6tF4/z008/eXXcSIQpBT9RK4Xa2lo6a9YsarFYPDYG7pTCkiVL6Nq1a+mBAwfo1q1b6XXXXUfbtWtHa2trKaWUVlVV0U6dOtFevXrR7777jh48eJB+88039MMPP6Q2m42uWbOGAqB//PEHPXHiBC0qKqKUUjpv3jwaFxdHFy1aRPft20cXLFhALRYLffvtt6Vzt2zZkiYnJ9Np06bRvXv30l27dtHNmzdTk8lE3333XZqfn0+3b99O33rrLY9K4auvvqJZWVm0vr6eHj9+nMbExNCDBw8qtlErhccee4xmZGTQFStW0L1799Lp06dTQghdt26dtA0A2qhRI7p48WJ64MAB+vrrr1MAdP369dI21113HW3fvj1dv3493blzJx01ahRNSUlx25hs3bqVAqCffPIJPXHiBC0oKJB+q4SEBHrllVfSzZs3023bttGePXvS/v37S/vu2rWLJiYm0qlTp9I9e/bQ7du305tvvpm2b9+eVldXu71PCxYsoL169aKUUvr777/TpKQkWl5ertgGAG3cuDFdtmwZ3b9/Px07diyNj4+nV111FV26dCndv38/HT9+PE1ISKCFhYWK/dRKwdO9u/nmm2nLli3p119/TXfv3k0nTJhAY2Ji6J49e9xeR3FxMY2Pj6fbtm2jlFLauXNnunTpUsU2I0aMoFlZWfS9996jBw4coL/++it97bXXpPVqpTB06FDatm1b+v3339OdO3fSO++8kyYnJ7v9HWfPnk0BeHw+xca7devW9KOPPqL79++nkydPpiaTie7bt0/abs6cOfS7776j//zzD920aRPt27ev4rfXUwqejhuJMKXgJyNHjqQmk4kmJibSxMRESgihiYmJ9KOPPvK477Rp06Tt5X81NTUu2xYVFVEA9Oeff6aUUvr2229Ti8Wi+9D/9NNPFAA9dOiQYnnz5s3p448/rlj2yCOP0NatW0vfW7ZsSS+//HLFNp9++ilNSUmhZ86c8XhdcoYOHUofeeQR6fvVV19Nn3zyScU2cqVQWVlJY2Nj6fz5812Oc9lll0nfAdCHHnpIsU3Hjh3plClTKKWU7tu3jwJQKJK6ujravHlzt43J0aNHKQC6YcMGxfJp06ZRk8kkKQlKKf3www8pIURq8EeOHElvu+02xX41NTU0Pj6erlq1SveclFLaq1cvOmfOHOl7586d6aJFixTbAKAPP/yw9L2goIACUPSyi4uLKQC6du1axX5qpeDu3u3fv58CoF988YWLjHfffbfb65gzZw7t2bOn9H3GjBm0b9++0nfx2B9//LHuMeRKQdz+22+/ldbX1tbS7Oxst7/j2LFjaUpKiltZKXU23rNmzZKW1dfX08TERLpw4ULd/cTOw7FjxxTHUSsFb48bCbCYQgC48MILsW3bNmzbtg1bt27F1KlTMXLkSHzzzTcAgOXLlyMpKUn6W758ubRvixYtpH3Fv9jYWGzbtg033ngjWrdujeTkZJxzzjkAgMOHDwMQgpKdO3dG8+bNDctZVlaGY8eOoX///orlOTk5yM/PR1VVlbTsggsuUGwzePBgtGnTBq1bt8awYcOwePFiFBYWuj3fiRMn8Pnnn2PkyJHSslGjRmHp0qWw2Wya+xw4cAB1dXWaMu7atUuxrGfPnorvzZo1w6lTpwAAu3fvBgBcdNFF0vqYmBj07t3brczuyM7ORlZWluJ8lFIUFBQAEAKkq1atUvzWmZmZqKmpwf79+3WP+8cff2DHjh244447pGUjR47U9Mf36NFD+pyVlQWTyYTu3btLy9LT0xEbGyvJpIeRe6f+Dfr37+/yG6hZvHix4ve+66678Mcff2Dnzp0AIAV4r7jiCrfHERFlufjii6VlsbGx6NOnj9v9qJd1PuX3w2w2o3HjxtL9AIAffvgBV155JVq0aIHk5GRceumlAJzvo6/HjUTM4RagIRAfH69IV+zZsye+//57TJ8+HVdeeSWuv/56RVZC48aNpc8xMTEuqY5VVVW44oorcOmll2LJkiVo0qQJAKBLly6KoC8hxCd51ftpvUDqQF9SUhI2b96MX375BevWrcPChQvxxBNP4Pvvv8f555+veZ533nkHNpvNpSG22+347LPPcNNNN3klo3pZbGysyz48z7s9jj9onQ+AdE6e53HXXXdhypQpLvtmZmbqHnfx4sWw2Wxo2rSptIxSCp7nsXXrVkU2klYgU71M6z4YuRZP+2j9BnJ+/vln7N69G48++igee+wxabndbsfixYsxd+5ct8fXO6cvdOzYUeoEGek4ubsfR44cwTXXXIO77roLU6dOhdVqxbFjxzBo0CCPSRi+3OdwwyyFIGE2m6Wed3JyMtq1ayf9JScnu913z549OH36NKZPn47LLrsM5557LkpKShQvyPnnn49du3bh2LFjmscQH0a73S4tS0lJQfPmzbFx40bFtj/++CNat26NhIQEt3KZTCb0798fzz//PLZs2YKmTZviv//9r+a2PM/j7bffxlNPPeViCQ0fPlw3K6Vdu3awWCyaMnbp0sWtfHI6d+4MQEhJFLHZbNiyZYvb/bTum1F69+6N7du3o23btorfu127dkhPT9fcp6ysDP/73/8wf/58xT3666+/cNlll/mUveMv4n3+8ccfFct/+uknt7/BokWLMHjwYPz111+Ka3n99dfx/vvvo7q6WlJw3377rVeybNq0SVpWV1eHvLw8t/vdcsstsFgsuuMdSkpKDJ0fECzA6upqzJkzB5dccgk6duwY8b19f2CWQgCoq6vDyZMnAQCVlZX45ptv8M033+C5557z6XgtW7aExWLBG2+8gUcffRT5+fmYMmWKopd2++2345VXXsH111+PV155BW3btsU///yDwsJC3HbbbWjZsiU4jsOXX36J2267DRaLBampqXjyySfx6KOPon379hgwYADWr1+PBQsWYP78+W5lWrNmDf755x/0798fWVlZ2LJlC44ePSo1vmq+/vprHDlyBPfff7/k+hK5++67MXjwYOTn56NVq1aKdQkJCZgwYQL+85//ICsrCz179sTHH3+MNWvW4LvvvjN8D9u3b4/rrrsODz74IBYtWoSsrCzMmjULZWVlbnu7VqsV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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pmmcif.df['ATOM']['B_iso_or_equiv'].plot(kind='line')\n", "plt.title('B-Factors Along the Amino Acid Chain')\n", "plt.xlabel('Residue Number')\n", "plt.ylabel('B-factor in $A^2$')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "image/png": "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FGnaaDSKXr16tejTsmXLRHBwsDhz5ow4e/asCAsLE5s3b26xrzVr1oioqCghxP9/MDh27JhXdZL3eA2CAADi599sbOuumunTp+PVV1/F4MGDMWvWLGzZssXrtgcNGuTVehkZGdLfarUagwYNQmlpqdf78db+/ftx3333tZhnNBohhGixvz59+iAkJESa7tGjB06ePNlmu83bXt72fffdh/37919zncuWLcOYMWMQFBQEAHj00Udx9uxZbN68+Yrb7d+/H3379m1xDal79+648847W9ShUCiQkpIiTTdfDxkwYECLebW1tWhqarrm+rt3745HH30Uy5cvl+ratm0bJkyY0GK9QYMGQaVSSdNDhw6F2+3GkSNHsH//fpw7dw7/9E//hIiICOn1zDPPoK6uDjU1NRgwYAB++ctfon///vjNb36DRYsWoby8/JrrpdYYEAQA2LdvHxQKBRITE2WX5+Tk4Mcff8SkSZPgcDjwwAMPYOzYsV61HR4efl01iUt+aLj5gval85qamuDxeK6r7baC8NL5wcHBrZaJ6/jxYyHENd/Oevz4cXzxxRd48803oVaroVarER4eDpfL5dXFarn9XV6HUqls8cbcvKw5kC6ddz39BoBJkybBbDajpqYGy5cvR3p6OlJTU6+4zaX7av73Xbt2LXbt2iW99u7di8OHD0Or1UKlUmHz5s2wWCxIT0/HJ598gjvuuAMbN268rprp/zEgCPX19Xj77beRlZUFnU7X5nq/+MUvkJOTg/feew8rV67EBx98gPr6egAX30yv51PmpS69rbaxsRF2ux19+vQBAMTExAAAKisrpXV27drV4s2k+Q39anX069cPVqu1xTyr1QqFQoG+ffted/39+vUDgFZHV9988420zFvLly9Hnz59sHv37hZvjGvXrsWmTZuk23blxr1fv37Yv38/Tp06Jc07efIkDh06dM113KgRI0YgISEBf/rTn/D++++3OnoAALvd3qIPf/vb3xAcHIykpCT069cPoaGhOHr0KAwGQ6tXc8ApFAoMGjQIs2fPxpYtW2A0GrF69Wq/9fNWxYDoZNxuN6qqquBwOFBaWopVq1Zh0KBBuHDhAt5+++02t3v22WexadMm6bD/008/RXx8PLp27QoAuP3227F161YcP34cp06duq5P9gUFBdi0aRMOHDiAyZMn4+TJk5g8eTKA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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pmmcif.df['ATOM']['type_symbol'].value_counts().plot(kind='bar')\n", "plt.title('Distribution of Atom Types')\n", "plt.xlabel('elements')\n", "plt.ylabel('count')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Computing the Root Mean Square Deviation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "BioPandas also comes with certain convenience functions, for example, ..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Root-mean-square deviation (RMSD) is simply a measure of the average distance between atoms of 2 protein or ligand structures. This calculation of the Cartesian error follows the equation:\n", "\n", "$$\n", "RMSD(a, b) = \\sqrt{\\frac{1}{n} \\sum^{n}_{i=1} \\big((a_{ix})^2 + (a_{iy})^2 + (a_{iz})^2 \\big)}\n", "= \\sqrt{\\frac{1}{n} \\sum^{n}_{i=1} || a_i + b_i||_2^2}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, assuming that the we have the following 2 conformations of a ligand molecule\n", "\n", "![](./img/ligand_rmsd.png)\n", "\n", "we can compute the RMSD as follows:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSD: 2.6444 Angstrom\n" ] } ], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "l_1 = PandasMmcif().read_mmcif('./data/lig_conf_1.cif')\n", "l_2 = PandasMmcif().read_mmcif('./data/lig_conf_2.cif')\n", "r = PandasMmcif.rmsd(l_1.df['HETATM'], l_2.df['HETATM'],\n", " s=None) # all atoms, including hydrogens\n", "print('RMSD: %.4f Angstrom' % r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File links: [lig_conf_1.cif](https://raw.githubusercontent.com/rasbt/biopandas/main/docs/tutorials/data/lig_conf_1.cif), [lig_conf_2.cif](https://raw.githubusercontent.com/rasbt/biopandas/main/docs/tutorials/data/lig_conf_2.cif)]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSD: 1.7249 Angstrom\n" ] } ], "source": [ "r = PandasMmcif.rmsd(l_1.df['HETATM'], l_2.df['HETATM'], \n", " s='carbon') # carbon atoms only\n", "print('RMSD: %.4f Angstrom' % r)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSD: 1.9959 Angstrom\n" ] } ], "source": [ "r = PandasMmcif.rmsd(l_1.df['HETATM'], l_2.df['HETATM'], \n", " s='heavy') # heavy atoms only\n", "print('RMSD: %.4f Angstrom' % r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, we can compute the RMSD between 2 related protein structures:\n", "\n", "![](./img/1t48_rmsd.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The hydrogen-free RMSD:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSD: 0.7377 Angstrom\n" ] } ], "source": [ "p_1 = PandasMmcif().read_mmcif('./data/1t48_995.cif')\n", "p_2 = PandasMmcif().read_mmcif('./data/1t49_995.cif')\n", "r = PandasMmcif.rmsd(p_1.df['ATOM'], p_2.df['ATOM'], s='heavy')\n", "print('RMSD: %.4f Angstrom' % r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or the RMSD between the main chains only:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSD: 0.4781 Angstrom\n" ] } ], "source": [ "p_1 = PandasMmcif().read_mmcif('./data/1t48_995.cif')\n", "p_2 = PandasMmcif().read_mmcif('./data/1t49_995.cif')\n", "r = PandasMmcif.rmsd(p_1.df['ATOM'], p_2.df['ATOM'], s='main chain')\n", "print('RMSD: %.4f Angstrom' % r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Filtering PDBs by Distance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the `distance` method to compute the distance between each atom (or a subset of atoms) in our data frame and a three-dimensional reference point. For example:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "p_1 = PandasMmcif().read_mmcif('./data/3eiy.cif')\n", "\n", "reference_point = (9.362, 41.410, 10.542)\n", "distances = p_1.distance(xyz=reference_point, records=('ATOM',))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[File link: [3eiy.cif](https://raw.githubusercontent.com/rasbt/biopandas/main/docs/tutorials/data/3eiy.cif)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The distance method returns a Pandas Series object:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 19.267419\n", "1 18.306060\n", "2 16.976934\n", "3 16.902897\n", "4 18.124171\n", "dtype: float64" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "distances.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we can use this `Series` object, for instance, to select certain atoms in our DataFrame that fall within a desired distance threshold. For example, let's select all atoms that are within 7A of our reference point: " ] }, { "cell_type": "code", "execution_count": 33, "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", " \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", "
group_PDBidtype_symbollabel_atom_id...auth_comp_idauth_asym_idauth_atom_idpdbx_PDB_model_num
786ATOM787CCB...LEUACB1
787ATOM788CCG...LEUACG1
788ATOM789CCD1...LEUACD11
789ATOM790CCD2...LEUACD21
790ATOM791NN...VALAN1
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " group_PDB id type_symbol label_atom_id ... auth_comp_id auth_asym_id auth_atom_id pdbx_PDB_model_num\n", "786 ATOM 787 C CB ... LEU A CB 1\n", "787 ATOM 788 C CG ... LEU A CG 1\n", "788 ATOM 789 C CD1 ... LEU A CD1 1\n", "789 ATOM 790 C CD2 ... LEU A CD2 1\n", "790 ATOM 791 N N ... VAL A N 1\n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_within_7A = p_1.df['ATOM'][distances < 7.0]\n", "all_within_7A.tail()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visualized in PyMOL, this subset (yellow surface) would look as follows:\n", " \n", "![](./img/3eiy_7a.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Converting Amino Acid codes from 3- to 1-letter codes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Residues in the `residue_name` field can be converted into 1-letter amino acid codes, which may be useful for further sequence analysis, for example, pair-wise or multiple sequence alignments:" ] }, { "cell_type": "code", "execution_count": 34, "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", "
auth_asym_idauth_comp_id
1378BI
1386BN
1394BY
1406BR
1417BT
\n", "
" ], "text/plain": [ " auth_asym_id auth_comp_id\n", "1378 B I\n", "1386 B N\n", "1394 B Y\n", "1406 B R\n", "1417 B T" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from biopandas.mmcif import PandasMmcif\n", "\n", "\n", "pmmcif = PandasMmcif().fetch_mmcif('5mtn')\n", "sequence = pmmcif.amino3to1()\n", "sequence.tail()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As shown above, the `amino3to1` method returns a `DataFrame` containing the `auth_asym_id` (chain ID) and `auth_comp_id` (residue name) of the translated 1-letter amino acids. If you like to work with the sequence as a Python list of string characters, you could do the following:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['V', 'R', 'H', 'Y', 'T']" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sequence_list = list(sequence.loc[sequence['auth_asym_id'] == 'A', 'auth_comp_id'])\n", "sequence_list[-5:] # last 5 residues of chain A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And if you prefer to work with the sequence as a string, you can use the `join` method: " ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SLEPEPWFFKNLSRKDAERQLLAPGNTHGSFLIRESESTAGSFSLSVRDFDQGEVVKHYKIRNLDNGGFYISPRITFPGLHELVRHYT'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "''.join(sequence.loc[sequence['auth_asym_id'] == 'A', 'auth_comp_id'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To iterate over the sequences of multi-chain proteins, you can use the `unique` method as shown below:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Chain ID: A\n", "SLEPEPWFFKNLSRKDAERQLLAPGNTHGSFLIRESESTAGSFSLSVRDFDQGEVVKHYKIRNLDNGGFYISPRITFPGLHELVRHYT\n", "\n", "Chain ID: B\n", "SVSSVPTKLEVVAATPTSLLISWDAPAVTVVYYLITYGETGSPWPGGQAFEVPGSKSTATISGLKPGVDYTITVYAHRSSYGYSENPISINYRT\n" ] } ], "source": [ "for chain_id in sequence['auth_asym_id'].unique():\n", " print('\\nChain ID: %s' % chain_id)\n", " print(''.join(sequence.loc[sequence['auth_asym_id'] == chain_id, 'auth_comp_id']))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.7" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }