Commit 64462997 authored by cmaffeo2's avatar cmaffeo2
Browse files

Fixed ENM so it produces bonds across intrahelical connections

parent 8fc5e3da
......@@ -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_)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment