def get_overhang_segs(overhang_ds_edges, overhang_ss_edges, ss_overhang_sequences): overhang_segs = {} for index in overhang_ds_edges: e = overhang_ds_edges[index] tmp = copy( (mrdna.DoubleStrandedSegment(name='helix%s' % (index + 100, ), num_bp=int(e.nBp), start_position=list(e.nStart_c), end_position=list(e.nStop_c)))) overhang_segs[e.index] = tmp ss_overhang_segs = {} for index in overhang_ss_edges: e = overhang_ss_edges[index] if e.out_orientation == 5: tmp = copy( (mrdna.SingleStrandedSegment(name='helix%s' % (index + 200, ), num_nt=int(e.nBp), start_position=list(e.nStart_c), end_position=list(e.nStop_c)))) elif e.out_orientation == 3: tmp = copy((mrdna.SingleStrandedSegment( name='helix%s' % (index + 200, ), num_nt=int(e.nBp), start_position=list(e.nStop_c), end_position=list(e.nStart_c), ))) tmp.sequence = ss_overhang_sequences[index] ss_overhang_segs[e.index] = (tmp) return (overhang_segs, ss_overhang_segs)
def create_helix(self): if self.is_dsdna: self.dna = mrdna.DoubleStrandedSegment(name=self.name, start_position = self.start_position, end_position=self.end_position, num_bp = self.num_bp) else: self.dna = mrdna.SingleStrandedSegment(name=self.name, start_position = self.start_position, end_position=self.end_position, num_nt = self.num_bp)
def apply_connection(self,ss_length): if ss_length == 0: self.A.helix.connect_end3(self.B.helix.start5 if self.forward_B else self.B.helix.end5, type_ = "terminal_crossover") if self.forward_A else self.A.helix.connect_start3(self.B.helix.start5 if self.forward_B else self.B.helix.end5, type_ ="terminal_crossover") else: self.ss = mrdna.SingleStrandedSegment(str(np.random.rand()), start_position = self.A.nStop_c if self.forward_A else self.A.nStart_c, stop_position = self.B.nStart_c if self.forward_B else self.B.nStop_c , num_nt=ss_length) self.A.helix.connect_end3(self.ss) if self.forward_A else self.A.helix.connect_start3(self.ss) self.B.helix.connect_start5(self.ss) if self.forward_B else self.B.helix.connect_end5(self.ss)
def join_spacerless_overhangs(ss_here, c1_positive, c2_positive, overhang_segs, segs, c1, c2, vertex_index): single_stranded_dna = [] if ss_here == 0: if c1_positive: segs[c1].connect_end3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5( segs[c1].end3, type_="terminal_crossover") else: segs[c1[::-1]].connect_start3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5( segs[c1[::-1]].start3, type_="terminal_crossover") if c2_positive: segs[c2].connect_start5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3( segs[c2].start5, type_="terminal_crossover") else: segs[c2[::-1]].connect_end5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3( segs[c2[::-1]].end5, type_="terminal_crossover") else: if c1_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (np.random.randint(0, high=int(1e10)), ), start_position=segs[c1].end_position, end_position=overhang_segs[vertex_index].start_position, num_nt=ss_here)) segs[c1].connect_end3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (np.random.randint(0, high=int(1e10)), ), start_position=segs[c1[::-1]].start_position, end_position=overhang_segs[vertex_index].start_position, num_nt=ss_here)) segs[c1[::-1]].connect_start3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) if c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (np.random.randint(0, high=int(1e10)), ), start_position=overhang_segs[vertex_index].end_position, end_position=segs[c2].start_position, num_nt=ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (np.random.randint(0, high=int(1e10)), ), start_position=segs[c2[::-1]].end_position, end_position=overhang_segs[vertex_index].start_position, num_nt=ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) return single_stranded_dna
def join_segments(c1_positive, c2_positive, segs, c1, c2, ssDNA_index, SPACERS): single_stranded_dna = [] if SPACERS != 0: r1 = np.random.rand(1)[0] - 0.5 r2 = np.random.rand(1)[0] - 0.5 if c1_positive and c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1].end_position + r1, end_position=segs[c2].start_position + r2, num_nt=SPACERS)) segs[c1].connect_end3(ss) segs[c2].connect_start5(ss) elif c1_positive and not c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1].end_position + r1, end_position=segs[c2[::-1]].end_position + r2, num_nt=SPACERS)) segs[c1].connect_end3(ss) segs[c2[::-1]].connect_end5(ss) elif not c1_positive and c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1[::-1]].start_position + r1, end_position=segs[c2].start_position + r2, num_nt=SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2].connect_start5(ss) elif not c1_positive and not c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1[::-1]].start_position + r1, end_position=segs[c2[::-1]].end_position + r2, num_nt=SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) else: if c1_positive and c2_positive: segs[c1].connect_end3(segs[c2].start5, type_="terminal_crossover") elif c1_positive and not c2_positive: segs[c1].connect_end3(segs[c2[::-1]].end5, type_="terminal_crossover") elif not c1_positive and c2_positive: segs[c1[::-1]].connect_start3(segs[c2].start5, type_="terminal_crossover") elif not c1_positive and not c2_positive: segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") return single_stranded_dna
def get_segments(FNAME, LENGTH_OF_SMALLEST, SPACERS,nicks=1,overhangs = None): locs,faces = read_ply(FNAME) mentioned_edges = set() face_data = [] for index,i in enumerate(faces): print (FACE) face_data.append(FACE(i,index)) #NICKS #now we work out where the nicks are so we can choose the correct orientation of our strands. assign_nicks(face_data) nick_locs = [] for f in face_data: nick_locs.append(f.nick) mentioned_edges = set(nick_locs) #NICKS #choose orientation for i in face_data: for e in i.e: if e not in mentioned_edges and e[::-1] not in mentioned_edges: i.ori.append(1) mentioned_edges.add(e) else: i.ori.append(-1) edges = [] for i in mentioned_edges: edges.append( edge(i,locs[i[0]],locs[i[1]]) ) min_length = np.min([x.rawlen for x in edges]) max_length = np.max([x.rawlen for x in edges]) #ds overhangs #rework this data structure... if overhangs is not None: #overhang_ss_edges_sequences = list(overhangs['ss_seq']) ss_overhang_sequences = {} overhang_ds_edges = {} overhang_ss_edges = {} for i in range(len(overhangs)): vertex = overhangs.iloc[i]['overhang'] vertex_location = locs[vertex] bp = overhangs.iloc[i]['ds_length'] length = bp * min_length / float(LENGTH_OF_SMALLEST) / 3.4 end = length * np.array(vertex_location) / np.sqrt(np.sum(np.array(vertex_location)**2)) + np.array(vertex_location) overhang_ds_edges[vertex] = edge(vertex,vertex_location,end,overhang=True,bp_overhang=bp) #ss overhangs bp_ss = overhangs.iloc[i]['ss_length'] length_ss = bp_ss * min_length / float(LENGTH_OF_SMALLEST) / 3.4 start_ss = end end_ss = end + length_ss * np.array(vertex_location) / np.sqrt(np.sum(np.array(vertex_location)**2)) overhang_ss_edges[vertex] = edge(vertex,start_ss,end_ss,overhang=True,bp_overhang=bp_ss,out_orientation=overhangs.iloc[i]['out_side']) ss_overhang_sequences[vertex] = overhangs.iloc[i]['ss_seq'] for i in edges + list(overhang_ds_edges.values()) + list(overhang_ss_edges.values()): i.normalize(min_length,LENGTH_OF_SMALLEST) else: for i in edges: i.normalize(min_length,LENGTH_OF_SMALLEST) single_stranded_dna = [] segs = {} for index, e in enumerate(edges): segs[tuple(e.index)] = ( mrdna.DoubleStrandedSegment(name = 'helix%s'%(index,), num_bp = e.nBp, start_position = e.nStart_c, end_position = e.nStop_c )) if overhangs is not None: #overhangs overhang_segs = {} for index in overhang_ds_edges: e = overhang_ds_edges[index] tmp = copy((mrdna.DoubleStrandedSegment(name = 'helix%s'%(index+100,), num_bp = int(e.nBp), start_position = list(e.nStart_c), end_position = list(e.nStop_c) ))) overhang_segs[e.index] = tmp #overhangs ss_overhang_segs = {} for index in overhang_ss_edges: e = overhang_ss_edges[index] if e.out_orientation == 5: tmp = copy((mrdna.SingleStrandedSegment(name = 'helix%s'%(index+200,), num_nt = int(e.nBp), start_position = list(e.nStart_c), end_position = list(e.nStop_c) ))) elif e.out_orientation == 3: tmp = copy((mrdna.SingleStrandedSegment(name = 'helix%s'%(index+200,), num_nt = int(e.nBp), start_position = list(e.nStop_c), end_position = list(e.nStart_c), ))) else: print ('BUG') #tmp.sequence = overhangs.iloc[index]['ss_seq'] tmp.sequence = ss_overhang_sequences[index] #APPLY SEQUENCE HERE USING THE NEW DATA STRUCTURE print (tmp.sequence) ss_overhang_segs[e.index]= (tmp) ssDNA_index = 0 if overhangs is not None: #CONNECT SS_DNA TO OVERHANGS for index in overhang_ss_edges: #connected if they have the same index! ss = overhang_ss_edges[index] if overhangs is not None: dsseg = overhang_segs[index] ssseg = ss_overhang_segs[index] #the dsDNA faces outwards if overhang_ss_edges[index].out_orientation == 3: overhang_segs[index].connect_end3(ss_overhang_segs[index]) elif overhang_ss_edges[index].out_orientation == 5: overhang_segs[index].connect_end5(ss_overhang_segs[index]) def intersection(lst1, lst2): lst3 = [value for value in lst1 if value in lst2] return lst3 for f in face_data: for con in f.connections: ### See if we have an overhang overhang_here = False if overhangs is not None: vertex_index = intersection(con[0],con[1])[0] face_index = f.index for i in range(len(overhangs)): if (overhangs.iloc[i]['face'] == face_index and overhangs.iloc[i]['overhang'] == vertex_index): overhang_here = True ss_here = overhangs.iloc[i]['ss_extra'] ### if overhang_here: print (f.index) ssDNA_index += 1 c1,c2 = con c1_positive = c1 in segs c2_positive = c2 in segs if SPACERS != 0: if overhang_here: #TODO : TIDAY ALL OF THIS UP! if ss_here == 0: print ('adding overhang here without ss!') if c1_positive: segs[c1].connect_end3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1].end3, type_="terminal_crossover") else: segs[c1[::-1]].connect_start3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1[::-1]].start3, type_="terminal_crossover") if c2_positive: segs[c2].connect_start5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2].start5, type_="terminal_crossover") else: segs[c2[::-1]].connect_end5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") else: # add the connectivity here! print ('adding overhang here with spacers = %s!'%(ss_here,)) print (ss_here) if c1_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c1].end_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) segs[c1].connect_end3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c1[::-1]].start_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) segs[c1[::-1]].connect_start3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) if c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = overhang_segs[vertex_index].end_position , end_position = segs[c2].start_position, num_nt = ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c2[::-1]].end_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) else: r1 = np.random.rand(1)[0] - 0.5 r2 = np.random.rand(1)[0] - 0.5 if c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position + r1, end_position = segs[c2].start_position + r2, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2].connect_start5(ss) elif c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position + r1, end_position = segs[c2[::-1]].end_position + r2, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2[::-1]].connect_end5(ss) elif not c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position +r1, end_position = segs[c2].start_position + r2, num_nt = SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2].connect_start5(ss) elif not c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position +r1 , end_position = segs[c2[::-1]].end_position + r2, num_nt = SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) else: #let's also add connectivity to the appropriate overhang... if overhang_here: #TODO: need to add additional spacers here! if ss_here == 0: if c1_positive: segs[c1].connect_end3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1].end3, type_="terminal_crossover") else: segs[c1[::-1]].connect_start3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1[::-1]].start3, type_="terminal_crossover") if c2_positive: segs[c2].connect_start5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2].start5, type_="terminal_crossover") else: segs[c2[::-1]].connect_end5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") else: if c1_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c1].end_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) segs[c1].connect_end3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c1[::-1]].start_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) segs[c1[::-1]].connect_start3(ss) overhang_segs[vertex_index].connect_start5(ss) single_stranded_dna.append(ss) if c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = overhang_segs[vertex_index].end_position , end_position = segs[c2].start_position, num_nt = ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2].connect_start5(ss) single_stranded_dna.append(ss) else: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(np.random.randint(0,high = int(1e10)),), start_position = segs[c2[::-1]].end_position , end_position = overhang_segs[vertex_index].start_position, num_nt = ss_here)) overhang_segs[vertex_index].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) if not overhang_here: if c1_positive and c2_positive: segs[c1].connect_end3(segs[c2].start5, type_="terminal_crossover") elif c1_positive and not c2_positive: segs[c1].connect_end3(segs[c2[::-1]].end5, type_="terminal_crossover") elif not c1_positive and c2_positive: segs[c1[::-1]].connect_start3(segs[c2].start5, type_="terminal_crossover") elif not c1_positive and not c2_positive: segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") #NICKS #TODO: just have nicks on non-overhang sides!!! #the list of faces which correspond to overhangs should be accessible no? no_nick_faces = [] if type(overhangs) != type(None): #if overhangs != None: no_nick_faces = list(overhangs['face']) if nicks: print ("adding nicks!") for f in face_data: nick = f.nick if ((nick in segs) and (f.index not in no_nick_faces)): segs[nick].add_nick(10,on_fwd_strand=True) else: print ('failure') #make sure that all the ssDNA has the sequence 'TTT...' for s in single_stranded_dna: s.sequence = s.num_nt * 'T' if overhangs is not None: segs_list = [segs[i] for i in segs] + single_stranded_dna + [overhang_segs[i] for i in overhang_segs] + [ss_overhang_segs[i] for i in ss_overhang_segs] else: segs_list = [segs[i] for i in segs] + single_stranded_dna return segs_list
def get_segments(FNAME, LENGTH_OF_SMALLEST, SPACERS): locs,faces = read_ply(FNAME) mentioned_edges = set() face_data = [face(i) for i in faces] for i in face_data: for e in i.e: if e not in mentioned_edges and e[::-1] not in mentioned_edges: i.ori.append(1) mentioned_edges.add(e) else: i.ori.append(-1) edges = [] for i in mentioned_edges: edges.append( edge(i,locs[i[0]],locs[i[1]]) ) min_length = np.min([x.rawlen for x in edges]) max_length = np.max([x.rawlen for x in edges]) for i in edges: i.normalize(min_length,LENGTH_OF_SMALLEST) single_stranded_dna = [] segs = {} for index, e in enumerate(edges): segs[tuple(e.index)] = ( mrdna.DoubleStrandedSegment(name = 'helix%s'%(index,), num_bp = e.nBp, start_position = e.nStart_c, end_position = e.nStop_c )) ssDNA_index = 0 for f in face_data: for con in f.connections: ssDNA_index += 1 c1,c2 = con c1_positive = c1 in segs c2_positive = c2 in segs if c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position , end_position = segs[c2].start_position, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2].connect_start5(ss) elif c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position , end_position = segs[c2[::-1]].end_position, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2[::-1]].connect_end5(ss) elif not c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position , end_position = segs[c2].start_position, num_nt = SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2].connect_start5(ss) elif not c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position , end_position = segs[c2[::-1]].end_position, num_nt = SPACERS)) #segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5) segs[c1[::-1]].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) ''' if c1_positive and c2_positive: segs[c1].connect_end3(segs[c2].start5) elif c1_positive and not c2_positive: segs[c1].connect_end3(segs[c2[::-1]].end5) elif not c1_positive and c2_positive: segs[c1[::-1]].connect_start3(segs[c2].start5) elif not c1_positive and not c2_positive: segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5) else: print ('ohfuck') ''' #todo: add terminal crossovers to allow 0 free ssDNA. segs_list = [segs[i] for i in segs] + single_stranded_dna return segs_list
def get_segments(FNAME, LENGTH_OF_SMALLEST, SPACERS,overhangs = None): locs,faces = read_ply(FNAME) mentioned_edges = set() face_data = [] for index,i in enumerate(faces): print (FACE) face_data.append(FACE(i,index)) #NICKS #now we work out where the nicks are so we can choose the correct orientation of our strands. assign_nicks(face_data) nick_locs = [] for f in face_data: nick_locs.append(f.nick) mentioned_edges = set(nick_locs) #NICKS #choose orientation for i in face_data: for e in i.e: if e not in mentioned_edges and e[::-1] not in mentioned_edges: i.ori.append(1) mentioned_edges.add(e) else: i.ori.append(-1) edges = [] for i in mentioned_edges: edges.append( edge(i,locs[i[0]],locs[i[1]]) ) min_length = np.min([x.rawlen for x in edges]) max_length = np.max([x.rawlen for x in edges]) #ds overhangs #rework this data structure... if overhangs is not None: overhang_ds_edges = [] overhang_ss_edges = [] for i in range(len(overhangs)): vertex = overhangs.iloc[i]['overhang'] vertex_location = locs[vertex] ##ds overhangs bp = overhangs.iloc[i]['ds_length'] length = bp * min_length / float(LENGTH_OF_SMALLEST) / 3.4 end = length * np.array(vertex_location) / np.sqrt(np.sum(np.array(vertex_location)**2)) + np.array(vertex_location) overhang_ds_edges.append(edge(vertex,vertex_location,end,overhang=True,bp_overhang=bp)) #ss overhangs bp_ss = overhangs.iloc[i]['ss_length'] length_ss = bp_ss * min_length / float(LENGTH_OF_SMALLEST) / 3.4 start_ss = end end_ss = end + length_ss * np.array(vertex_location) / np.sqrt(np.sum(np.array(vertex_location)**2)) overhang_ss_edges.append(edge(vertex,start_ss,end_ss,overhang=True,bp_overhang=bp_ss,out_orientation=overhangs.iloc[i]['out_side'])) for i in edges + overhang_ds_edges + overhang_ss_edges: i.normalize(min_length,LENGTH_OF_SMALLEST) else: for i in edges: i.normalize(min_length,LENGTH_OF_SMALLEST) single_stranded_dna = [] segs = {} for index, e in enumerate(edges): segs[tuple(e.index)] = ( mrdna.DoubleStrandedSegment(name = 'helix%s'%(index,), num_bp = e.nBp, start_position = e.nStart_c, end_position = e.nStop_c )) if overhangs is not None: #overhangs overhang_segs = {} for index, e in enumerate(overhang_ds_edges): tmp = copy((mrdna.DoubleStrandedSegment(name = 'helix%s'%(index+100,), num_bp = int(e.nBp), start_position = list(e.nStart_c), end_position = list(e.nStop_c) ))) overhang_segs[e.index] = tmp #overhangs ss_overhang_segs = {} for index, e in enumerate(overhang_ss_edges): if e.out_orientation == 5: tmp = copy((mrdna.SingleStrandedSegment(name = 'helix%s'%(index+200,), num_nt = int(e.nBp), start_position = list(e.nStart_c), end_position = list(e.nStop_c) ))) elif e.out_orientation == 3: tmp = copy((mrdna.SingleStrandedSegment(name = 'helix%s'%(index,), num_nt = int(e.nBp), start_position = list(e.nStop_c), end_position = list(e.nStart_c), ))) else: print ('BUG') ss_overhang_segs[e.index]= (tmp) ssDNA_index = 0 if overhangs is not None: #CONNECT SS_DNA TO OVERHANGS for ss in overhang_ss_edges: #connected if they have the same index! index = ss.index if overhangs is not None: dsseg = overhang_segs[index] ssseg = ss_overhang_segs[index] #the dsDNA faces outwards if overhang_ss_edges[index].out_orientation == 3: overhang_segs[index].connect_end3(ss_overhang_segs[index]) elif overhang_ss_edges[index].out_orientation == 5: overhang_segs[index].connect_end5(ss_overhang_segs[index]) def intersection(lst1, lst2): lst3 = [value for value in lst1 if value in lst2] return lst3 for f in face_data: for con in f.connections: ### See if we have an overhang overhang_here = False if overhangs is not None: vertex_index = intersection(con[0],con[1])[0] face_index = f.index for i in range(len(overhangs)): if (overhangs.iloc[i]['face'] == face_index and overhangs.iloc[i]['overhang'] == vertex_index): overhang_here = True ### if overhang_here: print (f.index) #but obviously there isn't only one overhang? ssDNA_index += 1 c1,c2 = con c1_positive = c1 in segs c2_positive = c2 in segs if SPACERS != 0: if overhang_here: print ('adding overhang here!') if c1_positive: segs[c1].connect_end3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1].end3, type_="terminal_crossover") else: segs[c1[::-1]].connect_start3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1[::-1]].start3, type_="terminal_crossover") if c2_positive: segs[c2].connect_start5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2].start5, type_="terminal_crossover") else: segs[c2[::-1]].connect_end5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") else: if c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position , end_position = segs[c2].start_position, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2].connect_start5(ss) elif c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1].end_position , end_position = segs[c2[::-1]].end_position, num_nt = SPACERS)) segs[c1].connect_end3(ss) segs[c2[::-1]].connect_end5(ss) elif not c1_positive and c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position , end_position = segs[c2].start_position, num_nt = SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2].connect_start5(ss) elif not c1_positive and not c2_positive: ss = copy(mrdna.SingleStrandedSegment("strand%s"%(ssDNA_index,), start_position = segs[c1[::-1]].start_position , end_position = segs[c2[::-1]].end_position, num_nt = SPACERS)) #segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5) segs[c1[::-1]].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) else: #let's also add connectivity to the appropriate overhang... if overhang_here: if c1_positive: segs[c1].connect_end3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1].end3, type_="terminal_crossover") else: segs[c1[::-1]].connect_start3(overhang_segs[vertex_index].start5, type_="terminal_crossover") overhang_segs[vertex_index].connect_start5(segs[c1[::-1]].start3, type_="terminal_crossover") if c2_positive: segs[c2].connect_start5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2].start5, type_="terminal_crossover") else: segs[c2[::-1]].connect_end5(overhang_segs[vertex_index].start3, type_="terminal_crossover") overhang_segs[vertex_index].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") if not overhang_here: if c1_positive and c2_positive: segs[c1].connect_end3(segs[c2].start5, type_="terminal_crossover") elif c1_positive and not c2_positive: segs[c1].connect_end3(segs[c2[::-1]].end5, type_="terminal_crossover") elif not c1_positive and c2_positive: segs[c1[::-1]].connect_start3(segs[c2].start5, type_="terminal_crossover") elif not c1_positive and not c2_positive: segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") #NICKS nicks = False if nicks == True: for f in face_data: nick = f.nick if nick in segs: segs[nick].add_nick(10,on_fwd_strand=True) else: print ('failure') if overhangs is not None: segs_list = [segs[i] for i in segs] + single_stranded_dna + [overhang_segs[i] for i in overhang_segs] + [ss_overhang_segs[i] for i in ss_overhang_segs] else: segs_list = [segs[i] for i in segs] + single_stranded_dna return segs_list
def get_segments(FNAME, LENGTH_OF_SMALLEST, SPACERS): locs, faces = read_ply(FNAME) mentioned_edges = set() face_data = [face(i) for i in faces] #NICKS #now we work out where the nicks are so we can choose the correct orientation of our strands. assign_nicks(face_data) nick_locs = [] for f in face_data: nick_locs.append(f.nick) mentioned_edges = set(nick_locs) #NICKS for i in face_data: for e in i.e: if e not in mentioned_edges and e[::-1] not in mentioned_edges: i.ori.append(1) mentioned_edges.add(e) else: i.ori.append(-1) edges = [] for i in mentioned_edges: edges.append(edge(i, locs[i[0]], locs[i[1]])) min_length = np.min([x.rawlen for x in edges]) max_length = np.max([x.rawlen for x in edges]) for i in edges: i.normalize(min_length, LENGTH_OF_SMALLEST) single_stranded_dna = [] segs = {} for index, e in enumerate(edges): segs[tuple(e.index)] = (mrdna.DoubleStrandedSegment( name='helix%s' % (index, ), num_bp=e.nBp, start_position=e.nStart_c, end_position=e.nStop_c)) ssDNA_index = 0 for f in face_data: for con in f.connections: ssDNA_index += 1 c1, c2 = con c1_positive = c1 in segs c2_positive = c2 in segs if SPACERS != 0: if c1_positive and c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1].end_position, end_position=segs[c2].start_position, num_nt=SPACERS)) segs[c1].connect_end3(ss) segs[c2].connect_start5(ss) elif c1_positive and not c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1].end_position, end_position=segs[c2[::-1]].end_position, num_nt=SPACERS)) segs[c1].connect_end3(ss) segs[c2[::-1]].connect_end5(ss) elif not c1_positive and c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1[::-1]].start_position, end_position=segs[c2].start_position, num_nt=SPACERS)) segs[c1[::-1]].connect_start3(ss) segs[c2].connect_start5(ss) elif not c1_positive and not c2_positive: ss = copy( mrdna.SingleStrandedSegment( "strand%s" % (ssDNA_index, ), start_position=segs[c1[::-1]].start_position, end_position=segs[c2[::-1]].end_position, num_nt=SPACERS)) #segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5) segs[c1[::-1]].connect_start3(ss) segs[c2[::-1]].connect_end5(ss) single_stranded_dna.append(ss) else: if c1_positive and c2_positive: segs[c1].connect_end3(segs[c2].start5, type_="terminal_crossover") elif c1_positive and not c2_positive: segs[c1].connect_end3(segs[c2[::-1]].end5, type_="terminal_crossover") elif not c1_positive and c2_positive: segs[c1[::-1]].connect_start3(segs[c2].start5, type_="terminal_crossover") elif not c1_positive and not c2_positive: segs[c1[::-1]].connect_start3(segs[c2[::-1]].end5, type_="terminal_crossover") #NICKS for f in face_data: nick = f.nick if nick in segs: segs[nick].add_nick(5, on_fwd_strand=True) else: print('failure') # segs_list = [segs[i] for i in segs] + single_stranded_dna return segs_list