Exemple #1
0
def test_simple_sampler():
    # SimpleSamplerTool migrated from Python to C++.
    SST = SimpleSamplerTool(0.014)
    SST.construct_hemisphere_grid(SST.incr)
    result = (SST.incr == 0.014)
    result &= (len(SST.angles) == 32227)
    reference_psi = [
        0.0, 0.014024967203525862, 0.028049934407051724, 0.042074901610577586,
        0.056099868814103448, 0.070124836017629311, 0.084149803221155173,
        0.098174770424681035, 0.1121997376282069, 0.12622470483173276,
        0.14024967203525862, 0.15427463923878448, 0.16829960644231035,
        0.18232457364583621, 0.19634954084936207, 0.21037450805288793,
        0.22439947525641379, 0.23842444245993966, 0.25244940966346552,
        0.26647437686699138, 0.28049934407051724, 0.2945243112740431,
        0.30854927847756897, 0.32257424568109483, 0.33659921288462069,
        0.35062418008814655, 0.36464914729167242, 0.37867411449519828,
        0.39269908169872414, 0.40672404890225, 0.42074901610577586,
        0.43477398330930173, 0.44879895051282759, 0.46282391771635345,
        0.47684888491987931, 0.49087385212340517, 0.50489881932693104,
        0.5189237865304569, 0.53294875373398276, 0.54697372093750862,
        0.56099868814103448, 0.57502365534456035, 0.58904862254808621,
        0.60307358975161207, 0.61709855695513793, 0.6311235241586638,
        0.64514849136218966, 0.65917345856571552, 0.67319842576924138,
        0.68722339297276724, 0.70124836017629311, 0.71527332737981897,
        0.72929829458334483, 0.74332326178687069, 0.75734822899039655,
        0.77137319619392242, 0.78539816339744828, 0.79942313060097414,
        0.8134480978045, 0.82747306500802587, 0.84149803221155173,
        0.85552299941507759, 0.86954796661860345, 0.88357293382212931,
        0.89759790102565518, 0.91162286822918104, 0.9256478354327069,
        0.93967280263623276, 0.95369776983975862, 0.96772273704328449,
        0.98174770424681035, 0.99577267145033621, 1.0097976386538621,
        1.0238226058573878, 1.0378475730609138, 1.0518725402644398,
        1.0658975074679655, 1.0799224746714913, 1.0939474418750172,
        1.1079724090785432, 1.121997376282069, 1.1360223434855947,
        1.1500473106891207, 1.1640722778926467, 1.1780972450961724,
        1.1921222122996982, 1.2061471795032241, 1.2201721467067501,
        1.2341971139102759, 1.2482220811138016, 1.2622470483173276,
        1.2762720155208536, 1.2902969827243793, 1.3043219499279051,
        1.318346917131431, 1.332371884334957, 1.3463968515384828,
        1.3604218187420085, 1.3744467859455345, 1.3884717531490605,
        1.4024967203525862, 1.416521687556112, 1.4305466547596379,
        1.4445716219631639, 1.4585965891666897, 1.4726215563702154,
        1.4866465235737414, 1.5006714907772674, 1.5146964579807931,
        1.5287214251843189, 1.5427463923878448, 1.5567713595913708,
        1.5707963267948966
    ]
    all_psi = []
    for i in SST.angles:
        if i.psi not in all_psi: all_psi.append(i.psi)
    result &= (all_psi == reference_psi)
    one_slice_phi = [
        i.phi for i in SST.angles if i.psi == 0.014024967203525862
    ]
    reference_phi = [
        0.0, 1.0471975511965976, 2.0943951023931953, 3.1415926535897931,
        4.1887902047863905, 5.2359877559829879
    ]
    result &= (one_slice_phi == reference_phi)
    return result
