Skip to content
This repository has been archived by the owner on Mar 20, 2020. It is now read-only.

Commit

Permalink
#23 Graph.test.GFATest is migrated to DB versions. All GFATests passing.
Browse files Browse the repository at this point in the history
  • Loading branch information
josiahseaman committed Aug 19, 2019
1 parent d70fb50 commit 40811bd
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 42 deletions.
42 changes: 12 additions & 30 deletions Graph/gfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,38 +104,34 @@ def save_as_gfa(self, file: str):
self.gfa.to_file(file)

@classmethod
def from_graph(cls, graph: Graph):
def from_graph(cls, graph: GraphGenome):
"""Constructs the lines of a GFA file listing paths, then sequence nodes in arbitrary order."""
gfa = gfapy.Gfa()
for path in graph.paths:
node_series = ",".join([traverse.node.id + traverse.strand for traverse in path.nodes])
node_series = ",".join([traverse.node.name + traverse.strand for traverse in path.nodes])
gfa.add_line('\t'.join(['P', path.accession, node_series, ",".join(['*' for _ in path.nodes])]))
for node in graph.nodes.values(): # in no particular order
gfa.add_line('\t'.join(['S', str(node.id), node.seq]))
for node in graph.nodes: # in no particular order
gfa.add_line('\t'.join(['S', str(node.name), node.seq]))
return cls(gfa, "from Graph")

def to_paths(self) -> List[Path]:
def to_paths(self) -> GraphGenome:
graph = self.to_graph()
return graph.paths

def to_graph(self) -> GraphGenome:
# create parent object for this genome
gdb = GraphGenome.objects.get_or_create(name=self.source_path)[0]
for segment in self.gfa.segments:
node_id = segment.name
Node.objects.get_or_create(seq=segment.sequence, name=node_id, graph=gdb)

paths = []
for path in self.gfa.paths:
p = Path(path.name, graph=gdb).save()
p = Path(accession=path.name, graph=gdb)
p.save()
p.append_gfa_nodes(path.segment_names)
paths.append(p)
# path_names = [path.name for path in self.gfa.paths]
# list(Path.objects.get(name__in=path_names))
return paths

def to_graph(self) -> GraphGenome:
paths = self.to_paths()
if paths:
return paths[0].graph
else:
return None
return gdb

# Extract all paths into graph
# path_names = [p.name for p in self.gfa.paths]
Expand All @@ -149,20 +145,6 @@ def to_graph(self) -> GraphGenome:
# return graph


'''
class XGWrapper:
@staticmethod
def save(gfa):
pass
@staticmethod
def load(gfa):
pass
class GraphStack:
def __init__(graphs: List[Graph]):
self.graphs = graphs
'''

if __name__ == "__main__":
location_of_xg = sys.argv[0]
31 changes: 21 additions & 10 deletions Graph/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ class NodeMissingError(ValueError):
class GraphGenome(models.Model):
name = models.CharField(max_length=1000)

@property
def paths(self):
"""Getter only. Shortcut for DB."""
return self.path_set.all()

@property
def nodes(self):
"""Getter only. Shortcut for DB."""
return self.node_set.all()

def save_as_xg(self, file: str, xg_bin: str):
"""XG is a graph format used by VG (variation graph). This method exports
a database GraphGenome as an XG file."""
from Graph.gfa import GFA
gfa = GFA.from_graph(self)
gfa.save_as_xg(file, xg_bin)


class Node(models.Model):
seq = models.CharField(max_length=255, blank=True)
Expand Down Expand Up @@ -147,8 +164,8 @@ def __hash__(self):
return hash(self.accession)

@property
def nodes(self):
return NodeTraversal.objects.get(path=self).order_by('order')
def nodes(self) -> Iterable['NodeTraversal']:
return NodeTraversal.objects.filter(path=self).order_by('order').all()

def append_gfa_nodes(self, nodes):
assert hasattr(nodes[0], 'orient') and hasattr(nodes[0], 'name'), 'Expecting gfapy.Gfa.path'
Expand Down Expand Up @@ -199,7 +216,8 @@ def save(self, **kwargs):
"""Checks the largest 'order' value in the current path and increments by 1.
IMPORTANT NOTE: save() does not get called if you do NodeTraverseal.objects.create
or get_or_create"""
# self.order = self.path.nodetraversal_set.all().order_by('-order').first().order + 1
last_traversal = self.path.nodetraversal_set.all().order_by('-order').first()
self.order = 0 if not last_traversal else last_traversal.order + 1
super(NodeTraversal, self).save(**kwargs)


Expand Down Expand Up @@ -240,13 +258,6 @@ def save_as_pickle(self, file):
from memory."""
pickle.dump(self, file)

def save_as_xg(self, file: str, xg_bin: str):
"""XG is a graph format used by VG (variation graph). This method exports
a database GraphGenome as an XG file."""
from Graph.gfa import GFA
gfa = GFA.from_graph(self)
gfa.save_as_xg(file, xg_bin)

def append_node_to_path(self, node_id, strand, path_name, path_index):
"""This is the preferred way to build a graph in a truly non-linear way.
Nodes will be created if necessary.
Expand Down
4 changes: 2 additions & 2 deletions Graph/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ def test_gfa(self):

def test_load_gfa_to_graph(self):
graph, gfa = self.make_graph_from_gfa()
self.assertEqual(len(graph.paths), 3)
self.assertEqual(len(graph.nodes), 15)
self.assertEqual(graph.paths.count(), 3)
self.assertEqual(graph.nodes.count(), 15)

# def test_gfa_to_sliced_graph(self):
# graph, gfa = self.make_graph_from_gfa()
Expand Down

0 comments on commit 40811bd

Please sign in to comment.