Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
code added to visualize relations
  • Loading branch information
proost committed Jun 14, 2017
1 parent 4320104 commit 0ee5743
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 12 deletions.
16 changes: 15 additions & 1 deletion planet/controllers/clade.py
Expand Up @@ -35,10 +35,11 @@ def clade_view(clade_id):

families_count = current_clade.families.count()
interpro_count = current_clade.interpro.count()
association_count = current_clade.sequence_sequence_clade_associations.count()

return render_template('clade.html', clade=current_clade,
families_count=families_count, interpro_count=interpro_count,
species=species)
association_count=association_count, species=species)


@clade.route('/families/<int:clade_id>/')
Expand Down Expand Up @@ -105,3 +106,16 @@ def clade_interpro_table(clade_id):
interpro = Clade.query.get(clade_id).interpro.order_by(Interpro.label)

return Response(render_template('tables/interpro.csv', interpro=interpro), mimetype='text/plain')


@clade.route('/associations/<int:clade_id>/')
@clade.route('/associations/<int:clade_id>/<int:page>')
@cache.cached()
def clade_associations(clade_id, page=1):

current_clade = Clade.query.get_or_404(clade_id)
associations = current_clade.sequence_sequence_clade_associations.paginate(page,
g.page_items,
False).items

return render_template('pagination/clade_relations.html', relations=associations)
6 changes: 6 additions & 0 deletions planet/models/relationships/__init__.py
Expand Up @@ -44,6 +44,12 @@
db.Column('target_id', db.Integer, db.ForeignKey('sequences.id'), index=True)
)

sequence_sequence_clade = db.Table('sequence_sequence_clade',
db.Column('id', db.Integer, primary_key=True),
db.Column('sequence_one_id', db.Integer, db.ForeignKey('sequences.id'), index=True),
db.Column('sequence_two_id', db.Integer, db.ForeignKey('sequences.id'), index=True)
)

family_xref = db.Table('family_xref',
db.Column('id', db.Integer, primary_key=True),
db.Column('gene_family_id', db.Integer, db.ForeignKey('gene_families.id'), index=True),
Expand Down
41 changes: 41 additions & 0 deletions planet/models/relationships/sequence_sequence_clade.py
@@ -0,0 +1,41 @@
from planet import db


class SequenceSequenceCladeAssociation(db.Model):
__tablename__ = 'sequence_sequence_clade'
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, primary_key=True)

sequence_one_id = db.Column(db.Integer, db.ForeignKey('sequences.id', ondelete='CASCADE'))
sequence_two_id = db.Column(db.Integer, db.ForeignKey('sequences.id', ondelete='CASCADE'))

clade_id = db.Column(db.Integer, db.ForeignKey('clades.id', ondelete='CASCADE'), index=True)
tree_id = db.Column(db.Integer, db.ForeignKey('trees.id', ondelete='CASCADE'), index=True)

duplication = db.Column(db.Boolean)
duplication_consistency_score = db.Column(db.Float)

tree = db.relationship('Tree', lazy='joined',
backref=db.backref('sequence_sequence_clade_associations',
lazy='dynamic',
passive_deletes=True)
)

clade = db.relationship('Clade', lazy='joined',
backref=db.backref('sequence_sequence_clade_associations',
lazy='dynamic',
passive_deletes=True)
)

def __str__(self):
return "%d" % self.id

@property
def readable_type(self):
return "Duplication" if self.duplication else "Speciation"

@property
def readable_score(self):

return "%.3f" % self.duplication_consistency_score if self.duplication else "Not available"
10 changes: 10 additions & 0 deletions planet/models/sequences.py
Expand Up @@ -59,6 +59,16 @@ class Sequence(db.Model):
backref=db.backref('target_sequence', lazy='joined'),
lazy='dynamic')

clade_associations_one = db.relationship('SequenceSequenceCladeAssociation',
primaryjoin="SequenceSequenceCladeAssociation.sequence_one_id == Sequence.id",
backref=db.backref('sequence_one', lazy='joined'),
lazy='dynamic')

clade_associations_two = db.relationship('SequenceSequenceCladeAssociation',
primaryjoin="SequenceSequenceCladeAssociation.sequence_two_id == Sequence.id",
backref=db.backref('sequence_two', lazy='joined'),
lazy='dynamic')

xrefs = db.relationship('XRef', secondary=sequence_xref, lazy='joined')

