def __init__(self, strand_low: Strand, strand_high: Strand, priority_strand: Strand): super(MergeCommand, self).__init__("merge strands") # Store strands self._strand_low = strand_low self._strand_high = strand_high self._s_set = s_set = priority_strand.strandSet() # Store oligos self._new_oligo = priority_strand.oligo().shallowCopy() self._s_low_oligo = s_low_olg = strand_low.oligo() self._s_high_oligo = s_high_olg = strand_high.oligo() # self._s_set_idx = low_strandset_idx # update the new oligo length if it's not a loop if s_low_olg != s_high_olg: self._new_oligo._setLength(s_low_olg.length() + s_high_olg.length(), emit_signals=True) # Create the new_strand by copying the priority strand to # preserve its properties new_idxs = strand_low.lowIdx(), strand_high.highIdx() new_strand = strand_low.shallowCopy() new_strand.setIdxs(new_idxs) new_strand.setConnectionHigh(strand_high.connectionHigh()) self._new_strand = new_strand # Update the oligo for things like its 5prime end and isCircular self._new_oligo._strandMergeUpdate(strand_low, strand_high, new_strand) # set the new sequence by concatenating the sequence properly if strand_low._sequence or strand_high._sequence: tL = strand_low.totalLength() tH = strand_high.totalLength() seqL = strand_low._sequence if strand_low._sequence else "".join( [" " for i in range(tL)]) seqH = strand_high._sequence if strand_high._sequence else "".join( [" " for i in range(tH)]) if new_strand.isForward(): new_strand._sequence = seqL + seqH else: new_strand._sequence = seqH + seqL
class CreateStrandCommand(UndoCommand): """ Create a new Strand based with bounds (base_idx_low, base_idx_high), and insert it into the strandset at position strandset_idx. Also, create a new Oligo, add it to the Part, and point the new Strand at the oligo. """ def __init__(self, strandset, base_idx_low, base_idx_high, strandset_idx): super(CreateStrandCommand, self).__init__("create strand") self._strandset = strandset self._s_set_idx = strandset_idx doc = strandset.document() self._strand = Strand(strandset, base_idx_low, base_idx_high) colorList = prefs.STAP_COLORS if strandset.isStaple() else prefs.SCAF_COLORS color = random.choice(colorList).name() self._new_oligo = Oligo(None, color) # redo will set part self._new_oligo.setLength(self._strand.totalLength()) # end def def redo(self): # Add the new strand to the StrandSet strand_list strand = self._strand strandset = self._strandset strandset._strand_list.insert(self._s_set_idx, strand) # Set up the new oligo oligo = self._new_oligo oligo.setStrand5p(strand) oligo.addToPart(strandset.part()) strand.setOligo(oligo) if strandset.isStaple(): strand.reapplySequence() # Emit a signal to notify on completion strandset.strandsetStrandAddedSignal.emit(strandset, strand) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.virtualHelix()) # end def def undo(self): # Remove the strand from StrandSet strand_list and selectionList strand = self._strand strandset = self._strandset strandset._doc.removeStrandFromSelection(strand) strandset._strand_list.pop(self._s_set_idx) # Get rid of the new oligo oligo = self._new_oligo oligo.setStrand5p(None) oligo.removeFromPart() # Emit a signal to notify on completion strand.strandRemovedSignal.emit(strand) strand.setOligo(None) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.virtualHelix()) # end def # end class
def __init__(self, strand_low: Strand, strand_high: Strand, priority_strand: Strand): super(MergeCommand, self).__init__("merge strands") # Store strands self._strand_low = strand_low self._strand_high = strand_high self._s_set = s_set = priority_strand.strandSet() # Store oligos self._new_oligo = priority_strand.oligo().shallowCopy() self._s_low_oligo = s_low_olg = strand_low.oligo() self._s_high_oligo = s_high_olg = strand_high.oligo() # self._s_set_idx = low_strandset_idx # update the new oligo length if it's not a loop if s_low_olg != s_high_olg: self._new_oligo._setLength(s_low_olg.length() + s_high_olg.length(), emit_signals=True) # Create the new_strand by copying the priority strand to # preserve its properties new_idxs = strand_low.lowIdx(), strand_high.highIdx() new_strand = strand_low.shallowCopy() new_strand.setIdxs(new_idxs) new_strand.setConnectionHigh(strand_high.connectionHigh()) self._new_strand = new_strand # Update the oligo for things like its 5prime end and isCircular self._new_oligo._strandMergeUpdate(strand_low, strand_high, new_strand) # set the new sequence by concatenating the sequence properly if strand_low._sequence or strand_high._sequence: tL = strand_low.totalLength() tH = strand_high.totalLength() seqL = strand_low._sequence if strand_low._sequence else "".join([" " for i in range(tL)]) seqH = strand_high._sequence if strand_high._sequence else "".join([" " for i in range(tH)]) if new_strand.isForward(): new_strand._sequence = seqL + seqH else: new_strand._sequence = seqH + seqL
class CreateStrandCommand(UndoCommand): """Create a new `Strand` based with bounds (base_idx_low, base_idx_high), and insert it into the strandset at position strandset_idx. Also, create a new Oligo, add it to the Part, and point the new Strand at the oligo. `Strand` explicitly do not create `Oligo` as do to the 1 to many nature of Oligos """ def __init__(self, strandset, base_idx_low, base_idx_high, color, update_segments=True): """ TODO: Now that parts have a UUID this could be instantiated via a document, uuid, id_num, is_fwd, base_idx_low, ... instead of an object to be independent of parts keeping strandsets live """ super(CreateStrandCommand, self).__init__("create strand") self._strandset = strandset strandset.document() self._strand = Strand(strandset, base_idx_low, base_idx_high) self._new_oligo = Oligo( None, color, length=self._strand.totalLength()) # redo will set part self.update_segments = update_segments # end def def strand(self): return self._strand # end def def redo(self): # Add the new strand to the StrandSet strand_list strand = self._strand strandset = self._strandset strandset._addToStrandList(strand, self.update_segments) # Set up the new oligo oligo = self._new_oligo oligo.setStrand5p(strand) strand.setOligo(oligo) oligo.addToPart(strandset.part(), emit_signals=True) # strand.reapplySequence() # Emit a signal to notify on completion strandset.strandsetStrandAddedSignal.emit(strandset, strand) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.idNum()) # end def def undo(self): # Remove the strand from StrandSet strand_list and selectionList strand = self._strand strandset = self._strandset strandset._document.removeStrandFromSelection(strand) strandset._removeFromStrandList(strand, self.update_segments) # Get rid of the new oligo oligo = self._new_oligo oligo.setStrand5p(None) oligo.removeFromPart(emit_signals=True) # Emit a signal to notify on completion strand.strandRemovedSignal.emit(strand) strand.setOligo(None) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.idNum())
def __init__(self, strand: Strand, base_idx: int, update_sequence: bool = True): super(SplitCommand, self).__init__("split strand") # Store inputs self._old_strand = strand # TODO possibly implement selection preserving # doc = strand.document() # self.was_selected = was_selected = doc.isModelStrandSelected(strand) # if was_selected: # self.select_values = doc.getSelectedStrandValue(strand) # else: # self.select_values = (None, None) old_sequence = strand._sequence is5to3 = strand.isForward() self._s_set = strand.strandSet() self._old_oligo = oligo = strand.oligo() # Create copies self.strand_low = strand_low = strand.shallowCopy() self.strand_high = strand_high = strand.shallowCopy() if oligo.isCircular(): self._l_oligo = self._h_oligo = l_oligo = h_oligo = oligo.shallowCopy() else: self._l_oligo = l_oligo = oligo.shallowCopy() self._h_oligo = h_oligo = oligo.shallowCopy() color_list = pathstyles.STAP_COLORS # Determine oligo retention based on strand priority if is5to3: # strand_low has priority i_new_low = base_idx color_low = oligo.getColor() color_high = random.choice(color_list) olg5p, olg3p = l_oligo, h_oligo std5p, std3p = strand_low, strand_high else: # strand_high has priority i_new_low = base_idx - 1 color_low = random.choice(color_list) color_high = oligo.getColor() olg5p, olg3p = h_oligo, l_oligo std5p, std3p = strand_high, strand_low # this is for updating a connected xover view object # there is only ever one xover a strand is in charge of self._strand3p = std3p self._strand5p = std5p # Update strand connectivity strand_low.setConnectionHigh(None) strand_high.setConnectionLow(None) # Resize strands and update decorators strand_low.setIdxs((strand.lowIdx(), i_new_low)) strand_high.setIdxs((i_new_low + 1, strand.highIdx())) # Update the oligo for things like its 5prime end and isCircular olg5p._strandSplitUpdate(std5p, std3p, olg3p, strand) if not oligo.isCircular(): # Update the oligo color if necessary l_oligo._setColor(color_low) h_oligo._setColor(color_high) # settle the oligo length length = 0 for strand in std3p.generator3pStrand(): length += strand.totalLength() # end for olg5p._setLength(olg5p.length() - length, emit_signals=True) olg3p._setLength(length, emit_signals=True) # end if if update_sequence and old_sequence: if is5to3: # strand_low has priority tL = strand_low.totalLength() strand_low._sequence = old_sequence[0:tL] strand_high._sequence = old_sequence[tL:] else: tH = strand_high.totalLength() strand_high._sequence = old_sequence[0:tH] strand_low._sequence = old_sequence[tH:]
class CreateStrandCommand(UndoCommand): """ Create a new Strand based with bounds (base_idx_low, base_idx_high), and insert it into the strandset at position strandset_idx. Also, create a new Oligo, add it to the Part, and point the new Strand at the oligo. """ def __init__(self, strandset, base_idx_low, base_idx_high, strandset_idx): super(CreateStrandCommand, self).__init__("create strand") self._strandset = strandset self._s_set_idx = strandset_idx doc = strandset.document() self._strand = Strand(strandset, base_idx_low, base_idx_high) colorList = prefs.STAP_COLORS if strandset.isStaple( ) else prefs.SCAF_COLORS color = random.choice(colorList).name() self._new_oligo = Oligo(None, color) # redo will set part self._new_oligo.setLength(self._strand.totalLength()) # end def def redo(self): # Add the new strand to the StrandSet strand_list strand = self._strand strandset = self._strandset strandset._strand_list.insert(self._s_set_idx, strand) # Set up the new oligo oligo = self._new_oligo oligo.setStrand5p(strand) oligo.addToPart(strandset.part()) strand.setOligo(oligo) if strandset.isStaple(): strand.reapplySequence() # Emit a signal to notify on completion strandset.strandsetStrandAddedSignal.emit(strandset, strand) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.virtualHelix()) # end def def undo(self): # Remove the strand from StrandSet strand_list and selectionList strand = self._strand strandset = self._strandset strandset._doc.removeStrandFromSelection(strand) strandset._strand_list.pop(self._s_set_idx) # Get rid of the new oligo oligo = self._new_oligo oligo.setStrand5p(None) oligo.removeFromPart() # Emit a signal to notify on completion strand.strandRemovedSignal.emit(strand) strand.setOligo(None) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit(strandset.part(), strandset.virtualHelix()) # end def # end class
class CreateStrandCommand(UndoCommand): """Create a new `Strand` based with bounds (base_idx_low, base_idx_high), and insert it into the strandset at position strandset_idx. Also, create a new Oligo, add it to the Part, and point the new Strand at the oligo. `Strand` explicitly do not create `Oligo` as do to the 1 to many nature of Oligos """ def __init__(self, strandset, base_idx_low, base_idx_high, color, update_segments=True): """ TODO: Now that parts have a UUID this could be instantiated via a document, uuid, id_num, is_fwd, base_idx_low, ... instead of an object to be independent of parts keeping strandsets live """ super(CreateStrandCommand, self).__init__("create strand") self._strandset = strandset doc = strandset.document() self._strand = Strand(strandset, base_idx_low, base_idx_high) self._new_oligo = Oligo(None, color, length=self._strand.totalLength()) # redo will set part self.update_segments = update_segments # end def def strand(self): return self._strand # end def def redo(self): # Add the new strand to the StrandSet strand_list strand = self._strand strandset = self._strandset strandset._addToStrandList(strand, self.update_segments) # Set up the new oligo oligo = self._new_oligo oligo.setStrand5p(strand) strand.setOligo(oligo) oligo.addToPart(strandset.part(), emit_signals=True) # strand.reapplySequence() # Emit a signal to notify on completion strandset.strandsetStrandAddedSignal.emit(strandset, strand) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit( strandset.part(), strandset.idNum()) # end def def undo(self): # Remove the strand from StrandSet strand_list and selectionList strand = self._strand strandset = self._strandset strandset._document.removeStrandFromSelection(strand) strandset._removeFromStrandList(strand, self.update_segments) # Get rid of the new oligo oligo = self._new_oligo oligo.setStrand5p(None) oligo.removeFromPart(emit_signals=True) # Emit a signal to notify on completion strand.strandRemovedSignal.emit(strand) strand.setOligo(None) # for updating the Slice View displayed helices strandset.part().partStrandChangedSignal.emit( strandset.part(), strandset.idNum())