Skip to content

Commit

Permalink
Merge pull request #94 from sizmailov/docs/live_examples
Browse files Browse the repository at this point in the history
Docs/live examples
  • Loading branch information
sizmailov authored Feb 19, 2019
2 parents 4f1a542 + cfda70d commit 61ad28d
Show file tree
Hide file tree
Showing 22 changed files with 876 additions and 235 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.log
*.pyc
.idea/*
venv
coverage
tests_dataset/*/
cmake-build-*
Expand Down
1 change: 1 addition & 0 deletions build_docs.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash

python -m pip install -r docs/requirements.txt
export TEST_DATA_PATH=$PWD/tests_dataset
make -C ./docs html
touch ./docs/build/html/.nojekyll
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
build
auto_examples
*.pdb
5 changes: 5 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
sphinx
sphinx-autodoc-annotation
sphinx-rtd-theme
sphinx-gallery
matplotlib
Pillow
tabulate
biopython
19 changes: 18 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
'sphinx.ext.mathjax',
'sphinx.ext.autodoc',
'sphinx_autodoc_annotation',
'sphinx_gallery.gen_gallery',
]

autosummary_generate = True
Expand Down Expand Up @@ -318,7 +319,7 @@ def process_docs(app, objtype, fullname, object, options, docstringlines):


def skip(app, what, name, obj, skip, options):
skip_list = [ "__module__","__weakref__"]
skip_list = [ "__module__", "__weakref__"]
if name in skip_list:
return True
return skip
Expand All @@ -328,3 +329,19 @@ def setup(app):
app.connect('autodoc-process-signature', strip_argumet_types)
app.connect('autodoc-process-docstring', process_docs)
app.connect("autodoc-skip-member", skip)

import os

sphinx_gallery_conf = {
# path to your examples scripts
'examples_dirs': './examples',
# path where to save gallery generated examples
'gallery_dirs': 'auto_examples',
'filename_pattern': '/',
'default_thumb_file': os.path.abspath('images/python-logo.png'),
'line_numbers': True,

'expected_failing_examples': [
'examples/PDB/read_pdb_errors.py',
]
}
7 changes: 7 additions & 0 deletions docs/source/examples/PDB/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@


Read/Write PDB files
--------------------



26 changes: 26 additions & 0 deletions docs/source/examples/PDB/read_pdb_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
PDB read with errors
--------------------
If your PDB is arbitrary formatted it might be successfully read but
the result might be unexpected.
Most likely you will get messed atom/residue ids, wrong coordinates or if you are lucky an Exception which will tell you
what is wrong with your PDB file.
Please see how to read non-standard, but well-formatted pdb file: :ref:`read-write-non-standard-pdb`
"""

import pyxmolpp2
import os

pdb_filename = os.path.join(os.environ["TEST_DATA_PATH"], "trjtool/GB1/run00001.pdb")

# Define a PDB file with standard records fields layout
pdb_file = pyxmolpp2.pdb.PdbFile(pdb_filename)

##############################################################################
# Failed read:
frame = pdb_file.get_frame()
45 changes: 45 additions & 0 deletions docs/source/examples/PDB/read_write_non_standard_pdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
.. _read-write-non-standard-pdb:
Non-standard PDB io
-------------------
``pyxmolpp2`` supports reading/writing non-standard PDB files. To read such file you need to specify
a set of new records (usually based on :py:class:`~pyxmolpp2.pdb.StandardPdbRecords` records).
Full set of available :py:class:`~pyxmolpp2.pdb.RecordName`, :py:class:`~pyxmolpp2.pdb.FiledName` and standard values you can find `here <https://github.com/sizmailov/pyxmolpp2/blob/master/src/xmol/pdb/BundledPDBRecordTypesBaseInit.cpp#L32>`_
"""

import pyxmolpp2
from pyxmolpp2.pdb import AlteredPdbRecords, StandardPdbRecords, FieldName, RecordName, PdbFile
import os

# Create PDB records description based on standard records
altered_records = AlteredPdbRecords(pyxmolpp2.pdb.StandardPdbRecords.instance())

# Expand ATOM.serial record to columns 7-12
altered_records.alter_record(RecordName("ATOM"), FieldName("serial"), [7, 12])

pdb_filename = os.path.join(os.environ["TEST_DATA_PATH"], "trjtool/GB1/run00001.pdb")

# Define a PDB file with altered records fields layout
pdb_file = PdbFile(pdb_filename, altered_records)

# Read all frames (i.e. MODELS) from PDB
frames = pdb_file.get_frames()

# Print some info about frames
print("PDB contains %d MODELS: " % len(frames))
for frame in frames:
print("\tMODEL #%d contains %d molecules, total %d atoms" % (
frame.index,
frame.asChains.size,
frame.asAtoms.size
))