Exemple #2
0
def test_simple_sampler():
  # SimpleSamplerTool migrated from Python to C++.
  SST = SimpleSamplerTool(0.014)
  SST.construct_hemisphere_grid(SST.incr)
  result = (SST.incr == 0.014)
  result &= (len(SST.angles) == 32227)
  reference_psi = [0.0, 0.014024967203525862, 0.028049934407051724, 0.042074901610577586, 0.056099868814103448, 0.070124836017629311, 0.084149803221155173, 0.098174770424681035, 0.1121997376282069, 0.12622470483173276, 0.14024967203525862, 0.15427463923878448, 0.16829960644231035, 0.18232457364583621, 0.19634954084936207, 0.21037450805288793, 0.22439947525641379, 0.23842444245993966, 0.25244940966346552, 0.26647437686699138, 0.28049934407051724, 0.2945243112740431, 0.30854927847756897, 0.32257424568109483, 0.33659921288462069, 0.35062418008814655, 0.36464914729167242, 0.37867411449519828, 0.39269908169872414, 0.40672404890225, 0.42074901610577586, 0.43477398330930173, 0.44879895051282759, 0.46282391771635345, 0.47684888491987931, 0.49087385212340517, 0.50489881932693104, 0.5189237865304569, 0.53294875373398276, 0.54697372093750862, 0.56099868814103448, 0.57502365534456035, 0.58904862254808621, 0.60307358975161207, 0.61709855695513793, 0.6311235241586638, 0.64514849136218966, 0.65917345856571552, 0.67319842576924138, 0.68722339297276724, 0.70124836017629311, 0.71527332737981897, 0.72929829458334483, 0.74332326178687069, 0.75734822899039655, 0.77137319619392242, 0.78539816339744828, 0.79942313060097414, 0.8134480978045, 0.82747306500802587, 0.84149803221155173, 0.85552299941507759, 0.86954796661860345, 0.88357293382212931, 0.89759790102565518, 0.91162286822918104, 0.9256478354327069, 0.93967280263623276, 0.95369776983975862, 0.96772273704328449, 0.98174770424681035, 0.99577267145033621, 1.0097976386538621, 1.0238226058573878, 1.0378475730609138, 1.0518725402644398, 1.0658975074679655, 1.0799224746714913, 1.0939474418750172, 1.1079724090785432, 1.121997376282069, 1.1360223434855947, 1.1500473106891207, 1.1640722778926467, 1.1780972450961724, 1.1921222122996982, 1.2061471795032241, 1.2201721467067501, 1.2341971139102759, 1.2482220811138016, 1.2622470483173276, 1.2762720155208536, 1.2902969827243793, 1.3043219499279051, 1.318346917131431, 1.332371884334957, 1.3463968515384828, 1.3604218187420085, 1.3744467859455345, 1.3884717531490605, 1.4024967203525862, 1.416521687556112, 1.4305466547596379, 1.4445716219631639, 1.4585965891666897, 1.4726215563702154, 1.4866465235737414, 1.5006714907772674, 1.5146964579807931, 1.5287214251843189, 1.5427463923878448, 1.5567713595913708, 1.5707963267948966]
  all_psi = []
  for i in SST.angles:
    if i.psi not in all_psi:  all_psi.append(i.psi)
  result &= (all_psi==reference_psi)
  one_slice_phi = [i.phi for i in SST.angles if i.psi==0.014024967203525862]
  reference_phi = [0.0, 1.0471975511965976, 2.0943951023931953, 3.1415926535897931, 4.1887902047863905, 5.2359877559829879]
  result &= (one_slice_phi==reference_phi)
  return result
  def two_color_grid_search(self):
    '''creates candidate reciprocal lattice points based on two beams and performs
    2-D grid search based on maximizing the functional using N_UNIQUE_V candidate
    vectors (N_UNIQUE_V is usually 30 from Guildea paper)'''

    assert len(self.imagesets) == 1
    detector = self.imagesets[0].get_detector()

    mm_spot_pos = self.map_spots_pixel_to_mm_rad(self.reflections,detector,scan=None)

    self.map_centroids_to_reciprocal_space(mm_spot_pos,detector,self.beams[0],
                                           goniometer=None)
    self.reciprocal_lattice_points1 = mm_spot_pos['rlp'].select(
          (self.reflections['id'] == -1))

    rlps1 = mm_spot_pos['rlp'].select(
          (self.reflections['id'] == -1))

    self.map_centroids_to_reciprocal_space(mm_spot_pos,detector,self.beams[1],
                                           goniometer=None)
    self.reciprocal_lattice_points2 = mm_spot_pos['rlp'].select(
          (self.reflections['id'] == -1))
    # assert len(self.beams) == 3
    rlps2 = mm_spot_pos['rlp'].select(
          (self.reflections['id'] == -1))

    self.reciprocal_lattice_points=rlps1.concatenate(rlps2)

    #self.map_centroids_to_reciprocal_space(mm_spot_pos,detector,self.beams[2],goniometer=None)

    #self.reciprocal_lattice_points = mm_spot_pos['rlp'].select(
     #          (self.reflections['id'] == -1)&(1/self.reflections['rlp'].norms() > d_min))

    print "Indexing from %i reflections" %len(self.reciprocal_lattice_points)

    def compute_functional(vector):
      '''computes functional for 2-D grid search'''
      two_pi_S_dot_v = 2 * math.pi * self.reciprocal_lattice_points.dot(vector)
      return flex.sum(flex.cos(two_pi_S_dot_v))

    from rstbx.array_family import flex
    from rstbx.dps_core import SimpleSamplerTool
    assert self.target_symmetry_primitive is not None
    assert self.target_symmetry_primitive.unit_cell() is not None
    SST = SimpleSamplerTool(
      self.params.real_space_grid_search.characteristic_grid)
    SST.construct_hemisphere_grid(SST.incr)
    cell_dimensions = self.target_symmetry_primitive.unit_cell().parameters()[:3]
    unique_cell_dimensions = set(cell_dimensions)

    print("Makring search vecs")
    spiral_method = True
    if spiral_method:
        basis_vec_noise =True
        noise_scale = 2.
        #_N = 200000   # massively oversample the hemisphere so we can apply noise to our search
        _N = 100000
        print "Number of search vectors: %i" %( _N * len(unique_cell_dimensions))
        J = _N*2
        _thetas = [np.arccos( (2.*j - 1. - J)/J)
            for j in range(1,J+1)]
        _phis = [ np.sqrt( np.pi*J) *np.arcsin( (2.*j - 1. - J)/J )
            for j in range(1,J+1)]
        _x = np.sin(_thetas)*np.cos(_phis)
        _y = np.sin(_thetas)*np.sin(_phis)
        _z = np.cos(_thetas)
        nn = int(_N * 1.01)
        _u_vecs = np.array(zip(_x,_y,_z))[-nn:]

        rec_pts = np.array([self.reciprocal_lattice_points[i] for i in range(len(self.reciprocal_lattice_points))])
        N_unique = len(unique_cell_dimensions)

        # much faster to use numpy for massively over-sampled hemisphere..
        func_vals = np.zeros( nn*N_unique)
        vecs = np.zeros( (nn*N_unique, 3) )
        for i, l in enumerate(unique_cell_dimensions):
          # create noise model on top of lattice lengths...
          if basis_vec_noise:
            vec_mag = np.random.normal( l, scale=noise_scale, size=_u_vecs.shape[0] )
            vec_mag = vec_mag[:,None]
          else:
            vec_mag = l

          ul = _u_vecs * vec_mag
          func_slc = slice( i*nn, (i+1)*nn)
          vecs[func_slc] = ul
          func_vals[func_slc] = np.sum( np.cos( 2*np.pi*np.dot(rec_pts, ul.T) ),
                                      axis=0)

        order = np.argsort(func_vals)[::-1]  # sort function values, largest values first
        function_values = func_vals[order]
        vectors = vecs[order]

    else:  # fall back on original flex method
        vectors = flex.vec3_double()
        function_values = flex.double()
        print "Number of search vectors: %i" % (   len(SST.angles)* len(unique_cell_dimensions))
        for i, direction in enumerate(SST.angles):
          for l in unique_cell_dimensions:
            v = matrix.col(direction.dvec) * l
            f = compute_functional(v.elems)
            vectors.append(v.elems)
            function_values.append(f)
        perm = flex.sort_permutation(function_values, reverse=True)
        vectors = vectors.select(perm)
        function_values = function_values.select(perm)

    print("made search vecs")

    unique_vectors = []
    i = 0
    while len(unique_vectors) < N_UNIQUE_V:
      v = matrix.col(vectors[i])
      is_unique = True
      if i > 0:
        for v_u in unique_vectors:
          if v.length() < v_u.length():
            if is_approximate_integer_multiple(v, v_u):
              is_unique = False
              break
          elif is_approximate_integer_multiple(v_u, v):
            is_unique = False
            break
      if is_unique:
        unique_vectors.append(v)
      i += 1

    print ("chose unique basis vecs")
    if self.params.debug:
      for i in range(N_UNIQUE_V):
        v = matrix.col(vectors[i])
        print v.elems, v.length(), function_values[i]

    basis_vectors = [v.elems for v in unique_vectors]
    self.candidate_basis_vectors = basis_vectors

    if self.params.optimise_initial_basis_vectors:
      self.params.optimize_initial_basis_vectors = False
      # todo: verify this reference to self.reciprocal_lattice_points is correct
      optimised_basis_vectors = optimise_basis_vectors(
        self.reciprocal_lattice_points, basis_vectors)
      optimised_function_values = flex.double([
        compute_functional(v) for v in optimised_basis_vectors])

      perm = flex.sort_permutation(optimised_function_values, reverse=True)
      optimised_basis_vectors = optimised_basis_vectors.select(perm)
      optimised_function_values = optimised_function_values.select(perm)

      unique_vectors = [matrix.col(v) for v in optimised_basis_vectors]

    print "Number of unique vectors: %i" %len(unique_vectors)

    if self.params.debug:
      for i in range(len(unique_vectors)):
        print compute_functional(unique_vectors[i].elems), unique_vectors[i].length(), unique_vectors[i].elems
        print

    crystal_models = []
    self.candidate_basis_vectors = unique_vectors

    if self.params.debug:
      self.debug_show_candidate_basis_vectors()
    if self.params.debug_plots:
      self.debug_plot_candidate_basis_vectors()


    candidate_orientation_matrices \
      = self.find_candidate_orientation_matrices(
        unique_vectors)
        # max_combinations=self.params.basis_vector_combinations.max_try)

    FILTER_BY_MAG = True
    if FILTER_BY_MAG:
      print("\n\n FILTERING BY MAG\n\n")
      FILTER_TOL = 10,3   # within 5 percent of params and 1 percent of ang
      target_uc = self.params.known_symmetry.unit_cell.parameters()
      good_mats = []
      for c in candidate_orientation_matrices:
        uc = c.get_unit_cell().parameters()
        comps = []
        for i in range(3):
          tol = 0.01* FILTER_TOL[0] * target_uc[i]
          low = target_uc[i] - tol/2.
          high = target_uc[i] + tol/2
          comps.append(  low < uc[i] < high )
        for i in range(3,6):
          low = target_uc[i] - FILTER_TOL[1]
          high = target_uc[i] + FILTER_TOL[1]
          comps.append( low < uc[i] < high )
        if all( comps):
          print("matrix is ok:", c)
          good_mats.append(c)
        print("\nFilter kept %d / %d mats" % \
              (len(good_mats), len(candidate_orientation_matrices)))
      candidate_orientation_matrices = good_mats

    crystal_model, n_indexed = self.choose_best_orientation_matrix(
      candidate_orientation_matrices)
    orange = 2
    if crystal_model is not None:
      crystal_models = [crystal_model]
    else:
      crystal_models = []

    #assert len(crystal_models) > 0

    candidate_orientation_matrices = crystal_models

    #for i in range(len(candidate_orientation_matrices)):
      #if self.target_symmetry_primitive is not None:
        ##print "symmetrizing model"
        ##self.target_symmetry_primitive.show_summary()
        #symmetrized_model = self.apply_symmetry(
          #candidate_orientation_matrices[i], self.target_symmetry_primitive)
        #candidate_orientation_matrices[i] = symmetrized_model
    self.candidate_crystal_models = candidate_orientation_matrices

    # memory leak somewhere... probably not here.. but just in case...
    del _x, _y, _z, _u_vecs, order, rec_pts, vecs, func_vals, vectors, function_values
  def real_space_grid_search(self):
    d_min = self.params.refinement_protocol.d_min_start

    sel = (self.reflections['id'] == -1)
    if d_min is not None:
      sel &= (1/self.reflections['rlp'].norms() > d_min)
    reciprocal_lattice_points = self.reflections['rlp'].select(sel)

    logger.info("Indexing from %i reflections" %len(reciprocal_lattice_points))

    def compute_functional(vector):
      two_pi_S_dot_v = 2 * math.pi * reciprocal_lattice_points.dot(vector)
      return flex.sum(flex.cos(two_pi_S_dot_v))

    from rstbx.array_family import flex
    from rstbx.dps_core import SimpleSamplerTool
    assert self.target_symmetry_primitive is not None
    assert self.target_symmetry_primitive.unit_cell() is not None
    SST = SimpleSamplerTool(
      self.params.real_space_grid_search.characteristic_grid)
    SST.construct_hemisphere_grid(SST.incr)
    cell_dimensions = self.target_symmetry_primitive.unit_cell().parameters()[:3]
    unique_cell_dimensions = set(cell_dimensions)
    logger.info(
      "Number of search vectors: %i" %(len(SST.angles) * len(unique_cell_dimensions)))
    vectors = flex.vec3_double()
    function_values = flex.double()
    for i, direction in enumerate(SST.angles):
      for l in unique_cell_dimensions:
        v = matrix.col(direction.dvec) * l
        f = compute_functional(v.elems)
        vectors.append(v.elems)
        function_values.append(f)

    perm = flex.sort_permutation(function_values, reverse=True)
    vectors = vectors.select(perm)
    function_values = function_values.select(perm)

    unique_vectors = []
    i = 0
    while len(unique_vectors) < 30:
      v = matrix.col(vectors[i])
      is_unique = True
      if i > 0:
        for v_u in unique_vectors:
          if v.length() < v_u.length():
            if is_approximate_integer_multiple(v, v_u):
              is_unique = False
              break
          elif is_approximate_integer_multiple(v_u, v):
            is_unique = False
            break
      if is_unique:
        unique_vectors.append(v)
      i += 1

    for i in range(30):
      v = matrix.col(vectors[i])
      logger.debug("%s %s %s" %(str(v.elems), str(v.length()), str(function_values[i])))

    basis_vectors = [v.elems for v in unique_vectors]
    self.candidate_basis_vectors = basis_vectors

    if self.params.optimise_initial_basis_vectors:
      optimised_basis_vectors = optimise_basis_vectors(
        reciprocal_lattice_points, basis_vectors)
      optimised_function_values = flex.double([
        compute_functional(v) for v in optimised_basis_vectors])

      perm = flex.sort_permutation(optimised_function_values, reverse=True)
      optimised_basis_vectors = optimised_basis_vectors.select(perm)
      optimised_function_values = optimised_function_values.select(perm)

      unique_vectors = [matrix.col(v) for v in optimised_basis_vectors]

    logger.info("Number of unique vectors: %i" %len(unique_vectors))

    for i in range(len(unique_vectors)):
      logger.debug("%s %s %s" %(
        str(compute_functional(unique_vectors[i].elems)),
        str(unique_vectors[i].length()),
        str(unique_vectors[i].elems)))

    crystal_models = []
    self.candidate_basis_vectors = unique_vectors
    self.debug_show_candidate_basis_vectors()
    if self.params.debug_plots:
      self.debug_plot_candidate_basis_vectors()
    candidate_orientation_matrices \
      = self.find_candidate_orientation_matrices(
        unique_vectors,
        max_combinations=self.params.basis_vector_combinations.max_try)
    crystal_model, n_indexed = self.choose_best_orientation_matrix(
      candidate_orientation_matrices)
    if crystal_model is not None:
      crystal_models = [crystal_model]
    else:
      crystal_models = []

    #assert len(crystal_models) > 0

    candidate_orientation_matrices = crystal_models

    #for i in range(len(candidate_orientation_matrices)):
      #if self.target_symmetry_primitive is not None:
        ##print "symmetrizing model"
        ##self.target_symmetry_primitive.show_summary()
        #symmetrized_model = self.apply_symmetry(
          #candidate_orientation_matrices[i], self.target_symmetry_primitive)
        #candidate_orientation_matrices[i] = symmetrized_model

    self.candidate_crystal_models = candidate_orientation_matrices
