def optimize_origin_offset_local_scope(self): """Local scope: find the optimal origin-offset closest to the current overall detector position (local minimum, simple minimization)""" from libtbx.test_utils import approx_equal from rstbx.indexing_api import dps_extended detector = self.imagesets[0].get_detector() beam = self.imagesets[0].get_beam() s0 = matrix.col(beam.get_s0()) # construct two vectors that are perpendicular to the beam. Gives a basis for refining beam axis = matrix.col((1, 0, 0)) beamr0 = s0.cross(axis).normalize() beamr1 = beamr0.cross(s0).normalize() beamr2 = beamr1.cross(s0).normalize() assert approx_equal(s0.dot(beamr1), 0.) assert approx_equal(s0.dot(beamr2), 0.) assert approx_equal(beamr2.dot(beamr1), 0.) # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2 if self.horizon_phil.indexing.mm_search_scope: scope = self.horizon_phil.indexing.mm_search_scope plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size( )[0] plot_px_sz *= self.wide_search_binning grid = max(1, int(scope / plot_px_sz)) widegrid = 2 * grid + 1 scores = flex.double() for y in xrange(-grid, grid + 1): for x in xrange(-grid, grid + 1): new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2 score = 0 for i in range(len(self.imagesets)): score += self.get_origin_offset_score( new_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) scores.append(score) def igrid(x): return x - (widegrid // 2) idxs = [igrid(i) * plot_px_sz for i in xrange(widegrid)] # if there are several similarly high scores, then choose the closest # one to the current beam centre potential_offsets = flex.vec3_double() sel = scores > (0.9 * flex.max(scores)) for i in sel.iselection(): offset = (idxs[i % widegrid]) * beamr1 + ( idxs[i // widegrid]) * beamr2 potential_offsets.append(offset.elems) #print offset.length(), scores[i] wide_search_offset = matrix.col(potential_offsets[flex.min_index( potential_offsets.norms())]) #plot_max = flex.max(scores) #idx_max = flex.max_index(scores) #wide_search_offset = (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2 else: wide_search_offset = None # DO A SIMPLEX MINIMIZATION from scitbx.simplex import simplex_opt class test_simplex_method(object): def __init__(selfOO, wide_search_offset=None): selfOO.starting_simplex = [] selfOO.n = 2 selfOO.wide_search_offset = wide_search_offset for ii in range(selfOO.n + 1): selfOO.starting_simplex.append(flex.random_double( selfOO.n)) selfOO.optimizer = simplex_opt(dimension=selfOO.n, matrix=selfOO.starting_simplex, evaluator=selfOO, tolerance=1e-7) selfOO.x = selfOO.optimizer.get_solution() selfOO.offset = selfOO.x[0] * 0.2 * beamr1 + selfOO.x[ 1] * 0.2 * beamr2 if selfOO.wide_search_offset is not None: selfOO.offset += selfOO.wide_search_offset def target(selfOO, vector): trial_origin_offset = vector[0] * 0.2 * beamr1 + vector[ 1] * 0.2 * beamr2 if selfOO.wide_search_offset is not None: trial_origin_offset += selfOO.wide_search_offset target = 0 for i in range(len(self.imagesets)): target -= self.get_origin_offset_score( trial_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) return target MIN = test_simplex_method(wide_search_offset=wide_search_offset) new_offset = MIN.offset if self.horizon_phil.indexing.plot_search_scope: scope = self.horizon_phil.indexing.mm_search_scope plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size( )[0] grid = max(1, int(scope / plot_px_sz)) scores = flex.double() for y in xrange(-grid, grid + 1): for x in xrange(-grid, grid + 1): new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2 score = 0 for i in range(len(self.imagesets)): score += self.get_origin_offset_score( new_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) scores.append(score) def show_plot(widegrid, excursi): excursi.reshape(flex.grid(widegrid, widegrid)) plot_max = flex.max(excursi) idx_max = flex.max_index(excursi) def igrid(x): return x - (widegrid // 2) idxs = [igrid(i) * plot_px_sz for i in xrange(widegrid)] from matplotlib import pyplot as plt plt.figure() CS = plt.contour( [igrid(i) * plot_px_sz for i in xrange(widegrid)], [igrid(i) * plot_px_sz for i in xrange(widegrid)], excursi.as_numpy_array()) plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f") plt.title("Wide scope search for detector origin offset") plt.scatter([0.0], [0.0], color='g', marker='o') plt.scatter([new_offset[0]], [new_offset[1]], color='r', marker='*') plt.scatter([idxs[idx_max % widegrid]], [idxs[idx_max // widegrid]], color='k', marker='s') plt.axes().set_aspect("equal") plt.xlabel("offset (mm) along beamr1 vector") plt.ylabel("offset (mm) along beamr2 vector") plt.savefig("search_scope.png") #changing value trial_origin_offset = (idxs[idx_max % widegrid]) * beamr1 + ( idxs[idx_max // widegrid]) * beamr2 return trial_origin_offset show_plot(widegrid=2 * grid + 1, excursi=scores) return dps_extended.get_new_detector(self.imagesets[0].get_detector(), new_offset)
def run(args): assert args in [[], ["--verbose"]] if (len(args) != 0): cout = sys.stdout else: cout = null_out() edge_list_bonds = [(0,1),(0,4),(1,2),(2,3),(3,4)] bond_list = [ (("C1*", "C2*"), 1.529), (("C1*", "O4*"), 1.412), (("C2*", "C3*"), 1.526), (("C3*", "C4*"), 1.520), (("C4*", "O4*"), 1.449)] angle_list = [ (("C1*", "C2*", "C3*"), 101.3), (("C2*", "C3*", "C4*"), 102.3), (("C3*", "C4*", "O4*"), 104.2), (("C4*", "O4*", "C1*"), 110.0)] sites_cart, geo_manager = cctbx.geometry_restraints.manager \ .construct_non_crystallographic_conserving_bonds_and_angles( sites_cart=sites_cart_3p, edge_list_bonds=edge_list_bonds, edge_list_angles=[]) for bond_atom_names,distance_ideal in bond_list: i,j = [atom_names.index(atom_name) for atom_name in bond_atom_names] bond_params = geo_manager.bond_params_table[i][j] assert approx_equal(bond_params.distance_ideal, distance_ideal, eps=1.e-2) bond_params.distance_ideal = distance_ideal bond_params.weight = 1/0.02**2 assert geo_manager.angle_proxies is None geo_manager.angle_proxies = cctbx.geometry_restraints.shared_angle_proxy() for angle_atom_names,angle_ideal in angle_list: i_seqs = [atom_names.index(atom_name) for atom_name in angle_atom_names] geo_manager.angle_proxies.append(cctbx.geometry_restraints.angle_proxy( i_seqs=i_seqs, angle_ideal=angle_ideal, weight=1/3**2)) geo_manager.show_sorted( site_labels=atom_names, sites_cart=sites_cart, f=cout) def lbfgs(sites_cart): for i_lbfgs_restart in xrange(3): minimized = cctbx.geometry_restraints.lbfgs.lbfgs( sites_cart=sites_cart, geometry_restraints_manager=geo_manager) assert is_below_limit(value=minimized.final_target_value, limit=1e-10) return minimized lbfgs(sites_cart=sites_cart_3p) lbfgs(sites_cart=sites_cart_2p) conformer_counts = [0] * 4 sites_cart = sites_cart.deep_copy() mt = flex.mersenne_twister(seed=0) for i_trial in xrange(20): while True: for i in xrange(sites_cart.size()): sites_cart[i] = mt.random_double_point_on_sphere() try: lbfgs(sites_cart=sites_cart) except RuntimeError, e: if (not str(e).startswith( "Bond distance > max_reasonable_bond_distance: ")): raise else: break rmsd_list = flex.double() for reference_sites in [ sites_cart_3p, sites_cart_2p, sites_cart_a, sites_cart_b]: sup = scitbx.math.superpose.least_squares_fit( reference_sites=reference_sites, other_sites=sites_cart) rmsd = reference_sites.rms_difference(sup.other_sites_best_fit()) rmsd_list.append(rmsd) oline = " ".join(["%.3f" % rmsd for rmsd in rmsd_list]) print >> cout, oline assert is_below_limit(min(rmsd_list), 1e-3) conformer_counts[flex.min_index(rmsd_list)] += 1
def run(args): assert args in [[], ["--verbose"]] if (len(args) != 0): cout = sys.stdout else: cout = null_out() edge_list_bonds = [(0, 1), (0, 4), (1, 2), (2, 3), (3, 4)] bond_list = [(("C1*", "C2*"), 1.529), (("C1*", "O4*"), 1.412), (("C2*", "C3*"), 1.526), (("C3*", "C4*"), 1.520), (("C4*", "O4*"), 1.449)] angle_list = [ (("C1*", "C2*", "C3*"), 101.3), (("C2*", "C3*", "C4*"), 102.3), (("C3*", "C4*", "O4*"), 104.2), (("C4*", "O4*", "C1*"), 110.0) ] sites_cart, geo_manager = cctbx.geometry_restraints.manager \ .construct_non_crystallographic_conserving_bonds_and_angles( sites_cart=sites_cart_3p, edge_list_bonds=edge_list_bonds, edge_list_angles=[]) for bond_atom_names, distance_ideal in bond_list: i, j = [atom_names.index(atom_name) for atom_name in bond_atom_names] bond_params = geo_manager.bond_params_table[i][j] assert approx_equal(bond_params.distance_ideal, distance_ideal, eps=1.e-2) bond_params.distance_ideal = distance_ideal bond_params.weight = 1 / 0.02**2 assert geo_manager.angle_proxies is None geo_manager.angle_proxies = cctbx.geometry_restraints.shared_angle_proxy() for angle_atom_names, angle_ideal in angle_list: i_seqs = [ atom_names.index(atom_name) for atom_name in angle_atom_names ] geo_manager.angle_proxies.append( cctbx.geometry_restraints.angle_proxy(i_seqs=i_seqs, angle_ideal=angle_ideal, weight=1 / 3**2)) geo_manager.show_sorted(site_labels=atom_names, sites_cart=sites_cart, f=cout) def lbfgs(sites_cart): for i_lbfgs_restart in range(3): minimized = cctbx.geometry_restraints.lbfgs.lbfgs( sites_cart=sites_cart, geometry_restraints_manager=geo_manager) assert is_below_limit(value=minimized.final_target_value, limit=1e-10) return minimized lbfgs(sites_cart=sites_cart_3p) lbfgs(sites_cart=sites_cart_2p) conformer_counts = [0] * 4 sites_cart = sites_cart.deep_copy() mt = flex.mersenne_twister(seed=0) for i_trial in range(20): while True: for i in range(sites_cart.size()): sites_cart[i] = mt.random_double_point_on_sphere() try: lbfgs(sites_cart=sites_cart) except RuntimeError as e: if (not str(e).startswith( "Bond distance > max_reasonable_bond_distance: ")): raise else: break rmsd_list = flex.double() for reference_sites in [ sites_cart_3p, sites_cart_2p, sites_cart_a, sites_cart_b ]: sup = scitbx.math.superpose.least_squares_fit( reference_sites=reference_sites, other_sites=sites_cart) rmsd = reference_sites.rms_difference(sup.other_sites_best_fit()) rmsd_list.append(rmsd) oline = " ".join(["%.3f" % rmsd for rmsd in rmsd_list]) print(oline, file=cout) assert is_below_limit(min(rmsd_list), 1e-3) conformer_counts[flex.min_index(rmsd_list)] += 1 print("conformer_counts:", conformer_counts) # if (libtbx.env.has_module("iotbx")): import iotbx.pdb.hierarchy hierarchy = iotbx.pdb.hierarchy.root() model = iotbx.pdb.hierarchy.model(id="") chain = iotbx.pdb.hierarchy.chain(id="A") model.append_chain(chain) hierarchy.append_model(model) # sites_cart_pentagon = pentagon_sites_cart() for i_stack, sites_cart in enumerate( [sites_cart_3p, sites_cart_2p, sites_cart_a, sites_cart_b]): atom_group = iotbx.pdb.hierarchy.atom_group(resname=" U", altloc="") sup = scitbx.math.superpose.least_squares_fit( reference_sites=sites_cart_pentagon, other_sites=sites_cart) sites_cart_out = sup.other_sites_best_fit() for site_label, site_cart in zip(atom_names, sites_cart_out): atom = iotbx.pdb.hierarchy.atom() atom.name = " %-3s" % site_label atom.xyz = matrix.col(site_cart) + matrix.col( (0, 0, i_stack * 1.5)) atom.occ = 1 atom.b = 20 atom.element = " " + site_label[0] atom_group.append_atom(atom) residue_group = iotbx.pdb.hierarchy.residue_group(resseq="%4d" % (i_stack + 1), icode=" ") residue_group.append_atom_group(atom_group) chain.append_residue_group(residue_group) hierarchy.atoms().reset_serial() pdb_str = hierarchy.as_pdb_string(append_end=True) file_name = "puckers.pdb" print("Writing file:", file_name) open(file_name, "w").write("""\ REMARK random_puckers.py REMARK 1 = 3' REMARK 2 = 2' REMARK 3 = A REMARK 4 = B """ + pdb_str) # print("OK")
def __init__(self, hex_cell, vertices_cart): assert len(vertices_cart) > 0 vertices_hex = hex_cell.fractionalize(sites_cart=vertices_cart) self.min = vertices_hex.min() self.max = vertices_hex.max() self.pivot = vertices_hex[flex.min_index(vertices_hex.dot())]
def optimize_origin_offset_local_scope(self): """Local scope: find the optimal origin-offset closest to the current overall detector position (local minimum, simple minimization)""" from libtbx.test_utils import approx_equal from rstbx.indexing_api import dps_extended detector = self.imagesets[0].get_detector() beam = self.imagesets[0].get_beam() s0 = matrix.col(beam.get_s0()) # construct two vectors that are perpendicular to the beam. Gives a basis for refining beam axis = matrix.col((1,0,0)) beamr0 = s0.cross(axis).normalize() beamr1 = beamr0.cross(s0).normalize() beamr2 = beamr1.cross(s0).normalize() assert approx_equal(s0.dot(beamr1), 0.) assert approx_equal(s0.dot(beamr2), 0.) assert approx_equal(beamr2.dot(beamr1), 0.) # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2 if self.horizon_phil.indexing.mm_search_scope: scope = self.horizon_phil.indexing.mm_search_scope plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size()[0] plot_px_sz *= self.wide_search_binning grid = max(1,int(scope/plot_px_sz)) widegrid = 2 * grid + 1 scores = flex.double() for y in xrange(-grid,grid+1): for x in xrange(-grid,grid+1): new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2 score = 0 for i in range(len(self.imagesets)): score += self.get_origin_offset_score(new_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) scores.append(score) def igrid(x): return x - (widegrid//2) idxs = [igrid(i)*plot_px_sz for i in xrange(widegrid)] # if there are several similarly high scores, then choose the closest # one to the current beam centre potential_offsets = flex.vec3_double() sel = scores > (0.9*flex.max(scores)) for i in sel.iselection(): offset = (idxs[i%widegrid])*beamr1 + (idxs[i//widegrid])*beamr2 potential_offsets.append(offset.elems) #print offset.length(), scores[i] wide_search_offset = matrix.col( potential_offsets[flex.min_index(potential_offsets.norms())]) #plot_max = flex.max(scores) #idx_max = flex.max_index(scores) #wide_search_offset = (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2 else: wide_search_offset = None # DO A SIMPLEX MINIMIZATION from scitbx.simplex import simplex_opt class test_simplex_method(object): def __init__(selfOO, wide_search_offset=None): selfOO.starting_simplex=[] selfOO.n = 2 selfOO.wide_search_offset = wide_search_offset for ii in range(selfOO.n+1): selfOO.starting_simplex.append(flex.random_double(selfOO.n)) selfOO.optimizer = simplex_opt(dimension=selfOO.n, matrix=selfOO.starting_simplex, evaluator=selfOO, tolerance=1e-7) selfOO.x = selfOO.optimizer.get_solution() selfOO.offset = selfOO.x[0]*0.2*beamr1 + selfOO.x[1]*0.2*beamr2 if selfOO.wide_search_offset is not None: selfOO.offset += selfOO.wide_search_offset def target(selfOO, vector): trial_origin_offset = vector[0]*0.2*beamr1 + vector[1]*0.2*beamr2 if selfOO.wide_search_offset is not None: trial_origin_offset += selfOO.wide_search_offset target = 0 for i in range(len(self.imagesets)): target -= self.get_origin_offset_score(trial_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) return target MIN = test_simplex_method(wide_search_offset=wide_search_offset) new_offset = MIN.offset if self.horizon_phil.indexing.plot_search_scope: scope = self.horizon_phil.indexing.mm_search_scope plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size()[0] grid = max(1,int(scope/plot_px_sz)) scores = flex.double() for y in xrange(-grid,grid+1): for x in xrange(-grid,grid+1): new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2 score = 0 for i in range(len(self.imagesets)): score += self.get_origin_offset_score(new_origin_offset, self.solution_lists[i], self.amax_lists[i], self.spot_lists[i], self.imagesets[i]) scores.append(score) def show_plot(widegrid,excursi): excursi.reshape(flex.grid(widegrid, widegrid)) plot_max = flex.max(excursi) idx_max = flex.max_index(excursi) def igrid(x): return x - (widegrid//2) idxs = [igrid(i)*plot_px_sz for i in xrange(widegrid)] from matplotlib import pyplot as plt plt.figure() CS = plt.contour([igrid(i)*plot_px_sz for i in xrange(widegrid)], [igrid(i)*plot_px_sz for i in xrange(widegrid)], excursi.as_numpy_array()) plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f") plt.title("Wide scope search for detector origin offset") plt.scatter([0.0],[0.0],color='g',marker='o') plt.scatter([new_offset[0]] , [new_offset[1]],color='r',marker='*') plt.scatter([idxs[idx_max%widegrid]] , [idxs[idx_max//widegrid]],color='k',marker='s') plt.axes().set_aspect("equal") plt.xlabel("offset (mm) along beamr1 vector") plt.ylabel("offset (mm) along beamr2 vector") plt.show() #changing value trial_origin_offset = (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2 return trial_origin_offset show_plot(widegrid = 2 * grid + 1, excursi = scores) return dps_extended.get_new_detector(self.imagesets[0].get_detector(), new_offset)