def find_basis_vectors(self, reciprocal_lattice_vectors): """Find a list of likely basis vectors. Args: reciprocal_lattice_vectors (scitbx.array_family.flex.vec3_double): The list of reciprocal lattice vectors to search for periodicity. """ used_in_indexing = flex.bool(reciprocal_lattice_vectors.size(), True) logger.info("Indexing from %i reflections" % used_in_indexing.count(True)) vectors, weights = self.score_vectors(reciprocal_lattice_vectors) perm = flex.sort_permutation(weights, reverse=True) vectors = vectors.select(perm) weights = weights.select(perm) groups = group_vectors(vectors, weights, max_groups=self._params.max_vectors) unique_vectors = [] unique_weights = [] for g in groups: idx = flex.max_index(flex.double(g.weights)) unique_vectors.append(g.vectors[idx]) unique_weights.append(g.weights[idx]) logger.info("Number of unique vectors: %i" % len(unique_vectors)) for v, w in zip(unique_vectors, unique_weights): logger.debug("%s %s %s" % (w, v.length(), str(v.elems))) return unique_vectors, used_in_indexing
def restrict_target_angles_to_quick_winners(self, quick_sampling): # find which target_grid directions are near neighbors to # the quick_sampling winners from the first round of testing. # in the second round, restrict the calculation of FFTs to those directions self.restricted = flex.Direction() target = flex.double() for iz in self.angles: # fairly inefficient in Python; expect big improvement in C++ v = iz.dvec target.append(v[0]) target.append(v[1]) target.append(v[2]) kn = int(2 * self.second_round_sampling) #construct k-d tree for the reference set A = AnnAdaptor(data=target, dim=3, k=kn) query = flex.double() for j in quick_sampling: v = j.dvec query.append(v[0]) query.append(v[1]) query.append(v[2]) if abs((math.pi / 2.) - j.psi) < 0.0001: #take care of equatorial boundary query.append(-v[0]) query.append(-v[1]) query.append(-v[2]) A.query(query) #find nearest neighbors of query points neighbors = flex.sqrt(A.distances) neighborid = A.nn accept_flag = flex.bool(len(self.angles)) for idx in range(len(neighbors)): # use small angle approximation to test if target is within desired radius if neighbors[idx] < self.quick_grid: accept_flag[neighborid[idx]] = True #go through all of the original target angles for iz in range(len(self.angles)): if accept_flag[iz]: self.restricted.append(self.angles[iz]) self.angles = self.restricted
def restrict_target_angles_to_quick_winners(self,quick_sampling): # find which target_grid directions are near neighbors to # the quick_sampling winners from the first round of testing. # in the second round, restrict the calculation of FFTs to those directions self.restricted = flex.Direction() target = flex.double() for iz in self.angles: # fairly inefficient in Python; expect big improvement in C++ v = iz.dvec target.append(v[0]);target.append(v[1]);target.append(v[2]); kn = int(2 *self.second_round_sampling) #construct k-d tree for the reference set A = AnnAdaptor(data = target, dim = 3, k = kn) query = flex.double() for j in quick_sampling: v = j.dvec query.append(v[0]);query.append(v[1]); query.append(v[2]); if abs((math.pi/2.) - j.psi) < 0.0001: #take care of equatorial boundary query.append(-v[0]);query.append(-v[1]); query.append(-v[2]); A.query(query) #find nearest neighbors of query points neighbors = flex.sqrt(A.distances) neighborid = A.nn accept_flag = flex.bool(len(self.angles)) for idx in xrange(len(neighbors)): # use small angle approximation to test if target is within desired radius if neighbors[idx] < self.quick_grid: accept_flag[neighborid[idx]] = True #go through all of the original target angles for iz in xrange(len(self.angles)): if accept_flag[iz]: self.restricted.append(self.angles[iz]) self.angles = self.restricted