def torsion_search_nested(clusters, sites_cart, last_chi_symmetric=None, increment_degrees=10): """ Iterate over all possible sidechain Chi angle combinations. """ from scitbx.array_family import flex from scitbx.matrix import rotate_point_around_axis n_angles = len(clusters) assert (n_angles >= 1) angle_range = 180 r1 = [ifloor(-angle_range / increment_degrees)] * n_angles r2 = [iceil(angle_range / increment_degrees)] * n_angles if (last_chi_symmetric): r1[-1] = ifloor(-90 / increment_degrees) r2[-1] = iceil(90 / increment_degrees) nested_loop = flex.nested_loop(begin=r1, end=r2, open_range=False) selection = clusters[0].atoms_to_rotate for angles in nested_loop: xyz_moved = sites_cart.deep_copy() for i, angle_fraction in enumerate(angles): cl = clusters[i] for atom in cl.atoms_to_rotate: new_xyz = rotate_point_around_axis( axis_point_1=xyz_moved[cl.axis[0]], axis_point_2=xyz_moved[cl.axis[1]], point=xyz_moved[atom], angle=angle_fraction * increment_degrees, deg=True) xyz_moved[atom] = new_xyz yield xyz_moved
def torsion_search_nested(clusters, scorer, sites_cart): n_angles = len(clusters) print n_angles if (n_angles == 3): r1 = [-3, -7, -9] r2 = [3, 7, 9] elif (n_angles == 4): r1 = [-5, -5, -10, -10] r2 = [5, 5, 10, 10] else: return nested_loop = flex.nested_loop(begin=r1, end=r2, open_range=False) selection = clusters[0].atoms_to_rotate scorer.reset(sites_cart=sites_cart, selection=selection) for angles in nested_loop: xyz_moved = sites_cart.deep_copy() for i, angle in enumerate(angles): cl = clusters[i] for atom in cl.atoms_to_rotate: new_xyz = rotate_point_around_axis( axis_point_1=xyz_moved[cl.axis[0]], axis_point_2=xyz_moved[cl.axis[1]], point=xyz_moved[atom], angle=angle, deg=True) xyz_moved[atom] = new_xyz scorer.update(sites_cart=xyz_moved, selection=selection) return scorer
def candidate_orientation_matrices(basis_vectors, max_combinations=None): # select unique combinations of input vectors to test # the order of combinations is such that combinations comprising vectors # nearer the beginning of the input list will appear before combinations # comprising vectors towards the end of the list n = len(basis_vectors) # hardcoded limit on number of vectors, fixes issue #72 # https://github.com/dials/dials/issues/72 n = min(n, 100) basis_vectors = basis_vectors[:n] combinations = flex.vec3_int(flex.nested_loop((n, n, n))) combinations = combinations.select( flex.sort_permutation(combinations.as_vec3_double().norms())) # select only those combinations where j > i and k > j i, j, k = combinations.as_vec3_double().parts() sel = flex.bool(len(combinations), True) sel &= j > i sel &= k > j combinations = combinations.select(sel) if max_combinations is not None and max_combinations < len(combinations): combinations = combinations[:max_combinations] half_pi = 0.5 * math.pi min_angle = 20 / 180 * math.pi # 20 degrees, arbitrary cutoff for i, j, k in combinations: a = basis_vectors[i] b = basis_vectors[j] angle = a.angle(b) if angle < min_angle or (math.pi - angle) < min_angle: continue a_cross_b = a.cross(b) gamma = a.angle(b) if gamma < half_pi: # all angles obtuse if possible please b = -b a_cross_b = -a_cross_b c = basis_vectors[k] if abs(half_pi - a_cross_b.angle(c)) < min_angle: continue alpha = b.angle(c, deg=True) if alpha < half_pi: c = -c if a_cross_b.dot(c) < 0: # we want right-handed basis set, therefore invert all vectors a = -a b = -b c = -c model = Crystal(a, b, c, space_group_symbol="P 1") uc = model.get_unit_cell() cb_op_to_niggli = uc.change_of_basis_op_to_niggli_cell() model = model.change_basis(cb_op_to_niggli) uc = model.get_unit_cell() params = uc.parameters() if uc.volume() > (params[0] * params[1] * params[2] / 100): # unit cell volume cutoff from labelit 2004 paper yield model
def torsion_search_nested ( clusters, sites_cart, last_chi_symmetric=None, increment_degrees=10) : """ Iterate over all possible sidechain Chi angle combinations. """ from scitbx.array_family import flex from scitbx.matrix import rotate_point_around_axis n_angles = len(clusters) assert (n_angles >= 1) angle_range = 180 r1 = [ifloor(-angle_range/increment_degrees)] * n_angles r2 = [iceil(angle_range/increment_degrees)] * n_angles if (last_chi_symmetric) : r1[-1] = ifloor(-90/increment_degrees) r2[-1] = iceil(90/increment_degrees) nested_loop = flex.nested_loop(begin=r1, end=r2, open_range=False) selection = clusters[0].atoms_to_rotate for angles in nested_loop: xyz_moved = sites_cart.deep_copy() for i, angle_fraction in enumerate(angles): cl = clusters[i] for atom in cl.atoms_to_rotate: new_xyz = rotate_point_around_axis( axis_point_1 = xyz_moved[cl.axis[0]], axis_point_2 = xyz_moved[cl.axis[1]], point = xyz_moved[atom], angle = angle_fraction*increment_degrees, deg=True) xyz_moved[atom] = new_xyz yield xyz_moved
def torsion_search_nested( clusters, scorer, sites_cart): n_angles = len(clusters) print n_angles if(n_angles == 3): r1 = [-3,-7,-9] r2 = [3,7,9] elif(n_angles == 4): r1 = [-5,-5,-10,-10] r2 = [5,5,10,10] else: return nested_loop = flex.nested_loop(begin=r1, end=r2, open_range=False) selection = clusters[0].atoms_to_rotate scorer.reset(sites_cart = sites_cart, selection = selection) for angles in nested_loop: xyz_moved = sites_cart.deep_copy() for i, angle in enumerate(angles): cl = clusters[i] for atom in cl.atoms_to_rotate: new_xyz = rotate_point_around_axis( axis_point_1 = xyz_moved[cl.axis[0]], axis_point_2 = xyz_moved[cl.axis[1]], point = xyz_moved[atom], angle = angle, deg=True) xyz_moved[atom] = new_xyz scorer.update(sites_cart = xyz_moved, selection = selection) return scorer
def get_subset_of_grid_points(gridding, grid_indices): """Use a set of indices to mask the grid - returns masked grid points""" import numpy mask_binary = numpy.zeros(gridding.n_grid_points(), dtype=bool) mask_binary.put(grid_indices, True) grid = flex.grid(gridding.n_real()) for i, p in enumerate(flex.nested_loop(gridding.n_real())): assert i == grid(p) if mask_binary[i]: yield p
def exercise_writer(): from iotbx import file_reader from cctbx import uctbx, sgtbx from scitbx.array_family import flex file_name = libtbx.env.find_in_repositories( relative_path= "phenix_regression/wizards/partial_refine_001_map_coeffs.mtz", test=os.path.isfile) if file_name is None: print "Can't find map coefficients file, skipping." return mtz_in = file_reader.any_file(file_name, force_type="hkl").file_object miller_arrays = mtz_in.as_miller_arrays() map_coeffs = miller_arrays[0] fft_map = map_coeffs.fft_map(resolution_factor=1 / 3.0) fft_map.apply_sigma_scaling() fft_map.as_ccp4_map(file_name="2mFo-DFc.map") m = iotbx.ccp4_map.map_reader(file_name="2mFo-DFc.map") real_map = fft_map.real_map_unpadded() mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, map_coeffs.unit_cell().parameters()) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) #assert approx_equal(mmm.mean, m.header_mean) # random small maps of different sizes for nxyz in flex.nested_loop((1, 1, 1), (4, 4, 4)): mt = flex.mersenne_twister(0) grid = flex.grid(nxyz) map = mt.random_double(size=grid.size_1d()) map.reshape(grid) real_map = fft_map.real_map_unpadded() iotbx.ccp4_map.write_ccp4_map( file_name="random.map", unit_cell=uctbx.unit_cell((1, 1, 1, 90, 90, 90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0, 0, 0), gridding_last=tuple(fft_map.n_real()), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random.map") mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, (1, 1, 1, 90, 90, 90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # gridding_first = (0, 0, 0) gridding_last = tuple(fft_map.n_real()) map_box = maptbx.copy(map, gridding_first, gridding_last) map_box.reshape(flex.grid(map_box.all())) iotbx.ccp4_map.write_ccp4_map( file_name="random_box.map", unit_cell=uctbx.unit_cell((1, 1, 1, 90, 90, 90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"]))
def exercise_writer () : from iotbx import file_reader from cctbx import uctbx, sgtbx from scitbx.array_family import flex file_name = libtbx.env.find_in_repositories( relative_path="phenix_regression/wizards/partial_refine_001_map_coeffs.mtz", test=os.path.isfile) if file_name is None : print "Can't find map coefficients file, skipping." return mtz_in = file_reader.any_file(file_name, force_type="hkl").file_object miller_arrays = mtz_in.as_miller_arrays() map_coeffs = miller_arrays[0] fft_map = map_coeffs.fft_map(resolution_factor=1/3.0) fft_map.apply_sigma_scaling() fft_map.as_ccp4_map(file_name="2mFo-DFc.map") m = iotbx.ccp4_map.map_reader(file_name="2mFo-DFc.map") real_map = fft_map.real_map_unpadded() mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, map_coeffs.unit_cell().parameters()) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) #assert approx_equal(mmm.mean, m.header_mean) # random small maps of different sizes for nxyz in flex.nested_loop((1,1,1),(4,4,4)): mt = flex.mersenne_twister(0) grid = flex.grid(nxyz) map = mt.random_double(size=grid.size_1d()) map.reshape(grid) real_map = fft_map.real_map_unpadded() iotbx.ccp4_map.write_ccp4_map( file_name="random.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0,0,0), gridding_last=tuple(fft_map.n_real()), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random.map") mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, (1,1,1,90,90,90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # gridding_first = (0,0,0) gridding_last = tuple(fft_map.n_real()) map_box = maptbx.copy(map, gridding_first, gridding_last) map_box.reshape(flex.grid(map_box.all())) iotbx.ccp4_map.write_ccp4_map( file_name="random_box.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"]))
def pairwise_lcv(unit_cells=None, parameters=None): """Calculate the LCV for all pairs of unit cells/parameters""" assert [unit_cells, parameters].count(None) == 1, "Provide either unit_cells or parameters" if unit_cells: parameters = [uc.parameters() for uc in unit_cells] num_objs = len(parameters) diags = numpy.empty([num_objs], dtype=object) dist = numpy.empty([num_objs]*2, dtype=object) for i_uc1, uc1 in enumerate(parameters): diags[i_uc1] = unit_cell_diagonals(*uc1) for i_uc1, i_uc2 in flex.nested_loop((num_objs, num_objs)): dist[i_uc1, i_uc2] = lcv_from_diagonals(uc1_diags=diags[i_uc1], uc2_diags=diags[i_uc2]) return dist
def pairwise_ecv(unit_cells=None, parameters=None): """Calculate the Euclidean Cell Variation (ECV) for all pairs of unit cells/parameters""" assert [unit_cells, parameters].count(None) == 1, "Provide either unit_cells or parameters" if unit_cells: parameters = [uc.parameters() for uc in unit_cells] num_objs = len(parameters) diags = numpy.empty([num_objs], dtype=object) dist = numpy.empty([num_objs]*2, dtype=object) for i_uc1, uc1 in enumerate(parameters): diags[i_uc1] = unit_cell_diagonals(*uc1) for i_uc1, i_uc2 in flex.nested_loop((num_objs, num_objs)): dist[i_uc1, i_uc2] = flex.double(fractional_change_for_diagonals(diags[i_uc1],diags[i_uc2])).norm() return dist
def __init__(self, func, grid_size, periodic, lazy_normals, descending_normals): """ Construct a map of func with the given grid_size """ self.func = func nx, ny, nz = self.grid_size = grid_size self.periodic = periodic if periodic: self.grid_cell = 1/nx, 1/ny, 1/nz else: self.grid_cell = 1/(nx-1), 1/(ny-1), 1/(nz-1) hx, hy, hz = self.grid_cell map = flex.double(flex.grid(grid_size)) loop = flex.nested_loop(end=grid_size) while not loop.over(): p = loop() map[p] = func((p[0]*hx, p[1]*hy, p[2]*hz)) loop.incr() self.map = map self.lazy_normals = lazy_normals self.descending_normals = descending_normals
def get_grid_points_within_index_cutoff_of_origin(grid_index_cutoff): """Find all points relative to the origin within a certain number of grid points""" # Round the max grid index down to the nearest int - outer bound on the x,y,z coords outer_bound_box = int(grid_index_cutoff) # Calculate r/sqrt(3) - inner bound on x,y,z coords inner_bound_box = grid_index_cutoff / numpy.math.sqrt(3) # Calculate r^2 - limiting sphere rad_sq = grid_index_cutoff**2 # List of allowed grid indices grid_points = [] for x, y, z in flex.nested_loop(begin=(-outer_bound_box, -outer_bound_box, -outer_bound_box), end=(outer_bound_box + 1, outer_bound_box + 1, outer_bound_box + 1)): if (abs(x) <= inner_bound_box) and (abs(y) <= inner_bound_box) and ( abs(z) <= inner_bound_box): grid_points.append((x, y, z)) elif (x**2 + y**2 + z**2) <= rad_sq: grid_points.append((x, y, z)) return grid_points
def exercise5(n_trials): def check(): a, b, c, d = abcd(x=[x1, x2, x3]) answer = [x1, x2, x3] answer.sort() answer = flex.double(answer) r = scitbx.math.cubic_equation_real(a=a, b=b, c=c, d=d) for ri in r.residual(): assert approx_equal(ri, 0.0) solution = list(r.x) solution.sort() solution = flex.double(solution) diff = flex.abs(solution - answer) assert approx_equal(diff, [0, 0, 0]) for x in [x1, x2, x3, r.x[0], r.x[1], r.x[2]]: assert approx_equal(residual(a=a, b=b, c=c, d=d, x=x), 0) for x1, x2, x3 in flex.nested_loop([-2] * 3, [2] * 3, open_range=False): check() for i in xrange(n_trials): x1 = random.randint(-10, 10) x2 = random.randint(-10, 10) x3 = random.randint(-10, 10) check()
def exercise5(n_trials): def check(): a, b, c, d = abcd(x=[x1, x2, x3]) answer = [x1, x2, x3] answer.sort() answer = flex.double(answer) r = scitbx.math.cubic_equation_real(a=a, b=b, c=c, d=d) for ri in r.residual(): assert approx_equal(ri, 0.0) solution = list(r.x) solution.sort() solution = flex.double(solution) diff = flex.abs(solution - answer) assert approx_equal(diff, [0, 0, 0]) for x in [x1, x2, x3, r.x[0], r.x[1], r.x[2]]: assert approx_equal(residual(a=a, b=b, c=c, d=d, x=x), 0) for x1, x2, x3 in flex.nested_loop([-2] * 3, [2] * 3, open_range=False): check() for i in range(n_trials): x1 = random.randint(-10, 10) x2 = random.randint(-10, 10) x3 = random.randint(-10, 10) check()
def inner_mask(self): """Get grid points rejected subject to min_dist""" for p in flex.nested_loop(self.parent.grid_size()): if self._inner_mask_binary[self.indexer(p)]: yield p
def exercise(space_group_info, redundancy_counter=0): n_real = (12,12,12) miller_max = (2,2,2) gt = maptbx.grid_tags(n_real) uc = space_group_info.any_compatible_unit_cell(volume=1000) fl = sgtbx.search_symmetry_flags(use_space_group_symmetry=True) gt.build(space_group_info.type(), fl) fft = fftpack.real_to_complex_3d(n_real) map0 = flex.double(flex.grid(fft.m_real()).set_focus(fft.n_real()), 0) weight_map = map0.deep_copy() map = map0.deep_copy() ta = gt.tag_array() order_z = space_group_info.group().order_z() problems_expected = (redundancy_counter != 0) for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): xyz = [i/n for i,n in zip(ijk, n_real)] ss = sgtbx.site_symmetry( unit_cell=uc, space_group=space_group_info.group(), original_site=xyz, min_distance_sym_equiv=1e-5) m = space_group_info.group().multiplicity( site=boost.rational.vector(ijk, n_real)) assert m == ss.multiplicity() w = m / order_z weight_map[ijk] = w map[ijk] = w elif (redundancy_counter != 0): redundancy_counter -= 1 ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t map[ijk] = map[ijk_asu] sf_map = fft.forward(map) del map mi = miller.index_generator( space_group_info.type(), False, miller_max).to_array() assert mi.size() != 0 from_map = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map, conjugate_flag=True) sf = [iround(abs(f)) for f in from_map.data()] if (sf != [0]*len(sf)): assert problems_expected return else: not problems_expected # map_p1 = map0.deep_copy() map_sw = map0.deep_copy() for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): v = random.random()*2-1 map_p1[ijk] = v map_sw[ijk] = v * weight_map[ijk] else: ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t assert map_p1[ijk_asu] != 0 map_p1[ijk] = map_p1[ijk_asu] # # fft followed by symmetry summation in reciprocal space sf_map_sw = fft.forward(map_sw) del map_sw sf_sw = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_sw, conjugate_flag=True).data() del sf_map_sw # # symmetry expansion in real space (done above already) followed fft sf_map_p1 = fft.forward(map_p1) del map_p1 sf_p1 = maptbx.structure_factors.from_map( space_group=sgtbx.space_group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_p1, conjugate_flag=True).data() del sf_map_p1 # corr = flex.linear_correlation(x=flex.abs(sf_sw), y=flex.abs(sf_p1)) assert corr.is_well_defined assert approx_equal(corr.coefficient(), 1)
def exercise_writer(): from cctbx import uctbx, sgtbx from scitbx.array_family import flex mt = flex.mersenne_twister(0) nxyz = ( 4, 4, 4, ) grid = flex.grid(nxyz) real_map_data = mt.random_double(size=grid.size_1d()) real_map_data.reshape(grid) unit_cell = uctbx.unit_cell((10, 10, 10, 90, 90, 90)) iotbx.ccp4_map.write_ccp4_map( file_name="four_by_four.map", unit_cell=unit_cell, space_group=sgtbx.space_group_info("P1").group(), map_data=real_map_data, labels=flex.std_string(["iotbx.ccp4_map.tst"])) input_real_map = iotbx.ccp4_map.map_reader(file_name="four_by_four.map") input_map_data = input_real_map.map_data() real_map_mmm = real_map_data.as_1d().min_max_mean() input_map_mmm = input_map_data.as_1d().min_max_mean() cc = flex.linear_correlation(real_map_data.as_1d(), input_map_data.as_1d()).coefficient() assert cc > 0.999 assert approx_equal(input_real_map.unit_cell_parameters, unit_cell.parameters()) assert approx_equal(real_map_mmm.min, input_real_map.header_min, eps=0.001) assert approx_equal(real_map_mmm.min, input_map_mmm.min, eps=0.001) # random small maps of different sizes for nxyz in flex.nested_loop((2, 1, 1), (4, 4, 4)): mt = flex.mersenne_twister(0) grid = flex.grid(nxyz) real_map = mt.random_double(size=grid.size_1d()) real_map = real_map - 0.5 real_map.reshape(grid) iotbx.ccp4_map.write_ccp4_map( file_name="random.map", unit_cell=uctbx.unit_cell((1, 1, 1, 90, 90, 90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0, 0, 0), gridding_last=tuple(grid.last(False)), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random.map") mmm = flex.double(list(real_map)).min_max_mean() m1 = real_map.as_1d() m2 = m.map_data().as_1d() cc = flex.linear_correlation(m1, m2).coefficient() assert cc > 0.999 assert approx_equal(m.unit_cell_parameters, (1, 1, 1, 90, 90, 90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # write unit_cell_grid explicitly to map iotbx.ccp4_map.write_ccp4_map( file_name="random_b.map", unit_cell=uctbx.unit_cell((1, 1, 1, 90, 90, 90)), space_group=sgtbx.space_group_info("P1").group(), unit_cell_grid=real_map.all(), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random_b.map") m1 = real_map.as_1d() m2 = m.map_data().as_1d() cc = flex.linear_correlation(m1, m2).coefficient() assert cc > 0.999 mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, (1, 1, 1, 90, 90, 90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # gridding_first = (0, 0, 0) gridding_last = tuple(grid.last(False)) map_box = maptbx.copy(real_map, gridding_first, gridding_last) map_box.reshape(flex.grid(map_box.all())) iotbx.ccp4_map.write_ccp4_map( file_name="random_box.map", unit_cell=uctbx.unit_cell((1, 1, 1, 90, 90, 90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"])) print "OK"
def grid_points(self): return flex.nested_loop(self.grid_size())
def get_grid_points_within_index_cutoff_of_grid_sites(grid_sites, max_grid_dist, min_grid_dist=None): """Find all points on a grid within a certain number of grid points of grid sites (not necessarily integer sites)""" # Calculate the size of the grid we need to check over min_x = ifloor(min([s[0] for s in grid_sites]) - max_grid_dist) if min_x < 0: min_x = 0 min_y = ifloor(min([s[1] for s in grid_sites]) - max_grid_dist) if min_y < 0: min_y = 0 min_z = ifloor(min([s[2] for s in grid_sites]) - max_grid_dist) if min_z < 0: min_z = 0 max_x = iceil(max([s[0] for s in grid_sites]) + max_grid_dist) max_y = iceil(max([s[1] for s in grid_sites]) + max_grid_dist) max_z = iceil(max([s[2] for s in grid_sites]) + max_grid_dist) # Grid Extremities min_grid = (min_x, min_y, min_z) max_grid = (max_x + 1, max_y + 1, max_z + 1) # Round the max grid distance down to the nearest int - outer bound on the dx,dy,dz values outer_bound_box = int(max_grid_dist) # Calculate r/sqrt(3) - inner bound on dx, dy, dz values inner_bound_box = max_grid_dist / numpy.math.sqrt(3) # Calculate r^2 - limiting sphere rad_sq = max_grid_dist**2 # List of allowed grid indices outer_points = [] inner_points = [] # Iterate through and add valid points for gp in flex.nested_loop(min_grid, max_grid): for site in grid_sites: dx, dy, dz = [abs(p1 - p2) for p1, p2 in zip(gp, site)] if (dx > outer_bound_box) or (dy > outer_bound_box) or ( dz > outer_bound_box): continue elif (dx <= inner_bound_box) and (dy <= inner_bound_box) and ( dz <= inner_bound_box): outer_points.append(gp) break elif (dx**2 + dy**2 + dz**2) <= rad_sq: outer_points.append(gp) break # Filter the grid points that are too close to the protein if min_grid_dist: # Round the min grid distance up to the nearest int - outer bound on the dx,dy,dz values outer_bound_box = int(min_grid_dist) + 1 # Calculate r/sqrt(3) - inner bound on dx, dy, dz values inner_bound_box = min_grid_dist / numpy.math.sqrt(3) # Calculate r^2 - limiting sphere rad_sq = min_grid_dist**2 # Iterate through and add valid points for gp in outer_points: for site in grid_sites: dx, dy, dz = [abs(p1 - p2) for p1, p2 in zip(gp, site)] if (dx > outer_bound_box) or (dy > outer_bound_box) or ( dz > outer_bound_box): continue elif (dx <= inner_bound_box) and (dy <= inner_bound_box) and ( dz <= inner_bound_box): inner_points.append(gp) break elif (dx**2 + dy**2 + dz**2) <= rad_sq: inner_points.append(gp) break if min_grid_dist: total_point = [gp for gp in outer_points if gp not in inner_points] else: total_points = outer_points return total_points, outer_points, inner_points
def create_native_map(native_crystal_symmetry, native_sites, alignment, reference_map, site_mask_radius=6.0, step=0.5, filename=None, verbose=False): """ Transform the reference-aligned map back to the native crystallographic frame native_sites - defines region that map will be masked around native_crystal_symmetry - crystal symmetry reference_map - DensityMap object of the map in the reference frame alignment - Alignment object used to map between the reference frame and the native frame site_mask_radius - Define mask radius around native_sites step - grid sampling step """ start=time.time() # Output unit cell and spacegroup native_unit_cell = native_crystal_symmetry.unit_cell() native_space_group = native_crystal_symmetry.space_group() # ===============================================================================>>> # Create a supercell containing the native_sites at the centre # ===============================================================================>>> # How many unit cells to include in the supercell box_frac_min_max = native_unit_cell.box_frac_around_sites(sites_cart=native_sites, buffer=site_mask_radius+1.0) supercell_size = tuple([iceil(ma-mi) for mi, ma in zip(*box_frac_min_max)]) # create supercell in the native frame supercell = make_supercell(native_unit_cell, size=supercell_size) # Create gridding for the real unit cell based on fixed step size tmp_gridding = cctbx.maptbx.crystal_gridding(unit_cell=native_unit_cell, step=step) # Extract the n_real from this gridding to be applied to the real griddings uc_n_real = tmp_gridding.n_real() sc_n_real = tuple(flex.int(tmp_gridding.n_real())*flex.int(supercell_size)) if verbose: print('Generating supercell of size {}. Unit cell grid size: {}. Supercell grid size: {}.'.format(supercell_size, uc_n_real, sc_n_real)) # Get griddings based on the n_real determined above uc_gridding = cctbx.maptbx.crystal_gridding(unit_cell=native_unit_cell, pre_determined_n_real=uc_n_real) sc_gridding = cctbx.maptbx.crystal_gridding(unit_cell=supercell, pre_determined_n_real=sc_n_real) # ===============================================================================>>> # Mask the supercell grid around the protein model # ===============================================================================>>> # calculate the origin of the supercell (centred on the protein model) - adding origin translates "grid frame" to "crystallographic frame" model_centroid = tuple((flex.double(native_sites.max()) + flex.double(native_sites.min()))/2.0) origin = calculate_offset_to_centre_grid(grid_centre=supercell.orthogonalize((0.5,0.5,0.5)), centre_on=model_centroid) # sample the map points near to the protein (transform the structure to be centre of the grid) masked_points_indices = cctbx.maptbx.grid_indices_around_sites(unit_cell = supercell, fft_n_real = sc_gridding.n_real(), fft_m_real = sc_gridding.n_real(), sites_cart = native_sites - origin, site_radii = flex.double(native_sites.size(),site_mask_radius)) # Create iterator over these points masked_points_grid_iter = get_subset_of_grid_points(gridding=sc_gridding, grid_indices=masked_points_indices) # Convert grid points to cartesian points g2c = cctbx.maptbx.grid2cart(sc_gridding.n_real(), supercell.orthogonalization_matrix()) masked_points_cart = flex.vec3_double(map(g2c, masked_points_grid_iter)) + origin # from bamboo.pymol_utils.shapes import Sphere # points = ['from pymol import cmd','from pymol.cgo import *'] # for i,p in enumerate(masked_points_cart): # if i%100==0: points.append(Sphere(p, 0.2).as_cmd('steve')) # points = '\n'.join(points) # with open(filename+'.pml.py', 'w') as fh: fh.write(points) # ===============================================================================>>> # Sample masked points from the reference-aligned map # ===============================================================================>>> # Transform points to the reference frame masked_points_transformed = alignment.nat2ref(masked_points_cart) # Sample the map at these points masked_values = reference_map.get_cart_values(masked_points_transformed) # ===============================================================================>>> # Create a native-aligned map in the supercell # ===============================================================================>>> # Create a map of the density sc_map_data = numpy.zeros(sc_gridding.n_grid_points(), dtype=numpy.float64) sc_map_data.put(masked_points_indices, masked_values) sc_map_data = flex.double(sc_map_data) sc_map_data.reshape(flex.grid(sc_gridding.n_real())) # Transform the points back to the native frame (simple origin shift) sc_map_data = cctbx.maptbx.rotate_translate_map(unit_cell = supercell, map_data = sc_map_data, rotation_matrix = scitbx.matrix.rec([1,0,0,0,1,0,0,0,1], (3,3)).elems, translation_vector = (-1.0*scitbx.matrix.rec(origin, (3,1))).elems ) # ===============================================================================>>> # Apply translations to populate all unit cells of supercell # ===============================================================================>>> # Create a copy to contain the combined map data combined_sc_map_data = copy.deepcopy(sc_map_data) # Apply unit cell translation operators for x,y,z in flex.nested_loop(supercell_size): if x==y==z==0: continue # Calculate the translation vector unit_cell_shift = native_unit_cell.orthogonalize((x,y,z)) # Tranform the map rt_map_data = cctbx.maptbx.rotate_translate_map(unit_cell = supercell, map_data = sc_map_data, rotation_matrix = scitbx.matrix.rec([1,0,0,0,1,0,0,0,1], (3,3)).elems, translation_vector = scitbx.matrix.rec(unit_cell_shift, (3,1)).elems ) # Set any values that are filled in combined_sc_map_data to 0 rt_map_data.set_selected(flex.abs(combined_sc_map_data) > 1e-6, 0.0) # Add values to combined_sc_map_data combined_sc_map_data = combined_sc_map_data + rt_map_data # ===============================================================================>>> # Select the first (on origin) unit cell of the supercell # ===============================================================================>>> # Get the indices for the first unit cell supercell_grid = flex.grid(sc_gridding.n_real()) supercell_mask = map(supercell_grid, flex.nested_loop(uc_gridding.n_real())) # Extract the map data for those values (and reshape to the right size of the unit cell) uc_map_data = combined_sc_map_data.select(supercell_mask) uc_map_data.reshape(flex.grid(uc_gridding.n_real())) # ===============================================================================>>> # Apply symmetry operations to generate whole unit cell # ===============================================================================>>> # Create a copy to contain the combined map data combined_uc_map_data = copy.deepcopy(uc_map_data) # Apply all symmetry operations to unit cell data for sym_op in native_space_group.all_ops(): if sym_op.as_xyz() == 'x,y,z': continue # Get the transformation matrix rt_mx = sym_op.as_rational().as_float() # Tranform the map rt_map_data = cctbx.maptbx.rotate_translate_map(unit_cell = native_unit_cell, map_data = combined_uc_map_data, rotation_matrix = rt_mx.r.elems, #translation_vector = native_unit_cell.orthogonalize((-1.0*rt_mx.t).elems) ) translation_vector = native_unit_cell.orthogonalize(rt_mx.t.elems) ) # Set any values that are filled in combined_uc_map_data to 0 rt_map_data.set_selected(flex.abs(combined_uc_map_data) > 1e-6, 0) # Add values to combined_uc_map_data combined_uc_map_data = combined_uc_map_data + rt_map_data # ===============================================================================>>> # Write output maps # ===============================================================================>>> if filename is not None: iotbx.ccp4_map.write_ccp4_map( file_name = filename, unit_cell = native_unit_cell, space_group = native_space_group, map_data = combined_uc_map_data, labels = flex.std_string(['Map from pandda']) ) # iotbx.ccp4_map.write_ccp4_map( file_name = filename.replace('.ccp4','.supercell.ccp4'), # unit_cell = supercell, # space_group = cctbx.sgtbx.space_group('P1'), # map_data = sc_map_data, # labels = flex.std_string(['Map from pandda']) ) return combined_uc_map_data
def get_grid_points_within_index_cutoff_of_grid_sites_2( grid_sites, max_grid_dist, min_grid_dist=None): """Find all points on a grid within a certain number of grid points of grid sites (not necessarily integer sites)""" # Find the size of the grid that we'll need max_x = iceil(max([s[0] for s in grid_sites]) + max_grid_dist) max_y = iceil(max([s[1] for s in grid_sites]) + max_grid_dist) max_z = iceil(max([s[2] for s in grid_sites]) + max_grid_dist) max_grid = (max_x + 2, max_y + 2, max_z + 2) # Round the grid sites to the nearest grid point int_grid_sites = [ tuple([int(round(x, 0)) for x in site]) for site in grid_sites ] # Grid objects grid_indexer = flex.grid(max_grid) grid_size = flex.product(flex.int(max_grid)) # Outer mask outer_indices_mask = numpy.zeros(grid_size, dtype=int) # Find all of the grid vectors within max_dist of grid sites outer_grid_vectors = get_grid_points_within_index_cutoff_of_origin( grid_index_cutoff=max_grid_dist) outer_grid_points = [] for site in int_grid_sites: outer_grid_points.extend( combine_grid_point_and_grid_vectors( site, grid_vectors=outer_grid_vectors)) # They may overlap, so find unique grid_points outer_grid_points = list(set(outer_grid_points)) # Filter those that are outside of the grid outer_grid_points = [ gp for gp in outer_grid_points if not (([i + 1 for i in range(3) if gp[i] < 0]) or ([i + 1 for i in range(3) if gp[i] > max_grid[i]])) ] # Map the grid points to the associated 1d index outer_grid_indices = [grid_indexer(gp) for gp in outer_grid_points] # Create a binary mask of the points [outer_indices_mask.put(i, 1) for i in outer_grid_indices] # Inner mask inner_indices_mask = numpy.zeros(grid_size, dtype=int) if min_grid_dist: # Find all of the grid vectors within min_dist of grid sites inner_grid_vectors = get_grid_points_within_index_cutoff_of_origin( grid_index_cutoff=min_grid_dist) inner_grid_points = [] for site in int_grid_sites: inner_grid_points.extend( combine_grid_point_and_grid_vectors( site, grid_vectors=inner_grid_vectors)) # They may overlap, so find unique grid_points inner_grid_points = list(set(inner_grid_points)) # Filter those that are outside of the grid inner_grid_points = [ gp for gp in inner_grid_points if not (([i + 1 for i in range(3) if gp[i] < 0]) or ([i + 1 for i in range(3) if gp[i] >= max_grid[i]])) ] # Map the grid points to the associated 1d index inner_grid_indices = [grid_indexer(gp) for gp in inner_grid_points] # Create a binary mask of the points [inner_indices_mask.put(i, 1) for i in inner_grid_indices] # Convert from the mask back to grid points outer_points = [ gp for i, gp in enumerate(flex.nested_loop(max_grid)) if outer_indices_mask[i] == 1 ] inner_points = [ gp for i, gp in enumerate(flex.nested_loop(max_grid)) if inner_indices_mask[i] == 1 ] total_points = [ gp for i, gp in enumerate(flex.nested_loop(max_grid)) if (inner_indices_mask[i] == 0 and outer_indices_mask[i] == 1) ] return total_points, outer_points, inner_points
def exercise(space_group_info, redundancy_counter=0): n_real = (12, 12, 12) miller_max = (2, 2, 2) gt = maptbx.grid_tags(n_real) uc = space_group_info.any_compatible_unit_cell(volume=1000) fl = sgtbx.search_symmetry_flags(use_space_group_symmetry=True) gt.build(space_group_info.type(), fl) fft = fftpack.real_to_complex_3d(n_real) map0 = flex.double(flex.grid(fft.m_real()).set_focus(fft.n_real()), 0) weight_map = map0.deep_copy() map = map0.deep_copy() ta = gt.tag_array() order_z = space_group_info.group().order_z() problems_expected = (redundancy_counter != 0) for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): xyz = [i / n for i, n in zip(ijk, n_real)] ss = sgtbx.site_symmetry(unit_cell=uc, space_group=space_group_info.group(), original_site=xyz, min_distance_sym_equiv=1e-5) m = space_group_info.group().multiplicity( site=boost.rational.vector(ijk, n_real)) assert m == ss.multiplicity() w = m / order_z weight_map[ijk] = w map[ijk] = w elif (redundancy_counter != 0): redundancy_counter -= 1 ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t map[ijk] = map[ijk_asu] sf_map = fft.forward(map) del map mi = miller.index_generator(space_group_info.type(), False, miller_max).to_array() assert mi.size() != 0 from_map = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map, conjugate_flag=True) sf = [iround(abs(f)) for f in from_map.data()] if (sf != [0] * len(sf)): assert problems_expected return else: not problems_expected # map_p1 = map0.deep_copy() map_sw = map0.deep_copy() for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): v = random.random() * 2 - 1 map_p1[ijk] = v map_sw[ijk] = v * weight_map[ijk] else: ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t assert map_p1[ijk_asu] != 0 map_p1[ijk] = map_p1[ijk_asu] # # fft followed by symmetry summation in reciprocal space sf_map_sw = fft.forward(map_sw) del map_sw sf_sw = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_sw, conjugate_flag=True).data() del sf_map_sw # # symmetry expansion in real space (done above already) followed fft sf_map_p1 = fft.forward(map_p1) del map_p1 sf_p1 = maptbx.structure_factors.from_map(space_group=sgtbx.space_group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_p1, conjugate_flag=True).data() del sf_map_p1 # corr = flex.linear_correlation(x=flex.abs(sf_sw), y=flex.abs(sf_p1)) assert corr.is_well_defined assert approx_equal(corr.coefficient(), 1)
def exercise_writer(use_mrcfile=None,output_axis_order=[3,2,1]): from cctbx import uctbx, sgtbx from scitbx.array_family import flex mt = flex.mersenne_twister(0) nxyz = (4,5,6,) grid = flex.grid(nxyz) real_map_data = mt.random_double(size=grid.size_1d()) real_map_data.reshape(grid) unit_cell=uctbx.unit_cell((10,10,10,90,90,90)) if use_mrcfile: from iotbx.mrcfile import create_output_labels labels=create_output_labels( program_name='test', limitations=['extract_unique'], output_labels=['test label'], ) iotbx.mrcfile.write_ccp4_map( file_name="four_five_six.mrc", unit_cell=unit_cell, space_group=sgtbx.space_group_info("P1").group(), map_data=real_map_data, labels=labels, output_axis_order=output_axis_order) input_real_map = iotbx.mrcfile.map_reader(file_name="four_five_six.mrc") for x in input_real_map.labels: print("LABEL: ",x) assert str(input_real_map.labels).find('extract_unique')>-1 else: iotbx.ccp4_map.write_ccp4_map( file_name="four_five_six.map", unit_cell=unit_cell, space_group=sgtbx.space_group_info("P1").group(), map_data=real_map_data, labels=flex.std_string(["iotbx.ccp4_map.tst"])) input_real_map = iotbx.ccp4_map.map_reader(file_name="four_five_six.map") input_map_data=input_real_map.map_data() real_map_mmm = real_map_data.as_1d().min_max_mean() input_map_mmm = input_map_data.as_double().as_1d().min_max_mean() cc=flex.linear_correlation(real_map_data.as_1d(),input_map_data.as_double().as_1d()).coefficient() assert cc > 0.999 print("\nMRCFILE with 4x5x6 map and axis order %s %s" %(output_axis_order,cc)) assert approx_equal(input_real_map.unit_cell().parameters(), unit_cell.parameters()) assert approx_equal(real_map_mmm.min, input_real_map.header_min,eps=0.001) assert approx_equal(real_map_mmm.min, input_map_mmm.min,eps=0.001) # random small maps of different sizes for nxyz in flex.nested_loop((2,1,1),(4,4,4)): mt = flex.mersenne_twister(0) grid = flex.grid(nxyz) real_map = mt.random_double(size=grid.size_1d()) real_map=real_map-0.5 real_map.reshape(grid) if use_mrcfile: iotbx.mrcfile.write_ccp4_map( file_name="random.mrc", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0,0,0), gridding_last=tuple(grid.last(False)), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.mrcfile.map_reader(file_name="random.mrc") else: iotbx.ccp4_map.write_ccp4_map( file_name="random.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0,0,0), gridding_last=tuple(grid.last(False)), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random.map") mmm = flex.double(list(real_map)).min_max_mean() m1=real_map.as_1d() m2=m.map_data().as_double().as_1d() cc=flex.linear_correlation(m1,m2).coefficient() assert cc > 0.999 assert approx_equal(m.unit_cell().parameters(), (1,1,1,90,90,90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # write unit_cell_grid explicitly to map iotbx.ccp4_map.write_ccp4_map( file_name="random_b.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), unit_cell_grid=real_map.all(), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random_b.map") m1=real_map.as_1d() m2=m.map_data().as_double().as_1d() cc=flex.linear_correlation(m1,m2).coefficient() assert cc > 0.999 mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, (1,1,1,90,90,90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # gridding_first = (0,0,0) gridding_last=tuple(grid.last(False)) map_box = maptbx.copy(real_map, gridding_first, gridding_last) map_box.reshape(flex.grid(map_box.all())) if use_mrcfile: iotbx.mrcfile.write_ccp4_map( file_name="random_box.mrc", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"])) else: iotbx.ccp4_map.write_ccp4_map( file_name="random_box.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"])) print("OK")
def total_mask(self): """Return the grid points allowed by the mask - combination of max_dist (allowed) and min_dist (rejected)""" for p in flex.nested_loop(self.parent.grid_size()): if self._total_mask_binary[self.indexer(p)]: yield p
def outer_mask(self): """Get grid points allowed subject to max_dist""" for p in flex.nested_loop(self.parent.grid_size()): if self._outer_mask_binary[self.indexer(p)]: yield p