Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
  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