Beispiel #1
0
    def __unmaskedMatrix( self, contacts, rec_mask, lig_mask ):
        """
        Map contacts between selected rec and lig atoms back to all atoms
        matrix.
        
        @param contacts: contact matrix, array sum_rec_mask x sum_lig_mask
        @type  contacts: array
        @param rec_mask: atom mask
        @type  rec_mask: [1|0]
        @param lig_mask: atom mask
        @type  lig_mask: [1|0]

        @return: atom contact matrix, array N_atoms_rec x N_atoms_lig
        @rtype: array
        """
        l_rec = len( self.rec_model )
        l_lig = len( self.lig_model )

        ## map contacts back to all atoms matrix
        r = N.zeros( l_rec * l_lig )
        rMask = N.ravel( N.outerproduct( rec_mask, lig_mask ) )

        ## (Optimization: nonzero is time consuming step)
        N.put( r, N.nonzero( rMask ), N.ravel( contacts ) )

        return N.resize( r, (l_rec, l_lig))
Beispiel #2
0
 def UpdateJacobian(self, B, dx, dF):
     """
     Use Broyden method (following Numerical Recipes in C, 9.7)
     to update inverse Jacobian
     B is previous inverse Jacobian (n x n)
     dx is delta x for last step (n)
     dF is delta errors for last step (n)
     """
     
     dotdxB = dot(dx, B)
     denom = dot(dotdxB, dF)
     if abs(denom) < tiniestValue:
         return B       # what else to do?
     
     return B + outerproduct((dx - dot(B, dF)), dotdxB)/denom
         
     
Beispiel #3
0
    def random_contacts(self, contMat, n, maskRec=None, maskLig=None):
        """
        Create randomized surface contact matrix with same number of
        contacts and same shape as given contact matrix.
        
        @param contMat: template contact matrix
        @type  contMat: matrix
        @param n: number of matrices to generate
        @type  n: int
        @param maskRec: surface masks (or something similar)
        @type  maskRec: [1|0]
        @param maskLig: surface masks (or something similar)
        @type  maskLig: [1|0]
        
        @return: list of [n] random contact matricies
        @rtype: [matrix]
        """
        a, b = N.shape(contMat)
        nContacts = N.sum(N.sum(contMat))

        if not maskLig:
            r_size, l_size = N.shape(contMat)
            maskLig = N.ones(l_size)
            maskRec = N.ones(r_size)

        c_mask = N.ravel(N.outerproduct(maskRec, maskLig))
        c_pos = N.nonzero(c_mask)

        # get array with surface positions from complex
        cont = N.take(N.ravel(contMat), c_pos)
        length = len(cont)

        result = []

        for i in range(n):
            # create random array
            ranCont = mathUtils.randomMask(nContacts, length)

            # blow up to size of original matrix
            r = N.zeros(a * b)
            N.put(r, c_pos, ranCont)

            result += [N.reshape(r, (a, b))]

        return result
Beispiel #4
0
    def random_contacts( self, contMat, n, maskRec=None, maskLig=None ):
        """
        Create randomized surface contact matrix with same number of
        contacts and same shape as given contact matrix.
        
        @param contMat: template contact matrix
        @type  contMat: matrix
        @param n: number of matrices to generate
        @type  n: int
        @param maskRec: surface masks (or something similar)
        @type  maskRec: [1|0]
        @param maskLig: surface masks (or something similar)
        @type  maskLig: [1|0]
        
        @return: list of [n] random contact matricies
        @rtype: [matrix]
        """
        a,b = N.shape( contMat )
        nContacts = N.sum( N.sum( contMat ))

        if not maskLig:
            r_size, l_size = N.shape( contMat )
            maskLig = N.ones( l_size )
            maskRec = N.ones( r_size )

        c_mask = N.ravel( N.outerproduct( maskRec, maskLig ) )
        c_pos = N.nonzero( c_mask )

        # get array with surface positions from complex
        cont = N.take( N.ravel(contMat), c_pos )
        length = len( cont )

        result = []

        for i in range( n ):
            # create random array
            ranCont = mathUtils.randomMask( nContacts,length )

            # blow up to size of original matrix
            r = N.zeros(a*b)
            N.put( r, c_pos, ranCont)

            result += [ N.reshape( r, (a,b) ) ]

        return result
