Skip to content

Instantly share code, notes, and snippets.

@aschreyer
Last active December 12, 2015 08:48
Show Gist options
  • Save aschreyer/4746434 to your computer and use it in GitHub Desktop.
Save aschreyer/4746434 to your computer and use it in GitHub Desktop.
@paginate
def fetch_all_descendants(self, fragment_id, *expr, **kwargs):
"""
Returns all the descending fragments of the fragment with the given
fragment_id using an recursive SQL query.
"""
# query part that will be used in both parts of the recursive query
query = Fragment.query.with_entities(Fragment.fragment_id)
query = query.join(FragmentHierarchy, FragmentHierarchy.child_id==Fragment.fragment_id)
# fragment_id is the recursive term
descendants = query.filter(FragmentHierarchy.parent_id==fragment_id)
descendants = descendants.cte(name="descendants", recursive=True)
# alias is necessary to reference to the statement in the recursive part
desc_alias = aliased(descendants, name="d")
# recursive part
end = query.join(desc_alias, desc_alias.c.fragment_id==FragmentHierarchy.parent_id)
end = end.filter(FragmentHierarchy.child_id!=None)
descendants = descendants.union(end)
# Join the recursive statement against the fragments table to get all
# the fragment entities and add optional filter expressions
query = self.query.join(descendants, Fragment.fragment_id==descendants.c.fragment_id)
query = query.filter(and_(*expr)).order_by(Fragment.fragment_id.asc())
return query
def fetch_all_leaves(self, fragment_id, *expr, **kwargs):
"""
Returns only the terminal (leaf) fragments of the fragment with the
given fragment_id.
"""
return self.fetch_all_descendants(fragment_id, Fragment.is_terminal==True,
*expr, **kwargs)
# pick a rule-of-three compliant fragments
fragment = root.Descendants.filter(Fragment.is_rule_of_three==True).all()[3]
fragment.ism
u'c1cc(cnc1)c2ccncn2'
# fragments are mapped onto ligands and their atoms:
# pick a random one of the list
lf = fragment.LigandFragments[0]
# this is the ligand this fragment is part of
lf.Ligand
<Ligand(1OPJ/2/B/STI`4)>
# get all the hydrogen bonds this fragment has in this ligand
lf.Contacts.filter(Contact.is_hbond==True).all()
[<Contact(79831427, 79830051)>, <Contact(79830056, 79829947)>]
from credoscript.models import *
# get the root fragment of Imatinib
sti = ChemComp.query.filter_by(het_id='STI').first()
root = sti.Fragments.filter(ChemCompFragment.is_root==True).first()
# The Descendants property is implemented with the fetch_all_descendants()
# method of the FragmentAdaptor class
root.Descendants.all()
[<Fragment(3)>, <Fragment(641)>, <Fragment(683)>,
<Fragment(1116)>, <Fragment(2181)>, <Fragment(3366)>,
<Fragment(8362)>, <Fragment(14861)>, <Fragment(16510)>,
<Fragment(20127)>, <Fragment(28509)>, <Fragment(33256)>,
<Fragment(34818)>, <Fragment(43139)>, <Fragment(43835)>]
# only the terminal fragments
# implemented through fetch_all_leaves() with @property decorator
root.Leaves.all()
[<Fragment(3)>, <Fragment(641)>, <Fragment(683)>,
<Fragment(1116)>, <Fragment(2181)>, <Fragment(3366)>]
# only rule-of-three compliant descendants
root.Descendants.filter(Fragment.is_rule_of_three==True).all()
[<Fragment(1116)>, <Fragment(2181)>, <Fragment(3366)>,
<Fragment(8362)>, <Fragment(16510)>]
WITH RECURSIVE descendants(fragment_id) AS
(
SELECT f.*
FROM pdbchem.fragment_hierarchies h
JOIN pdbchem.fragments f ON f.fragment_id = h.child_id
WHERE h.parent_id = fragment_in_id
UNION
SELECT f.*
FROM pdbchem.fragments f,
pdbchem.fragment_hierarchies h,
descendants d
WHERE h.child_id = f.fragment_id
AND h.parent_id = d.fragment_id
AND h.child_id IS NOT NULL
)
SELECT *
FROM descendants
ORDER BY 1 DESC;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment