def build_struct(self, name, params, position): """ Build the DNA helix based on parameters in the UI. @param name: The name to assign the node in the model tree. @type name: str @param params: The list of parameters gathered from the PM. @type params: tuple @param position: The position in 3d model space at which to create the DNA strand. This is always 0, 0, 0. @type position: position """ # No error checking in build_struct, do all your error # checking in gather_parameters numberOfBases, \ dnaForm, \ basesPerTurn, \ endPoint1, \ endPoint2 = params if Veq(endPoint1, endPoint2): raise CadBug("DNA endpoints cannot be the same point.") if numberOfBases < 1: msg = redmsg("Cannot to preview/insert a DNA duplex with 0 bases.") self.MessageGroupBox.insertHtmlMessage(msg, setAsDefault=False) self.dna = None # Fixes bug 2530. Mark 2007-09-02 return None if dnaForm == 'B-DNA': dna = B_Dna_PAM3() else: raise PluginBug("Unsupported DNA Form: " + dnaForm) self.dna = dna # needed for done msg # Create the model tree group node. dnaGroup = Group(self.name, self.win.assy, self.win.assy.part.topnode) try: # Make the DNA duplex. <dnaGroup> will contain three chunks: # - Strand1 # - Strand2 # - Axis dna.make(dnaGroup, numberOfBases, basesPerTurn, endPoint1, endPoint2) return dnaGroup except (PluginBug, UserError): # Why do we need UserError here? Mark 2007-08-28 rawDnaGroup.kill() raise PluginBug( "Internal error while trying to create DNA duplex.") pass
def _modifyStructure(self, params): """ Modify the structure based on the parameters specified. Overrides EditCommand._modifystructure. This method removes the old structure and creates a new one using self._createStructure. This was needed for the structures like this (Dna, Nanotube etc) . . See more comments in the method. """ assert self.struct self.dna = B_Dna_PAM3() number_of_basePairs_from_struct,\ numberOfBases, \ dnaForm, \ dnaModel, \ basesPerTurn, \ duplexRise, \ endPoint1, \ endPoint2 , \ color = params #Delete unused parameters. del endPoint1 del endPoint2 del number_of_basePairs_from_struct numberOfBasePairsToAddOrRemove = self._determine_numberOfBasePairs_to_change( ) ladderEndAxisAtom = self.get_axisEndAtom_at_resize_end() if numberOfBasePairsToAddOrRemove != 0: resizeEnd_final_position = self._get_resizeEnd_final_position( ladderEndAxisAtom, abs(numberOfBasePairsToAddOrRemove), duplexRise) self.dna.modify(self.struct, ladderEndAxisAtom, numberOfBasePairsToAddOrRemove, basesPerTurn, duplexRise, ladderEndAxisAtom.posn(), resizeEnd_final_position) #Find new end points of structure parameters after modification #and set these values in the propMgr. new_end1, new_end2 = self.struct.getAxisEndPoints() params_to_set_in_propMgr = (numberOfBases, dnaForm, dnaModel, basesPerTurn, duplexRise, new_end1, new_end2, color) #TODO: Need to set these params in the PM #and then self.previousParams = params_to_set_in_propMgr self.previousParams = params return
def _modifyStructure(self, params): """ Modify the structure based on the parameters specified. Overrides EditCommand._modifystructure. This method removes the old structure and creates a new one using self._createStructure. This was needed for the structures like this (Dna, Nanotube etc) . . See more comments in the method. """ if self.currentStruct is None: print_compact_stack("bug: self.currentStruct doesn't exist"\ "exiting self._modifyStructure") return assert isinstance(self.currentStruct, self.win.assy.DnaSegment) self.dna = B_Dna_PAM3() duplexRise = self.currentStruct.getDuplexRise() basesPerTurn = self.currentStruct.getBasesPerTurn() numberOfBasePairsToAddOrRemove = self._determine_numberOfBasePairs_to_change( ) ladderEndAxisAtom = self.get_axisEndAtom_at_resize_end() if ladderEndAxisAtom is None: print_compact_stack("bug: unable to resize the DnaSegment"\ "%r, end axis ato not found"%self.currentStruct) return if numberOfBasePairsToAddOrRemove != 0: resizeEnd_final_position = self._get_resizeEnd_final_position( ladderEndAxisAtom, abs(numberOfBasePairsToAddOrRemove), duplexRise) self.dna.modify(self.currentStruct, ladderEndAxisAtom, numberOfBasePairsToAddOrRemove, basesPerTurn, duplexRise, ladderEndAxisAtom.posn(), resizeEnd_final_position) self.previousParams = params return
def _createStructure(self): """ Creates and returns the structure (in this case a L{Group} object that contains the DNA strand and axis chunks. @return : group containing that contains the DNA strand and axis chunks. @rtype: L{Group} @note: This needs to return a DNA object once that model is implemented """ params = self._gatherParameters() # No error checking in build_struct, do all your error # checking in gather_parameters number_of_basePairs_from_struct,\ numberOfBases, \ dnaForm, \ dnaModel, \ basesPerTurn, \ duplexRise, \ endPoint1, \ endPoint2, \ color_junk = params #Note: color_junk is not used. Ideally it should do struct.setColor(color) #but the color combobox in the PM directly sets the color of the #structure to the specified one when the current index in the combobx #changes #If user enters the number of basepairs and hits preview i.e. endPoint1 #and endPoint2 are not entered by the user and thus have default value #of V(0, 0, 0), then enter the endPoint1 as V(0, 0, 0) and compute #endPoint2 using the duplex length. #Do not use '==' equality check on vectors! its a bug. Use same_vals # or Veq instead. if Veq(endPoint1, endPoint2) and Veq(endPoint1, V(0, 0, 0)): endPoint2 = endPoint1 + \ self.win.glpane.right*getDuplexLength('B-DNA', numberOfBases) if numberOfBases < 1: msg = redmsg("Cannot preview/insert a DNA duplex with 0 bases.") self.propMgr.updateMessage(msg) self.dna = None # Fixes bug 2530. Mark 2007-09-02 return None if dnaForm == 'B-DNA': if dnaModel == 'PAM3': dna = B_Dna_PAM3() elif dnaModel == 'PAM5': dna = B_Dna_PAM5() else: print "bug: unknown dnaModel type: ", dnaModel else: raise PluginBug("Unsupported DNA Form: " + dnaForm) self.dna = dna # needed for done msg # self.name needed for done message if self.create_name_from_prefix: # create a new name name = self.name = gensym(self.prefix, self.win.assy) # (in _build_struct) self._gensym_data_for_reusing_name = (self.prefix, name) else: # use externally created name self._gensym_data_for_reusing_name = None # (can't reuse name in this case -- not sure what prefix it was # made with) name = self.name # Create the model tree group node. # Make sure that the 'topnode' of this part is a Group (under which the # DNa group will be placed), if the topnode is not a group, make it a # a 'Group' (applicable to Clipboard parts).See part.py # --Part.ensure_toplevel_group method. This is an important line # and it fixes bug 2585 self.win.assy.part.ensure_toplevel_group() dnaSegment = DnaSegment(self.name, self.win.assy, self.win.assy.part.topnode, editCommand=self) try: # Make the DNA duplex. <dnaGroup> will contain three chunks: # - Strand1 # - Strand2 # - Axis dna.make(dnaSegment, numberOfBases, basesPerTurn, duplexRise, endPoint1, endPoint2) #set some properties such as duplexRise and number of bases per turn #This information will be stored on the DnaSegment object so that #it can be retrieved while editing this object. #This works with or without dna_updater. Now the question is #should these props be assigned to the DnaSegment in #dnaDuplex.make() itself ? This needs to be answered while modifying #make() method to fit in the dna data model. --Ninad 2008-03-05 #WARNING 2008-03-05: Since self._modifyStructure calls #self._createStructure() #If in the near future, we actually permit modifying a #structure (such as dna) without actually recreating the whole #structre, then the following properties must be set in #self._modifyStructure as well. Needs more thought. props = (duplexRise, basesPerTurn) dnaSegment.setProps(props) return dnaSegment except (PluginBug, UserError): # Why do we need UserError here? Mark 2007-08-28 dnaSegment.kill() raise PluginBug( "Internal error while trying to create DNA duplex.")