Exemple #5
0
    def get_finegrained_SST(self, coarse_sampling_grid=0.005):
        d_min = self.params.refinement_protocol.d_min_start
        sel = self.reflections["id"] == -1
        if d_min is not None:
            sel &= 1 / self.reflections["rlp"].norms() > d_min
        reciprocal_lattice_points = self.reflections["rlp"].select(sel)
        print("Indexing from %i reflections COARSE" %
              len(reciprocal_lattice_points))

        from rstbx.array_family import flex
        from rstbx.dps_core import SimpleSamplerTool

        assert self.target_symmetry_primitive is not None
        assert self.target_symmetry_primitive.unit_cell() is not None
        SST = SimpleSamplerTool(coarse_sampling_grid)
        SST.construct_hemisphere_grid(SST.incr)
        cell_dimensions = self.target_symmetry_primitive.unit_cell(
        ).parameters()[:3]
        unique_cell_dimensions = set(cell_dimensions)
        print("Number of search vectors COARSE: %i" %
              (len(SST.angles) * len(unique_cell_dimensions)))
        vectors = flex.vec3_double()
        function_values = flex.double()
        import time
        time1 = time.time()
        SST_all_angles = flex.Direction()
        for i, direction in enumerate(SST.angles):
            for l in unique_cell_dimensions:
                v = matrix.col(direction.dvec) * l
                f = compute_functional(v.elems, reciprocal_lattice_points)
                vectors.append(v.elems)
                function_values.append(f)
                SST_all_angles.append(direction)
        time2 = time.time()
        print('COARSE GRID SEARCH TIME=', time2 - time1)

        perm = flex.sort_permutation(function_values, reverse=True)
        vectors = vectors.select(perm)
        function_values = function_values.select(perm)

        unique_vectors = []
        unique_indices = []
        i = 0
        while len(unique_vectors) < 30:
            v = matrix.col(vectors[i])
            is_unique = True
            if i > 0:
                for v_u in unique_vectors:
                    if v.length() < v_u.length():
                        if is_approximate_integer_multiple(
                                v,
                                v_u,
                                relative_tolerance=0.2,
                                angular_tolerance=5.0):
                            is_unique = False
                            break
                    elif is_approximate_integer_multiple(
                            v_u, v, relative_tolerance=0.2,
                            angular_tolerance=5.0):
                        is_unique = False
                        break
            if is_unique:
                unique_vectors.append(v)
                unique_indices.append(perm[i])
            i += 1

        # Evaluate which SST angles contributed to the unique vectors
        SST_filter = flex.Direction()
        for v in unique_indices:
            direction = SST.angles[v // len(unique_cell_dimensions)]
            SST_filter.append(direction)
        SST.construct_hemisphere_grid_finegrained(0.0001, coarse_sampling_grid,
                                                  SST_filter)
        return SST
Exemple #6
0
 def search_directions(self):
     """Generator of the search directions (i.e. vectors with length 1)."""
     SST = SimpleSamplerTool(self._params.characteristic_grid)
     SST.construct_hemisphere_grid(SST.incr)
     for direction in SST.angles:
         yield matrix.col(direction.dvec)
Exemple #7
0
 def __init__(self, characteristic_grid, max_cell):
     SimpleSamplerTool.__init__(self, characteristic_grid)
     self.construct_hemisphere_grid(self.incr)
     self.max_cell = max_cell
Exemple #8
0
    def real_space_grid_search(self):
        d_min = self.params.refinement_protocol.d_min_start

        sel = (self.reflections['id'] == -1)
        if d_min is not None:
            sel &= (1 / self.reflections['rlp'].norms() > d_min)
        reciprocal_lattice_points = self.reflections['rlp'].select(sel)

        logger.info("Indexing from %i reflections" %
                    len(reciprocal_lattice_points))

        def compute_functional(vector):
            two_pi_S_dot_v = 2 * math.pi * reciprocal_lattice_points.dot(
                vector)
            return flex.sum(flex.cos(two_pi_S_dot_v))

        from rstbx.array_family import flex
        from rstbx.dps_core import SimpleSamplerTool
        assert self.target_symmetry_primitive is not None
        assert self.target_symmetry_primitive.unit_cell() is not None
        SST = SimpleSamplerTool(
            self.params.real_space_grid_search.characteristic_grid)
        SST.construct_hemisphere_grid(SST.incr)
        cell_dimensions = self.target_symmetry_primitive.unit_cell(
        ).parameters()[:3]
        unique_cell_dimensions = set(cell_dimensions)
        logger.info("Number of search vectors: %i" %
                    (len(SST.angles) * len(unique_cell_dimensions)))
        vectors = flex.vec3_double()
        function_values = flex.double()
        for i, direction in enumerate(SST.angles):
            for l in unique_cell_dimensions:
                v = matrix.col(direction.dvec) * l
                f = compute_functional(v.elems)
                vectors.append(v.elems)
                function_values.append(f)

        perm = flex.sort_permutation(function_values, reverse=True)
        vectors = vectors.select(perm)
        function_values = function_values.select(perm)

        unique_vectors = []
        i = 0
        while len(unique_vectors) < 30:
            v = matrix.col(vectors[i])
            is_unique = True
            if i > 0:
                for v_u in unique_vectors:
                    if v.length() < v_u.length():
                        if is_approximate_integer_multiple(v, v_u):
                            is_unique = False
                            break
                    elif is_approximate_integer_multiple(v_u, v):
                        is_unique = False
                        break
            if is_unique:
                unique_vectors.append(v)
            i += 1

        for i in range(30):
            v = matrix.col(vectors[i])
            logger.debug(
                "%s %s %s" %
                (str(v.elems), str(v.length()), str(function_values[i])))

        basis_vectors = [v.elems for v in unique_vectors]
        self.candidate_basis_vectors = basis_vectors

        if self.params.optimise_initial_basis_vectors:
            optimised_basis_vectors = optimise_basis_vectors(
                reciprocal_lattice_points, basis_vectors)
            optimised_function_values = flex.double(
                [compute_functional(v) for v in optimised_basis_vectors])

            perm = flex.sort_permutation(optimised_function_values,
                                         reverse=True)
            optimised_basis_vectors = optimised_basis_vectors.select(perm)
            optimised_function_values = optimised_function_values.select(perm)

            unique_vectors = [matrix.col(v) for v in optimised_basis_vectors]

        logger.info("Number of unique vectors: %i" % len(unique_vectors))

        for i in range(len(unique_vectors)):
            logger.debug(
                "%s %s %s" % (str(compute_functional(
                    unique_vectors[i].elems)), str(unique_vectors[i].length()),
                              str(unique_vectors[i].elems)))

        crystal_models = []
        self.candidate_basis_vectors = unique_vectors
        self.debug_show_candidate_basis_vectors()
        if self.params.debug_plots:
            self.debug_plot_candidate_basis_vectors()
        candidate_orientation_matrices \
          = self.find_candidate_orientation_matrices(
            unique_vectors,
            max_combinations=self.params.basis_vector_combinations.max_try)
        crystal_model, n_indexed = self.choose_best_orientation_matrix(
            candidate_orientation_matrices)
        if crystal_model is not None:
            crystal_models = [crystal_model]
        else:
            crystal_models = []

        #assert len(crystal_models) > 0

        candidate_orientation_matrices = crystal_models

        #for i in range(len(candidate_orientation_matrices)):
        #if self.target_symmetry_primitive is not None:
        ##print "symmetrizing model"
        ##self.target_symmetry_primitive.show_summary()
        #symmetrized_model = self.apply_symmetry(
        #candidate_orientation_matrices[i], self.target_symmetry_primitive)
        #candidate_orientation_matrices[i] = symmetrized_model

        self.candidate_crystal_models = candidate_orientation_matrices
Exemple #9
0
 def __init__(self,characteristic_grid,max_cell):
   SimpleSamplerTool.__init__(self,characteristic_grid)
   self.construct_hemisphere_grid(self.incr)
   self.max_cell=max_cell
    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.

        """
        from rstbx.array_family import (
            flex,
        )  # required to load scitbx::af::shared<rstbx::Direction> to_python converter

        used_in_indexing = flex.bool(reciprocal_lattice_vectors.size(), True)

        logger.info("Indexing from %i reflections" %
                    used_in_indexing.count(True))

        def compute_functional(vector):
            two_pi_S_dot_v = 2 * math.pi * reciprocal_lattice_vectors.dot(
                vector)
            return flex.sum(flex.cos(two_pi_S_dot_v))

        from rstbx.dps_core import SimpleSamplerTool

        SST = SimpleSamplerTool(self._params.characteristic_grid)
        SST.construct_hemisphere_grid(SST.incr)
        cell_dimensions = self._target_unit_cell.parameters()[:3]
        unique_cell_dimensions = set(cell_dimensions)
        logger.info("Number of search vectors: %i" %
                    (len(SST.angles) * len(unique_cell_dimensions)))
        vectors = flex.vec3_double()
        function_values = flex.double()
        for i, direction in enumerate(SST.angles):
            for l in unique_cell_dimensions:
                v = matrix.col(direction.dvec) * l
                f = compute_functional(v.elems)
                vectors.append(v.elems)
                function_values.append(f)

        perm = flex.sort_permutation(function_values, reverse=True)
        vectors = vectors.select(perm)
        function_values = function_values.select(perm)

        unique_vectors = []
        i = 0
        while len(unique_vectors) < 30:
            v = matrix.col(vectors[i])
            is_unique = True
            if i > 0:
                for v_u in unique_vectors:
                    if v.length() < v_u.length():
                        if _is_approximate_integer_multiple(v, v_u):
                            is_unique = False
                            break
                    elif _is_approximate_integer_multiple(v_u, v):
                        is_unique = False
                        break
            if is_unique:
                unique_vectors.append(v)
            i += 1

        for i in range(30):
            v = matrix.col(vectors[i])
            logger.debug(
                "%s %s %s" %
                (str(v.elems), str(v.length()), str(function_values[i])))

        logger.info("Number of unique vectors: %i" % len(unique_vectors))

        for i in range(len(unique_vectors)):
            logger.debug("%s %s %s" % (
                str(compute_functional(unique_vectors[i].elems)),
                str(unique_vectors[i].length()),
                str(unique_vectors[i].elems),
            ))

        return unique_vectors, used_in_indexing