# Write first model to PDB file using altered records
frames[0].to_pdb("out.pdb", altered_records)
31 changes: 31 additions & 0 deletions docs/source/examples/PDB/read_write_standard_pdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Standard PDB io
---------------
"""

import pyxmolpp2
import os

pdb_filename = os.path.join(os.environ["TEST_DATA_PATH"], "pdb/rcsb/1PGB.pdb")

# Define a PDB file with standard records fields layout
pdb_file = pyxmolpp2.pdb.PdbFile(pdb_filename)

# Read all frames (i.e. MODELS) from PDB
frames = pdb_file.get_frames()


# Print some info about frames
print("PDB contains %d MODELS: " % len(frames))
for frame in frames:
print("\tMODEL #%d contains %d molecules, total %d atoms" % (
frame.index,
frame.asChains.size,
frame.asAtoms.size
))


# Write first model to PDB file using altered records
frames[0].to_pdb("out.pdb")
6 changes: 6 additions & 0 deletions docs/source/examples/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


Examples gallery
================

Here you can find typical usages of the library
123 changes: 123 additions & 0 deletions docs/source/examples/basics/FCRA.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
"""
.. |Atom| replace:: :py:class:`~pyxmolpp2.polymer.Atom`
.. |Residue| replace:: :py:class:`~pyxmolpp2.polymer.Residue`
.. |Chain| replace:: :py:class:`~pyxmolpp2.polymer.Chain`
.. |Frame| replace:: :py:class:`~pyxmolpp2.polymer.Frame`
.. |AtomSelection| replace:: :py:class:`~pyxmolpp2.polymer.AtomSelection`
.. |ResidueSelection| replace:: :py:class:`~pyxmolpp2.polymer.ResidueSelection`
.. |ChainSelection| replace:: :py:class:`~pyxmolpp2.polymer.ChainSelection`
Frame/Chain/Residue/Atom hierarchy
----------------------------------
The `pyxmolpp2` library implements |Frame|/|Chain|/|Residue|/|Atom| hierarchy to represent a molecular system.
Every |Atom| exists as a part of some |Residue|. |Residue| is always a part of |Chain|. |Chain| is always a part of |Frame|.
For instance this implies that you can not create an |Atom| without pre-existed |Residue|.
Why not allow ``Atom.residue`` to be :py:class:`None` if Atom exists by it's own?
The choice was between flexibility of construction code versus complexity of it's further usage.
The rationale behind that design decision is fact that expression ``atom.residue.chain.frame.index``
is always correct, and no `not-None` checks are required. Such checks across the library and user code would
increases it's complexity and make it more prone to errors.
.. danger::
|Atom|/|Residue|/|Chain| is alive until it's |Frame| exists. |Frame| exists until python holds a reference to it.
No frame - no game.
"""


import pyxmolpp2
import os

pdb_filename = os.path.join(os.environ["TEST_DATA_PATH"], "pdb/rcsb/1UBQ.pdb")
pdb_file = pyxmolpp2.pdb.PdbFile(pdb_filename)

frame = pdb_file.get_frame()

##############################################################################

# print chain names of 1UBQ entry
print([ chain.name.str for chain in frame.asChains ])

##############################################################################

# print residue names of 1UBQ entry
print([ res.name.str for res in frame.asResidues])

##############################################################################
# print info about first atom:
a = frame.asAtoms[0]
from tabulate import tabulate

print(tabulate([
("name", a.name),
("id", a.id),
("[x,y,z]", a.r),
("rId", a.rId),
("rName", a.rName),
("cName", a.cName),
]))

##############################################################################
# we can find frame by atom
assert a.frame == frame

##############################################################################
# If you destroy all references to frame it will be eliminated with all it's content

asel = frame.asAtoms # valid as long reference to frame exists
rsel = frame.asResidues # valid as long reference to frame exists
csel = frame.asChains # valid as long reference to frame exists
a = frame.asAtoms[0] # valid as long reference to frame exists

##############################################################################
# Let's `accidentally` destroy frame, by dropping only reference:
frame = None


##############################################################################
try:
print(asel[0])
except pyxmolpp2.polymer.DeadAtomSelectionAccess as e:
print("AtomSelection error:")
print(e)
pass

##############################################################################
try:
print(rsel[0])
except pyxmolpp2.polymer.DeadResidueSelectionAccess as e:
print("ResidueSelection error:")
print(e)
pass

##############################################################################
try:
print(csel[0])
except pyxmolpp2.polymer.DeadChainSelectionAccess as e:
print("ChainSelection error:")
print(e)
pass

##############################################################################



##############################################################################
try:
print(a.name)
except RuntimeError as e:
print("Atom access error:")
print(e)
pass
3 changes: 3 additions & 0 deletions docs/source/examples/basics/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

Basics
------
Loading

0 comments on commit 61ad28d

Please sign in to comment.