Beispiel #5
0
    def rotate(self, angle_degrees, axis_x, axis_y, axis_z ):
        """Follows the right hand rule.

        I visualize the right hand rule most easily as follows:
        Naturally, using your right hand, wrap it around the axis of
        rotation. Your fingers now point in the direction of rotation.

        """
        angleRadians = angle_degrees / 180.0 * math.pi
        u = self.__make_normalized_vert3(axis_x, axis_y, axis_z )
        u=-u #follow right hand rule
        S = Numeric.zeros( (3,3), Numeric.Float )
        S[0,1] = -u[2]
        S[0,2] = u[1]
        S[1,0] = u[2]
        S[1,2] = -u[0]
        S[2,0] = -u[1]
        S[2,1] = u[0]
        U = Numeric.outerproduct(u,u)
        R = U + math.cos(angleRadians)*(MLab.eye(3)-U) + math.sin(angleRadians)*S
        R = Numeric.concatenate( (R,Numeric.zeros( (3,1), Numeric.Float)), axis=1)
        R = Numeric.concatenate( (R,Numeric.zeros( (1,4), Numeric.Float)), axis=0)
        R[3,3] = 1.0
        self.matrix = numpy.dot(R,self.matrix)
Beispiel #6
0
def SolveNonLinearEquations(parent, u, numMethSettings, lastConvX, lastX, lastJac, lastConvJac=None):

    #parent.InfoMessage('In:', (time.asctime(), time.time()))
    #Load numerical method settings
    maxIter = numMethSettings.maxIter
    damp = numMethSettings.dampingFactor
    stayThreshold = numMethSettings.stayThreshold
    tolerance = numMethSettings.tolerance
    maxStep = numMethSettings.maxStep
    minimErr = numMethSettings.minimizeErr
    tryToRestart = numMethSettings.tryToRestart
    tryLastConverged = numMethSettings.tryLastConverged
    if hasattr(numMethSettings, 'solveMethod'):
        solveMethod = numMethSettings.solveMethod
    else:
        if hasattr(parent, 'CalculateJacobian'):
            solveMethod = NR
        else:
            solveMethod = SECANT
    if hasattr(numMethSettings, 'monitorConv'): monitorConv = numMethSettings.monitorConv
    else: monitorConv = False
    if hasattr(numMethSettings, 'freqJacMsg'): freqJacMsg = numMethSettings.freqJacMsg
    else: freqJacMsg = 10
    
    #Load stuff from the unknowns
    nuEquations = u.GetNumberOfUnknowns()
    x = u.GetValues()
    isFix = u.GetIsFixed()
    initx = u.GetInitValues()
    scaleFactors = u.GetScaleFactors()
    lowBounds = u.GetLowBounds()
    highBounds = u.GetHighBounds()
    
    #Init arrays
    jacobian = zeros((nuEquations, nuEquations), Float)
    deltaX = ones(nuEquations, Float) #Set initial deltaX to 1.0 to ensure that convergence check works
    rhs = zeros(nuEquations, Float)
    oldRhs = zeros(nuEquations, Float)

    #Init some vars
    iter = 0
    converged = False
    needsAFirstCalculation = True
    maxError = None
    parentPath = parent.GetPath()
    
    #Start from last vals? 
    if tryToRestart:
        if lastX and len(lastX) == nuEquations:
            #Should it really waste the time checking on the specs?
            for i in range(nuEquations):
                if not isFix[i]:
                    x[i] = lastX[i]
                    
    #Use last converged?
    elif tryLastConverged:
        if lastConvX and len(lastConvX) == nuEquations:
            try:
                #Keep the specs:
                for i in range(nuEquations):
                    if isFix[i]:
                        lastConvX[i] = x[i]
                parent.CalculateRHS(lastConvX, oldRhs, isFix, initx)
                maxErr = max(abs(oldRhs))
                if maxErr < stayThreshold:
                    x = Numeric.array(lastConvX)
                    initx = Numeric.array(lastConvX)
                    u.SetInitValues(lastConvX)
                    rhs[:] = oldRhs[:]
                    needsAFirstCalculation = False
            except:
                pass
    
            
    #Lets do stuff for the first iteration
    if needsAFirstCalculation:
        #print 'FirstCalcIn:', time.asctime()
        try:
            parent.CalculateRHS(x, rhs, isFix, initx)
            #Check to see if the previous solution is better
            if not tryToRestart and maxError != None and maxError < max(abs(rhs)):
                x = Numeric.array(lastConvX)
                initx = Numeric.array(lastConvX)
                u.SetInitValues(lastConvX)
                rhs[:] = oldRhs[:]  #OldRhs was used to store rhs for the last converged solution
        except:
            parent.InfoMessage('CouldNotInitialize', (parentPath,))
            return x, rhs, converged, jacobian
        
    try:
        converged = CheckForConvergence(rhs, scaleFactors, tolerance)
        if converged: 
            parent.InfoMessage('Converged', (parentPath, iter))
            return x, rhs, converged, lastConvJac
        
        #parent.InfoMessage('FirstJacobianIn:', (time.asctime(), time.time()))
        
        doCrudeDiff = True
        parent.InfoMessage('TowerCalcJacobian', (parentPath,))
        if solveMethod == NR and hasattr(parent, 'CalculateJacobian'):
            parent.CalculateJacobian(x, jacobian, isFix, initx)
            jacobian = inverse(jacobian)
            doCrudeDiff = False
            
        elif solveMethod == BROYDEN:
            if tryToRestart and lastX and len(lastX) == nuEquations:
                if lastJac:
                    jacobian[:] = lastJac[:]
                    doCrudeDiff = False
            elif tryLastConverged and lastConvX and len(lastConvX) == nuEquations:
                if lastConvJac:
                    jacobian[:] = lastConvJac[:]
                    doCrudeDiff = False
            elif hasattr(parent, 'CalculateJacobian'):
                parent.CalculateJacobian(x, jacobian, isFix, initx)
                jacobian = inverse(jacobian)
                doCrudeDiff = False
        
        if doCrudeDiff:
            xForJac = array(x, Float)
            rhsForJac = array(rhs, Float)
            shift = 0.0001
            
            #Pass a message every x calculations, so the solver doesn't look dead
            distCnt = 0
            msgEvery = freqJacMsg
            for j in range(nuEquations):
                distCnt +=1
                if distCnt == msgEvery:
                    parent.InfoMessage('CalcDisturbance', (j+1, nuEquations, parentPath))
                    distCnt = 0   
                    
                old = xForJac[j]
                xForJac[j] = xForJac[j] + shift * scaleFactors[j]
                parent.CalculateRHS(xForJac, rhsForJac, isFix, initx)
                jacobian[:, j] = (rhsForJac - rhs)/(shift * scaleFactors[j])
                xForJac[j] = old
            jacobian = inverse(jacobian)
        deltaX = -dot(jacobian, rhs) 
        #parent.InfoMessage('FirstJacobianOut:', (time.asctime(), time.time()))
    except:
        #Bye
        parent.InfoMessage('CouldNotInvertJacobian', (parentPath,))
        return x, rhs, converged, jacobian

    maxStep = None
    errHistory = []
    currMaxErr = max(abs(rhs))
    while iter <= maxIter:
        iter += 1
        oldRhs[:] = rhs[:]
        stepLength = 1.0*damp
        currx = Numeric.array(x)
        maxErr = currMaxErr
        
        #Make sure the step is not too large
        if maxStep != None:
            for i in range(len(deltaX)):
                if deltaX[i]/scaleFactors[i] > maxStep:
                    deltaX[i] = maxStep*scaleFactors[i]
                elif deltaX[i]/scaleFactors[i] < -maxStep:
                    deltaX[i] = -maxStep*scaleFactors[i]
                    
        cntHere = 0
        #Loop until max error (max rhs) decreases
        while 1:
            actualDeltaX = stepLength*deltaX
            
            x = UpdateX(currx, actualDeltaX, lowBounds, highBounds)
            if hasattr(parent, 'SanityCheck'):
                parent.SanityCheck(x, initx)
                
            try:
                parent.CalculateRHS(x, rhs, isFix, initx)
                converged = CheckForConvergence(rhs, scaleFactors, tolerance)
                if converged: 
                    parent.InfoMessage('Converged', (parentPath, iter))
                    #parent.InfoMessage('Out:', (time.asctime(), time.time()))
                    return x, rhs, converged, jacobian
                
                currMaxErr = max(abs(rhs))
                if minimErr and currMaxErr > maxErr:
                    stepLength *= 0.25
                    cntHere += 1
                else:
                    break

            except:
                stepLength *= 0.25
                
            if stepLength < 0.0000001:
                parent.InfoMessage('CouldNotConverge', (parentPath, iter))
                return x, rhs, False, jacobian
        
        parent.InfoMessage('EqnBasedUOpError', (parentPath, iter, currMaxErr))
        
        if monitorConv:
            #Monitor if it is not converging and it is just wasting time
            if cntHere > 4 and currMaxErr > 1000.0*tolerance:
                errHistory.append(currMaxErr)
                
                #It needed to reduce the error 7 times more than 4 times in a row.
                #Indicator there could be something wrong
                if len(errHistory) > 4:
                    parent.InfoMessage('NotConverging', (parentPath,))
                    return x, rhs, converged, jacobian
            else:
                errHistory = []
            
            
        try:
            #parent.InfoMessage('JacobianIn:', (time.asctime(), time.time()))
            parent.InfoMessage('TowerCalcJacobian', (parentPath,))
            if solveMethod == NR and hasattr(parent, 'CalculateJacobian'):
                jacobian = zeros((nuEquations, nuEquations), Float)
                parent.CalculateJacobian(x, jacobian, isFix, initx)
                jacobian = inverse(jacobian) 
            
            elif solveMethod == BROYDEN:
                xLastBr = array(x)
                rhsLastBr = array(rhs)
                usedBr = True
                dF = rhs - oldRhs 
                dotdxB = dot(actualDeltaX, jacobian)
                denom = dot(dotdxB, dF)
                if not abs(denom) < TINYESTVALUE:
                    jacobian = jacobian + outerproduct((actualDeltaX - dot(jacobian, dF)), dotdxB)/denom

            else: #Do Secant
                xForJac = array(x, Float)
                rhsForJac = array(rhs, Float)
                shift = 0.0001
                
                #Pass a message every x calculations, so the solver doesn't look dead
                distCnt = 0
                msgEvery = freqJacMsg
                for j in range(nuEquations):
                    distCnt +=1
                    if distCnt == msgEvery:
                        parent.InfoMessage('CalcDisturbance', (j+1, nuEquations, parentPath))
                        distCnt = 0
                        
                    old = xForJac[j]
                    xForJac[j] = xForJac[j] + shift * scaleFactors[j]
                    parent.CalculateRHS(xForJac, rhsForJac, isFix, initx)
                    jacobian[:, j] = (rhsForJac - rhs)/(shift * scaleFactors[j])
                    xForJac[j] = old
           
                jacobian = inverse(jacobian)
                
            deltaX = -dot(jacobian, rhs)
            #parent.InfoMessage('JacobianOut:', (time.asctime(), time.time()))
            
        except:
            parent.InfoMessage('CouldNotInvertJacobian', (parentPath,))
            break
    
    parent.InfoMessage('CouldNotConverge', (parentPath, iter))
    return x, rhs, converged, jacobian
