def addInsertion(self, idx: int, length: int, use_undostack: bool = True): """Adds an insertion or skip at idx. length should be:: >0 for an insertion -1 for a skip Args: idx (int): length (int): use_undostack (bool): optional, default is True """ cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if not self.hasInsertionAt(idx): # make sure length is -1 if a skip if length < 0: length = -1 if use_undostack: # on import no need to blank sequences cmds.append(self.oligo().applySequenceCMD(None)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None)) cmds.append(AddInsertionCommand(self, idx, length)) util.execCommandList(self, cmds, desc="Add Insertion", use_undostack=use_undostack)
def createStrand(self, base_idx_low, base_idx_high, color=None, use_undostack=True): """Assumes a strand is being created at a valid set of indices. Args: base_idx_low (int): low index of strand base_idx_high (int): high index of strand color (:obj:`str`, optional): default=True use_undostack (:obj:`bool`, optional): default=True Returns: object: Strand if successful, None otherwise """ # print("sss creating strand") part = self._part # NOTE: this color defaulting thing is problematic for tests if color is None: color = part.getProperty('color') bounds_low, bounds_high = self.getBoundsOfEmptyRegionContaining(base_idx_low) if bounds_low is not None and bounds_low <= base_idx_low and \ bounds_high is not None and bounds_high >= base_idx_high: c = CreateStrandCommand(self, base_idx_low, base_idx_high, color, update_segments=use_undostack) x, y = part.getVirtualHelixOrigin(self._id_num) d = "%s:(%0.2f,%0.2f).%d^%d" % (self.part().getName(), x, y, self._is_fwd, base_idx_low) # print("strand", d) util.execCommandList(self, [c], desc=d, use_undostack=use_undostack) return c.strand() else: # print("could not create strand", bounds_low, bounds_high, base_idx_low, base_idx_high) return None
def addInsertion(self, idx, length, use_undostack=True): """Adds an insertion or skip at idx. length should be:: >0 for an insertion -1 for a skip Args: idx (int): length (int): use_undostack (bool): optional, default is True """ cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if not self.hasInsertionAt(idx): # make sure length is -1 if a skip if length < 0: length = -1 if use_undostack: # on import no need to blank sequences cmds.append(self.oligo().applySequenceCMD(None)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None)) cmds.append(AddInsertionCommand(self, idx, length)) util.execCommandList(self, cmds, desc="Add Insertion", use_undostack=use_undostack)
def _addPart(self, part, use_undostack=True): """Add part to the document via AddPartCommand.""" c = self.AddPartCommand(self, part) util.execCommandList(self, [c], desc="Add part", use_undostack=use_undostack) return c.part()
def createStrand(self, base_idx_low: int, base_idx_high: int, color: str = None, use_undostack: bool = True) -> StrandT: """Assumes a strand is being created at a valid set of indices. Args: base_idx_low: low index of strand base_idx_high: high index of strand color (optional): default is ``None`` use_undostack (optional): default is ``True`` Returns: :class:`Strand` if successful, ``None`` otherwise """ part = self._part # NOTE: this color defaulting thing is problematic for tests if color is None: color = part.getProperty('color') bounds_low, bounds_high = self.getBoundsOfEmptyRegionContaining(base_idx_low) if bounds_low is not None and bounds_low <= base_idx_low and \ bounds_high is not None and bounds_high >= base_idx_high: c = CreateStrandCommand(self, base_idx_low, base_idx_high, color, update_segments=use_undostack) x, y = part.getVirtualHelixOrigin(self._id_num) d = "%s:(%0.2f,%0.2f).%d^%d" % (self.part().getName(), x, y, self._is_fwd, base_idx_low) util.execCommandList(self, [c], desc=d, use_undostack=use_undostack) return c.strand() else: return None
def addMods(self, document: DocT, mod_id: str, idx: int, use_undostack: bool = True): """Used to add mods during a merge operation.""" cmds = [] idx_low, idx_high = self.idxs() if idx_low == idx or idx == idx_high: check_mid1 = self.part().getModID(self, idx) check_mid2 = document.getMod(mod_id) print("strand.addMods:", check_mid1, check_mid2) if check_mid2 is not None: if check_mid1 != mod_id: if check_mid1 is not None: cmds.append( RemoveModsCommand(document, self, idx, check_mid1)) # print("adding a {} modification at {}".format(mod_id, idx)) cmds.append(AddModsCommand(document, self, idx, mod_id)) util.execCommandList(self, cmds, desc="Add Modification", use_undostack=use_undostack) else: print(check_mid1, mod_id)
def applyColor(self, color, use_undostack=True): if color == self._color: return # oligo already has color c = ApplyColorCommand(self, color) util.execCommandList(self, [c], desc="Color Oligo", use_undostack=use_undostack)
def createStrand(self, base_idx_low: int, base_idx_high: int, color: str = None, use_undostack: bool = True) -> StrandT: """Assumes a strand is being created at a valid set of indices. Args: base_idx_low: low index of strand base_idx_high: high index of strand color (optional): default is ``None`` use_undostack (optional): default is ``True`` Returns: :class:`Strand` if successful, ``None`` otherwise """ part = self._part # NOTE: this color defaulting thing is problematic for tests if color is None: color = part.getProperty('color') bounds_low, bounds_high = self.getBoundsOfEmptyRegionContaining(base_idx_low) if bounds_low is not None and bounds_low <= base_idx_low and \ bounds_high is not None and bounds_high >= base_idx_high: c = CreateStrandCommand(self, base_idx_low, base_idx_high, color, update_segments=use_undostack) x, y, _ = part.getVirtualHelixOrigin(self._id_num) d = "%s:(%0.2f,%0.2f).%d^%d" % (self.part().getName(), x, y, self._is_fwd, base_idx_low) util.execCommandList(self, [c], desc=d, use_undostack=use_undostack) return c.strand() else: return None
def removeStrand(self, strand: StrandT, use_undostack: bool = True, solo: bool = True): """Remove a :class:`Strand` from the set Args: strand: the :class:`Strand` to remove use_undostack (optional): default = ``True`` solo ( optional): solo is an argument to enable limiting signals emiting from the command in the case the command is instantiated part of a larger command, default=``True`` """ cmds = [] if not self.isStrandInSet(strand): raise IndexError("Strandset.removeStrand: strand not in set") if strand.sequence() is not None: cmds.append(strand.oligo().applySequenceCMD(None)) cmds += strand.clearDecoratorCommands() cmds.append(RemoveStrandCommand(self, strand, solo=solo)) util.execCommandList(self, cmds, desc="Remove strand", use_undostack=use_undostack)
def changeInsertion(self, idx, length, use_undostack=True): """ Args: idx (int): length (int): use_undostack (bool): optional, default is True """ cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if self.hasInsertionAt(idx): if length == 0: self.removeInsertion(idx) else: # make sure length is -1 if a skip if length < 0: length = -1 cmds.append(self.oligo().applySequenceCMD(None)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None)) cmds.append(ChangeInsertionCommand(self, idx, length)) util.execCommandList(self, cmds, desc="Change Insertion", use_undostack=use_undostack)
def RipOffAcceptedSlot(self): self.doc.undoStack().undo() # undo preview_rip_off_command before applying rip_off_command cmds = [] cmd = RemoveOligoCommand(self.activeDomain.oligo()) cmds.append(cmd) d = "%s rip off" % self.activeDomain._name util.execCommandList(self.activeDomain, cmds, d, use_undostack=True) self.hide()
def resize(self, new_idxs, use_undostack=True): cmds = [] if self.strandSet().isScaffold(): cmds.append(self.oligo().applySequenceCMD(None)) cmds += self.getRemoveInsertionCommands(new_idxs) cmds.append(ResizeCommand(self, new_idxs)) util.execCommandList( self, cmds, desc="Resize strand", use_undostack=use_undostack)
def resize(self, new_idxs, use_undostack=True, update_segments=True): cmds = [] cmds += self.getRemoveInsertionCommands(new_idxs) cmds.append( ResizeCommand(self, new_idxs, update_segments=update_segments)) util.execCommandList(self, cmds, desc="Resize strand", use_undostack=use_undostack)
def removeMods(self, mod_id, idx, use_undostack=True): """Used to add mods during a merge operation.""" cmds = [] idx_low, idx_high = self.idxs() print("attempting to remove") if idx_low == idx or idx == idx_high: print("removing a modification at {}".format(idx)) cmds.append(RemoveModsCommand(self, idx, mod_id)) util.execCommandList( self, cmds, desc="Remove Modification", use_undostack=use_undostack)
def resize(self, new_idxs: SegmentT, use_undostack: bool = True, update_segments: bool = True): cmds = [] # Delete sequences and remove inserations upon resize cmds.append(self.oligo().applySequenceCMD(None)) cmds += self.getRemoveInsertionCommands(new_idxs) cmds.append(ResizeCommand(self, new_idxs, update_segments=update_segments)) util.execCommandList(self, cmds, desc="Resize strand", use_undostack=use_undostack)
def mergeStrands(self, priority_strand, other_strand, use_undostack=True): """ Merge the priority_strand and other_strand into a single new strand. The oligo of priority should be propagated to the other and all of its connections. """ low_and_high_strands = self.strandsCanBeMerged(priority_strand, other_strand) if low_and_high_strands: strand_low, strand_high = low_and_high_strands is_in_set, overlap, low_strandset_idx = self._findIndexOfRangeFor(strand_low) if is_in_set: c = MergeCommand(strand_low, strand_high, low_strandset_idx, priority_strand) util.execCommandList(self, [c], desc="Merge", use_undostack=use_undostack)
def removeInsertion(self, idx, use_undostack=True): cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if self.hasInsertionAt(idx): if use_undostack: cmds.append(self.oligo().applySequenceCMD(None, use_undostack=use_undostack)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None, use_undostack=use_undostack)) cmds.append(RemoveInsertionCommand(self, idx)) util.execCommandList( self, cmds, desc="Remove Insertion", use_undostack=use_undostack)
def createDeserializedStrand(self, base_idx_low, base_idx_high, color, use_undostack=False): """Passes a strand to AddStrandCommand that was read in from file input. Omits the step of checking _couldStrandInsertAtLastIndex, since we assume that deserialized strands will not cause collisions. """ c = CreateStrandCommand(self, base_idx_low, base_idx_high, color, update_segments=use_undostack) x, y = self._part.getVirtualHelixOrigin(self._id_num) d = "(%0.2f,%0.2f).%d^%d" % (x, y, self._is_fwd, base_idx_low) # print("strand", d) util.execCommandList(self, [c], desc=d, use_undostack=use_undostack) return 0
def splitStrand(self, strand, base_idx, update_sequence=True, use_undostack=True): """ Break strand into two strands. Reapply sequence by default (disabled during autostaple). """ if self.strandCanBeSplit(strand, base_idx): is_in_set, overlap, strandset_idx = self._findIndexOfRangeFor(strand) if is_in_set: c = SplitCommand(strand, base_idx, strandset_idx, update_sequence) util.execCommandList(self, [c], desc="Split", use_undostack=use_undostack) return True else: return False else: return False
def createStrand(self, base_idx_low, base_idx_high, use_undostack=True): """ Assumes a strand is being created at a valid set of indices. """ boundsLow, boundsHigh = self.getBoundsOfEmptyRegionContaining(base_idx_low) can_insert, strandset_idx = self.getIndexToInsert(base_idx_low, base_idx_high) if can_insert: c = CreateStrandCommand(self, base_idx_low, base_idx_high, strandset_idx) row, col = self._virtual_helix.coord() # d = "(%d,%d).%d + [%d,%d]" % \ # (row, col, self._strand_type, base_idx_low, base_idx_high) d = "(%d,%d).%d^%d" % (row, col, self._strand_type, strandset_idx) util.execCommandList(self, [c], desc=d, use_undostack=use_undostack) return strandset_idx else: return -1
def toeholdChangeAccepted(self): # triggered when user accepts a toehold operation dict = self._oligo._toehold_cmd_dict stack = [] ''' reset all toehold command state to None in oligo command dict; undo all executed command, command will be redo-ed after pushed onto undo stack; ''' for prime,cmd in dict.iteritems(): if cmd is not None: stack.append(cmd) cmd.undo() dict[prime] = None d = '%s create toehold' % self._name # record the accepted sequence of command as a macro util.execCommandList(self,stack,d,use_undostack=True)
def removeInsertion(self, idx: int, use_undostack: bool = True): """ Args: idx (int): use_undostack (bool): optional, default is True """ cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if self.hasInsertionAt(idx): if use_undostack: cmds.append(self.oligo().applySequenceCMD(None)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None)) cmds.append(RemoveInsertionCommand(self, idx)) util.execCommandList(self, cmds, desc="Remove Insertion", use_undostack=use_undostack)
def removeStrand(self, strand, strandset_idx=None, use_undostack=True, solo=True): """ solo is an argument to enable limiting signals emiting from the command in the case the command is instantiated part of a larger command """ cmds = [] if strandset_idx == None: is_in_set, overlap, strandset_idx = self._findIndexOfRangeFor(strand) if not is_in_set: raise IndexError if self.isScaffold() and strand.sequence() is not None: cmds.append(strand.oligo().applySequenceCMD(None)) cmds += strand.clearDecoratorCommands() cmds.append(RemoveStrandCommand(self, strand, strandset_idx, solo)) util.execCommandList(self, cmds, desc="Remove strand", use_undostack=use_undostack) return strandset_idx
def createDeserializedStrand(self, base_idx_low, base_idx_high, use_undostack=False): """ Passes a strand to AddStrandCommand that was read in from file input. Omits the step of checking _couldStrandInsertAtLastIndex, since we assume that deserialized strands will not cause collisions. """ boundsLow, boundsHigh = self.getBoundsOfEmptyRegionContaining(base_idx_low) assert(base_idx_low < base_idx_high) assert(boundsLow <= base_idx_low) assert(base_idx_high <= boundsHigh) can_insert, strandset_idx = self.getIndexToInsert(base_idx_low, base_idx_high) if can_insert: c = CreateStrandCommand(self, base_idx_low, base_idx_high, strandset_idx) util.execCommandList(self, [c], desc=None, use_undostack=use_undostack) return strandset_idx else: return -1
def addMods(self, mod_id, idx, use_undostack=True): """Used to add mods during a merge operation.""" cmds = [] idx_low, idx_high = self.idxs() if idx_low == idx or idx == idx_high: check_mid1 = self.part().getModID(self, idx) check_mid2 = self.part().getMod(mod_id) if check_mid2 is not None: if check_mid1 != mod_id: if check_mid1 is not None: cmds.append(RemoveModsCommand(self, idx, check_mid1)) # print("adding a {} modification at {}".format(mod_id, idx)) cmds.append(AddModsCommand(self, idx, mod_id)) util.execCommandList( self, cmds, desc="Add Modification", use_undostack=use_undostack) else: print(check_mid, mod_id)
def changeInsertion(self, idx, length, use_undostack=True): cmds = [] idx_low, idx_high = self.idxs() if idx_low <= idx <= idx_high: if self.hasInsertionAt(idx): if length == 0: self.removeInsertion(idx) else: # make sure length is -1 if a skip if length < 0: length = -1 cmds.append(self.oligo().applySequenceCMD(None, use_undostack=use_undostack)) for strand in self.getComplementStrands(): cmds.append(strand.oligo().applySequenceCMD(None, use_undostack=use_undostack)) cmds.append( ChangeInsertionCommand(self, idx, length)) util.execCommandList( self, cmds, desc="Change Insertion", use_undostack=use_undostack)
def removeStrand(self, strand, use_undostack=True, solo=True): """Remove a :class:`Strand` from the set Args: strand (Strand): the :class:`Strand` to remove use_undostack (:obj:`bool`, optional): default=True solo (:obj:`bool`, optional): solo is an argument to enable limiting signals emiting from the command in the case the command is instantiated part of a larger command, default=True """ cmds = [] if not self.isStrandInSet(strand): raise IndexError("Strandset.removeStrand: strand not in set") if strand.sequence() is not None: cmds.append(strand.oligo().applySequenceCMD(None)) cmds += strand.clearDecoratorCommands() cmds.append(RemoveStrandCommand(self, strand, solo=solo)) util.execCommandList(self, cmds, desc="Remove strand", use_undostack=use_undostack)
def deleteSelection(self): cmds = [] doc = self._document u_s = doc.undoStack() do_exec = True for item in self.selectedItems(): if isinstance(item, OutlineOligoItem): model = item.oligo() cmds += model.destroy() elif isinstance(item, OutlineVirtualHelixItem): if do_exec: do_exec = False u_s.beginMacro("delete Virtual Helices") part = item.part() part.removeVirtualHelix(item.idNum()) else: print("item undeletable", item.__class__.__name__) if do_exec: util.execCommandList(doc, cmds, desc="Clear Items", use_undostack=True) else: u_s.endMacro()
def deleteSelection(self): cmds = [] doc = self._document u_s = doc.undoStack() do_exec = True for item in self.selectedItems(): if isinstance(item, OutlineOligoItem): model = item.cnModel() cmds += model.destroy() elif isinstance(item, OutlineVirtualHelixItem): if do_exec: do_exec = False u_s.beginMacro("delete Virtual Helices") part = item.cnModel() part.removeVirtualHelix(item.idNum()) else: print("item undeletable", item.__class__.__name__) if do_exec: util.execCommandList(doc, cmds, desc="Clear Items", use_undostack=True) else: u_s.endMacro()
def _addPart(self, part, use_undostack=True): """Add part to the document via AddPartCommand.""" c = self.AddPartCommand(self, part) util.execCommandList( self, [c], desc="Add part", use_undostack=use_undostack) return c.part()
def createToehold(self,toehold,use_undostack = True): # put removed toeholds back, no need to check if_can_create_toehold cmd = CreateToeholdCommand(self._vh,toehold._domain,toehold._prime) list = [cmd] d = "createToehold %s at %s".format(toehold._name,toehold._domain._name) util.execCommandList(self,list,d,use_undostack=use_undostack)
def applySequence(self, sequence, use_undostack=True): c = ApplySequenceCommand(self, sequence) util.execCommandList(self, [c], desc="Apply Sequence", use_undostack=use_undostack)
def removeToehold(self,toehold,use_undostack=True): cmd = RemoveToeholdCommand(self,toehold) stack=[cmd] d = '%s remove toehold' % self._name util.execCommandList(self,stack,d,use_undostack=use_undostack)
def previewRipOff(self): cmd = PreviewRipOffCommand(self) stack=[cmd] d = 'preview %s rip off' % self.domain5p()._name util.execCommandList(self,stack,d,use_undostack=True)
def remove(self, use_undostack=True): c = RemoveOligoCommand(self) util.execCommandList(self, [c], desc="Color Oligo", use_undostack=use_undostack)