Ejemplo n.º 1
0
    def get_top_solutions(self, ai, input_directions, size, cutoff_divisor):
        # size was 30 in the Rossmann DPS paper
        kval_cutoff = ai.getXyzSize() / cutoff_divisor

        hemisphere_solutions = flex.Direction()
        hemisphere_solutions.reserve(size)

        for i in range(len(input_directions)):
            sampled_direction = ai.fft_result(input_directions[i])
            if sampled_direction.kval > kval_cutoff:
                hemisphere_solutions.append(sampled_direction)

        if (hemisphere_solutions.size() < 3):
            return hemisphere_solutions
        kvals = flex.double([
            hemisphere_solutions[x].kval
            for x in range(len(hemisphere_solutions))
        ])

        perm = flex.sort_permutation(kvals, True)

        #  conventional algorithm; just take the top scoring hits.
        #  use this for quick_grid, when it is known ahead of time
        #  that many (hundreds) of directions will be retained

        hemisphere_solutions_sort = flex.Direction(
            [hemisphere_solutions[p] for p in perm[0:min(size, len(perm))]])

        return hemisphere_solutions_sort
Ejemplo n.º 2
0
    def get_top_solutions(self, ai, input_directions, size, cutoff_divisor,
                          grid):

        kval_cutoff = ai.getXyzSize() / cutoff_divisor

        hemisphere_solutions = flex.Direction()
        hemisphere_solutions.reserve(size)
        #print "# of input directions", len(input_directions)
        for i in range(len(input_directions)):
            D = sampled_direction = ai.fft_result(input_directions[i])

            #hardcoded parameter in for silicon example.  Not sure at this point how
            #robust the algorithm is when this value is relaxed.

            if D.real < self.max_cell and sampled_direction.kval > kval_cutoff:
                if diagnostic: directional_show(D, "%5d" % i)
                hemisphere_solutions.append(sampled_direction)
        if (hemisphere_solutions.size() < 3):
            return hemisphere_solutions
        kvals = flex.double([
            hemisphere_solutions[x].kval
            for x in range(len(hemisphere_solutions))
        ])

        perm = flex.sort_permutation(kvals, True)

        #  need to be more clever than just taking the top 30.
        #  one huge cluster around a strong basis direction could dominate the
        #  whole hemisphere map, preventing the discovery of three basis vectors

        perm_idx = 0
        unique_clusters = 0
        hemisphere_solutions_sort = flex.Direction()
        while perm_idx < len(perm) and \
              unique_clusters < size:
            test_item = hemisphere_solutions[perm[perm_idx]]
            direction_ok = True
            for list_item in hemisphere_solutions_sort:
                distance = math.sqrt(
                    math.pow(list_item.dvec[0] - test_item.dvec[0], 2) +
                    math.pow(list_item.dvec[1] - test_item.dvec[1], 2) +
                    math.pow(list_item.dvec[2] - test_item.dvec[2], 2))
                if distance < 0.087:  #i.e., 5 degrees radius for clustering analysis
                    direction_ok = False
                    break
            if direction_ok:
                unique_clusters += 1
            hemisphere_solutions_sort.append(test_item)
            perm_idx += 1

        return hemisphere_solutions_sort
Ejemplo n.º 3
0
    def get_top_solutions(self, ai, input_directions, size, cutoff_divisor,
                          grid):
        # size was 30 in the Rossmann DPS paper

        kval_cutoff = ai.getXyzSize() / cutoff_divisor

        hemisphere_solutions = flex.Direction()
        hemisphere_solutions.reserve(size)
        for i in range(len(input_directions)):
            D = sampled_direction = ai.fft_result(input_directions[i])

            if D.real < self.max_cell_input and sampled_direction.kval > kval_cutoff:
                #directional_show(D, "ddd %5d"%i)
                hemisphere_solutions.append(sampled_direction)

        if (hemisphere_solutions.size() < 3):
            return hemisphere_solutions
        kvals = flex.double([
            hemisphere_solutions[x].kval
            for x in range(len(hemisphere_solutions))
        ])

        perm = flex.sort_permutation(kvals, True)

        #  need to be more clever than just taking the top 30.
        #  one huge cluster around a strong basis direction could dominate the
        #  whole hemisphere map, preventing the discovery of three basis vectors

        perm_idx = 0
        unique_clusters = 0
        hemisphere_solutions_sort = flex.Direction()
        while perm_idx < len(perm) and \
              unique_clusters < size:
            test_item = hemisphere_solutions[perm[perm_idx]]
            direction_ok = True
            for list_item in hemisphere_solutions_sort:
                distance = math.sqrt(
                    math.pow(list_item.dvec[0] - test_item.dvec[0], 2) +
                    math.pow(list_item.dvec[1] - test_item.dvec[1], 2) +
                    math.pow(list_item.dvec[2] - test_item.dvec[2], 2))
                if distance < 0.087:  #i.e., 5 degrees
                    direction_ok = False
                    break
            if direction_ok:
                unique_clusters += 1
                hemisphere_solutions_sort.append(test_item)
            perm_idx += 1

        return hemisphere_solutions_sort
Ejemplo n.º 4
0
 def refine_top_solutions_by_grid_search(self, old_solutions, ai):
     new_solutions = flex.Direction()
     final_target_grid = self.characteristic_grid / 100.
     for item in old_solutions:
         new_solutions.append(
             ai.refine_direction(candidate=item,
                                 current_grid=self.incr,
                                 target_grid=final_target_grid))
     return new_solutions
Ejemplo n.º 5
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