Beispiel #7
0
    def conservationScore( self, cons_type='cons_ent', ranNr=150,
                           log=StdLog(), verbose=1 ):
        """
        Score of conserved residue pairs in the interaction surface.
        Optionally, normalized by radom surface contacts.

        @param cons_type: precalculated conservation profile name,
                          see L{Biskit.PDBDope}.
        @type  cons_type: str
        @param ranNr: number of random matricies to use (default: 150)
        @type  ranNr: int
        @param log: log file [STDOUT]
        @type  log: Biskit.LogFile
        @param verbose: give progress report [1]
        @type  verbose: bool | int

        @return: conservation score
        @rtype: float
        """
        try:
            recCons = self.rec().profile( cons_type, updateMissing=1 )
        except:
            if verbose:
                log.add('\n'+'*'*30+'\nNO HHM PROFILE FOR RECEPTOR\n'+\
                        '*'*30+'\n')
            recCons = N.ones( self.rec().lenResidues() )
        try:
            ligCons = self.lig().profile( cons_type, updateMissing=1 )
        except:
            if verbose:
                log.add(\
                            '\n'+'*'*30+'\nNO HHM PROFILE FOR LIGAND\n'+'*'*30+'\n')
            ligCons = N.ones( self.lig().lenResidues() )

        if self.rec().profile( 'surfMask' ):
            recSurf = self.rec().profile( 'surfMask' )
        else:
            d = PDBDope(self.rec())
            d.addSurfaceMask()

        if self.lig().profile( 'surfMask' ):
            ligSurf = self.lig().profile( 'surfMask' )
        else:
            d = PDBDope(self.lig())
            d.addSurfaceMask()

        surfMask = N.ravel(N.outerproduct( recSurf, ligSurf ))

        missing = N.outerproduct( N.equal( recCons, 0), N.equal(ligCons,0))

        cont = self.resContacts() * N.logical_not(missing)

        consMat = N.outerproduct( recCons, ligCons )

        score = cont* consMat

        # get a random score
        if ranNr != 0:
            if self.verbose:
                self.log.write('.')
            ranMat =  mathUtils.random2DArray( cont, ranNr, mask=surfMask )
            random_score = N.sum(N.sum( ranMat * consMat ))/( ranNr*1.0 )
            return N.sum(N.sum(score))/random_score

        else:
            return N.sum(N.sum(score))/ N.sum(N.sum(cont))