Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Yoann DUFRESNE
linked reads molecule ordering
Commits
ed49295c
Commit
ed49295c
authored
May 17, 2020
by
Yoann Dufresne
Browse files
bugfix d2_algo
parent
15906856
Changes
1
Hide whitespace changes
Inline
Side-by-side
deconvolution/d2graph/d2_algorithms.py
View file @
ed49295c
import
networkx
as
nx
from
deconvolution.d2graph.d2_path
import
Unitig
#
from deconvolution.d2graph.d2_path import Unitig
""" Remove unnecessary transitions
...
...
@@ -84,87 +84,87 @@ def filter_singeltons(graph):
return
graph
""" Compute the unambiguous paths in a d2g. The d2g must not contain singletons.
The unitigs are sorted by increasing penalty first and decreasing size second.
@param d2g a d2g graph
@return a list of unitigs
"""
def
compute_unitigs
(
d2g
):
unitigs
=
[]
used_nodes
=
{
int
(
node
):
False
for
node
in
d2g
.
nodes
()}
for
node_id
in
d2g
.
nodes
():
node_idx
=
int
(
node_id
)
node
=
d2g
.
node_by_idx
[
node_idx
]
# If already tested
if
used_nodes
[
node
.
idx
]:
continue
used_nodes
[
node
.
idx
]
=
True
if
d2g
.
degree
(
str
(
node
.
idx
))
>
2
:
# Not a unitig
continue
# Create new unitigs
unitig
=
compute_unitig_from
(
d2g
,
node
)
unitigs
.
append
(
unitig
)
for
node
in
unitig
:
used_nodes
[
node
.
idx
]
=
True
# Sort the unitigs
unitigs
.
sort
(
key
=
lambda
x
:
(
x
.
normalized_penalty
(),
-
len
(
x
)))
return
unitigs
""" Compute a unitig starting from the node regarding the graph.
The unitig will be extended on both sides
@param d2g The d2g to look for unitig
@param node The start node of the unitig
@return The constructed unitig
"""
def
compute_unitig_from
(
d2g
,
node
):
unitig
=
Unitig
(
d2g
)
unitig
.
add_path
([
node
])
if
d2g
.
degree
(
str
(
node
.
idx
))
==
2
:
left
,
right
=
d2g
.
neighbors
(
str
(
node
.
idx
))
else
:
left
=
next
(
d2g
.
neighbors
(
str
(
node
.
idx
)))
right
=
None
# Extends first side
prev_node
=
node
current_node
=
d2g
.
node_by_idx
[
int
(
left
)]
unitig
=
extend_unitig
(
unitig
,
d2g
,
prev_node
,
current_node
)
unitig
.
revert
()
# Extends second side
prev_node
=
node
current_node
=
d2g
.
node_by_idx
[
int
(
right
)]
if
right
is
not
None
else
None
unitig
=
extend_unitig
(
unitig
,
d2g
,
prev_node
,
current_node
)
return
unitig
""" Directional extension of the unitig. Uses the previous and current nodes to detect the extension direction.
@param unitig The unitig to extend. Will be modified during the execution.
@param d2g The d2g to follow for extension
@param prev_node Node already added in the unitig
@param current_node Node to add into the unitig and used to select the next node to add. If not set, stop the extension.
@return Return the modified unitig.
"""
def
extend_unitig
(
unitig
,
d2g
,
prev_node
,
current_node
):
if
current_node
is
None
:
return
unitig
# Add the node
unitig
.
add_right
(
current_node
)
# Look for the next node
next_candidates
=
list
(
d2g
.
neighbors
(
str
(
current_node
.
idx
)))
next_candidates
.
remove
(
str
(
prev_node
.
idx
))
# Select next node
next_node
=
d2g
.
node_by_idx
[
int
(
next_candidates
[
0
])]
if
len
(
next_candidates
)
==
1
else
None
# Continue extension
return
extend_unitig
(
unitig
,
d2g
,
current_node
,
next_node
)
#
""" Compute the unambiguous paths in a d2g. The d2g must not contain singletons.
#
The unitigs are sorted by increasing penalty first and decreasing size second.
#
@param d2g a d2g graph
#
@return a list of unitigs
#
"""
#
def compute_unitigs(d2g):
#
unitigs = []
#
used_nodes = {int(node): False for node in d2g.nodes()}
#
#
for node_id in d2g.nodes():
#
node_idx = int(node_id)
#
node = d2g.node_by_idx[node_idx]
#
#
# If already tested
#
if used_nodes[node.idx]:
#
continue
#
used_nodes[node.idx] = True
#
#
if d2g.degree(str(node.idx)) > 2:
#
# Not a unitig
#
continue
#
#
# Create new unitigs
#
unitig = compute_unitig_from(d2g, node)
#
unitigs.append(unitig)
#
for node in unitig:
#
used_nodes[node.idx] = True
#
#
# Sort the unitigs
#
unitigs.sort(key=lambda x: (x.normalized_penalty(), -len(x)))
#
#
return unitigs
#
#
#
""" Compute a unitig starting from the node regarding the graph.
#
The unitig will be extended on both sides
#
@param d2g The d2g to look for unitig
#
@param node The start node of the unitig
#
@return The constructed unitig
#
"""
#
def compute_unitig_from(d2g, node):
#
unitig = Unitig(d2g)
#
unitig.add_path([node])
#
if d2g.degree(str(node.idx)) == 2:
#
left, right = d2g.neighbors(str(node.idx))
#
else:
#
left = next(d2g.neighbors(str(node.idx)))
#
right = None
#
#
# Extends first side
#
prev_node = node
#
current_node = d2g.node_by_idx[int(left)]
#
unitig = extend_unitig(unitig, d2g, prev_node, current_node)
#
unitig.revert()
#
#
# Extends second side
#
prev_node = node
#
current_node = d2g.node_by_idx[int(right)] if right is not None else None
#
unitig = extend_unitig(unitig, d2g, prev_node, current_node)
#
#
return unitig
#
#
#
""" Directional extension of the unitig. Uses the previous and current nodes to detect the extension direction.
#
@param unitig The unitig to extend. Will be modified during the execution.
#
@param d2g The d2g to follow for extension
#
@param prev_node Node already added in the unitig
#
@param current_node Node to add into the unitig and used to select the next node to add. If not set, stop the extension.
#
@return Return the modified unitig.
#
"""
#
def extend_unitig(unitig, d2g, prev_node, current_node):
#
if current_node is None:
#
return unitig
#
#
# Add the node
#
unitig.add_right(current_node)
#
#
# Look for the next node
#
next_candidates = list(d2g.neighbors(str(current_node.idx)))
#
next_candidates.remove(str(prev_node.idx))
#
# Select next node
#
next_node = d2g.node_by_idx[int(next_candidates[0])] if len(next_candidates) == 1 else None
#
# Continue extension
#
return extend_unitig(unitig, d2g, current_node, next_node)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment