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))
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
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
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
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)
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
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))