Beispiel #1
0
    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
Beispiel #4
0
    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
Beispiel #8
0
    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
Beispiel #10
0
    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