def autoScafMidSeam(self, strands): """docstring for autoScafMidSeam""" part = self.part() strand_type = StrandType.SCAFFOLD idx = part.activeBaseIndex() for i in range(1, len(strands)): row1, col1, ss_idx1 = strands[i - 1] # previous strand row2, col2, ss_idx2 = strands[i] # current strand vh1 = part.virtualHelixAtCoord((row1, col1)) vh2 = part.virtualHelixAtCoord((row2, col2)) strand1 = vh1.scaffoldStrandSet()._strand_list[ss_idx1] strand2 = vh2.scaffoldStrandSet()._strand_list[ss_idx2] # determine if the pair of strands are neighbors neighbors = part.getVirtualHelixNeighbors(vh1) if vh2 in neighbors: p2 = neighbors.index(vh2) if vh2.number() % 2 == 1: # resize and install external xovers try: # resize to the nearest prexover on either side of idx new_lo = util.nearest(idx, part.getPreXoversHigh(strand_type, p2, max_idx=idx - 10)) new_hi = util.nearest(idx, part.getPreXoversLow(strand_type, p2, min_idx=idx + 10)) if strand1.canResizeTo(new_lo, new_hi) and \ strand2.canResizeTo(new_lo, new_hi): # do the resize strand1.resize((new_lo, new_hi)) strand2.resize((new_lo, new_hi)) # install xovers part.createXover(strand1, new_hi, strand2, new_hi) part.createXover(strand2, new_lo, strand1, new_lo) except ValueError: pass # nearest not found in the expanded list # go back an install the internal xovers if i > 2: row0, col0, ss_idx0 = strands[i - 2] # two strands back vh0 = part.virtualHelixAtCoord((row0, col0)) strand0 = vh0.scaffoldStrandSet()._strand_list[ss_idx0] if vh0 in neighbors: p0 = neighbors.index(vh0) l0, h0 = strand0.idxs() l1, h1 = strand1.idxs() o_low, o_high = util.overlap(l0, h0, l1, h1) try: l_list = list(filter(lambda x: x > o_low and \ x < o_high, part.getPreXoversLow(strand_type, p0))) l_x = l_list[len(l_list) // 2] h_list = list(filter(lambda x: x > o_low and \ x < o_high, part.getPreXoversHigh(strand_type, p0))) h_x = h_list[len(h_list) // 2] # install high xover first part.createXover(strand0, h_x, strand1, h_x) # install low xover after getting new strands # following the breaks caused by the high xover strand3 = vh0.scaffoldStrandSet()._strand_list[ss_idx0] strand4 = vh1.scaffoldStrandSet()._strand_list[ss_idx1] part.createXover(strand4, l_x, strand3, l_x) except IndexError: pass # filter was unhappy
def setComplementSequence(self, sequence_string, strand): """ This version takes anothers strand and only sets the indices that align with the given complimentary strand return the used portion of the sequence_string As it depends which direction this is going, and strings are stored in memory left to right, we need to test for is_drawn_5_to_3 to map the reverse compliment appropriately, as we traverse overlapping strands. We reverse the sequence ahead of time if we are applying it 5' to 3', otherwise we reverse the sequence post parsing if it's 3' to 5' Again, sequences are stored as strings in memory 5' to 3' so we need to jump through these hoops to iterate 5' to 3' through them correctly Perhaps it's wiser to merely store them left to right and reverse them at draw time, or export time """ s_low_idx, s_high_idx = self._base_idx_low, self._base_idx_high c_low_idx, c_high_idx = strand.idxs() # get the ovelap low_idx, high_idx = util.overlap(s_low_idx, s_high_idx, c_low_idx, c_high_idx) # only get the characters we're using, while we're at it, make it the # reverse compliment total_length = self.totalLength() # see if we are applying if sequence_string == None: # clear out string for in case of not total overlap use_seq = ''.join([' ' for x in range(total_length)]) else: # use the string as is use_seq = sequence_string[::-1] if self._is_drawn_5_to_3 \ else sequence_string temp = array(array_type, sixb(use_seq)) if self._sequence == None: temp_self = array(array_type, sixb(''.join([' ' for x in range(total_length)]))) else: temp_self = array(array_type, sixb(self._sequence) if self._is_drawn_5_to_3 \ else sixb(self._sequence[::-1])) # generate the index into the compliment string a = self.insertionLengthBetweenIdxs(s_low_idx, low_idx - 1) b = self.insertionLengthBetweenIdxs(low_idx, high_idx) c = strand.insertionLengthBetweenIdxs(c_low_idx, low_idx - 1) start = low_idx - c_low_idx + c end = start + b + high_idx - low_idx + 1 temp_self[low_idx - s_low_idx + a:high_idx - s_low_idx + 1 + a + b] = \ temp[start:end] # print "old sequence", self._sequence self._sequence = tostring(temp_self) # if we need to reverse it do it now if not self._is_drawn_5_to_3: self._sequence = self._sequence[::-1] # test to see if the string is empty(), annoyingly expensive if len(self._sequence.strip()) == 0: self._sequence = None # print "new sequence", self._sequence return self._sequence
def setComplementSequence(self, sequence_string, strand): """This version takes anothers strand and only sets the indices that align with the given complimentary strand. As it depends which direction this is going, and strings are stored in memory left to right, we need to test for is_forward to map the reverse compliment appropriately, as we traverse overlapping strands. We reverse the sequence ahead of time if we are applying it 5' to 3', otherwise we reverse the sequence post parsing if it's 3' to 5' Again, sequences are stored as strings in memory 5' to 3' so we need to jump through these hoops to iterate 5' to 3' through them correctly Perhaps it's wiser to merely store them left to right and reverse them at draw time, or export time Args: sequence_string (str): strand (Strand): Returns: str: the used portion of the sequence_string """ s_low_idx, s_high_idx = self._base_idx_low, self._base_idx_high c_low_idx, c_high_idx = strand.idxs() is_forward = self._is_forward self_seq = self._sequence # get the ovelap low_idx, high_idx = util.overlap(s_low_idx, s_high_idx, c_low_idx, c_high_idx) # only get the characters we're using, while we're at it, make it the # reverse compliment total_length = self.totalLength() # see if we are applying if sequence_string is None: # clear out string for in case of not total overlap use_seq = ''.join([' ' for x in range(total_length)]) else: # use the string as is use_seq = sequence_string[::-1] if is_forward else sequence_string temp = array(ARRAY_TYPE, sixb(use_seq)) if self_seq is None: temp_self = array( ARRAY_TYPE, sixb(''.join([' ' for x in range(total_length)]))) else: temp_self = array( ARRAY_TYPE, sixb(self_seq) if is_forward else sixb(self_seq[::-1])) # generate the index into the compliment string a = self.insertionLengthBetweenIdxs(s_low_idx, low_idx - 1) b = self.insertionLengthBetweenIdxs(low_idx, high_idx) c = strand.insertionLengthBetweenIdxs(c_low_idx, low_idx - 1) start = low_idx - c_low_idx + c end = start + b + high_idx - low_idx + 1 temp_self[low_idx - s_low_idx + a:high_idx - s_low_idx + 1 + a + b] = temp[start:end] # print("old sequence", self_seq) self._sequence = tostring(temp_self) # if we need to reverse it do it now if not is_forward: self._sequence = self._sequence[::-1] # test to see if the string is empty(), annoyingly expensive # if len(self._sequence.strip()) == 0: if not self._sequence: self._sequence = None # print("new sequence", self._sequence) return self._sequence
def autoScafMidSeam(self, strands): """docstring for autoScafMidSeam""" part = self.part() strand_type = StrandType.SCAFFOLD idx = part.activeBaseIndex() for i in range(1, len(strands)): row1, col1, ss_idx1 = strands[i - 1] # previous strand row2, col2, ss_idx2 = strands[i] # current strand vh1 = part.virtualHelixAtCoord((row1, col1)) vh2 = part.virtualHelixAtCoord((row2, col2)) strand1 = vh1.scaffoldStrandSet()._strand_list[ss_idx1] strand2 = vh2.scaffoldStrandSet()._strand_list[ss_idx2] # determine if the pair of strands are neighbors neighbors = part.getVirtualHelixNeighbors(vh1) if vh2 in neighbors: p2 = neighbors.index(vh2) if vh2.number() % 2 == 1: # resize and install external xovers try: # resize to the nearest prexover on either side of idx new_lo = util.nearest( idx, part.getPreXoversHigh(strand_type, p2, max_idx=idx - 10)) new_hi = util.nearest( idx, part.getPreXoversLow(strand_type, p2, min_idx=idx + 10)) if strand1.canResizeTo(new_lo, new_hi) and \ strand2.canResizeTo(new_lo, new_hi): # do the resize strand1.resize((new_lo, new_hi)) strand2.resize((new_lo, new_hi)) # install xovers part.createXover(strand1, new_hi, strand2, new_hi) part.createXover(strand2, new_lo, strand1, new_lo) except ValueError: pass # nearest not found in the expanded list # go back an install the internal xovers if i > 2: row0, col0, ss_idx0 = strands[i - 2] # two strands back vh0 = part.virtualHelixAtCoord((row0, col0)) strand0 = vh0.scaffoldStrandSet()._strand_list[ss_idx0] if vh0 in neighbors: p0 = neighbors.index(vh0) l0, h0 = strand0.idxs() l1, h1 = strand1.idxs() o_low, o_high = util.overlap(l0, h0, l1, h1) try: l_list = list(filter(lambda x: x > o_low and \ x < o_high, part.getPreXoversLow(strand_type, p0))) l_x = l_list[len(l_list) // 2] h_list = list(filter(lambda x: x > o_low and \ x < o_high, part.getPreXoversHigh(strand_type, p0))) h_x = h_list[len(h_list) // 2] # install high xover first part.createXover(strand0, h_x, strand1, h_x) # install low xover after getting new strands # following the breaks caused by the high xover strand3 = vh0.scaffoldStrandSet( )._strand_list[ss_idx0] strand4 = vh1.scaffoldStrandSet( )._strand_list[ss_idx1] part.createXover(strand4, l_x, strand3, l_x) except IndexError: pass # filter was unhappy