def update_numberOfBases(self): """ Updates the numberOfBases in the PM while a resize handle is being dragged. @see: self.getCursorText() where it is called. """ #@Note: originally (before 2008-04-05, it was called in #DnaStrand_ResizeHandle.on_drag() but that 'may' have some bugs #(not verified) also see self.getCursorText() to know why it is #called there (basically a workaround for bug 2729 if self.grabbedHandle is None: return currentPosition = self.grabbedHandle.currentPosition resize_end = self.grabbedHandle.origin new_duplexLength = vlen( currentPosition - resize_end ) numberOfBasePairs_to_change = getNumberOfBasePairsFromDuplexLength('B-DNA', new_duplexLength) original_numberOfBases = self.struct.getNumberOfBases() #If the dot product of handle direction and the direction in which it #is dragged is negative, this means we need to subtract bases direction_of_drag = norm(currentPosition - resize_end) if dot(self.grabbedHandle.direction, direction_of_drag ) < 0: total_number_of_bases = original_numberOfBases - numberOfBasePairs_to_change self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases) else: total_number_of_bases = original_numberOfBases + numberOfBasePairs_to_change self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases - 1)
def getCursorText(self, endPoint1, endPoint2): """ This is used as a callback method in DnaLine mode @see: DnaLineMode.setParams, DnaLineMode_GM.Draw """ text = "" textColor = env.prefs[cursorTextColor_prefs_key] if endPoint1 is None or endPoint2 is None: return text, textColor if not env.prefs[dnaDuplexEditCommand_showCursorTextCheckBox_prefs_key]: return text, textColor numberOfBasePairsString = "" numberOfTurnsString = "" duplexLengthString = "" thetaString = "" duplexLength = vlen(endPoint2 - endPoint1) numberOfBasePairs = getNumberOfBasePairsFromDuplexLength("B-DNA", duplexLength, duplexRise=self.duplexRise) numberOfBasePairsString = self._getCursorText_numberOfBasePairs(numberOfBasePairs) numberOfTurnsString = self._getCursorText_numberOfTurns(numberOfBasePairs) duplexLengthString = self._getCursorText_length(duplexLength) if env.prefs[dnaDuplexEditCommand_cursorTextCheckBox_angle_prefs_key]: vec = endPoint2 - endPoint1 theta = self.glpane.get_angle_made_with_screen_right(vec) thetaString = "%5.2f deg" % theta commaString = ", " text = numberOfBasePairsString if text and numberOfTurnsString: text += commaString text += numberOfTurnsString if text and duplexLengthString: text += commaString text += duplexLengthString if text and thetaString: text += commaString text += thetaString # @TODO: The following updates the PM as the cursor moves. # Need to rename this method so that you that it also does more things # than just to return a textString -- Ninad 2007-12-20 self.propMgr.numberOfBasePairsSpinBox.setValue(numberOfBasePairs) return text, textColor
def createStructure(self, showPropMgr = True): """ Overrides superclass method. Creates the structure (DnaSegment) """ assert self.propMgr is not None if self.struct is not None: self.struct = None self.win.assy.part.ensure_toplevel_group() self.propMgr.endPoint1 = self.mouseClickPoints[0] self.propMgr.endPoint2 = self.mouseClickPoints[1] duplexLength = vlen(self.mouseClickPoints[0] - self.mouseClickPoints[1]) numberOfBasePairs = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', duplexLength, duplexRise = self.duplexRise) self.propMgr.numberOfBasePairsSpinBox.setValue(numberOfBasePairs) self.preview_or_finalize_structure(previewing = True) #Unpick the dna segments (while this command was still #running. ) This is necessary , so that when you strat drawing #rubberband line, it matches the display style of the glpane. #If something was selected, and while in DnaLineMode you changed the #display style, it will be applied only to the selected chunk. #(and the glpane's display style will not change. This , in turn #won't change the display of the rubberband line being drawn. #Another bug: What if something else in the glpane is selected? #complete fix would be to call unpick_all_in_the_glpane. But #that itself is undesirable. Okay for now -- Ninad 2008-02-20 #UPDATE 2008-02-21: The following code is commented out. Don't #change the selection state of the ##if self._fallbackDnaGroup is not None: ##for segment in self._fallbackDnaGroup.members: ##segment.unpick() #Now append this dnaSegment to self._segmentList self._segmentList.append(self.struct) #clear the mouseClickPoints list self.mouseClickPoints = [] self.graphicsMode.resetVariables() self.win.win_update() #fixes bug 2810
def createStructure(self): """ Overrides superclass method. Creates the structure (DnaSegment) """ assert self.propMgr is not None if self.struct is not None: self.struct = None self.win.assy.part.ensure_toplevel_group() self.propMgr.endPoint1 = self.mouseClickPoints[0] self.propMgr.endPoint2 = self.mouseClickPoints[1] duplexLength = vlen(self.mouseClickPoints[0] - self.mouseClickPoints[1]) numberOfBasePairs = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', duplexLength, duplexRise = self.duplexRise) self.propMgr.numberOfBasePairsSpinBox.setValue(numberOfBasePairs) self.preview_or_finalize_structure(previewing=True) #Unpick the dna segments (while this command was still #running. ) This is necessary , so that when you strat drawing #rubberband line, it matches the display style of the glpane. #If something was selected, and while in DnaLineMode you changed the #display style, it will be applied only to the selected chunk. #(and the glpane's display style will not change. This , in turn #won't change the display of the rubberband line being drawn. #Another bug: What if something else in the glpane is selected? #complete fix would be to call unpick_all_in_the_glpane. But #that itself is undesirable. Okay for now -- Ninad 2008-02-20 #UPDATE 2008-02-21: The following code is commented out. Don't #change the selection state of the ##if self._fallbackDnaGroup is not None: ##for segment in self._fallbackDnaGroup.members: ##segment.unpick() #Now append this dnaSegment to self._segmentList self._segmentList.append(self.struct) #clear the mouseClickPoints list self.mouseClickPoints = [] self.graphicsMode.resetVariables() self.win.win_update() #fixes bug 2810
def _determine_numberOfBasePairs_to_change(self): """ """ duplexRise = self.struct.getDuplexRise() numberOfBasesToAddOrRemove = 0 # Following helps fixing bugs like 2904 and 2906 see also self.getCursorText() # and TODO items in that method. Also note that the grabbed handle case # is similar to the one in MultipleDnaSegmentResize_EditCommand. # needs refactoring and overall cleanup. if self.grabbedHandle is not None: currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - self.grabbedHandle.origin) # Even when the direction of drag is negative (i.e. the basepairs being # removed), make sure not to remove base pairs for very small movement # of the grabbed handle if changedLength < 0.2 * duplexRise: return 0 # This check quickly determines if the grabbed handle moved by a distance # more than the duplexRise and avoids further computations # This condition is applicable only when the direction of drag is # positive..i.e. bases bing added to the segment. if changedLength < duplexRise and dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 # If the segment is being shortened (determined by checking the # direction of drag) numberOfBasesToAddOrRemove = getNumberOfBasePairsFromDuplexLength( "B-DNA", changedLength, duplexRise=duplexRise ) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = -numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: # dna.modify will remove the first base pair it creates # (that basepair will only be used for proper alignment of the # duplex with the existing structure) So we need to compensate for # this basepair by adding 1 to the new number of base pairs. # UPDATE 2008-05-14: The following commented out code # i.e. "##numberOfBasesToAddOrRemove += 1" is not required in this # class , because the way we compute the number of base pairs to # be added is different than than how its done at the moment in the # superclass. In this method, we compute bases to be added from # the resize end and that computation INCLUDES the resize end. # so the number that it returns is already one more than the actual # bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 pass else: # The Property manager will be showing the current number # of base pairs (w. May be we can use that number directly here? # The following is safer to do so lets just recompute the # number of base pairs. (if it turns out to be slow, we will consider # using the already computed calue from the property manager new_numberOfBasePairs = self.propMgr.numberOfBasePairsSpinBox.value() endPoint1, endPoint2 = self.struct.getAxisEndPoints() if endPoint1 is None or endPoint2 is None: return 0 original_duplex_length = vlen(endPoint1 - endPoint2) original_numberOfBasePairs = self.struct.getNumberOfBasePairs() numberOfBasesToAddOrRemove = new_numberOfBasePairs - original_numberOfBasePairs if numberOfBasesToAddOrRemove > 0: # dna.modify will remove the first base pair it creates # (that basepair will only be used for proper alignment of the # duplex with the existing structure) So we need to compensate for # this basepair by adding 1 to the new number of base pairs. numberOfBasesToAddOrRemove += 1 return numberOfBasesToAddOrRemove
def _determine_numberOfBasePairs_to_change(self): """ Overrides superclass method @TODO: This is significantly different (and perhaps better) than the superclass method. See how to incorporate changes in this method in superclass. @see: self.getDnaRibbonParams() """ currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure duplexRise = self.struct.getDuplexRise() changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - \ self.grabbedHandle.origin) #Even when the direction of drag is negative (i.e. the basepairs being #removed), make sure not to remove base pairs for very small movement #of the grabbed handle if changedLength < 0.2*duplexRise: return 0 #This check quickly determines if the grabbed handle moved by a distance #more than the duplexRise and avoids further computations #This condition is applicable only when the direction of drag is #positive..i.e. bases bing added to the segment. if changedLength < duplexRise and \ dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 #If the segment is being shortened (determined by checking the #direction of drag) numberOfBasesToAddOrRemove = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', changedLength, duplexRise = duplexRise) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = - numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. #UPDATE 2008-05-14: The following commented out code #i.e. "##numberOfBasesToAddOrRemove += 1" is not required in this #class , because the way we compute the number of base pairs to #be added is different than than how its done at the moment in the #superclass. In this method, we compute bases to be added from #the resize end and that computation INCLUDES the resize end. #so the number that it returns is already one more than the actual #bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 ##print "*** numberOfBasesToAddOrRemove = ", numberOfBasesToAddOrRemove ##print "**** changedLength =", changedLength pass ###UPDATE 2008-06-26: for some reason, when the number of base pairs ###to be added (i.e. value of numberOfBasesToAddOrRemove) is 1 more ###than the actual number of base pairs to be added. So subtract 1 ###from this number. Cause not debugged. -- Ninad ##if numberOfBasesToAddOrRemove > 1: ##numberOfBasesToAddOrRemove -= 1 #UPDATE 2008-08-20: Note that DnaSegment_EditCommand.getCursorText() #does the job of removing the extra basepair from numberOfBasesToAddOrRemove #It(subtracting 1 basePair) is not done here as #self._modifyStructure() needs it without the subtraction. This is #prone to bugs and need to be cleaned up. -- Ninad return numberOfBasesToAddOrRemove
def _determine_numberOfBasePairs_to_change(self): """ """ duplexRise = self.struct.getDuplexRise() numberOfBasesToAddOrRemove = 0 #Following helps fixing bugs like 2904 and 2906 see also self.getCursorText() #and TODO items in that method. Also note that the grabbed handle case #is similar to the one in MultipleDnaSegmentResize_EditCommand. #needs refactoring and overall cleanup. if self.grabbedHandle is not None: currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - \ self.grabbedHandle.origin) #Even when the direction of drag is negative (i.e. the basepairs being #removed), make sure not to remove base pairs for very small movement #of the grabbed handle if changedLength < 0.2 * duplexRise: return 0 #This check quickly determines if the grabbed handle moved by a distance #more than the duplexRise and avoids further computations #This condition is applicable only when the direction of drag is #positive..i.e. bases bing added to the segment. if changedLength < duplexRise and \ dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 #If the segment is being shortened (determined by checking the #direction of drag) numberOfBasesToAddOrRemove = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', changedLength, duplexRise = duplexRise) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = -numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. #UPDATE 2008-05-14: The following commented out code #i.e. "##numberOfBasesToAddOrRemove += 1" is not required in this #class , because the way we compute the number of base pairs to #be added is different than than how its done at the moment in the #superclass. In this method, we compute bases to be added from #the resize end and that computation INCLUDES the resize end. #so the number that it returns is already one more than the actual #bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 pass else: #The Property manager will be showing the current number #of base pairs (w. May be we can use that number directly here? #The following is safer to do so lets just recompute the #number of base pairs. (if it turns out to be slow, we will consider #using the already computed calue from the property manager new_numberOfBasePairs = self.propMgr.numberOfBasePairsSpinBox.value( ) endPoint1, endPoint2 = self.struct.getAxisEndPoints() if endPoint1 is None or endPoint2 is None: return 0 original_duplex_length = vlen(endPoint1 - endPoint2) original_numberOfBasePairs = self.struct.getNumberOfBasePairs() numberOfBasesToAddOrRemove = new_numberOfBasePairs - original_numberOfBasePairs if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. numberOfBasesToAddOrRemove += 1 return numberOfBasesToAddOrRemove
def _determine_numberOfBasePairs_to_change(self): """ Overrides superclass method @TODO: This is significantly different (and perhaps better) than the superclass method. See how to incorporate changes in this method in superclass. @see: self.getDnaRibbonParams() """ currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure duplexRise = self.struct.getDuplexRise() changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - \ self.grabbedHandle.origin) #Even when the direction of drag is negative (i.e. the basepairs being #removed), make sure not to remove base pairs for very small movement #of the grabbed handle if changedLength < 0.2 * duplexRise: return 0 #This check quickly determines if the grabbed handle moved by a distance #more than the duplexRise and avoids further computations #This condition is applicable only when the direction of drag is #positive..i.e. bases bing added to the segment. if changedLength < duplexRise and \ dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 #If the segment is being shortened (determined by checking the #direction of drag) numberOfBasesToAddOrRemove = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', changedLength, duplexRise = duplexRise) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = -numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. #UPDATE 2008-05-14: The following commented out code #i.e. "##numberOfBasesToAddOrRemove += 1" is not required in this #class , because the way we compute the number of base pairs to #be added is different than than how its done at the moment in the #superclass. In this method, we compute bases to be added from #the resize end and that computation INCLUDES the resize end. #so the number that it returns is already one more than the actual #bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 ##print "*** numberOfBasesToAddOrRemove = ", numberOfBasesToAddOrRemove ##print "**** changedLength =", changedLength pass ###UPDATE 2008-06-26: for some reason, when the number of base pairs ###to be added (i.e. value of numberOfBasesToAddOrRemove) is 1 more ###than the actual number of base pairs to be added. So subtract 1 ###from this number. Cause not debugged. -- Ninad ##if numberOfBasesToAddOrRemove > 1: ##numberOfBasesToAddOrRemove -= 1 #UPDATE 2008-08-20: Note that DnaSegment_EditCommand.getCursorText() #does the job of removing the extra basepair from numberOfBasesToAddOrRemove #It(subtracting 1 basePair) is not done here as #self._modifyStructure() needs it without the subtraction. This is #prone to bugs and need to be cleaned up. -- Ninad return numberOfBasesToAddOrRemove
def _determine_numberOfBasePairs_to_change(self): """ Overrides superclass method @TODO: This is significantly different (and perhaps better) than the superclass method. See how to incorporate changes in this method in superclass. @see: self.getDnaRibbonParams() """ currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure duplexRise = self.struct.getDuplexRise() changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - \ self.grabbedHandle.origin) #Even when the direction of drag is negative (i.e. the basepairs being #removed), make sure not to remove base pairs for very small movement #of the grabbed handle if changedLength < 0.2 * duplexRise: return 0 #This check quickly determines if the grabbed handle moved by a distance #more than the duplexRise and avoids further computations #This condition is applicable only when the direction of drag is #positive..i.e. bases bing added to the segment. if changedLength < duplexRise and \ dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 #If the segment is being shortened (determined by checking the #direction of drag) numberOfBasesToAddOrRemove = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', changedLength, duplexRise = duplexRise) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = -numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. #UPDATE 2008-05-14: The following is not required in this particular #class , because the way we compute the number of base pairs to #be added is different than than how its done at the moment in the #superclass. In this method, we compute bases to be added from #the resize end and that computation INCLUDES the resize end. #so the number that it returns is already one more than the actual #bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 pass return numberOfBasesToAddOrRemove
def getCursorText(self, endPoint1, endPoint2): """ This is used as a callback method in DnaLine mode @see: DnaLineMode.setParams, DnaLineMode_GM.Draw """ text = '' textColor = env.prefs[cursorTextColor_prefs_key] if endPoint1 is None or endPoint2 is None: return text, textColor if not env.prefs[dnaDuplexEditCommand_showCursorTextCheckBox_prefs_key]: return text, textColor numberOfBasePairsString = '' numberOfTurnsString = '' duplexLengthString = '' thetaString = '' duplexLength = vlen(endPoint2 - endPoint1) numberOfBasePairs = getNumberOfBasePairsFromDuplexLength( 'B-DNA', duplexLength, duplexRise=self.duplexRise) numberOfBasePairsString = self._getCursorText_numberOfBasePairs( numberOfBasePairs) numberOfTurnsString = self._getCursorText_numberOfTurns( numberOfBasePairs) duplexLengthString = self._getCursorText_length(duplexLength) if env.prefs[dnaDuplexEditCommand_cursorTextCheckBox_angle_prefs_key]: vec = endPoint2 - endPoint1 theta = self.glpane.get_angle_made_with_screen_right(vec) thetaString = "%5.2f deg" % theta commaString = ", " text = numberOfBasePairsString if text and numberOfTurnsString: text += commaString text += numberOfTurnsString if text and duplexLengthString: text += commaString text += duplexLengthString if text and thetaString: text += commaString text += thetaString #@TODO: The following updates the PM as the cursor moves. #Need to rename this method so that you that it also does more things #than just to return a textString -- Ninad 2007-12-20 self.propMgr.numberOfBasePairsSpinBox.setValue(numberOfBasePairs) return text, textColor
def _determine_numberOfBasePairs_to_change(self): """ Overrides superclass method @TODO: This is significantly different (and perhaps better) than the superclass method. See how to incorporate changes in this method in superclass. @see: self.getDnaRibbonParams() """ currentPosition = self.grabbedHandle.currentPosition fixedEndOfStructure = self.grabbedHandle.fixedEndOfStructure duplexRise = self.struct.getDuplexRise() changedLength = vlen(currentPosition - self.grabbedHandle.origin) direction_of_drag = norm(self.grabbedHandle.currentPosition - \ self.grabbedHandle.origin) #Even when the direction of drag is negative (i.e. the basepairs being #removed), make sure not to remove base pairs for very small movement #of the grabbed handle if changedLength < 0.2*duplexRise: return 0 #This check quickly determines if the grabbed handle moved by a distance #more than the duplexRise and avoids further computations #This condition is applicable only when the direction of drag is #positive..i.e. bases bing added to the segment. if changedLength < duplexRise and \ dot(self.grabbedHandle.direction, direction_of_drag) > 0: return 0 #If the segment is being shortened (determined by checking the #direction of drag) numberOfBasesToAddOrRemove = \ getNumberOfBasePairsFromDuplexLength( 'B-DNA', changedLength, duplexRise = duplexRise) if dot(self.grabbedHandle.direction, direction_of_drag) < 0: numberOfBasesToAddOrRemove = - numberOfBasesToAddOrRemove if numberOfBasesToAddOrRemove > 0: #dna.modify will remove the first base pair it creates #(that basepair will only be used for proper alignment of the #duplex with the existing structure) So we need to compensate for #this basepair by adding 1 to the new number of base pairs. #UPDATE 2008-05-14: The following is not required in this particular #class , because the way we compute the number of base pairs to #be added is different than than how its done at the moment in the #superclass. In this method, we compute bases to be added from #the resize end and that computation INCLUDES the resize end. #so the number that it returns is already one more than the actual #bases to be added. so commenting out the following line # -- Ninad 2008-05-14 ##numberOfBasesToAddOrRemove += 1 pass return numberOfBasesToAddOrRemove