def graph_items(exon_start_stop, transcripts, chrom, strand): from outrigger.index.events import stringify_location, opposite graph = connect(":memory:", graphs=['upstream', 'downstream']) items = [] triples = set() for transcript, exons in transcripts: for exon1, exon2 in zip(exons, exons[1:]): start1, stop1 = exon_start_stop[exon1] start2, stop2 = exon_start_stop[exon2] exon1_location = stringify_location(chrom, start1, stop1, strand, 'exon') exon2_location = stringify_location(chrom, start2, stop2, strand, 'exon') start = stop1 + 1 stop = start2 - 1 junction_location = stringify_location(chrom, start, stop, strand, 'junction') if exon1_location not in items: items.append(exon1_location) if exon2_location not in items: items.append(exon2_location) if junction_location not in items: items.append(junction_location) # Get unique integer for junction junction_i = items.index(junction_location) if strand == '-': exon1_triple = exon1_location, 'downstream', junction_location exon2_triple = exon2_location, 'upstream', junction_location else: exon1_triple = exon1_location, 'upstream', junction_location exon2_triple = exon2_location, 'downstream', junction_location exon_triples = exon1_triple, exon2_triple with graph.transaction() as tr: for exon_triple in exon_triples: if exon_triple not in triples: triples.add(exon_triple) exon, direction, junction = exon_triple # Get unique integer for exon exon_i = items.index(exon) tr.store(getattr(V(exon_i), direction)(junction_i)) tr.store( getattr(V(junction_i), opposite(direction))(exon_i)) else: continue items = tuple(items) return graph, items
def _skipped_exon(self, exon1_i, exon1_name): """Checks if this exon could be exon1 of an SE event""" events = {} exon23s = list(self.exons_one_junction_downstream(exon1_i)) exon23s = self.item_to_region[[self.items[i] for i in exon23s]] for exon_a, exon_b in itertools.combinations(exon23s, 2): if not exon_a.overlaps(exon_b): exon2 = min((exon_a, exon_b), key=lambda x: x._start) exon3 = max((exon_a, exon_b), key=lambda x: x._start) exon2_i = self.exons.index(exon2.name) exon3_i = self.exons.index(exon3.name) exon23_junction = list(self.graph.find( V(exon2_i).upstream).intersection( V().upstream(exon3_i))) if len(exon23_junction) > 0: # Isoform 1 - corresponds to Psi=0. Exclusion of exon2 exon13_junction = self.junctions_between_exons( exon1_i, exon3_i) # Isoform 2 - corresponds to Psi=1. Inclusion of exon2 exon12_junction = self.junctions_between_exons( exon1_i, exon2_i) junctions_i = list(itertools.chain( *[exon13_junction, exon12_junction, exon23_junction])) junctions = [self.items[i] for i in junctions_i] exons = exon1_name, exon2.name, exon3.name events[exons] = junctions return events
def test_hashable(): assert V(1).knows(2) != 2 d = {V(1).knows(2): 5} assert d[V(1).knows(2)] == 5 assert V(1).knows(3) not in d
def _make_graph(self, junction_exon_triples): self.graph = graphlite.connect(":memory:", graphs=DIRECTIONS) self.exons = tuple(junction_exon_triples[self.exon_col].unique()) self.n_exons = len(self.exons) self.junctions = tuple( junction_exon_triples[self.junction_col].unique()) # Exons are always first to make iteration easy self.items = tuple(np.concatenate([self.exons, self.junctions])) self.item_to_region = pd.Series(map(Region, self.items), index=self.items) with self.graph.transaction() as tr: for i, row in self.junction_exon_triples.iterrows(): junction = row[self.junction_col] exon = row[self.exon_col] junction_i = self.items.index(junction) exon_i = self.items.index(exon) self.log.debug('\n{} is {} of {}\n'.format( exon, row.direction, junction)) self.log.debug('{} is {} of {}\n'.format( junction, opposite(row.direction), exon)) tr.store(getattr(V(exon_i), row.direction)(junction_i)) tr.store( getattr(V(junction_i), opposite(row.direction))(exon_i)) # To speed up queries self.graph.db.execute("ANALYZE upstream") self.graph.db.execute("ANALYZE downstream")
def test_transaction_store(graph): with graph.transaction() as tr: tr.store(V(1).knows(7)) tr.store(V(1).knows(8)) assert V(1).knows(7) in graph assert V(1).knows(8) in graph
def assert_graph_items_equal(graph1, items1, graph2, items2): """Checks all relationships in graph1 exist in graph2, and vice versa""" from outrigger.common import DIRECTIONS for number1, item1 in enumerate(items1): for direction in DIRECTIONS: test = [ items1[i] for i in graph1.find(getattr(V(number1), direction)) ] number2 = items2.index(item1) true = [ items2[i] for i in graph2.find(getattr(V(number2), direction)) ] test.sort() true.sort() assert test == true for number2, item2 in enumerate(items2): for direction in DIRECTIONS: test = [ items2[i] for i in graph2.find(getattr(V(number2), direction)) ] number1 = items1.index(item2) true = [ items1[i] for i in graph1.find(getattr(V(number1), direction)) ] test.sort() true.sort() assert test == true
def test_transaction_atomic(graph): with pytest.raises(OperationalError): with graph.transaction() as tr: tr.store(V(1).knows(7)) tr.store(V(1).does(1)) assert V(1).knows(7) not in graph
def get_grandparents(person_id): db = current_app.config['db'] parent_ids = list(db.graph.find(V().begat(person_id))) grandparent_ids = [] for parent_id in parent_ids: grandparent_ids += list(db.graph.find(V().begat(parent_id))) return jsonify(grandparent_ids)
def test_transaction_nested(graph): with pytest.raises(OperationalError): with graph.transaction() as tr1: with graph.transaction() as tr2: tr2.store(V(1).does(2)) tr1.store(V(1).knows(5)) assert V(1).knows(5) not in graph
def test_transaction_many(graph): to_delete = (2, 3, 4) to_store = (6, 7, 8) with graph.transaction() as tr: tr.store_many(V(1).knows(n) for n in to_store) tr.delete_many(V(1).knows(n) for n in to_delete) for deleted, stored in zip(to_delete, to_store): assert V(1).knows(deleted) not in graph assert V(1).knows(stored) in graph
def get_siblings(person_id): db = current_app.config['db'] parent_ids = list(db.graph.find(V().begat(person_id))) sibling_ids = set([]) for parent_id in parent_ids: partial_sibling_ids = list(db.graph.find(V(parent_id).begat(None))) for partial_sibling_id in partial_sibling_ids: sibling_ids.add(partial_sibling_id) select_sibling_ids = list(sibling_ids) select_sibling_ids.remove(int(person_id)) return jsonify(select_sibling_ids)
def remove_person(person_id): db = current_app.config['db'] person = db.session.query(Person).filter_by(id=person_id).one() db.session.delete(person) # remove parent and child edges associated with this person parent_ids = list(db.graph.find(V().begat(person_id))) child_ids = list(db.graph.find(V(person_id).begat(None))) with db.graph.transaction() as tr: tr.delete_many(V(person_id).begat(id) for id in child_ids) tr.delete_many(V(id).begat(person_id) for id in parent_ids) return jsonify(True)
def graph(request): g = connect(':memory:', graphs=['likes', 'knows']) with g.transaction() as tr: # 1 knows 2,3,4 # 2,3 knows 1 # 1 likes 2,3 for i in (2, 3, 4): tr.store(V(1).knows(i)) if i != 4: tr.store(V(i).knows(1)) tr.store(V(1).likes(i)) request.addfinalizer(g.close) return g
def exons_one_junction_downstream(self, exon_i): """Get the exon(s) that are immediately downstream of this one Get exons that are downstream from this one, separated by one junction Parameters ---------- exon_i : int Integer identifier of the exon whose downstream exons you want. This is the exon's index location in self.exon_cols Returns ------- downstream_exons : graphlite.Query Integer identfiers of exons which are one junction downstream of the provided one """ return self.graph.find(V().downstream(exon_i)).traverse(V().upstream)
def exons_two_junctions_downstream(self, exon_i): """Get the exon(s) that are two junction hops downstream Go one exon downstream, then one more exon. This is all the 2nd level exon_cols Parameters ---------- exon_i : int Integer identifier of the exon whose downstream exon_cols you want. This is the exon's index location in self.exon_cols Returns ------- downstream_exons : graphlite.Query Integer identfiers of exon_cols which are separated from the original exon by a junction, exon, and another junction """ return self.graph.find(V().downstream(exon_i)).traverse( V().upstream).traverse(V().upstream).traverse(V().upstream)
def get_cousins(person_id): db = current_app.config['db'] parent_ids = list(db.graph.find(V().begat(person_id))) grandparent_ids = [] for parent_id in parent_ids: grandparent_ids += list(db.graph.find(V().begat(parent_id))) auntuncle_ids = set([]) for grandparent_id in grandparent_ids: partial_auntuncle_ids = list( db.graph.find(V(grandparent_id).begat(None))) for partial_auntuncle_id in partial_auntuncle_ids: auntuncle_ids.add(partial_auntuncle_id) select_auntuncle_ids = list(partial_auntuncle_id) for parent_id in parent_ids: select_auntuncle_ids.remove(int(parent_id)) cousin_ids = set([]) for auntuncle_id in select_auntuncle_ids: partial_cousin_ids = list(db.graph.find(V(auntuncle_id).begat(None))) for partial_cousin_id in partial_cousin_ids: cousin_ids.add(partial_cousin_id) return jsonify(cousin_ids)
def test_transaction_concurrency(graph): stored = [V(1).knows(i) for i in range(5, 9)] def store(value): def callback(): with graph.transaction() as tr: tr.store(value) return callback threads = [Thread(target=store(x)) for x in stored] [thread.start() for thread in threads] [thread.join() for thread in threads] for item in stored: assert item in graph
def test_transaction_delete(graph): queries = [ V(1).knows(2), V(1).likes, V().knows(3), V().knows, ] edges = [ V(1).knows(2), V(1).likes(2), V(1).knows(3), V(1).knows(4), ] for edge, query in zip(edges, queries): with graph.transaction() as tr: tr.delete(query) assert edge not in graph
def junctions_between_exons(self, exon_a, exon_b): """Get the junctions between exonA and exonB""" return self.graph.find( V(exon_a).upstream) \ .intersection(V(exon_b).downstream)
def test_difference(graph): assert list(graph.find(V(1).knows).difference(V().knows(1))) == [4]
def test_transaction_isolation(graph): with graph.transaction() as tr: tr.store(V(1).knows(5)) assert V(1).knows(5) not in graph
def test_traverse(graph): assert list(graph.find(V(1).knows).traverse(V().knows)) == [1, 1] assert list(graph.find(V(1).knows).traverse(V().knows(1))) == [2, 3]
def test_nested_traverse(graph): query = graph.find(V(1).likes)\ .traverse(V().knows)\ .traverse(V().knows) assert query.to(list) == [2, 3, 4]
def test_transaction_abort(graph): with graph.transaction() as tr: tr.store(V(1).knows(10)) tr.abort() assert V(1).knows(10) not in graph
def test_find(graph): assert list(graph.find(V(1).knows)) == [2, 3, 4] assert list(graph.find(V().knows(1))) == [2, 3]
def test_count(graph): assert graph.find(V(1).knows).count() == 3 assert graph.find(V(1).likes).count() == 2
def test_slice(graph): assert len(list(graph.find(V(1).knows)[:1])) == 1 assert list(graph.find(V(1).knows)[1:]) == [3, 4] assert list(graph.find(V(1).knows)[::2]) == [2, 4]
def test_to(graph): assert graph.find(V(1).knows).to(list) == [2, 3, 4] assert graph.find(V(1).knows).to(set) == set((2, 3, 4))
def test_edge(): assert not V(1).knows(2) == 3 assert V(1).knows(2) == V(1).knows(2) assert V(1).knows(3) != V(1).knows(2)
def test_union(graph): assert list(graph.find(V(1).knows).union(V(2).knows)) == [1, 2, 3, 4]