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")
Exemple #4
0
 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 __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)