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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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