def __init__(self, species_id, name, coding_sequence, type='protein_coding', is_chloroplast=False,
Expand Down
10 changes: 5 additions & 5 deletions planet/models/species.py
Expand Up @@ -16,11 +16,11 @@ class Species(db.Model):
profile_count = db.Column(db.Integer)
description = db.Column(db.Text)

sequences = db.relationship('Sequence', backref='species', lazy='dynamic', cascade="all, delete-orphan",passive_deletes=True)
networks = db.relationship('ExpressionNetworkMethod', backref='species', lazy='dynamic', cascade="all, delete-orphan",passive_deletes=True)
profiles = db.relationship('ExpressionProfile', backref='species', lazy='dynamic', cascade="all, delete-orphan",passive_deletes=True)
expression_specificities = db.relationship('ExpressionSpecificityMethod', backref='species', lazy='dynamic', cascade="all, delete-orphan",passive_deletes=True)
condition_tissues = db.relationship('ConditionTissue', backref='species', lazy='dynamic', cascade="all, delete-orphan",passive_deletes=True)
sequences = db.relationship('Sequence', backref='species', lazy='dynamic', cascade="all, delete-orphan", passive_deletes=True)
networks = db.relationship('ExpressionNetworkMethod', backref='species', lazy='dynamic', cascade="all, delete-orphan", passive_deletes=True)
profiles = db.relationship('ExpressionProfile', backref='species', lazy='dynamic', cascade="all, delete-orphan", passive_deletes=True)
expression_specificities = db.relationship('ExpressionSpecificityMethod', backref='species', lazy='dynamic', cascade="all, delete-orphan", passive_deletes=True)
condition_tissues = db.relationship('ConditionTissue', backref='species', lazy='dynamic', cascade="all, delete-orphan", passive_deletes=True)

def __init__(self, code, name, data_type='genome',
color="#C7C7C7", highlight="#DEDEDE", description=None):
Expand Down
41 changes: 35 additions & 6 deletions planet/models/trees.py
@@ -1,6 +1,7 @@
from planet import db
from planet.models.sequences import Sequence
from planet.models.clades import Clade
from planet.models.relationships.sequence_sequence_clade import SequenceSequenceCladeAssociation

import utils.phylo as phylo

Expand All @@ -22,7 +23,6 @@ class TreeMethod(db.Model):
trees = db.relationship('Tree',
backref=db.backref('method', lazy='joined'),
lazy='dynamic',
cascade="all, delete-orphan",
passive_deletes=True)

def reconcile_trees(self):
Expand All @@ -31,7 +31,11 @@ def reconcile_trees(self):
clades = Clade.query.all()

seq_to_species = {s.name: s.species.code for s in sequences}
seq_to_id = {s.name: s.id for s in sequences}
clade_to_species = {c.name: json.loads(c.species) for c in clades}
clade_to_id = {c.name: c.id for c in clades}

new_associations = []

for t in self.trees:
# Load tree from Newick string and start reconciliating
Expand All @@ -53,13 +57,38 @@ def reconcile_trees(self):

all_species = branch_one_species.union(branch_two_species)

c, s = phylo.get_clade(all_species, clade_to_species)
clade, _ = phylo.get_clade(all_species, clade_to_species)
duplication = phylo.is_duplication(branch_one_species, branch_two_species, clade_to_species)

if c is not None:
node.name = "%s_%s" % (c, "D" if duplication else "S")

print(newick.dumps([tree]))
duplication_consistency = None
if duplication:
duplication_consistency = phylo.duplication_consistency(branch_one_species, branch_two_species)

if clade is not None:
for seq_one in branch_one_seq:
for seq_two in branch_two_seq:
new_associations.append({
'sequence_one_id': seq_to_id[seq_one],
'sequence_two_id': seq_to_id[seq_two],
'tree_id': t.id,
'clade_id': clade_to_id[clade],
'duplication': 1 if duplication else 0,
'duplication_consistency_score': duplication_consistency
})
new_associations.append({
'sequence_one_id': seq_to_id[seq_two],
'sequence_two_id': seq_to_id[seq_one],
'tree_id': t.id,
'clade_id': clade_to_id[clade],
'duplication': 1 if duplication else 0,
'duplication_consistency_score': duplication_consistency
})

if len(new_associations) > 400:
db.engine.execute(SequenceSequenceCladeAssociation.__table__.insert(), new_associations)
new_associations = []

db.engine.execute(SequenceSequenceCladeAssociation.__table__.insert(), new_associations)


class Tree(db.Model):
Expand Down
1 change: 1 addition & 0 deletions planet/templates/clade.html
Expand Up @@ -36,6 +36,7 @@ <h3 class="banner-blue">Species Tree</h3>

{{ macro.pagination('Families', url_for('clade.clade_families', clade_id=clade.id), families_count, url_for('clade.clade_families_table', clade_id=clade.id), 'family') }}
{{ macro.pagination('Interpro domains', url_for('clade.clade_interpro', clade_id=clade.id), interpro_count, url_for('clade.clade_interpro_table', clade_id=clade.id), 'interpro') }}
{{ macro.pagination('Associations', url_for('clade.clade_associations', clade_id=clade.id), association_count, None, 'association') }}

{% endif %}
</div>
Expand Down
20 changes: 20 additions & 0 deletions planet/templates/pagination/clade_relations.html
@@ -0,0 +1,20 @@
<div class="table-responsive">
<table class="table table-striped">
<tbody>
{% for r in relations %}
<tr>
<td><a href="{{ url_for('sequence.sequence_view', sequence_id=r.sequence_one_id) }}">{{ r.sequence_one.name }}</a></td>
<td><a href="{{ url_for('sequence.sequence_view', sequence_id=r.sequence_two_id) }}">{{ r.sequence_two.name }}</a></td>
<td><a href="{{ url_for('clade.clade_view', clade_id=r.clade_id) }}">{{ r.clade.name }}</a></td>
<td>{{ r.readable_type }}</td>
<td>{{ r.readable_score }}</td>
<td><a href="{{ url_for('tree.trees_view', tree_id=r.tree_id) }}">{{ r.tree.label }}</a></td>
</tr>
{% else %}
<tr>
<td colspan="5"><em>No sequences sequence clade associations found</em></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
14 changes: 14 additions & 0 deletions utils/phylo.py
Expand Up @@ -29,3 +29,17 @@ def is_duplication(set_one, set_two, clades_to_species):
_, species_two = get_clade(set_two, clades_to_species)

return any([s in species_two for s in species_one])


def duplication_consistency(set_one, set_two):
"""
Calculates the duplication consistency score for two sets of species
:param set_one: set/list of species
:param set_two: set/list of species
:return: float with duplication consistency score
"""
union_size = len(set(set_one).union(set(set_two)))
intersection_size = len(set(set_one).intersection(set(set_two)))

return intersection_size/union_size

0 comments on commit 0ee5743

Please sign in to comment.