def __init__(self, fixed, moving): self.fixed = fixed self.moving = moving self.nsde = nsd_engine(self.fixed) self.d_fixed = math.sqrt(self.nsde.d_fixed) self.d_moving = math.sqrt(self.nsde.get_mean_distance(self.moving)) self.m_com = self.moving.mean() self.f_com = self.fixed.mean() self.n_mov = self.moving - self.m_com self.d = (self.d_fixed + self.d_moving) / 12 self.n = 6 pi = math.pi self.domain = [(-pi, pi), (-pi, pi), (-pi, pi), (-self.d, self.d), (-self.d, self.d), (-self.d, self.d)] self.x = None self.optimizer = de.differential_evolution_optimizer( self, population_size=12, f=0.85, cr=0.95, n_cross=2, eps=1e-2, show_progress=False, show_progress_nth_cycle=20)
def rosca(m=9, hemisphere=True): """ Regular grid on the unit sphere, Rosca (2010). """ def truncate(x): if (abs(x) < 1.e-6): return 0 else: return x def add(result, new): foud = False for s in result: d = math.sqrt((s[0] - new[0])**2 + (s[1] - new[1])**2 + (s[2] - new[2])**2) if (d < 1.e-3): return result.append(new) return d_l = math.sqrt(2) / m result = flex.vec3_double() for m_ in xrange(m + 1): if (m_ == 0): add(result, [0, 0, 1]) else: l_m = m_ * d_l d_phi = math.pi / (4 * m_) assert l_m >= 0 and l_m <= math.sqrt(2) for k in xrange(m_ + 1): arg1 = k * d_phi arg2 = l_m * math.sqrt(1 - l_m**2 / 4) x_km = truncate(math.cos(arg1) * arg2) y_km = truncate(math.sin(arg1) * arg2) z_m = truncate(1. - l_m**2 / 2) add(result, [x_km, y_km, z_m]) add(result, [y_km, x_km, z_m]) add(result, [-y_km, x_km, z_m]) add(result, [-x_km, y_km, z_m]) add(result, [x_km, -y_km, z_m]) add(result, [y_km, -x_km, z_m]) add(result, [-x_km, -y_km, z_m]) add(result, [-y_km, -x_km, z_m]) if (not hemisphere): add(result, [x_km, y_km, -z_m]) add(result, [y_km, x_km, -z_m]) add(result, [-y_km, x_km, -z_m]) add(result, [-x_km, y_km, -z_m]) add(result, [x_km, -y_km, -z_m]) add(result, [y_km, -x_km, -z_m]) add(result, [-x_km, -y_km, -z_m]) add(result, [-y_km, -x_km, -z_m]) for r in result: assert abs(1. - math.sqrt(r[0]**2 + r[1]**2 + r[2]**2)) < 1.e-6 # XXX for debugging if (0): f = "HETATM%5d O HOH A%4d %8.3f%8.3f%8.3f 1.00 23.99 O " o = open("junk.pdb", "w") for i, r in enumerate(result): print >> o, f % (i, i, r[0], r[1], r[2]) o.close() return result
def tst(): M = 10 xy = [] for ii in range(M): r = 10.0 phi = ii * (math.pi * 2 / M) x = r * math.cos(phi) y = r * math.sin(phi) xy.append(flex.double([x, y])) # build distance matrix dmat = [] for ii in range(M): tmp = [] for jj in range(M): x1 = xy[ii][0] x2 = xy[jj][0] y1 = xy[ii][1] y2 = xy[jj][1] dd = math.sqrt((x1 - x2)**2.0 + (y1 - y2)**2.0) if jj != ii: tmp.append((jj, dd)) dmat.append(tmp) spee = classic_spe_engine(dmat, l=1.0, max_cycle=5000) x, s = spee.embed(2, M) assert s < 1e-4 print("OK")
def embed(self, n_dimensions, n_points): x = [] for ii in range(n_points): x.append(flex.random_double(n_dimensions) * 100) l = float(self.l) for mm in range(self.max_cycle): atom_order = flex.sort_permutation(flex.random_double(len(x))) strain = 0.0 for ii in atom_order: n_contacts = len(self.dmat[ii]) jj_index = flex.sort_permutation( flex.random_double(n_contacts))[0] jj_info = self.dmat[ii][jj_index] jj = jj_info[0] td = jj_info[1] xi = x[ii] xj = x[jj] cd = math.sqrt(flex.sum((xi - xj) * (xi - xj))) new_xi = xi + l * 0.5 * (td - cd) / (cd + self.eps) * (xi - xj) new_xj = xj + l * 0.5 * (td - cd) / (cd + self.eps) * (xj - xi) strain += abs(cd - td) x[ii] = new_xi x[jj] = new_xj l = l - self.dl return x, strain / len(x)
def tst_dmatrix(): # expected values are the d_jmn at beta=1.0 and j=2, m=-2, -2<=n<=2 expect = [0.593133, 0.64806, 0.433605, 0.193411, 0.0528305] eps = 1e-4 d2 = dmatrix(2, 1.0) # dmatrix( max_L, beta ) for n in range(-2, 3): assert abs(expect[n + 2] - d2.djmn(2, -2, n)) < eps d4 = dmatrix(4, 1.0) for n in range(-2, 3): assert abs(expect[n + 2] - d4.djmn(2, -2, n)) < eps d7 = dmatrix(2, 1.0) for n in range(-2, 3): assert abs(expect[n + 2] - d7.djmn(2, -2, n)) < eps # check agains d(2,2,1) = -(1+cos(beta))*sin(beta)/2.0 for ii in range(10): expt = -(1.0 + math.cos(ii)) * math.sin(ii) / 2.0 assert abs(dmatrix(2, ii).djmn(2, 2, 1) - expt) < eps # check beta= multiple of pi/2 assert abs(dmatrix(20, math.pi).djmn(2, 2, 0)) < eps assert abs(dmatrix(2, math.pi * 2).djmn(2, 2, 0)) < eps assert abs( dmatrix(20, math.pi * 0.5).djmn(2, 2, 0) - math.sqrt(6.0) / 4.0) < eps
def kabsch_rotation(reference_sites, other_sites): """ Kabsch, W. (1976). Acta Cryst. A32, 922-923. A solution for the best rotation to relate two sets of vectors Based on a prototype by Erik McKee and Reetal K. Pai. This implementation does not handle degenerate situations correctly (e.g. if all atoms are on a line or plane) and should therefore not be used in applications. It is retained here for development purposes only. """ assert reference_sites.size() == other_sites.size() sts = matrix.sqr(other_sites.transpose_multiply(reference_sites)) eigs = eigensystem.real_symmetric((sts * sts.transpose()).as_sym_mat3()) vals = list(eigs.values()) vecs = list(eigs.vectors()) a3 = list(matrix.col(vecs[:3]).cross(matrix.col(vecs[3:6]))) a = matrix.sqr(list(vecs[:6]) + a3) b = list(a * sts) for i in xrange(3): d = math.sqrt(math.fabs(vals[i])) if (d > 0): for j in xrange(3): b[i * 3 + j] /= d b3 = list(matrix.col(b[:3]).cross(matrix.col(b[3:6]))) b = matrix.sqr(b[:6] + b3) return b.transpose() * a
def add(result, new): foud = False for s in result: d = math.sqrt((s[0] - new[0])**2 + (s[1] - new[1])**2 + (s[2] - new[2])**2) if (d < 1.e-3): return result.append(new) return
def nsd(self, moving, d_moving=None): if self.d_moving is None: self.d_moving = self.get_mean_distance(moving) if d_moving is not None: self.d_moving = d_moving # loop over all sites in fixed, find the minimum for each site tot_rho_mf = 0 tot_rho_fm = 0 for site in moving: dd = self.fixed - site dd = flex.min(dd.norms()) tot_rho_mf += dd * dd for site in self.fixed: dd = moving - site dd = flex.min(dd.norms()) tot_rho_fm += dd tot_rho_fm = tot_rho_fm / (self.fixed.size() * self.d_fixed) tot_rho_mf = tot_rho_mf / (moving.size() * self.d_moving) result = math.sqrt((tot_rho_fm + tot_rho_mf) / 2.0) return result
def get_mean_sigma( nlm_array ): coef = nlm_array.coefs() mean = abs( coef[0] ) var = flex.sum( flex.norm(coef) ) sigma = math.sqrt( var-mean*mean ) return mean, sigma
def scan( self ): fft = fftpack.complex_to_complex_2d( self.ngrid, self.ngrid ) inversion = False for beta in self.beta: self.cc_obj.set_beta( beta ) mm = self.cc_obj.mm_coef(0,inversion) if( self.pad > 0): mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input= mm scores = fft.backward( fft_input ).as_1d() self.scores = self.scores.concatenate( -flex.norm( scores ) ) self.best_indx = flex.min_index( self.scores ) self.best_score = math.sqrt( -self.scores[ self.best_indx ]) if self.check_inversion: ### Inversion of the Spherical Harmonics ### inversion = True inversion_scores = flex.double() for beta in self.beta: self.cc_obj.set_beta( beta ) mm = self.cc_obj.mm_coef(0,inversion) if( self.pad > 0): mm = self.cc_obj.mm_coef(self.pad, inversion) fft_input= mm.deep_copy() scores = fft.backward( fft_input ).as_1d() inversion_scores = inversion_scores.concatenate( -flex.norm( scores ) ) inv_best_indx = flex.min_index( inversion_scores ) inv_best_score = math.sqrt(-inversion_scores[ inv_best_indx ] ) if( inv_best_score < self.best_score ): self.score = inversion_scores self.best_indx = inv_best_indx self.best_score = inv_best_score self.inversion = True else: self.inversion = False b=self.best_indx//(self.ngrid*self.ngrid) a=(self.best_indx - self.ngrid*self.ngrid*b ) // self.ngrid g=self.best_indx - self.ngrid*self.ngrid*b - self.ngrid*a b = self.beta[b] g = math.pi*2.0 *( float(g)/(self.ngrid-1) ) a = math.pi*2.0 *( float(a)/(self.ngrid-1) ) self.best_ea = (a, b, g ) self.find_top( self.topn ) if( self.refine ): self.refined = [] self.refined_moving_nlm = [] self.refined_score = flex.double() for t in self.top_align: r = self.run_simplex( t ) self.refined.append ( r ) self.refined_score.append( self.get_cc( self.target( r ) ) ) self.refined_moving_nlm.append( self.cc_obj.rotate_moving_obj( r[0],r[1], r[2], self.inversion ) ) orders=flex.sort_permutation( self.refined_score, True ) self.best_score = -self.refined_score[orders[0]] # show the refined results if( self.show_result ): print("refined results:") for ii in range( self.topn ): o = orders[ii] o = ii print(ii, ":", list( self.refined[o] ), ":", self.refined_score[o]) ea = self.refined[ orders[0] ] self.best_ea = (ea[0], ea[1], ea[2] ) self.moving_nlm = self.cc_obj.rotate_moving_obj( ea[0],ea[1], ea[2], self.inversion )
def rms(flex_double): return math.sqrt(flex.mean(flex.pow2(flex_double)))