def run(args):
  assert len(args) == 0
  #
  r = geometry_restraints.angle_proxy_registry(
    strict_conflict_handling=True)
  r.initialize_table()
  r.process(
    source_info=source_info_server(),
    proxy=geometry_restraints.angle_proxy(
      i_seqs=(4,2,7), angle_ideal=0, weight=1))
  r.process(
    source_info=source_info_server(),
    proxy=geometry_restraints.angle_proxy(
      i_seqs=(5,2,3), angle_ideal=0, weight=1))
  assert r.lookup_i_proxy((4,2,7)) == 0
  assert r.lookup_i_proxy((7,2,4)) == 0
  assert r.lookup_i_proxy((2,7,4)) is None
  assert r.lookup_i_proxy((3,2,5)) == 1
  assert r.lookup_i_proxy((5,2,3)) == 1
  assert r.lookup_i_proxy((5,3,2)) is None
  #
  r = geometry_restraints.dihedral_proxy_registry(
    strict_conflict_handling=True)
  r.initialize_table()
  r.process(
    source_info=source_info_server(),
    proxy=geometry_restraints.dihedral_proxy(
      i_seqs=(4,7,2,3), angle_ideal=0, weight=1))
  r.process(
    source_info=source_info_server(),
    proxy=geometry_restraints.dihedral_proxy(
      i_seqs=(8,2,3,5), angle_ideal=0, weight=1))
  r.process(
    source_info=source_info_server(),
    proxy=geometry_restraints.dihedral_proxy(
      i_seqs=(6,3,1,9), angle_ideal=0, weight=1))
  assert r.lookup_i_proxy((3,2,7,4)) == (0, 1)
  assert r.lookup_i_proxy((4,2,7,3)) == (0, -1)
  assert r.lookup_i_proxy((4,7,2,3)) == (0, 1)
  assert r.lookup_i_proxy((3,7,2,4)) == (0, -1)
  assert r.lookup_i_proxy((5,2,3,8)) == (1, 1)
  assert r.lookup_i_proxy((6,3,1,9)) == (2, -1)
  #
  print "OK"
示例#2
0
def run(args):
    assert len(args) == 0
    #
    r = geometry_restraints.angle_proxy_registry(strict_conflict_handling=True)
    r.initialize_table()
    r.process(source_info=source_info_server(),
              proxy=geometry_restraints.angle_proxy(i_seqs=(4, 2, 7),
                                                    angle_ideal=0,
                                                    weight=1))
    r.process(source_info=source_info_server(),
              proxy=geometry_restraints.angle_proxy(i_seqs=(5, 2, 3),
                                                    angle_ideal=0,
                                                    weight=1))
    assert r.lookup_i_proxy((4, 2, 7)) == 0
    assert r.lookup_i_proxy((7, 2, 4)) == 0
    assert r.lookup_i_proxy((2, 7, 4)) is None
    assert r.lookup_i_proxy((3, 2, 5)) == 1
    assert r.lookup_i_proxy((5, 2, 3)) == 1
    assert r.lookup_i_proxy((5, 3, 2)) is None
    #
    r = geometry_restraints.dihedral_proxy_registry(
        strict_conflict_handling=True)
    r.initialize_table()
    r.process(source_info=source_info_server(),
              proxy=geometry_restraints.dihedral_proxy(i_seqs=(4, 7, 2, 3),
                                                       angle_ideal=0,
                                                       weight=1))
    r.process(source_info=source_info_server(),
              proxy=geometry_restraints.dihedral_proxy(i_seqs=(8, 2, 3, 5),
                                                       angle_ideal=0,
                                                       weight=1))
    r.process(source_info=source_info_server(),
              proxy=geometry_restraints.dihedral_proxy(i_seqs=(6, 3, 1, 9),
                                                       angle_ideal=0,
                                                       weight=1))
    assert r.lookup_i_proxy((3, 2, 7, 4)) == (0, 1)
    assert r.lookup_i_proxy((4, 2, 7, 3)) == (0, -1)
    assert r.lookup_i_proxy((4, 7, 2, 3)) == (0, 1)
    assert r.lookup_i_proxy((3, 7, 2, 4)) == (0, -1)
    assert r.lookup_i_proxy((5, 2, 3, 8)) == (1, 1)
    assert r.lookup_i_proxy((6, 3, 1, 9)) == (2, -1)
    #
    print("OK")
 def get_dummy_dihedral_proxies(self, only_psi_phi_pairs=True):
   from cctbx.geometry_restraints import dihedral_proxy
   atoms = self.get_phi_psi_atoms(only_psi_phi_pairs=only_psi_phi_pairs)
   proxies = []
   for dihedral in atoms:
     proxy = dihedral_proxy(
         i_seqs=[atom.i_seq for atom in dihedral],
         angle_ideal=0,
         weight=1)
     proxies.append(proxy)
   return proxies
def generate_torsion_restraints(
      pdb_hierarchy,
      sites_cart,
      selection=None,
      sigma=2.5,
      limit=15.0,
      chi_angles_only=False,
      top_out_potential=False,
      origin_id=2):
  torsion_proxies = geometry_restraints.shared_dihedral_proxy()
  if pdb_hierarchy.atoms().size() < 4:
    return torsion_proxies
  assert not pdb_hierarchy.atoms().extract_i_seq().all_eq(0)
  bool_pdbh_selection = flex.bool(pdb_hierarchy.atoms_size(), False)
  if (selection is not None):
    if (isinstance(selection, flex.bool)):
      bool_pdbh_selection = selection
    elif (isinstance(selection, flex.size_t)):
      bool_pdbh_selection.set_selected(selection, True)
  if selection is None:
    bool_pdbh_selection = flex.bool(pdb_hierarchy.atoms_size(), True)
  actual_selection = bool_pdbh_selection.iselection()
  assert len(sites_cart) == len(actual_selection)
  weight = 1.0 / (sigma**2)
  selection_to_sites_map = get_selection_to_sites_map(
                             sites_cart=sites_cart,
                             selection=actual_selection)
  residue_torsions = collect_residue_torsion_angles(
                   pdb_hierarchy=pdb_hierarchy,
                   atom_selection=bool_pdbh_selection,
                   chi_angles_only=chi_angles_only)
  for residue_info in residue_torsions:
    for chi in residue_info.chis:
      i_seqs = chi.i_seqs
      sites = []
      for i_seq in i_seqs:
        sites.append(selection_to_sites_map[i_seq])
      di = geometry_restraints.dihedral(
             sites=sites, angle_ideal=0.0, weight=weight)
      angle_ideal = di.angle_model
      dp = geometry_restraints.dihedral_proxy(
        i_seqs=i_seqs,
        angle_ideal=angle_ideal,
        weight=weight,
        limit=limit,
        top_out=top_out_potential,
        origin_id=origin_id)
      torsion_proxies.append(dp)
  return torsion_proxies
示例#5
0
文件: reference.py 项目: dials/cctbx
def generate_torsion_restraints(
      pdb_hierarchy,
      sites_cart,
      selection=None,
      sigma=2.5,
      limit=15.0,
      chi_angles_only=False,
      top_out_potential=False,
      origin_id=None):
  torsion_proxies = geometry_restraints.shared_dihedral_proxy()
  if pdb_hierarchy.atoms_size() < 4:
    return torsion_proxies
  assert not pdb_hierarchy.atoms().extract_i_seq().all_eq(0)
  bool_pdbh_selection = flex.bool(pdb_hierarchy.atoms_size(), False)
  if (selection is not None):
    if (isinstance(selection, flex.bool)):
      bool_pdbh_selection = selection
    elif (isinstance(selection, flex.size_t)):
      bool_pdbh_selection.set_selected(selection, True)
  if selection is None:
    bool_pdbh_selection = flex.bool(pdb_hierarchy.atoms_size(), True)
  actual_selection = bool_pdbh_selection.iselection()
  assert len(sites_cart) == len(actual_selection)
  weight = 1.0 / (sigma**2)
  selection_to_sites_map = get_selection_to_sites_map(
                             sites_cart=sites_cart,
                             selection=actual_selection)
  residue_torsions = collect_residue_torsion_angles(
                   pdb_hierarchy=pdb_hierarchy,
                   atom_selection=bool_pdbh_selection,
                   chi_angles_only=chi_angles_only)
  for residue_info in residue_torsions:
    for chi in residue_info.chis:
      i_seqs = chi.i_seqs
      sites = []
      for i_seq in i_seqs:
        sites.append(selection_to_sites_map[i_seq])
      di = geometry_restraints.dihedral(
             sites=sites, angle_ideal=0.0, weight=weight)
      angle_ideal = di.angle_model
      dp = geometry_restraints.dihedral_proxy(
        i_seqs=i_seqs,
        angle_ideal=angle_ideal,
        weight=weight,
        limit=limit,
        top_out=top_out_potential,
        origin_id=origin_id)
      torsion_proxies.append(dp)
  return torsion_proxies
 def get_dummy_dihedral_proxies(self, only_psi_phi_pairs=True):
     #
     # Needs testing. One of the candidates is 3j0d, chain I, the first
     # residue is missing CA atom.
     #
     from cctbx.geometry_restraints import dihedral_proxy
     atoms = self.get_phi_psi_atoms(only_psi_phi_pairs=only_psi_phi_pairs)
     proxies = []
     if atoms is None: return proxies
     for dihedral in atoms:
         if None not in dihedral:
             proxy = dihedral_proxy(
                 i_seqs=[atom.i_seq for atom in dihedral],
                 angle_ideal=0,
                 weight=1)
             proxies.append(proxy)
     return proxies
 def get_dummy_dihedral_proxies(self, only_psi_phi_pairs=True):
   #
   # Needs testing. One of the candidates is 3j0d, chain I, the first
   # residue is missing CA atom.
   #
   from cctbx.geometry_restraints import dihedral_proxy
   atoms = self.get_phi_psi_atoms(only_psi_phi_pairs=only_psi_phi_pairs)
   proxies = []
   if atoms is None: return proxies
   for dihedral in atoms:
     if None not in dihedral:
       proxy = dihedral_proxy(
           i_seqs=[atom.i_seq for atom in dihedral],
           angle_ideal=0,
           weight=1)
       proxies.append(proxy)
   return proxies
def read_pdb():

    pdbstring = """\
ATOM      0  CA  GLY A   3       5.804  -2.100   7.324  1.00  1.36           C
ATOM      1  C   GLY A   3       4.651  -1.149   7.578  1.00  1.01           C
ATOM      2  O   GLY A   3       3.598  -1.553   8.071  1.00  1.38           O
ATOM      3  N   GLY A   3       6.706  -1.622   6.294  1.00  1.11           N
ATOM      4  CA  PHE A   4       3.819   1.134   7.419  1.00  0.89           C
ATOM      5  CB  PHE A   4       4.397   2.380   8.094  1.00  1.13           C
ATOM      6  C   PHE A   4       3.185   1.509   6.084  1.00  0.94           C
ATOM      7  N   PHE A   4       4.852   0.121   7.242  1.00  0.88           N
ATOM      8  O   PHE A   4       2.361   2.421   6.010  1.00  1.47           O
ATOM      9  CA  LEU A   5       3.055   1.059   3.693  1.00  0.87           C
ATOM     10  CB  LEU A   5       3.965   0.435   2.634  1.00  1.13           C
ATOM     11  C   LEU A   5       1.634   0.527   3.541  1.00  0.87           C
ATOM     12  N   LEU A   5       3.576   0.800   5.030  1.00  0.92           N
ATOM     13  O   LEU A   5       1.246  -0.440   4.196  1.00  1.23           O
"""

    pdb_inp = iotbx.pdb.input(lines=flex.split_lines(pdbstring),
                              source_info=None)

    sites_cart = pdb_inp.atoms().extract_xyz()

    # TRANS    phi      1 C      2 N      2 CA     2 C        60.00  20.0 3
    # TRANS    psi      1 N      1 CA     1 C      2 N       160.00  30.0 2

    dihedral_proxies = geometry_restraints.shared_dihedral_proxy()

    # residue 1
    psi = geometry_restraints.dihedral_proxy(i_seqs=[3, 0, 1, 7],
                                             angle_ideal=160.0,
                                             weight=1 / 30.0**2,
                                             periodicity=3)
    dihedral_proxies.append(psi)

    # residue 2
    phi = geometry_restraints.dihedral_proxy(i_seqs=[1, 7, 4, 6],
                                             angle_ideal=60.0,
                                             weight=1 / 20.0**2,
                                             periodicity=3)
    dihedral_proxies.append(phi)

    psi = geometry_restraints.dihedral_proxy(i_seqs=[7, 4, 6, 8],
                                             angle_ideal=160.0,
                                             weight=1 / 30.0**2,
                                             periodicity=3)
    dihedral_proxies.append(psi)

    # residue 3
    phi = geometry_restraints.dihedral_proxy(i_seqs=[6, 12, 9, 11],
                                             angle_ideal=60.0,
                                             weight=1 / 20.0**2,
                                             periodicity=3)
    dihedral_proxies.append(phi)

    angle_proxies = geometry_restraints.shared_angle_proxy()

    ## Residue 1
    # a3
    a = geometry_restraints.angle_proxy(i_seqs=[3, 0, 1],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    # a7
    a = geometry_restraints.angle_proxy(i_seqs=[2, 1, 7],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    ## Residue 2
    # a1
    a = geometry_restraints.angle_proxy(i_seqs=[1, 7, 4],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    # a3
    a = geometry_restraints.angle_proxy(i_seqs=[7, 4, 6],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    # a7
    a = geometry_restraints.angle_proxy(i_seqs=[8, 6, 12],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    ## Residue 3
    # a1
    a = geometry_restraints.angle_proxy(i_seqs=[6, 12, 9],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    # a3
    a = geometry_restraints.angle_proxy(i_seqs=[12, 9, 11],
                                        angle_ideal=0,
                                        weight=1)
    angle_proxies.append(a)

    # compute dihedral
    #dihedral = geometry_restraints.dihedral(
    #    sites_cart=sites_cart,
    #    proxy=dihedral_proxies[0])

    # Shows real dihedral value
    #print dihedral.angle_model, dihedral.delta
    cfd_list = []

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='GLY',
        next_residue_name='PHE',
        conformation_proxies=None,
        i_phi_proxy=None,  # index into dihedral_proxies
        i_psi_proxy=0,
        i_dynamic_angles=[None, None, 0, None, None, None,
                          1],  # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None)
    cfd_list.append(cfd)

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='PHE',
        next_residue_name='LEU',
        conformation_proxies=None,
        i_phi_proxy=1,  # index into dihedral_proxies
        i_psi_proxy=2,
        i_dynamic_angles=[2, None, 3, None, None, None,
                          4],  # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None)
    cfd_list.append(cfd)

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='LEU',
        next_residue_name=None,
        conformation_proxies=None,
        i_phi_proxy=3,  # index into dihedral_proxies
        i_psi_proxy=None,
        i_dynamic_angles=[5, None, 6, None, None, None,
                          None],  # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None)
    cfd_list.append(cfd)

    for x in range(1, 4):
        print
        print 'Starting cycle', x
        print
        for cfd in cfd_list:
            cfd.update_restraints(sites_cart, dihedral_proxies, angle_proxies)
示例#9
0
def exercise_geometry_restraints_as_cif():
    quartz = xray.structure(crystal_symmetry=crystal.symmetry(
        (5.01, 5.01, 5.47, 90, 90, 120), "P6222"),
                            scatterers=flex.xray_scatterer([
                                xray.scatterer("Si", (1 / 2., 1 / 2., 1 / 3.)),
                                xray.scatterer("O", (0.197, -0.197, 0.83333))
                            ]))
    bond_proxies = geometry_restraints.shared_bond_simple_proxy((
        geometry_restraints.bond_simple_proxy(
            i_seqs=[0, 1],
            rt_mx_ji=sgtbx.rt_mx("x-y,x,z-2/3"),
            distance_ideal=1.6,
            weight=3.2),
        geometry_restraints.bond_simple_proxy(i_seqs=[0, 1],
                                              distance_ideal=1.7,
                                              weight=1.8),
    ))
    dihedral_proxies = geometry_restraints.shared_dihedral_proxy((
        geometry_restraints.dihedral_proxy(
            i_seqs=[1, 0, 1, 0],
            sym_ops=(sgtbx.rt_mx("1+y,1-x+y, z-1/3"), sgtbx.rt_mx(),
                     sgtbx.rt_mx("x-y,x,z-2/3"), sgtbx.rt_mx("1-x,y-x,1/3-z")),
            angle_ideal=-30,
            weight=2),
        geometry_restraints.dihedral_proxy(
            i_seqs=[1, 0, 1, 0],
            sym_ops=(sgtbx.rt_mx("1+y,1-x+y, z-1/3"), sgtbx.rt_mx(),
                     sgtbx.rt_mx("-y,x-y,z-1/3"), sgtbx.rt_mx("x-y,x,1/3+z")),
            angle_ideal=90,
            weight=3),
    ))
    angle_proxies = geometry_restraints.shared_angle_proxy((
        geometry_restraints.angle_proxy(i_seqs=[1, 0, 1],
                                        sym_ops=(sgtbx.rt_mx("x-y,x,z-2/3"),
                                                 sgtbx.rt_mx(),
                                                 sgtbx.rt_mx("-y,x-y,z-1/3")),
                                        angle_ideal=103,
                                        weight=2),
        geometry_restraints.angle_proxy(
            i_seqs=[1, 0, 1],
            sym_ops=(sgtbx.rt_mx("y+1,-x+y+1,z-1/3"), sgtbx.rt_mx(),
                     sgtbx.rt_mx("-y,x-y,z-1/3")),
            angle_ideal=110,
            weight=5),
        geometry_restraints.angle_proxy(i_seqs=[0, 1, 0],
                                        sym_ops=(sgtbx.rt_mx("y,-x+y,z+2/3"),
                                                 sgtbx.rt_mx(),
                                                 sgtbx.rt_mx("-x+y,-x,z+1/3")),
                                        angle_ideal=150,
                                        weight=5),
    ))
    bond_similarity_proxies = geometry_restraints.shared_bond_similarity_proxy(
        (geometry_restraints.bond_similarity_proxy(
            i_seqs=[(0, 1), (0, 1), (0, 1)],
            sym_ops=(sgtbx.rt_mx("x-y,x,z-2/3"), sgtbx.rt_mx("-y,x-y,z-1/3"),
                     sgtbx.rt_mx("y+1,-x+y+1,z-1/3")),
            weights=(1, 1, 1)), ))
    cif_block = iotbx.cif.model.block()
    iotbx.cif.restraints.add_to_cif_block(
        cif_block,
        quartz,
        bond_proxies=bond_proxies,
        angle_proxies=angle_proxies,
        dihedral_proxies=dihedral_proxies,
        bond_similarity_proxies=bond_similarity_proxies)
    s = StringIO()
    cif_block.show(out=s)
    assert not show_diff(
        s.getvalue(), """\
loop_
  _restr_distance_atom_site_label_1
  _restr_distance_atom_site_label_2
  _restr_distance_site_symmetry_2
  _restr_distance_target
  _restr_distance_target_weight_param
  _restr_distance_diff
  Si  O  2_554  1.6000  0.5590  -0.0160
  Si  O  1      1.7000  0.7454  -2.3838

loop_
  _restr_angle_atom_site_label_1
  _restr_angle_atom_site_label_2
  _restr_angle_atom_site_label_3
  _restr_angle_site_symmetry_1
  _restr_angle_site_symmetry_2
  _restr_angle_site_symmetry_3
  _restr_angle_target
  _restr_angle_target_weight_param
  _restr_angle_diff
  O   Si  O   2_554  1  4_554  103.0000  0.7071   1.6926
  O   Si  O   3_664  1  4_554  110.0000  0.4472  -1.3127
  Si  O   Si  3      1  5      150.0000  0.4472   3.0700

loop_
  _restr_torsion_atom_site_label_1
  _restr_torsion_atom_site_label_2
  _restr_torsion_atom_site_label_3
  _restr_torsion_atom_site_label_4
  _restr_torsion_site_symmetry_1
  _restr_torsion_site_symmetry_2
  _restr_torsion_site_symmetry_3
  _restr_torsion_site_symmetry_4
  _restr_torsion_angle_target
  _restr_torsion_weight_param
  _restr_torsion_diff
  O  Si  O  Si  3_664  1  2_554  7_655  -30.0000  0.7071   6.9078
  O  Si  O  Si  3_664  1  4_554  2       90.0000  0.5774  11.7036

loop_
  _restr_equal_distance_class_class_id
  _restr_equal_distance_class_target_weight_param
  _restr_equal_distance_class_average
  _restr_equal_distance_class_esd
  _restr_equal_distance_class_diff_max
  1  1.0000  1.6160  0.0000  0.0000

loop_
  _restr_equal_distance_atom_site_label_1
  _restr_equal_distance_atom_site_label_2
  _restr_equal_distance_site_symmetry_2
  _restr_equal_distance_class_id
  Si  O  2_554  1
  Si  O  4_554  1
  Si  O  3_664  1

""")
    def update_restraints(self, sites_cart, dihedral_proxies, angle_proxies):
        if 1:
            from libtbx.utils import null_out

            log = null_out()
        else:
            import sys

            log = sys.stdout
        try:
            phi = self._get_dihedral(
                sites_cart=sites_cart, dihedral_proxies=self.conformation_proxies, i_proxy=self.i_phi_proxy
            )
        except Exception:  # XXX BAD
            phi = None
        try:
            psi = self._get_dihedral(
                sites_cart=sites_cart, dihedral_proxies=self.conformation_proxies, i_proxy=self.i_psi_proxy
            )
        except Exception:  # XXX BAD
            psi = None

        # Shows real dihedral value
        if phi is not None:
            print >> log, "phi", phi.angle_model, phi.delta
        if psi is not None:
            print >> log, "psi", psi.angle_model, psi.delta

        if phi is not None and psi is not None:

            # get restraint from our database here
            geometry = pgd_lib.lookup(
                residue=self.residue_name, next_residue=self.next_residue_name, phi=phi.angle_model, psi=psi.angle_model
            )

            # grab angles from our database
            # using zip() on i_dynamic_angles and our values
            # plug it into restraints in angle proxies
            angles = [
                self._get_angle(sites_cart=sites_cart, angle_proxies=angle_proxies, i_proxy=i_proxy)
                for i_proxy in self.i_dynamic_angles
            ]

            for angle, angle_name, i_proxy in zip(
                angles, conformation_dependent_geometry.angles.angle_names, self.i_dynamic_angles
            ):
                # i_dynamic_angles contains None for angles/atoms that don't
                # exist so don't have restraints to update.
                if i_proxy is not None:

                    new_angle_ideal, new_weight = self._get_average_and_weight(geometry, angle_name)

                    # Create a new angle proxy here with our restraint
                    new_angle_proxy = geometry_restraints.angle_proxy(
                        i_seqs=angle_proxies[i_proxy].i_seqs, angle_ideal=new_angle_ideal, weight=new_weight
                    )

                    # Overwrite the old proxy
                    angle_proxies[i_proxy] = new_angle_proxy

                    # Show that we actually did update the proxy
                    proxy = angle_proxies[i_proxy]
                    print >> log, self.residue_name, self.next_residue_name,
                    print >> log, angle_name, proxy.i_seqs, proxy.angle_ideal, proxy.weight

            # grab dihedrals from our database
            # using zip() on i_dynamic_dihedrals and our values
            # plug it into restraints in dihedral proxies
            dihedrals = [
                self._get_dihedral(sites_cart=sites_cart, dihedral_proxies=dihedral_proxies, i_proxy=i_proxy)
                for i_proxy in self.i_dynamic_dihedrals
            ]

            for dihedral, dihedral_name, i_proxy in zip(
                dihedrals, conformation_dependent_geometry.angles.dihedral_names, self.i_dynamic_dihedrals
            ):
                # i_dynamic_dihedrals contains None for dihedrals/atoms that don't
                # exist so don't have restraints to update.
                if i_proxy is not None:

                    new_angle_ideal, new_weight = self._get_average_and_weight(geometry, dihedral_name)

                    new_angle_ideal = dihedral_proxies[i_proxy].angle_ideal
                    new_weight = dihedral_proxies[i_proxy].weight

                    # Create a new dihedral proxy here with our restraint
                    new_dihedral_proxy = geometry_restraints.dihedral_proxy(
                        i_seqs=dihedral_proxies[i_proxy].i_seqs, angle_ideal=new_angle_ideal, weight=new_weight
                    )

                    # Overwrite the old proxy
                    dihedral_proxies[i_proxy] = new_dihedral_proxy

                    # Show that we actually did update the proxy
                    proxy = dihedral_proxies[i_proxy]
                    print >> log, self.residue_name, self.next_residue_name,
                    print >> log, dihedral_name, proxy.i_seqs, proxy.angle_ideal, proxy.weight
def build_conformation_dependent_angle_proxies(
    angle_proxy_registry, dihedral_proxy_registry, monomer_mappings, connectivity_i_j, connectivity_j_k, sites_cart
):
    """
  Sets up conformation_dependent_restraints object.

  Finds atom indexes from registries

  Looks for C_prev in m_i, most atoms in m_j, N_next in m_k.
  """
    assert len(monomer_mappings) == 3

    if monomer_mappings[1] is None:
        residue_name = None
    else:
        residue_name = monomer_mappings[1].residue_name

    if monomer_mappings[2] is None:
        next_residue_name = None
    else:
        next_residue_name = monomer_mappings[2].residue_name

    dihedral_i_proxies = []
    conformation_proxies = geometry_restraints.shared_dihedral_proxy()
    for dihedral_number, dihedral_definition in enumerate(conformation_dependent_geometry.angles.dihedral_atoms):
        i_seqs = []
        for residue_index, atom_name in dihedral_definition:
            mm = monomer_mappings[residue_index]
            if mm is not None:
                i_seqs.append(getattr(mm.expected_atoms.get(atom_name), "i_seq", None))
        # account for missing atoms
        if len(i_seqs) == 4 and i_seqs.count(None) == 0:
            if dihedral_number == 0:
                # phi/psi: Restraints don't matter, we throw them away. This is just
                # so we can get eventually get the current value.
                phi = geometry_restraints.dihedral_proxy(
                    i_seqs=i_seqs, angle_ideal=60.0, weight=1 / 20.0 ** 2, periodicity=3
                )
                conformation_proxies.append(phi)
                dihedral_i_proxies.append(None)
                i_phi_proxy = 0
            elif dihedral_number == 1:
                psi = geometry_restraints.dihedral_proxy(
                    i_seqs=i_seqs, angle_ideal=160.0, weight=1 / 30.0 ** 2, periodicity=3
                )
                conformation_proxies.append(psi)
                dihedral_i_proxies.append(None)
                i_psi_proxy = 1
            elif dihedral_number == 2:
                # omega
                dihedral_i_proxy, dihedral_sign = dihedral_proxy_registry.lookup_i_proxy(i_seqs)
                dihedral_i_proxies.append(dihedral_i_proxy)
            else:
                pass
        # we're on a dihedral with missing length or atoms that are None
        else:
            if dihedral_number == 0:
                i_phi_proxy = None
            elif dihedral_number == 1:
                i_psi_proxy = None
            elif dihedral_number == 2:
                dihedral_i_proxies.append(None)
            else:
                pass

    angle_i_proxies = []
    for angle_definition in conformation_dependent_geometry.angles.angle_atoms:
        i_seqs = []
        for residue_index, atom_name in angle_definition:
            mm = monomer_mappings[residue_index]
            if mm is not None:
                i_seqs.append(getattr(mm.expected_atoms.get(atom_name), "i_seq", None))
        # account for missing atoms

        if len(i_seqs) == 3 and i_seqs.count(None) == 0:
            # go into angle_proxy_registry
            angle_i_proxy = angle_proxy_registry.lookup_i_proxy(i_seqs)
            angle_i_proxies.append(angle_i_proxy)
        else:
            # By filling in None for blanks, we can assume the lengths are equal
            # here and other places angle_atoms/angle_names are used
            angle_i_proxies.append(None)

    cfd = conformation_dependent_restraints(
        residue_name=residue_name,
        next_residue_name=next_residue_name,
        conformation_proxies=conformation_proxies,
        i_phi_proxy=i_phi_proxy,
        i_psi_proxy=i_psi_proxy,
        i_dynamic_angles=angle_i_proxies,
        i_dynamic_dihedrals=dihedral_i_proxies,
    )

    return cfd
    def update_restraints(self, sites_cart, dihedral_proxies, angle_proxies):
        if (1):
            from libtbx.utils import null_out
            log = null_out()
        else:
            import sys
            log = sys.stdout
        try:
            phi = self._get_dihedral(
                sites_cart=sites_cart,
                dihedral_proxies=self.conformation_proxies,
                i_proxy=self.i_phi_proxy)
        except Exception:  # XXX BAD
            phi = None
        try:
            psi = self._get_dihedral(
                sites_cart=sites_cart,
                dihedral_proxies=self.conformation_proxies,
                i_proxy=self.i_psi_proxy)
        except Exception:  # XXX BAD
            psi = None

        # Shows real dihedral value
        if phi is not None:
            print('phi', phi.angle_model, phi.delta, file=log)
        if psi is not None:
            print('psi', psi.angle_model, psi.delta, file=log)

        if phi is not None and psi is not None:

            # get restraint from our database here
            geometry = pgd_lib.lookup(residue=self.residue_name,
                                      next_residue=self.next_residue_name,
                                      phi=phi.angle_model,
                                      psi=psi.angle_model)

            # grab angles from our database
            # using zip() on i_dynamic_angles and our values
            # plug it into restraints in angle proxies
            angles = [
                self._get_angle(sites_cart=sites_cart,
                                angle_proxies=angle_proxies,
                                i_proxy=i_proxy)
                for i_proxy in self.i_dynamic_angles
            ]

            for angle, angle_name, i_proxy in zip(
                    angles, conformation_dependent_geometry.angles.angle_names,
                    self.i_dynamic_angles):
                # i_dynamic_angles contains None for angles/atoms that don't
                # exist so don't have restraints to update.
                if i_proxy is not None:

                    new_angle_ideal, new_weight = \
                                     self._get_average_and_weight(geometry, angle_name)

                    # Create a new angle proxy here with our restraint
                    new_angle_proxy = geometry_restraints.angle_proxy(
                        i_seqs=angle_proxies[i_proxy].i_seqs,
                        angle_ideal=new_angle_ideal,
                        weight=new_weight)

                    # Overwrite the old proxy
                    angle_proxies[i_proxy] = new_angle_proxy

                    # Show that we actually did update the proxy
                    proxy = angle_proxies[i_proxy]
                    print(self.residue_name,
                          self.next_residue_name,
                          end=' ',
                          file=log)
                    print(angle_name,
                          proxy.i_seqs,
                          proxy.angle_ideal,
                          proxy.weight,
                          file=log)

            # grab dihedrals from our database
            # using zip() on i_dynamic_dihedrals and our values
            # plug it into restraints in dihedral proxies
            dihedrals = [
                self._get_dihedral(sites_cart=sites_cart,
                                   dihedral_proxies=dihedral_proxies,
                                   i_proxy=i_proxy)
                for i_proxy in self.i_dynamic_dihedrals
            ]

            for dihedral, dihedral_name, i_proxy in zip(
                    dihedrals,
                    conformation_dependent_geometry.angles.dihedral_names,
                    self.i_dynamic_dihedrals):
                # i_dynamic_dihedrals contains None for dihedrals/atoms that don't
                # exist so don't have restraints to update.
                if i_proxy is not None:

                    new_angle_ideal, new_weight = \
                                     self._get_average_and_weight(geometry, dihedral_name)

                    new_angle_ideal = dihedral_proxies[i_proxy].angle_ideal
                    new_weight = dihedral_proxies[i_proxy].weight

                    # Create a new dihedral proxy here with our restraint
                    new_dihedral_proxy = geometry_restraints.dihedral_proxy(
                        i_seqs=dihedral_proxies[i_proxy].i_seqs,
                        angle_ideal=new_angle_ideal,
                        weight=new_weight)

                    # Overwrite the old proxy
                    dihedral_proxies[i_proxy] = new_dihedral_proxy

                    # Show that we actually did update the proxy
                    proxy = dihedral_proxies[i_proxy]
                    print(self.residue_name,
                          self.next_residue_name,
                          end=' ',
                          file=log)
                    print(dihedral_name,
                          proxy.i_seqs,
                          proxy.angle_ideal,
                          proxy.weight,
                          file=log)
def build_conformation_dependent_angle_proxies(angle_proxy_registry,
                                               dihedral_proxy_registry,
                                               monomer_mappings,
                                               connectivity_i_j,
                                               connectivity_j_k, sites_cart):
    """
  Sets up conformation_dependent_restraints object.

  Finds atom indexes from registries

  Looks for C_prev in m_i, most atoms in m_j, N_next in m_k.
  """
    assert len(monomer_mappings) == 3

    if monomer_mappings[1] is None:
        residue_name = None
    else:
        residue_name = monomer_mappings[1].residue_name

    if monomer_mappings[2] is None:
        next_residue_name = None
    else:
        next_residue_name = monomer_mappings[2].residue_name

    dihedral_i_proxies = []
    conformation_proxies = geometry_restraints.shared_dihedral_proxy()
    for dihedral_number, dihedral_definition in enumerate(
            conformation_dependent_geometry.angles.dihedral_atoms):
        i_seqs = []
        for residue_index, atom_name in dihedral_definition:
            mm = monomer_mappings[residue_index]
            if mm is not None:
                i_seqs.append(
                    getattr(mm.expected_atoms.get(atom_name), "i_seq", None))
        # account for missing atoms
        if len(i_seqs) == 4 and i_seqs.count(None) == 0:
            if dihedral_number == 0:
                # phi/psi: Restraints don't matter, we throw them away. This is just
                # so we can get eventually get the current value.
                phi = geometry_restraints.dihedral_proxy(i_seqs=i_seqs,
                                                         angle_ideal=60.0,
                                                         weight=1 / 20.0**2,
                                                         periodicity=3)
                conformation_proxies.append(phi)
                dihedral_i_proxies.append(None)
                i_phi_proxy = 0
            elif dihedral_number == 1:
                psi = geometry_restraints.dihedral_proxy(i_seqs=i_seqs,
                                                         angle_ideal=160.0,
                                                         weight=1 / 30.0**2,
                                                         periodicity=3)
                conformation_proxies.append(psi)
                dihedral_i_proxies.append(None)
                i_psi_proxy = 1
            elif dihedral_number == 2:
                # omega
                dihedral_i_proxy, dihedral_sign = dihedral_proxy_registry.lookup_i_proxy(
                    i_seqs)
                dihedral_i_proxies.append(dihedral_i_proxy)
            else:
                pass
        # we're on a dihedral with missing length or atoms that are None
        else:
            if dihedral_number == 0:
                i_phi_proxy = None
            elif dihedral_number == 1:
                i_psi_proxy = None
            elif dihedral_number == 2:
                dihedral_i_proxies.append(None)
            else:
                pass

    angle_i_proxies = []
    for angle_definition in conformation_dependent_geometry.angles.angle_atoms:
        i_seqs = []
        for residue_index, atom_name in angle_definition:
            mm = monomer_mappings[residue_index]
            if mm is not None:
                i_seqs.append(
                    getattr(mm.expected_atoms.get(atom_name), "i_seq", None))
        # account for missing atoms

        if len(i_seqs) == 3 and i_seqs.count(None) == 0:
            # go into angle_proxy_registry
            angle_i_proxy = angle_proxy_registry.lookup_i_proxy(i_seqs)
            angle_i_proxies.append(angle_i_proxy)
        else:
            # By filling in None for blanks, we can assume the lengths are equal
            # here and other places angle_atoms/angle_names are used
            angle_i_proxies.append(None)

    cfd = conformation_dependent_restraints(
        residue_name=residue_name,
        next_residue_name=next_residue_name,
        conformation_proxies=conformation_proxies,
        i_phi_proxy=i_phi_proxy,
        i_psi_proxy=i_psi_proxy,
        i_dynamic_angles=angle_i_proxies,
        i_dynamic_dihedrals=dihedral_i_proxies)

    return cfd
示例#14
0
def exercise_geometry_restraints_as_cif():
  quartz = xray.structure(
    crystal_symmetry=crystal.symmetry(
      (5.01,5.01,5.47,90,90,120), "P6222"),
    scatterers=flex.xray_scatterer([
      xray.scatterer("Si", (1/2.,1/2.,1/3.)),
      xray.scatterer("O", (0.197,-0.197,0.83333))]))
  bond_proxies = geometry_restraints.shared_bond_simple_proxy((
    geometry_restraints.bond_simple_proxy(
      i_seqs=[0,1],
      rt_mx_ji=sgtbx.rt_mx("x-y,x,z-2/3"),
      distance_ideal=1.6,
      weight=3.2),
    geometry_restraints.bond_simple_proxy(
      i_seqs=[0,1],
      distance_ideal=1.7,
      weight=1.8),
  ))
  dihedral_proxies = geometry_restraints.shared_dihedral_proxy((
    geometry_restraints.dihedral_proxy(
      i_seqs = [1,0,1,0],
      sym_ops = (sgtbx.rt_mx("1+y,1-x+y, z-1/3"),
                 sgtbx.rt_mx(),
                 sgtbx.rt_mx("x-y,x,z-2/3"),
                 sgtbx.rt_mx("1-x,y-x,1/3-z")),
      angle_ideal=-30,
      weight=2),
    geometry_restraints.dihedral_proxy(
      i_seqs = [1,0,1,0],
      sym_ops = (sgtbx.rt_mx("1+y,1-x+y, z-1/3"),
                 sgtbx.rt_mx(),
                 sgtbx.rt_mx("-y,x-y,z-1/3"),
                 sgtbx.rt_mx("x-y,x,1/3+z")),
      angle_ideal=90,
      weight=3),
  ))
  angle_proxies = geometry_restraints.shared_angle_proxy((
    geometry_restraints.angle_proxy(
      i_seqs = [1,0,1],
      sym_ops = (sgtbx.rt_mx("x-y,x,z-2/3"),
                 sgtbx.rt_mx(),
                 sgtbx.rt_mx("-y,x-y,z-1/3")),
      angle_ideal=103,
      weight=2),
    geometry_restraints.angle_proxy(
      i_seqs = [1,0,1],
      sym_ops = (sgtbx.rt_mx("y+1,-x+y+1,z-1/3"),
                 sgtbx.rt_mx(),
                 sgtbx.rt_mx("-y,x-y,z-1/3")),
      angle_ideal=110,
      weight=5),
    geometry_restraints.angle_proxy(
      i_seqs = [0,1,0],
      sym_ops = (sgtbx.rt_mx("y,-x+y,z+2/3"),
                 sgtbx.rt_mx(),
                 sgtbx.rt_mx("-x+y,-x,z+1/3")),
      angle_ideal=150,
      weight=5),
  ))
  bond_similarity_proxies = geometry_restraints.shared_bond_similarity_proxy((
    geometry_restraints.bond_similarity_proxy(
      i_seqs=[(0,1),(0,1),(0,1)],
      sym_ops=(sgtbx.rt_mx("x-y,x,z-2/3"),
               sgtbx.rt_mx("-y,x-y,z-1/3"),
               sgtbx.rt_mx("y+1,-x+y+1,z-1/3")),
      weights=(1,1,1)),
  ))
  cif_block = iotbx.cif.model.block()
  iotbx.cif.restraints.add_to_cif_block(
    cif_block, quartz,
    bond_proxies=bond_proxies,
    angle_proxies=angle_proxies,
    dihedral_proxies=dihedral_proxies,
    bond_similarity_proxies=bond_similarity_proxies)
  s = StringIO()
  cif_block.show(out=s)
  assert not show_diff(s.getvalue(), """\
loop_
  _restr_distance_atom_site_label_1
  _restr_distance_atom_site_label_2
  _restr_distance_site_symmetry_2
  _restr_distance_target
  _restr_distance_target_weight_param
  _restr_distance_diff
  Si  O  2_554  1.6000  0.5590  -0.0160
  Si  O  1      1.7000  0.7454  -2.3838

loop_
  _restr_angle_atom_site_label_1
  _restr_angle_atom_site_label_2
  _restr_angle_atom_site_label_3
  _restr_angle_site_symmetry_1
  _restr_angle_site_symmetry_2
  _restr_angle_site_symmetry_3
  _restr_angle_target
  _restr_angle_target_weight_param
  _restr_angle_diff
  O   Si  O   2_554  1  4_554  103.0000  0.7071   1.6926
  O   Si  O   3_664  1  4_554  110.0000  0.4472  -1.3127
  Si  O   Si  3      1  5      150.0000  0.4472   3.0700

loop_
  _restr_torsion_atom_site_label_1
  _restr_torsion_atom_site_label_2
  _restr_torsion_atom_site_label_3
  _restr_torsion_atom_site_label_4
  _restr_torsion_site_symmetry_1
  _restr_torsion_site_symmetry_2
  _restr_torsion_site_symmetry_3
  _restr_torsion_site_symmetry_4
  _restr_torsion_angle_target
  _restr_torsion_weight_param
  _restr_torsion_diff
  O  Si  O  Si  3_664  1  2_554  7_655  -30.0000  0.7071   6.9078
  O  Si  O  Si  3_664  1  4_554  2       90.0000  0.5774  11.7036

loop_
  _restr_equal_distance_class_class_id
  _restr_equal_distance_class_target_weight_param
  _restr_equal_distance_class_average
  _restr_equal_distance_class_esd
  _restr_equal_distance_class_diff_max
  1  1.0000  1.6160  0.0000  0.0000

loop_
  _restr_equal_distance_atom_site_label_1
  _restr_equal_distance_atom_site_label_2
  _restr_equal_distance_site_symmetry_2
  _restr_equal_distance_class_id
  Si  O  2_554  1
  Si  O  4_554  1
  Si  O  3_664  1

""")
示例#15
0
def _apply_link_using_proxies(link,
                              atom_group1,
                              atom_group2,
                              bond_params_table,
                              bond_asu_table,
                              geometry_proxy_registries,
                        #      distance,
                              rt_mx_ji,
                              ):
  ######################################
  def _get_restraint_i_seqs(atom_group1,
                            atom_group2,
                            restraint,
                            ):
    i_seqs = []
    keys = restraint.cif_keywords()
    if "value_dist" in keys:
      attrs = [
        "atom_1_comp_id",
        "atom_id_1",
        "atom_2_comp_id",
        "atom_id_2",
        ]
    elif "period" in keys:
      attrs = [
        "atom_1_comp_id",
        "atom_id_1",
        "atom_2_comp_id",
        "atom_id_2",
        "atom_3_comp_id",
        "atom_id_3",
        "atom_4_comp_id",
        "atom_id_4",
        ]
    elif "value_angle" in keys:
      attrs = [
        "atom_1_comp_id",
        "atom_id_1",
        "atom_2_comp_id",
        "atom_id_2",
        "atom_3_comp_id",
        "atom_id_3",
        ]
    elif "volume_sign" in keys:
      attrs = [
        "atom_centre_comp_id",
        "atom_id_centre",
        "atom_1_comp_id",
        "atom_id_1",
        "atom_2_comp_id",
        "atom_id_2",
        "atom_3_comp_id",
        "atom_id_3",
        ]
    elif "plane_id" in keys:
      attrs = [
        "atom_comp_id",
        "atom_id",
        ]
    else:
      assert 0
    for i, attr in enumerate(attrs):
      if i%2:
        # name
        name = getattr(restraint, attr)
        for atom in atoms:
          # uses names to confirm link
          if atom.name.strip()==name.strip():
            i_seqs.append(atom.i_seq)
            break
        else:
          # name not found, could be hydrogen or ...
          return None
      else:
        # atoms
        if getattr(restraint, attr)==1:
          atoms = atom_group1.atoms()
        else:
          atoms = atom_group2.atoms()
    return i_seqs
  ###############
  def _check_i_seqs(atom_group1, atom_group2, i_seqs):
    atoms = []
    for i_seq in i_seqs:
      for atom in list(atom_group1.atoms())+list(atom_group2.atoms()):
        if atom.i_seq==i_seq:
          atoms.append(atom)
          break
    d2 = linking_utils.get_distance2(*atoms) # XXXX needs to be sym aware
    if d2>9: return False
    return True
  #############
  assert link
  count = 0
  #
  bond_i_seqs = []
  for bond in link.bond_list:
    i_seqs = _get_restraint_i_seqs(atom_group1,
                                   atom_group2,
                                   bond,
      )
    if i_seqs is None: continue
    if not _check_i_seqs(atom_group1, atom_group2, i_seqs): # check distances
      tmp = atom_group2
      atom_group2 = atom_group1
      atom_group1 = tmp
      i_seqs = _get_restraint_i_seqs(atom_group1,
                                     atom_group2,
                                     bond,
        )
      if i_seqs is None: continue
    value = "value_dist"
    proxy = geometry_restraints.bond_simple_proxy(
      i_seqs=i_seqs,
      distance_ideal=getattr(bond, value),
      weight=1/bond.value_dist_esd**2)
    bond_params_table.update(i_seq=i_seqs[0],
                             j_seq=i_seqs[1],
                             params=proxy)
    #if rt_mx_ji is None: continue
    bond_asu_table.add_pair(
      i_seq=i_seqs[0],
      j_seq=i_seqs[1],
      rt_mx_ji=rt_mx_ji,
      )
    count+=1
    bond_i_seqs.append(i_seqs)
  #
  for angle in link.angle_list:
    i_seqs = _get_restraint_i_seqs(atom_group1,
                                   atom_group2,
                                   angle,
        )
    if i_seqs is None: continue
    proxy = geometry_restraints.angle_proxy(
      i_seqs=i_seqs,
      angle_ideal=angle.value_angle,
      weight=1/angle.value_angle_esd**2)
    geometry_proxy_registries.angle.add_if_not_duplicated(proxy=proxy)
  #
  for tor in link.tor_list:
    i_seqs = _get_restraint_i_seqs(atom_group1,
                                   atom_group2,
                                   tor,
        )
    if i_seqs is None: continue
    proxy = geometry_restraints.dihedral_proxy(
      i_seqs=i_seqs,
      angle_ideal=tor.value_angle,
      weight=1/tor.value_angle_esd**2,
      periodicity=tor.period,
      )
    geometry_proxy_registries.dihedral.add_if_not_duplicated(proxy=proxy)
  #
  for chir in link.chir_list:
    i_seqs = _get_restraint_i_seqs(atom_group1,
                                   atom_group2,
                                   chir,
        )
    if i_seqs is None: continue
    volume_ideal = 2.4
    if chir.volume_sign[:4].lower()=="nega":
      volume_ideal = -2.4
    elif chir.volume_sign[:4].lower()=="zero":
      volume_ideal = 0.
    proxy = geometry_restraints.chirality_proxy(
      i_seqs=i_seqs,
      volume_ideal=volume_ideal,
      both_signs=False,
      weight=25.,
      )
    geometry_proxy_registries.chirality.add_if_not_duplicated(proxy=proxy)
  #
  planes = {}
  weights = {}
  for plane in link.plane_list:
    i_seqs = _get_restraint_i_seqs(atom_group1,
                                   atom_group2,
                                   plane,
        )
    if i_seqs is None: continue
    planes.setdefault(plane.plane_id, [])
    planes[plane.plane_id]+=i_seqs
    weights.setdefault(plane.plane_id, [])
    weights[plane.plane_id].append(1/plane.dist_esd**2)
  if planes:
    for plane_id in planes:
      if len(planes[plane_id])<4: continue
      proxy = geometry_restraints.planarity_proxy(
        i_seqs=planes[plane_id],
        weights=weights[plane_id],
        )
      geometry_proxy_registries.planarity.add_if_not_duplicated(proxy=proxy)
  return count, bond_i_seqs
示例#16
0
def _apply_link_using_proxies(
    link,
    atom_group1,
    atom_group2,
    bond_params_table,
    bond_asu_table,
    geometry_proxy_registries,
    #      distance,
    rt_mx_ji,
    origin_id=None,
):
    assert origin_id

    ######################################
    def _get_restraint_i_seqs(
        atom_group1,
        atom_group2,
        restraint,
    ):
        i_seqs = []
        keys = restraint.cif_keywords()
        if "value_dist" in keys:
            attrs = [
                "atom_1_comp_id",
                "atom_id_1",
                "atom_2_comp_id",
                "atom_id_2",
            ]
        elif "period" in keys:
            attrs = [
                "atom_1_comp_id",
                "atom_id_1",
                "atom_2_comp_id",
                "atom_id_2",
                "atom_3_comp_id",
                "atom_id_3",
                "atom_4_comp_id",
                "atom_id_4",
            ]
        elif "value_angle" in keys:
            attrs = [
                "atom_1_comp_id",
                "atom_id_1",
                "atom_2_comp_id",
                "atom_id_2",
                "atom_3_comp_id",
                "atom_id_3",
            ]
        elif "volume_sign" in keys:
            attrs = [
                "atom_centre_comp_id",
                "atom_id_centre",
                "atom_1_comp_id",
                "atom_id_1",
                "atom_2_comp_id",
                "atom_id_2",
                "atom_3_comp_id",
                "atom_id_3",
            ]
        elif "plane_id" in keys:
            attrs = [
                "atom_comp_id",
                "atom_id",
            ]
        else:
            assert 0
        for i, attr in enumerate(attrs):
            if i % 2:
                # name
                name = getattr(restraint, attr)
                for atom in atoms:
                    # uses names to confirm link
                    if atom.name.strip() == name.strip():
                        i_seqs.append(atom.i_seq)
                        break
                else:
                    # name not found, could be hydrogen or ...
                    return None
            else:
                # atoms
                if getattr(restraint, attr) == 1:
                    atoms = atom_group1.atoms()
                else:
                    atoms = atom_group2.atoms()
        return i_seqs

    ###############
    def _check_i_seqs(atom_group1, atom_group2, i_seqs):
        atoms = []
        for i_seq in i_seqs:
            for atom in list(atom_group1.atoms()) + list(atom_group2.atoms()):
                if atom.i_seq == i_seq:
                    atoms.append(atom)
                    break
        d2 = linking_utils.get_distance2(*atoms)  # XXXX needs to be sym aware
        if d2 > 9: return False
        return True

    #############
    assert link
    count = 0
    #
    bond_i_seqs = []
    for bond in link.bond_list:
        i_seqs = _get_restraint_i_seqs(
            atom_group1,
            atom_group2,
            bond,
        )
        if i_seqs is None: continue
        if not _check_i_seqs(atom_group1, atom_group2,
                             i_seqs):  # check distances
            tmp = atom_group2
            atom_group2 = atom_group1
            atom_group1 = tmp
            i_seqs = _get_restraint_i_seqs(
                atom_group1,
                atom_group2,
                bond,
            )
            if i_seqs is None: continue
        value = "value_dist"
        assert origin_id
        proxy = geometry_restraints.bond_simple_proxy(
            i_seqs=i_seqs,
            distance_ideal=getattr(bond, value),
            weight=1 / bond.value_dist_esd**2,
            origin_id=origin_id,
        )
        bond_params_table.update(i_seq=i_seqs[0],
                                 j_seq=i_seqs[1],
                                 params=proxy)
        #if rt_mx_ji is None: continue
        bond_asu_table.add_pair(
            i_seq=i_seqs[0],
            j_seq=i_seqs[1],
            rt_mx_ji=rt_mx_ji,
        )
        count += 1
        bond_i_seqs.append(i_seqs)
    #
    for angle in link.angle_list:
        i_seqs = _get_restraint_i_seqs(
            atom_group1,
            atom_group2,
            angle,
        )
        if i_seqs is None: continue
        proxy = geometry_restraints.angle_proxy(
            i_seqs=i_seqs,
            angle_ideal=angle.value_angle,
            weight=1 / angle.value_angle_esd**2,
            origin_id=origin_id,
        )
        geometry_proxy_registries.angle.add_if_not_duplicated(proxy=proxy)
    #
    for tor in link.tor_list:
        i_seqs = _get_restraint_i_seqs(
            atom_group1,
            atom_group2,
            tor,
        )
        if i_seqs is None: continue
        proxy = geometry_restraints.dihedral_proxy(
            i_seqs=i_seqs,
            angle_ideal=tor.value_angle,
            weight=1 / tor.value_angle_esd**2,
            periodicity=tor.period,
            origin_id=origin_id,
        )
        geometry_proxy_registries.dihedral.add_if_not_duplicated(proxy=proxy)
    #
    for chir in link.chir_list:
        i_seqs = _get_restraint_i_seqs(
            atom_group1,
            atom_group2,
            chir,
        )
        if i_seqs is None: continue
        volume_ideal = 2.4
        if chir.volume_sign[:4].lower() == "nega":
            volume_ideal = -2.4
        elif chir.volume_sign[:4].lower() == "zero":
            volume_ideal = 0.
        both_signs = False
        if chir.volume_sign == 'both': both_signs = True
        proxy = geometry_restraints.chirality_proxy(
            i_seqs=i_seqs,
            volume_ideal=volume_ideal,
            both_signs=both_signs,
            weight=25.,
            origin_id=origin_id,
        )
        geometry_proxy_registries.chirality.add_if_not_duplicated(proxy=proxy)
    #
    planes = {}
    weights = {}
    for plane in link.plane_list:
        i_seqs = _get_restraint_i_seqs(
            atom_group1,
            atom_group2,
            plane,
        )
        if i_seqs is None: continue
        planes.setdefault(plane.plane_id, [])
        planes[plane.plane_id] += i_seqs
        weights.setdefault(plane.plane_id, [])
        weights[plane.plane_id].append(1 / plane.dist_esd**2)
    if planes:
        for plane_id in planes:
            if len(planes[plane_id]) < 4: continue
            proxy = geometry_restraints.planarity_proxy(
                i_seqs=planes[plane_id],
                weights=weights[plane_id],
                origin_id=origin_id,
            )
            geometry_proxy_registries.planarity.add_if_not_duplicated(
                proxy=proxy)
    return count, bond_i_seqs
def read_pdb():

    pdbstring = """\
ATOM      0  CA  GLY A   3       5.804  -2.100   7.324  1.00  1.36           C
ATOM      1  C   GLY A   3       4.651  -1.149   7.578  1.00  1.01           C
ATOM      2  O   GLY A   3       3.598  -1.553   8.071  1.00  1.38           O
ATOM      3  N   GLY A   3       6.706  -1.622   6.294  1.00  1.11           N
ATOM      4  CA  PHE A   4       3.819   1.134   7.419  1.00  0.89           C
ATOM      5  CB  PHE A   4       4.397   2.380   8.094  1.00  1.13           C
ATOM      6  C   PHE A   4       3.185   1.509   6.084  1.00  0.94           C
ATOM      7  N   PHE A   4       4.852   0.121   7.242  1.00  0.88           N
ATOM      8  O   PHE A   4       2.361   2.421   6.010  1.00  1.47           O
ATOM      9  CA  LEU A   5       3.055   1.059   3.693  1.00  0.87           C
ATOM     10  CB  LEU A   5       3.965   0.435   2.634  1.00  1.13           C
ATOM     11  C   LEU A   5       1.634   0.527   3.541  1.00  0.87           C
ATOM     12  N   LEU A   5       3.576   0.800   5.030  1.00  0.92           N
ATOM     13  O   LEU A   5       1.246  -0.440   4.196  1.00  1.23           O
"""

    pdb_inp = iotbx.pdb.input(
        lines=flex.split_lines(pdbstring), source_info=None)

    sites_cart = pdb_inp.atoms().extract_xyz()

# TRANS    phi      1 C      2 N      2 CA     2 C        60.00  20.0 3
# TRANS    psi      1 N      1 CA     1 C      2 N       160.00  30.0 2

    dihedral_proxies = geometry_restraints.shared_dihedral_proxy()

    # residue 1
    psi = geometry_restraints.dihedral_proxy(
        i_seqs=[3, 0, 1, 7],
        angle_ideal=160.0,
        weight=1/30.0**2,
        periodicity=3
        )
    dihedral_proxies.append(psi)

    # residue 2
    phi = geometry_restraints.dihedral_proxy(
        i_seqs=[1, 7, 4, 6],
        angle_ideal=60.0,
        weight=1/20.0**2,
        periodicity=3
        )
    dihedral_proxies.append(phi)

    psi = geometry_restraints.dihedral_proxy(
        i_seqs=[7, 4, 6, 8],
        angle_ideal=160.0,
        weight=1/30.0**2,
        periodicity=3
        )
    dihedral_proxies.append(psi)

    # residue 3
    phi = geometry_restraints.dihedral_proxy(
        i_seqs=[6, 12, 9, 11],
        angle_ideal=60.0,
        weight=1/20.0**2,
        periodicity=3
        )
    dihedral_proxies.append(phi)

    angle_proxies = geometry_restraints.shared_angle_proxy()

    ## Residue 1
    # a3
    a = geometry_restraints.angle_proxy(
        i_seqs=[3, 0, 1],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    # a7
    a = geometry_restraints.angle_proxy(
        i_seqs=[2, 1, 7],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    ## Residue 2
    # a1
    a = geometry_restraints.angle_proxy(
        i_seqs=[1, 7, 4],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    # a3
    a = geometry_restraints.angle_proxy(
        i_seqs=[7, 4, 6],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    # a7
    a = geometry_restraints.angle_proxy(
        i_seqs=[8, 6, 12],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    ## Residue 3
    # a1
    a = geometry_restraints.angle_proxy(
        i_seqs=[6, 12, 9],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    # a3
    a = geometry_restraints.angle_proxy(
        i_seqs=[12, 9, 11],
        angle_ideal=0,
        weight=1
        )
    angle_proxies.append(a)

    # compute dihedral
    #dihedral = geometry_restraints.dihedral(
    #    sites_cart=sites_cart,
    #    proxy=dihedral_proxies[0])

    # Shows real dihedral value
    #print dihedral.angle_model, dihedral.delta
    cfd_list = []

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='GLY',
        next_residue_name='PHE',
        conformation_proxies=None,
        i_phi_proxy=None, # index into dihedral_proxies
        i_psi_proxy=0,
        i_dynamic_angles=[None, None, 0, None, None, None, 1], # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None
        )
    cfd_list.append(cfd)

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='PHE',
        next_residue_name='LEU',
        conformation_proxies=None,
        i_phi_proxy=1, # index into dihedral_proxies
        i_psi_proxy=2,
        i_dynamic_angles=[2, None, 3, None, None, None, 4], # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None
        )
    cfd_list.append(cfd)

    cfd = conformation_dependent_restraints.conformation_dependent_restraints(
        residue_name='LEU',
        next_residue_name=None,
        conformation_proxies=None,
        i_phi_proxy=3, # index into dihedral_proxies
        i_psi_proxy=None,
        i_dynamic_angles=[5, None, 6, None, None, None, None], # indexes into angles in angle_proxies
        i_dynamic_dihedrals=None
        )
    cfd_list.append(cfd)

    for x in range(1, 4):
        print
        print 'Starting cycle', x
        print
        for cfd in cfd_list:
            cfd.update_restraints(sites_cart, dihedral_proxies, angle_proxies)