diff --git a/cadnano_segments.py b/cadnano_segments.py index 70dfbf46240e72adcbe76e14d394b517ce7c8080..35db031eb30caa0651b3a1decdcf2ccd2e42c315 100644 --- a/cadnano_segments.py +++ b/cadnano_segments.py @@ -319,10 +319,10 @@ class cadnano_part(SegmentModel): kwargs['num_bp'] = numBps seg = DoubleStrandedSegment(**kwargs,**posargs1) elif zMid in strandOccupancies[0]: - kwargs['num_nts'] = numBps + kwargs['num_nt'] = numBps seg = SingleStrandedSegment(**kwargs,**posargs1) elif zMid in strandOccupancies[1]: - kwargs['num_nts'] = numBps + kwargs['num_nt'] = numBps seg = SingleStrandedSegment(**kwargs,**posargs2) else: raise Exception("Segment could not be found") @@ -486,8 +486,8 @@ class cadnano_part(SegmentModel): def get_bead(self, hid, zid): # get segment, get nucleotide, seg, nt = self._get_segment_nucleotide(h,z) - # return seg.get_nearest_bead(seg,nt / seg.num_nts) - return seg.get_nearest_bead(seg,nt / (seg.num_nts-1)) + # return seg.get_nearest_bead(seg,nt / seg.num_nt) + return seg.get_nearest_bead(seg,nt / (seg.num_nt-1)) def read_json_file(filename): import json diff --git a/polygon_mesh.py b/polygon_mesh.py index b4e5bff3b69cfd3ab7680ca15e5d7ea8d08a9686..c7e5f23b4452d4bff56f39a077148eecb73e6796 100644 --- a/polygon_mesh.py +++ b/polygon_mesh.py @@ -329,7 +329,7 @@ def convert_maya_to_segments(helices): seg2 = SingleStrandedSegment("strand", start_position = ssSeg[0].get_position(), end_position = ssSeg[-1].get_position(), - num_nts = len(ssSeg)) + num_nt = len(ssSeg)) seg.connect_end3(seg2) connectionToSingleStrand[top] = seg2 other = ssSeg[-1].end3 @@ -357,7 +357,7 @@ def convert_maya_to_segments(helices): seg2 = SingleStrandedSegment("strand", start_position = ssSeg[-1].get_position(), end_position = ssSeg[0].get_position(), - num_nts = len(ssSeg)) + num_nt = len(ssSeg)) seg.connect_end5(seg2) connectionToSingleStrand[top.basepair] = seg2 other = ssSeg[0].end5 @@ -385,7 +385,7 @@ def convert_maya_to_segments(helices): seg2 = SingleStrandedSegment("strand", start_position = ssSeg[0].get_position(), end_position = ssSeg[-1].get_position(), - num_nts = len(ssSeg)) + num_nt = len(ssSeg)) seg.connect_start3(seg2) connectionToSingleStrand[bot] = seg2 other = ssSeg[-1].end3 @@ -409,7 +409,7 @@ def convert_maya_to_segments(helices): seg2 = SingleStrandedSegment("strand", start_position = ssSeg[-1].get_position(), end_position = ssSeg[0].get_position(), - num_nts = len(ssSeg)) + num_nt = len(ssSeg)) seg.connect_start5(seg2) connectionToSingleStrand[bot.basepair] = seg2 other = ssSeg[0].end5 diff --git a/segmentmodel.py b/segmentmodel.py index 7245600abea6cbb51ada40e94531a350bc4723d1..d8bb260b273a2de980ba70c0f6cb2ea1fef847e6 100644 --- a/segmentmodel.py +++ b/segmentmodel.py @@ -75,7 +75,7 @@ class Location(): if self.address == 0: pos = 0 elif self.address == 1: - pos = self.container.num_nts-1 + pos = self.container.num_nt-1 else: raise return pos @@ -133,7 +133,7 @@ class ConnectableElement(): def get_location_at(self, address, on_fwd_strand=True, new_type="crossover"): loc = None - if (self.num_nts == 1): + if (self.num_nt == 1): # import pdb # pdb.set_trace() ## Assumes that intrahelical connections have been made before crossovers @@ -332,7 +332,7 @@ class Segment(ConnectableElement, Group): radius = 3, ) - def __init__(self, name, num_nts, + def __init__(self, name, num_nt, start_position = None, end_position = None, segment_model = None): @@ -351,9 +351,9 @@ class Segment(ConnectableElement, Group): self._bead_model_generation = 0 # TODO: remove? self.segment_model = segment_model # TODO: remove? - self.num_nts = int(num_nts) + self.num_nt = int(num_nt) if end_position is None: - end_position = np.array((0,0,self.distance_per_nt*num_nts)) + start_position + end_position = np.array((0,0,self.distance_per_nt*num_nt)) + start_position self.start_position = start_position self.end_position = end_position @@ -373,14 +373,14 @@ class Segment(ConnectableElement, Group): loc.particle = None def contour_to_nt_pos(self, contour_pos, round_nt=False): - nt = contour_pos*(self.num_nts) - 0.5 + nt = contour_pos*(self.num_nt) - 0.5 if round_nt: assert( np.isclose(np.around(nt),nt) ) nt = np.around(nt) return nt def nt_pos_to_contour(self,nt_pos): - return (nt_pos+0.5)/(self.num_nts) + return (nt_pos+0.5)/(self.num_nt) def contour_to_position(self,s): p = interpolate.splev( s, self.position_spline_params ) @@ -424,9 +424,9 @@ class Segment(ConnectableElement, Group): bases = list(seqComplement.keys()) # bases = ['T'] ## FOR DEBUG if self.sequence is None: - self.sequence = [random.choice(bases) for i in range(self.num_nts)] + self.sequence = [random.choice(bases) for i in range(self.num_nt)] else: - assert(len(self.sequence) == self.num_nts) # TODO move + assert(len(self.sequence) == self.num_nt) # TODO move for i in range(len(self.sequence)): if self.sequence[i] is None: self.sequence[i] = random.choice(bases) @@ -455,7 +455,7 @@ class Segment(ConnectableElement, Group): y = np.cross(axis,angleVec) orientation = np.array([angleVec,y,axis]).T ## TODO: improve placement of ssDNA - # rot = rotationAboutAxis( axis, contour_position*self.twist_per_nt*self.num_nts, normalizeAxis=True ) + # rot = rotationAboutAxis( axis, contour_position*self.twist_per_nt*self.num_nt, normalizeAxis=True ) # orientation = rot.dot(orientation) else: orientation = orientation @@ -554,7 +554,7 @@ class Segment(ConnectableElement, Group): if l.address == 0: pos = 0.0 elif l.address == 1: - pos = self.num_nts-1 + pos = self.num_nt-1 else: pos = self.contour_to_nt_pos(l.address, round_nt=True) @@ -700,8 +700,8 @@ class Segment(ConnectableElement, Group): b = self._generate_one_bead( self.nt_pos_to_contour(0), 0) existing_beads = [b] + existing_beads - if existing_beads[-1].get_nt_position(self)-(self.num_nts-1) < -0.5: - b = self._generate_one_bead( self.nt_pos_to_contour(self.num_nts-1), 0) + if existing_beads[-1].get_nt_position(self)-(self.num_nt-1) < -0.5: + b = self._generate_one_bead( self.nt_pos_to_contour(self.num_nt-1), 0) existing_beads.append(b) assert(len(existing_beads) > 1) @@ -721,9 +721,9 @@ class Segment(ConnectableElement, Group): e_ds = eb2.get_contour_position(self) - eb1.get_contour_position(self) num_beads = self._get_num_beads( e_ds, max_basepairs_per_bead, max_nucleotides_per_bead ) ds = e_ds / (num_beads+1) - nts = ds*self.num_nts - eb1.num_nts += 0.5*nts - eb2.num_nts += 0.5*nts + nts = ds*self.num_nt + eb1.num_nt += 0.5*nts + eb2.num_nt += 0.5*nts ## Add beads if eb1.parent == self: @@ -775,7 +775,7 @@ class DoubleStrandedSegment(Segment): start_position, end_position, segment_model) - self.num_bp = self.num_nts + self.num_bp = self.num_nt self.local_twist = local_twist if num_turns is None: @@ -865,8 +865,8 @@ class DoubleStrandedSegment(Segment): else: end2.container._connect( end1.container, Connection( end2, end1, type_=type_ ), in_3prime_direction=True ) def _get_num_beads(self, contour, max_basepairs_per_bead, max_nucleotides_per_bead): - # return int(contour*self.num_nts // max_basepairs_per_bead) - return int(contour*(self.num_nts**2/(self.num_nts+1)) // max_basepairs_per_bead) + # return int(contour*self.num_nt // max_basepairs_per_bead) + return int(contour*(self.num_nt**2/(self.num_nt+1)) // max_basepairs_per_bead) def _generate_one_bead(self, contour_position, nts): pos = self.contour_to_position(contour_position) @@ -881,15 +881,15 @@ class DoubleStrandedSegment(Segment): assert(np.linalg.norm(opos-pos) < 10 ) o = SegmentParticle( Segment.orientation_particle, opos, name="O", contour_position = contour_position, - num_nts=nts, parent=self ) + num_nt=nts, parent=self ) bead = SegmentParticle( Segment.dsDNA_particle, pos, name="DNA", - num_nts=nts, parent=self, + num_nt=nts, parent=self, orientation_bead=o, contour_position=contour_position ) else: bead = SegmentParticle( Segment.dsDNA_particle, pos, name="DNA", - num_nts=nts, parent=self, + num_nt=nts, parent=self, contour_position=contour_position ) self._add_bead(bead) return bead @@ -899,13 +899,13 @@ class SingleStrandedSegment(Segment): """ Class that describes a segment of ssDNA. When built from cadnano models, should not span helices """ - def __init__(self, name, num_nts, start_position = None, + def __init__(self, name, num_nt, start_position = None, end_position = None, segment_model = None): if start_position is None: start_position = np.array((0,0,0)) self.distance_per_nt = 5 - Segment.__init__(self, name, num_nts, + Segment.__init__(self, name, num_nt, start_position, end_position, segment_model) @@ -949,10 +949,10 @@ class SingleStrandedSegment(Segment): # # TODOTODO # ## Ensure connections occur at ends, otherwise the structure doesn't make sense # # assert(np.isclose(c1,0) or np.isclose(c1,1)) - # assert(np.isclose(nt,0) or np.isclose(nt,self.num_nts-1)) + # assert(np.isclose(nt,0) or np.isclose(nt,self.num_nt-1)) if nt == 0: c1 = 0 - elif nt == self.num_nts-1: + elif nt == self.num_nt-1: c1 = 1 else: raise Exception("Crossovers can only be at the ends of an ssDNA segment") @@ -960,14 +960,14 @@ class SingleStrandedSegment(Segment): if other_nt == 0: c2 = 0 - elif other_nt == other.num_nts-1: + elif other_nt == other.num_nt-1: c2 = 1 else: c2 = other.nt_pos_to_contour(other_nt) if isinstance(other,SingleStrandedSegment): ## Ensure connections occur at opposing ends - assert(np.isclose(other_nt,0) or np.isclose(other_nt,self.num_nts-1)) + assert(np.isclose(other_nt,0) or np.isclose(other_nt,self.num_nt-1)) other_loc = other.get_location_at( c2, True ) # if ("22-2" in (self.name, other.name)): # pdb.set_trace() @@ -985,14 +985,14 @@ class SingleStrandedSegment(Segment): other._connect(self, Connection( other_loc, loc, type_="sscrossover" ), in_3prime_direction=True ) def _get_num_beads(self, contour, max_basepairs_per_bead, max_nucleotides_per_bead): - return int(contour*(self.num_nts**2/(self.num_nts+1)) // max_basepairs_per_bead) - # return int(contour*self.num_nts // max_nucleotides_per_bead) + return int(contour*(self.num_nt**2/(self.num_nt+1)) // max_basepairs_per_bead) + # return int(contour*self.num_nt // max_nucleotides_per_bead) def _generate_one_bead(self, contour_position, nts): pos = self.contour_to_position(contour_position) b = SegmentParticle( Segment.ssDNA_particle, pos, name="NAS", - num_nts=nts, parent=self, + num_nt=nts, parent=self, contour_position=contour_position ) self._add_bead(b) return b @@ -1004,7 +1004,7 @@ class StrandInSegment(Group): def __init__(self, segment, start, end, is_fwd): """ start/end should be provided expressed in nt coordinates, is_fwd tuples """ Group.__init__(self) - self.num_nts = 0 + self.num_nt = 0 # self.sequence = [] self.segment = segment self.start = start @@ -1012,8 +1012,8 @@ class StrandInSegment(Group): self.is_fwd = is_fwd nts = np.abs(end-start)+1 - self.num_nts = int(round(nts)) - assert( np.isclose(self.num_nts,nts) ) + self.num_nt = int(round(nts)) + assert( np.isclose(self.num_nt,nts) ) def _nucleotide_ids(self): nt0 = self.start # seg.contour_to_nt_pos(self.start) @@ -1022,7 +1022,7 @@ class StrandInSegment(Group): assert( (self.end-self.start) >= 0 or not self.is_fwd ) direction = (2*self.is_fwd-1) - return range(nt0,nt0 + direction*self.num_nts, direction) + return range(nt0,nt0 + direction*self.num_nt, direction) def get_sequence(self): """ return 5-to-3 """ @@ -1035,13 +1035,13 @@ class StrandInSegment(Group): def get_contour_points(self): c0,c1 = [self.segment.nt_pos_to_contour(p) for p in (self.start,self.end)] - return np.linspace(c0,c1,self.num_nts) + return np.linspace(c0,c1,self.num_nt) class Strand(Group): """ Represents an entire ssDNA strand from 5' to 3' as it routes through segments """ def __init__(self, segname = None): Group.__init__(self) - self.num_nts = 0 + self.num_nt = 0 self.children = self.strand_segments = [] self.segname = segname @@ -1064,11 +1064,11 @@ class Strand(Group): s = StrandInSegment( segment, start, end, is_fwd ) self.add( s ) - self.num_nts += s.num_nts + self.num_nt += s.num_nt def set_sequence(self,sequence): # , set_complement=True): ## validate input - assert( len(sequence) >= self.num_nts ) + assert( len(sequence) >= self.num_nt ) assert( np.all( [i in ('A','T','C','G') for i in sequence] ) ) seq_idx = 0 @@ -1076,7 +1076,7 @@ class Strand(Group): for s in self.children: seg = s.segment if seg.sequence is None: - seg.sequence = [None for i in range(seg.num_nts)] + seg.sequence = [None for i in range(seg.num_nt)] if s.is_fwd: for nt in s._nucleotide_ids(): @@ -1092,11 +1092,11 @@ class Strand(Group): # for ss in self.strand_segments: # sequence.extend( ss.get_sequence() ) - # assert( len(sequence) >= self.num_nts ) + # assert( len(sequence) >= self.num_nt ) # ret = ["5"+sequence[0]] +\ # sequence[1:-1] +\ # [sequence[-1]+"3"] - # assert( len(ret) == self.num_nts ) + # assert( len(ret) == self.num_nt ) # return ret def generate_atomic_model(self,scale): @@ -1111,7 +1111,7 @@ class Strand(Group): # if s.end == s.start: # pdb.set_trace() # assert(s.end != s.start) - assert( s.num_nts == 1 or (np.linalg.norm( seg.contour_to_position(contour[-1]) - seg.contour_to_position(contour[0]) ) > 0.1) ) + assert( s.num_nt == 1 or (np.linalg.norm( seg.contour_to_position(contour[-1]) - seg.contour_to_position(contour[0]) ) > 0.1) ) for c,seq in zip(contour,s.get_sequence()): if last is None: seq = "5"+seq @@ -1460,7 +1460,7 @@ class SegmentModel(ArbdModel): """ Simplify connections """ # d_nt = dict() # # for s in segments: - # d_nt[s] = 1.5/(s.num_nts-1) + # d_nt[s] = 1.5/(s.num_nt-1) # for s in segments: # ## replace consecutive crossovers with # cl = sorted( s.get_connections_and_locations("crossover"), key=lambda x: x[1].address ) @@ -1607,19 +1607,19 @@ class SegmentModel(ArbdModel): beadtype_s = dict() for segment in segments: for b in segment: - # b.num_nts = np.around( b.num_nts, decimals=1 ) - b.num_nts = 3*np.around( float(b.num_nts)/3, decimals=1 ) - key = (b.type_.name[0].upper(), b.num_nts) + # b.num_nt = np.around( b.num_nt, decimals=1 ) + b.num_nt = 3*np.around( float(b.num_nt)/3, decimals=1 ) + key = (b.type_.name[0].upper(), b.num_nt) if key in beadtype_s: b.type_ = beadtype_s[key] else: t = deepcopy(b.type_) if key[0] == "D": - t.__dict__["nts"] = b.num_nts*2 + t.__dict__["nts"] = b.num_nt*2 elif key[0] == "S": - t.__dict__["nts"] = b.num_nts + t.__dict__["nts"] = b.num_nt elif key[0] == "O": - t.__dict__["nts"] = b.num_nts + t.__dict__["nts"] = b.num_nt else: raise Exception("TODO") # print(t.nts) @@ -1641,7 +1641,7 @@ class SegmentModel(ArbdModel): parent = self._getParent(b1,b2) ## TODO: could be sligtly smarter about sep - sep = 0.5*(b1.num_nts+b2.num_nts) + sep = 0.5*(b1.num_nt+b2.num_nt) conversion = 0.014393265 # units "pN/AA" kcal_mol/AA^2 if b1.type_.name[0] == "D" and b2.type_.name[0] == "D": @@ -1672,7 +1672,7 @@ class SegmentModel(ArbdModel): if self.DEBUG: print("Adding intrahelical angle potentials") for b1,b2,b3 in self._get_intrahelical_angle_beads(): ## TODO: could be slightly smarter about sep - sep = 0.5*b1.num_nts+b2.num_nts+0.5*b3.num_nts + sep = 0.5*b1.num_nt+b2.num_nt+0.5*b3.num_nt parent = self._getParent(b1,b2,b3) kT = 0.58622522 # kcal/mol @@ -1988,7 +1988,7 @@ class SegmentModel(ArbdModel): add_end = False break if add_end: - seg.add_5prime(seg.num_nts-1,on_fwd_strand=False) + seg.add_5prime(seg.num_nt-1,on_fwd_strand=False) if 'start3' in seg.__dict__ and seg.start3.connection is None: add_end = True @@ -2005,7 +2005,7 @@ class SegmentModel(ArbdModel): add_end = False break if add_end: - seg.add_3prime(seg.num_nts-1) + seg.add_3prime(seg.num_nt-1) # print( [(l,l.get_connected_location()) for l in seg.locations] ) # addresses = np.array([l.address for l in seg.get_locations("5prime")]) @@ -2045,10 +2045,10 @@ class SegmentModel(ArbdModel): is_fwd = l.on_fwd_strand s = Strand() _recursively_build_strand(s, seg, pos, is_fwd) - # print("{} {}".format(seg.name,s.num_nts)) + # print("{} {}".format(seg.name,s.num_nt)) strands.append(s) - self.strands = sorted(strands, key=lambda s:s.num_nts)[::-1] # or something + self.strands = sorted(strands, key=lambda s:s.num_nt)[::-1] # or something ## relabel segname counter = 0 for s in self.strands: diff --git a/segmentmodel_example.py b/segmentmodel_example.py index 370df6a1a8ae8e882827770129d1c246b4f7dd8d..3da167b955fa0c6b50dcc48b2739409bf96f4e1d 100644 --- a/segmentmodel_example.py +++ b/segmentmodel_example.py @@ -18,12 +18,12 @@ if __name__ == "__main__": seg2 = SingleStrandedSegment("strand", start_position = seg1.end_position + np.array((5,0,5)), - num_nts = 12) + num_nt = 12) seg3 = SingleStrandedSegment("strand", start_position = seg1.start_position + np.array((-5,0,-5)), end_position = seg1.end_position + np.array((-5,0,5)), - num_nts = 128) + num_nt = 128) seg1.start3 seg1.start5