Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs/live examples #94

Merged
merged 11 commits into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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