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 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
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
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)
def __init__(self, characteristic_grid, max_cell): SimpleSamplerTool.__init__(self, characteristic_grid) self.construct_hemisphere_grid(self.incr) self.max_cell = max_cell
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
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