Skip to content
Snippets Groups Projects
Commit 64462997 authored by cmaffeo2's avatar cmaffeo2
Browse files

Fixed ENM so it produces bonds across intrahelical connections

parent 8fc5e3da
No related branches found
No related tags found
No related merge requests found
......@@ -39,10 +39,7 @@ class Nucleotide(Group):
return self.get_intrahelical_nucleotide(-1)
def get_intrahelical_nucleotide(self,offset=1):
""" Returns nucleotide in same strand-side of helix with some offset along 5'-to-3'
TODO: Does not yet cross intrahelical connections
"""
""" Returns nucleotide in same strand-side of helix with some offset along 5'-to-3' """
strand_piece = self.parent
is_fwd = strand_piece.is_fwd
......@@ -53,9 +50,17 @@ class Nucleotide(Group):
else:
nt_idx = hi-strand_piece.children.index(self) - offset
seg = strand_piece.segment
if nt_idx < 0 or nt_idx >= seg.num_nt:
return None
""" Cross intrahelical connections if possible """
ret = seg._ntpos_to_seg_and_ntpos(nt_idx, is_fwd)
if ret is None:
ret = seg._ntpos_to_seg_and_ntpos(nt_idx, is_fwd)
return None
else:
seg, nt_idx, is_fwd = ret
return seg._get_atomic_nucleotide(nt_idx, is_fwd)
else:
return seg._get_atomic_nucleotide(nt_idx, is_fwd)
......
......@@ -718,6 +718,36 @@ class Segment(ConnectableElement, Group):
return orientation
def _ntpos_to_seg_and_ntpos(self, nt_pos, is_fwd=True, visited_segs=tuple()):
""" Cross intrahelical to obtain a tuple of the segment nucleotide position """
""" TODO: This function could perhaps replace parts of SegmentParticle.get_contour_position """
if nt_pos >= 0 and nt_pos < self.num_nt:
return (self,nt_pos,is_fwd)
else:
c,A,B = self.get_contour_sorted_connections_and_locations(type_='intrahelical')[0 if nt_pos < 0 else -1]
## Special logic for circular segments
assert(A.container == self)
if A.container == B.container:
if (nt_pos < 0 and A.address > B.address) or (nt_pos >= self.num_nt and A.address < B.address):
A,B = (B,A)
other_seg = B.container
if A.address == (0 if nt_pos < 0 else 1) and other_seg not in visited_segs:
## Cross the crossover
other_pos = (nt_pos-self.num_nt) if nt_pos >= self.num_nt else -nt_pos-1
if B.address > 0.5:
other_pos = (other_seg.num_nt-1) - other_pos
other_fwd = not is_fwd if A.address == B.address else is_fwd
return other_seg._ntpos_to_seg_and_ntpos(other_pos, other_fwd,
list(visited_segs)+[self])
else:
## Could not find a path to nt_pos
return None
assert(False)
def get_contour_sorted_connections_and_locations(self,type_):
sort_fn = lambda c: c[1].address
cl = self.get_connections_and_locations(type_)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment