Beispiel #1
0
    def strandCanBeSplit(self, strand: StrandT, base_idx: int) -> bool:
        """Make sure the base index is within the strand
        Don't split right next to a 3Prime end
        Don't split on endpoint (AKA a crossover)

        Args:
            strand: the :class:`Strand`
            base_idx: the index to split at

        Returns:
            ``True`` if can be split, ``False`` otherwise
        """
        # no endpoints
        lo, hi = strand.idxs()
        if base_idx == lo or base_idx == hi:
            return False
        # make sure the base index within the strand
        elif lo > base_idx or base_idx > hi:
            return False
        elif self._is_fwd:
            if base_idx - lo > 0 and hi - base_idx > 1:
                return True
            else:
                return False
        elif base_idx - lo > 1 and hi - base_idx > 0:  # reverse
            return True
        else:
            return False
Beispiel #2
0
    def strandCanBeSplit(self, strand: StrandT, base_idx: int) -> bool:
        """Make sure the base index is within the strand
        Don't split right next to a 3Prime end
        Don't split on endpoint (AKA a crossover)

        Args:
            strand: the :class:`Strand`
            base_idx: the index to split at

        Returns:
            ``True`` if can be split, ``False`` otherwise
        """
        # no endpoints
        lo, hi = strand.idxs()
        if base_idx == lo or base_idx == hi:
            return False
        # make sure the base index within the strand
        elif lo > base_idx or base_idx > hi:
            return False
        elif self._is_fwd:
            if base_idx - lo > 0 and hi - base_idx > 1:
                return True
            else:
                return False
        elif base_idx - lo > 1 and hi - base_idx > 0:  # reverse
            return True
        else:
            return False
Beispiel #3
0
    def _addToStrandList(self, strand: StrandT, update_segments: bool = True):
        """Inserts strand into the strand_array at idx

        Args:
            strand: the strand to add
            update_segments (optional): whether to signal default=``True``
        """
        idx_low, idx_high = strand.idxs()
        for i in range(idx_low, idx_high + 1):
            self.strand_array[i] = strand
        insort_left(self.strand_heap, strand)
        if update_segments:
            self._part.refreshSegments(self._id_num)
Beispiel #4
0
    def _addToStrandList(self, strand: StrandT, update_segments: bool = True):
        """Inserts strand into the strand_array at idx

        Args:
            strand: the strand to add
            update_segments (optional): whether to signal default=``True``
        """
        idx_low, idx_high = strand.idxs()
        for i in range(idx_low, idx_high+1):
            self.strand_array[i] = strand
        insort_left(self.strand_heap, strand)
        if update_segments:
            self._part.refreshSegments(self._id_num)
Beispiel #5
0
    def _removeFromStrandList(self, strand: StrandT, update_segments: bool = True):
        """Remove strand from strand_array.

        Args:
            strand: the strand
            update_segments (optional): whether to signal default=``True``
        """
        self._document.removeStrandFromSelection(strand)  # make sure the strand is no longer selected
        idx_low, idx_high = strand.idxs()
        for i in range(idx_low, idx_high + 1):
            self.strand_array[i] = None
        i = bisect_left(self.strand_heap, strand)
        self.strand_heap.pop(i)
        if update_segments:
            self._part.refreshSegments(self._id_num)
Beispiel #6
0
    def _removeFromStrandList(self, strand: StrandT, update_segments: bool = True):
        """Remove strand from strand_array.

        Args:
            strand: the strand
            update_segments (optional): whether to signal default=``True``
        """
        self._document.removeStrandFromSelection(strand)  # make sure the strand is no longer selected
        idx_low, idx_high = strand.idxs()
        for i in range(idx_low, idx_high + 1):
            self.strand_array[i] = None
        i = bisect_left(self.strand_heap, strand)
        self.strand_heap.pop(i)
        if update_segments:
            self._part.refreshSegments(self._id_num)
Beispiel #7
0
    def strandModsRemovedSlot(self, strand: StrandT, document: DocT,
                              mod_id: str, idx: int):
        """Slot for removing a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        idx_l, idx_h = strand.idxs()
        # color = document.getModProperties(mod_id)['color']
        if idx == idx_h:
            self._high_cap.destroyMod()
        else:
            self._low_cap.destroyMod()
Beispiel #8
0
    def strandModsChangedSlot(self, strand: StrandT, document: DocT,
                              mod_id: str, idx: int):
        """Slot for changing a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        idx_l, idx_h = strand.idxs()
        color = document.getModProperties(mod_id)['color']
        if idx == idx_h:
            self._high_cap.changeMod(mod_id, color)
        else:
            self._low_cap.changeMod(mod_id, color)
Beispiel #9
0
    def strandModsAddedSlot(self, strand: StrandT, document: DocT, mod_id: str,
                            idx: int):
        """Slot for adding a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        if self._viewroot.are_signals_on:
            idx_l, idx_h = strand.idxs()
            color = document.getModProperties(mod_id)['color']
            if idx == idx_h:
                self._high_cap.showMod(mod_id, color)
            else:
                self._low_cap.showMod(mod_id, color)
Beispiel #10
0
    def strandModsRemovedSlot(self, strand: StrandT,
                                document: DocT,
                                mod_id: str,
                                idx: int):
        """Slot for removing a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        idx_l, idx_h = strand.idxs()
        # color = document.getModProperties(mod_id)['color']
        if idx == idx_h:
            self._high_cap.destroyMod()
        else:
            self._low_cap.destroyMod()
Beispiel #11
0
    def strandModsChangedSlot(self, strand: StrandT,
                                document: DocT,
                                mod_id: str,
                                idx: int):
        """Slot for changing a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        idx_l, idx_h = strand.idxs()
        color = document.getModProperties(mod_id)['color']
        if idx == idx_h:
            self._high_cap.changeMod(mod_id, color)
        else:
            self._low_cap.changeMod(mod_id, color)
Beispiel #12
0
    def strandModsAddedSlot(self, strand: StrandT,
                                document: DocT,
                                mod_id: str,
                                idx: int):
        """Slot for adding a modification on the Strand

        Args:
            strand:
            document:
            mod_id:
            idx:
        """
        if self._viewroot.are_signals_on:
            idx_l, idx_h = strand.idxs()
            color = document.getModProperties(mod_id)['color']
            if idx == idx_h:
                self._high_cap.showMod(mod_id, color)
            else:
                self._low_cap.showMod(mod_id, color)
Beispiel #13
0
    def __init__(self, strand: StrandT,
                        new_idxs: SegmentT,
                        update_segments: bool = True):
        super(ResizeCommand, self).__init__("resize strand")
        self.strand = strand
        self.old_indices = o_i = strand.idxs()
        self.new_idxs = new_idxs
        # an increase in length leads to positive delta
        self.delta = (new_idxs[1] - new_idxs[0]) - (o_i[1] - o_i[0])
        # now handle insertion deltas
        oldInsertions = strand.insertionsOnStrand(*o_i)
        newInsertions = strand.insertionsOnStrand(*new_idxs)
        o_l = 0
        for i in oldInsertions:
            o_l += i.length()
        n_l = 0
        for i in newInsertions:
            n_l += i.length()
        self.delta += (n_l - o_l)

        self.update_segments = update_segments
Beispiel #14
0
    def __init__(self,
                 strand: StrandT,
                 new_idxs: SegmentT,
                 update_segments: bool = True):
        super(ResizeCommand, self).__init__("resize strand")
        self.strand = strand
        self.old_indices = o_i = strand.idxs()
        self.new_idxs = new_idxs
        # an increase in length leads to positive delta
        self.delta = (new_idxs[1] - new_idxs[0]) - (o_i[1] - o_i[0])
        # now handle insertion deltas
        oldInsertions = strand.insertionsOnStrand(*o_i)
        newInsertions = strand.insertionsOnStrand(*new_idxs)
        o_l = 0
        for i in oldInsertions:
            o_l += i.length()
        n_l = 0
        for i in newInsertions:
            n_l += i.length()
        self.delta += (n_l - o_l)

        self.update_segments = update_segments
Beispiel #15
0
    def setComplementSequence(self, sequence: str, strand: StrandT) -> str:
        """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 (str):
            strand (Strand):

        Returns:
            str: the used portion of the sequence
        """
        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 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[::-1] if is_forward else sequence

        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