예제 #1
0
   def __init__(
         self,
         spacegroup,
         pept_axis,
         pept_orig,
         ligands,
         sym_of_ligand,
         max_dun_score,
         **kw,
   ):
      super(XtalSearchSpec, self).__init__()
      kw = rp.Bunch(kw)
      self.spacegroup = spacegroup
      self.pept_axis = pept_axis
      self.pept_orig = pept_orig
      self.ligands = ligands
      self.sym_of_ligand = sym_of_ligand
      self.max_dun_score = max_dun_score
      self.xtal_spec = mof.xtal_spec.get_xtal_spec(self.spacegroup)
      self.chm = rt.core.chemical.ChemicalManager.get_instance()
      self.rts = self.chm.residue_type_set('fa_standard')

      self.sfxn_rotamer = get_sfxn('rotamer')
      # self.sfxn_rotamer.set_weight(rt.core.scoring.ScoreType.fa_dun, 1.0)

      self.sfxn_sterics = get_sfxn('sterics')
      # self.sfxn_sterics.set_weight(rt.core.scoring.ScoreType.fa_atr, 1.00)
      # self.sfxn_sterics.set_weight(rt.core.scoring.ScoreType.fa_rep, 0.55)

      self.sfxn_minimize = get_sfxn('minimize')
예제 #2
0
def get_cli_args(argv=None, parent=None, **kw):
    parser = default_cli_parser(parent, **kw)
    argv = sys.argv[1:] if argv is None else argv
    argv = rp.app.options.make_argv_with_atfiles(argv, **kw)
    options = parser.parse_args(argv)
    # options = process_cli_args(options, **kw)
    return rp.Bunch(options)
예제 #3
0
파일: main.py 프로젝트: willsheffler/mof
def get_rotclouds(**kw):
    kw = rp.Bunch(kw)

    chiresl_asp1 = kw.chiresl_asp1 / kw.scale_number_of_rotamers
    chiresl_asp2 = kw.chiresl_asp2 / kw.scale_number_of_rotamers
    chiresl_cys1 = kw.chiresl_cys1 / kw.scale_number_of_rotamers
    chiresl_cys2 = kw.chiresl_cys2 / kw.scale_number_of_rotamers
    chiresl_his1 = kw.chiresl_his1 / kw.scale_number_of_rotamers
    chiresl_his2 = kw.chiresl_his2 / kw.scale_number_of_rotamers
    chiresl_glu1 = kw.chiresl_glu1 / kw.scale_number_of_rotamers
    chiresl_glu2 = kw.chiresl_glu2 / kw.scale_number_of_rotamers
    chiresl_glu3 = kw.chiresl_glu3 / kw.scale_number_of_rotamers

    os.makedirs(kw.rotcloud_cache, exist_ok=True)

    params = (kw.chiresl_his1, kw.chiresl_his2, kw.chiresl_cys1,
              kw.chiresl_cys2, kw.chiresl_asp1, kw.chiresl_asp2,
              kw.chiresl_glu1, kw.chiresl_glu2, kw.chiresl_glu3, kw.maxdun_cys,
              kw.maxdun_asp, kw.maxdun_glu, kw.maxdun_his)
    ident = mof.util.hash_str_to_int(str(params))

    cache_file = kw.rotcloud_cache + '/%i.pickle' % ident
    if os.path.exists(cache_file):
        lC, lD, lE, lH, lJ, dC, dD, dE, dH, dJ = rp.util.load(cache_file)
    else:
        print('building rotamer clouds')
        chi_range = lambda resl: np.arange(-180, 180, resl)
        chi_asp = [chi_range(x) for x in (chiresl_asp1, chiresl_asp2)]
        chi_cys = [chi_range(x) for x in (chiresl_cys1, chiresl_cys2)]
        chi_his = [chi_range(x) for x in (chiresl_his1, chiresl_his2)]
        chi_glu = [
            chi_range(x) for x in (chiresl_glu1, chiresl_glu2, chiresl_glu3)
        ]

        lC = mof.rotamer_cloud.RotCloudCysZN(grid=chi_cys, max_dun_score=4.0)
        lD = mof.rotamer_cloud.RotCloudAspZN(grid=chi_asp, max_dun_score=5.0)
        lE = mof.rotamer_cloud.RotCloudGluZN(grid=chi_glu, max_dun_score=5.0)
        lH = mof.rotamer_cloud.RotCloudHisZN(grid=chi_his, max_dun_score=5.0)
        lJ = mof.rotamer_cloud.RotCloudHisdZN(grid=chi_his, max_dun_score=5.0)

        dC = mof.rotamer_cloud.RotCloudDCysZN(grid=chi_cys, max_dun_score=4.0)
        dD = mof.rotamer_cloud.RotCloudDAspZN(grid=chi_asp, max_dun_score=5.0)
        dE = mof.rotamer_cloud.RotCloudDGluZN(grid=chi_glu, max_dun_score=5.0)
        dH = mof.rotamer_cloud.RotCloudDHisZN(grid=chi_his, max_dun_score=5.0)
        dJ = mof.rotamer_cloud.RotCloudDHisdZN(grid=chi_his, max_dun_score=5.0)

        rp.util.dump([lC, lD, lE, lH, lJ, dC, dD, dE, dH, dJ], cache_file)

    return dict(lC=lC,
                lD=lD,
                lE=lE,
                lH=lH,
                lJ=lJ,
                dC=dC,
                dD=dD,
                dE=dE,
                dH=dH,
                dJ=dJ)
예제 #4
0
def test_xtal_build_p213():
    arg = rp.Bunch()
    arg.min_cell_size = 0
    arg.max_cell_size = 999
    arg.clash_dis = 3.0,
    arg.contact_dis = 7.0,
    arg.min_contacts = 0,
    arg.max_sym_score = 9e9,

    pose = pose_from_file(path_to_test_data('test_xtal_build_p213.pdb'))

    xtal_posess = xtal_build(
        pdb_name='testpdb',
        xspec=xtal_spec.get_xtal_spec('p213'),
        pose=pose,
        peptide_sym='C3',
        peptide_orig=np.array([0, 0, 0, 1]),
        peptide_axis=np.array([0, 0, 1, 0]),
        metal_sym='C3',
        metal_origin=np.array([6.21626192, -9.70902624, 5.32956683, 1.]),
        metal_sym_axis=np.array([-0.55345815, -0.76326468, -0.33333333, 0.]),
        rpxbody=rp.Body(pose),
        tag='test_xtal_build_p213',
        **arg,
    )

    xalign, xpose, bodypdb = xtal_posess[0]
    print('verify bb coords')
    assert np.allclose(
        util.coord_find(xpose, 1, 'CA'),
        [-2.33104726, -4.58076386, -11.17135244],
    )
    assert np.allclose(
        util.coord_find(xpose, 2, 'CA'),
        [-5.24447638, -2.71997589, -12.75316055],
    )
    assert np.allclose(
        util.coord_find(xpose, 3, 'CA'),
        [-5.3331455, -4.53568805, -16.09169707],
    )
    print('verify space group and unit cell')
    assert xpose.pdb_info().crystinfo().spacegroup() == 'P 21 3'
    assert np.allclose(xpose.pdb_info().crystinfo().A(), 30.354578479691444)

    # print('test_xtal_build_p213')

    print('verify xtal alignment')
    xalign_should_be = np.array([
        [-0.47930882, -0.6610066, 0.57735027, -7.73090447],
        [0.81210292, -0.08459031, 0.57735027, -7.73090447],
        [-0.3327941, 0.74559691, 0.57735027, -7.73090447],
        [0., 0., 0., 1.],
    ])
    assert np.allclose(xalign, xalign_should_be, atol=1e-5)
예제 #5
0
def get_sfxn(tag='cli', **kw):
    kw = rp.Bunch(kw)
    tag = tag.lower()
    if tag is 'cli':
        return scoring.get_score_function()
    elif tag is 'rotamer':
        get_sfxn_weights(kw.sfxn_rotamer_weights)
        return get_sfxn_weights(kw.sfxn_rotamer_weights)
    elif tag is 'sterics':
        return get_sfxn_weights(kw.sfxn_sterics_weights)
    elif tag is 'minimize':
        return get_sfxn_weights(kw.sfxn_minimize_weights)
    else:
        return get_sfxn_weights(tag)
    raise ValueError(f'unknown rosetta scorefunction tag: {tag}')
예제 #6
0
def test_xtal_search_2res_i213(c3_peptide, rotcloud_asp, rotcloud_his):
   arg = rp.Bunch()
   arg.max_bb_redundancy = 1.0
   arg.err_tolerance = 1.5
   arg.dist_err_tolerance = 1.0
   arg.angle_err_tolerance = 15
   arg.min_dist_to_z_axis = 6.0
   arg.sym_axes_angle_tolerance = 5.0
   arg.angle_to_cart_err_ratio = 20.0
   arg.max_dun_score
   arg.min_cell_size = 0
   arg.max_cell_size = 999
   arg.clash_dis = 3.0
   arg.contact_dis = 7.0
   arg.min_contacts = 0
   arg.max_sym_score = 9e9
   arg.max_2res_score = 10

   search_spec = mof.xtal_search.XtalSearchSpec(
      spacegroup='i213',
      pept_orig=np.array([0, 0, 0, 1]),
      pept_axis=np.array([0, 0, 1, 0]),
      max_dun_score=arg.max_dun_score,
      sym_of_ligand=dict(HZ3='C3'),
      ligands=['HZ3'],
   )

   r = mof.xtal_search.xtal_search_two_residues(
      search_spec,
      c3_peptide,
      rotcloud_his,
      rotcloud_asp,
      **arg,
   )

   assert len(r) is 1
   assert np.allclose(r[0].xalign, [
      [-0.77574427, -0.25473024, 0.57735027, 6.70142185],
      [0.608475, -0.54444912, 0.57735027, 6.70142185],
      [0.16726927, 0.79917937, 0.57735027, 6.70142185],
      [0., 0., 0., 1.],
   ], atol=0.0001)
예제 #7
0
파일: data.py 프로젝트: willsheffler/mof
log = logging.getLogger(__name__)

data_dir = os.path.dirname(__file__)
motifs_dir = str(os.path.join(data_dir, "motifs"))
params_dir = str(os.path.join(data_dir, "rosetta_params"))
weights_dir = str(os.path.join(data_dir, "rosetta_weights"))

frank_space_groups = os.path.join(data_dir, "crystals_from_point.csv")

peptides_dir = os.path.join(data_dir, "peptides")
a_c3_peptide = os.path.join(peptides_dir, "c3_21res_c.101.12_0001.pdb")

params = rp.Bunch(
    HZ3=str(os.path.join(motifs_dir, "HZ3.params")),
    HZD=str(os.path.join(motifs_dir, "HZD.params")),
    HZ4=str(os.path.join(motifs_dir, "HZ4.params")),
    VZN=str(os.path.join(params_dir, "VZN.params")),
)

all_params_files = " ".join(params.values())


def c3_peptide():
    return pyrosetta.pose_from_file(
        os.path.join(data_dir, 'peptides/c3_21res_c.107.7_0001.pdb'))


def rotcloud_asp_small():
    return load(os.path.join(data_dir, 'rotcloud_asp_small.pickle'))

예제 #8
0
def xtal_build(
      pdb_name,
      xspec,
      aa1,
      aa2,
      pose,
      peptide_sym,
      peptide_orig,
      peptide_axis,
      metal_sym,
      metal_origin,
      metal_sym_axis,
      rpxbody,
      tag,
      clash_dis,
      contact_dis,
      min_contacts,
      max_sym_score,
      debug=False,
      **kw,
):
   kw = rp.Bunch(kw)
   if not kw.timer: kw.timer = rp.Timer().start()

   lj_sfxn = get_sfxn('sterics')

   sym1 = xspec.sym1
   orig1 = xspec.orig1
   axis1 = xspec.axis1
   axis1d = xspec.axis1d

   sym2 = xspec.sym2
   orig2 = xspec.orig2
   axis2 = xspec.axis2
   axis2d = xspec.axis2d

   dihedral = xspec.dihedral

   if np.allclose(orig2, [0, 0, 0, 1]):
      sym1, sym2 = sym2, sym1
      orig1, orig2 = orig2, orig1
      axis1, axis2 = axis2, axis1
      axis1d, axis2d = axis2d, axis1d
      swapped = True  # hopefully won't need this
      assert sym1 == metal_sym
      assert sym2 == peptide_sym
      # axis2 = np.array([0.57735, 0.57735, 0.57735, 0])
      # axis1 = np.array([1, 0, 0, 0])
      # orig2 = np.array([0.5, 0.5, 0, 1])
   elif np.allclose(orig1, [0, 0, 0, 1]):
      # assert np.allclose(orig1, [0, 0, 0, 1])
      assert sym1 == peptide_sym
      assert sym2 == metal_sym
      swapped = False
      # axis1 = np.array([0.57735, 0.57735, 0.57735, 0])
      # assert 0, 'maybe ok, check this new branch'
   else:
      # print('both sym elements not at origin')
      pass
      # raise NotImplementedError('both sym elements not at origin')

   if sym1 == peptide_sym:
      pt1, ax1 = peptide_orig, peptide_axis
      pt2, ax2 = metal_origin, metal_sym_axis
      first_is_peptide = True
   else:
      pt1, ax1 = metal_origin, metal_sym_axis
      pt2, ax2 = peptide_orig, peptide_axis
      first_is_peptide = False

   nfold1 = float(str(sym1)[1])
   nfold2 = float(str(sym2)[1])
   ax1 = ax1 / np.linalg.norm(ax1)
   ax2 = ax2 / np.linalg.norm(ax2)

   # print(rp.homog.line_angle(metal_sym_axis, peptide_axis), np.radians(dihedral))
   assert np.allclose(rp.homog.line_angle(metal_sym_axis, peptide_axis), np.radians(dihedral),
                      atol=1e-3)
   assert np.allclose(rp.homog.line_angle(ax1, ax2), np.radians(dihedral), atol=1e-3)

   # print(rp.homog.line_angle(ax1, ax2), np.radians(dihedral), dihedral)

   # print('sym1', sym1, orig1, axis1, ax1)
   # print('sym2', sym2, orig2, axis2, ax2)

   #
   # print('== xtal_build ==')

   # Xalign, _ = rp.homog.align_lines_isect_axis2(pt1, ax1, pt2, ax2, axis1, orig1, axis2, orig2)
   Xalign, scale = rp.homog.scale_translate_lines_isect_lines(pt1, ax1, pt2, ax2, orig1, axis1,
                                                              orig2, axis2)

   xpt1, xax1 = Xalign @ pt1, Xalign @ ax1
   xpt2, xax2 = Xalign @ pt2, Xalign @ ax2
   # print('aligned1', xpt1, xax1)
   # print('aligned2', xpt2, xax2)
   assert np.allclose(rp.homog.line_angle(xax1, axis1), 0.0, atol=0.001)
   assert np.allclose(rp.homog.line_angle(xax2, axis2), 0.0, atol=0.001)

   # from previous req that ax1 isect the origin??
   # assert np.allclose(rp.homog.line_angle(xpt1, axis1), 0.0, atol=0.001)

   isect_error2 = rp.homog.line_line_distance_pa(xpt2, xax2, [0, 0, 0, 1], orig2)
   assert np.allclose(isect_error2, 0, atol=0.001)

   # isect = rp.homog.line_line_closest_points_pa(xpt2, xax2, [0, 0, 0, 1], orig2)
   # isect = (isect[0] + isect[1]) / 2
   # orig = orig2  # not always??
   # celldims = [isect[i] / o for i, o in enumerate(orig[:3]) if abs(o) > 0.001]
   celldims = scale[:3]
   assert np.allclose(min(celldims), max(celldims), atol=0.001)
   celldim = abs(min(celldims))
   if not (kw.min_cell_size <= celldim <= kw.max_cell_size):
      print('     ', xspec.spacegroup, pdb_name, aa1, aa2, 'Fail on cell_size', celldim)
      return []

   nsym = int(peptide_sym[1])
   assert pose.size() % nsym == 0
   nres_asym = pose.size() // nsym
   xtal_pose = rt.protocols.grafting.return_region(pose, 1, nres_asym)

   solv_frac = mof.filters.approx_solvent_fraction(xtal_pose, xspec, celldim)
   if kw.max_solv_frac < solv_frac:
      print('     ', xspec.spacegroup, pdb_name, aa1, aa2, 'Fail on solv_frac', solv_frac)
      return []

   # rt.numeric.xyzVec(hz[0], hz[1], hz[2]))

   xtal_pose.apply_transform_Rx_plus_v(
      xyzMat.cols(Xalign[0, 0], Xalign[1, 0], Xalign[2, 0], Xalign[0, 1], Xalign[1, 1],
                  Xalign[2, 1], Xalign[0, 2], Xalign[1, 2], Xalign[2, 2]),
      xyzVec(Xalign[0, 3], Xalign[1, 3], Xalign[2, 3]))

   # check ZN sym center location vs zn position?????????

   # print('--------------')
   # print(celldim, orig1[:3], orig2[:3])
   # print('--------------')

   if xspec.frames is None:
      # raise NotImplementedError('no sym frames for', xspec.spacegroup)
      print(f'{f" generate sym frames for {spec.spacegroup} ":}')
      dummy_scale = 100.0
      if sym1 == peptide_sym:
         redundant_point = rp.homog.hpoint(dummy_scale * orig1[:3] + 10 * axis1[:3])
      else:
         redundant_point = rp.homog.hpoint(dummy_scale * orig2[:3] + 10 * axis2[:3])
      # redundant_point = rp.homog.rand_point()
      # redundant_point[:3] *= dummy_scale

      print('redundant_point', redundant_point)
      print(Xalign @ redundant_point)

      g1 = rp.homog.hrot(axis1, (2 * np.pi / nfold1) * np.arange(nfold1), dummy_scale * orig1[:3])
      g2 = rp.homog.hrot(axis2, (2 * np.pi / nfold2) * np.arange(nfold2), dummy_scale * orig2[:3])
      g = np.concatenate([g1, g2])
      symxforms = list()
      count = 0
      for x in rp.homog.expand_xforms(g, redundant_point=redundant_point, N=12,
                                      maxrad=3.0 * dummy_scale):
         symxforms.append(x)
         print(count)
         count += 1
      # rp.dump(list(symxforms), 'i213_redundant111_n16_maxrad2.pickle')
      # symxforms = rp.load('i213_redundant111_n16_maxrad2_ORIG.pickle')
      print('num symframes', len(symxforms), type(symxforms[0]))
      symxforms = np.stack(symxforms, axis=0)
      print('symframes shape', symxforms.shape)
      symxforms[:, :3, 3] /= dummy_scale
      # print(np.around(symxforms[:, :3, 3], 3))

      rp.dump(symxforms, 'new_symframes.pickle')

      symxforms[:, :3, 3] *= celldim
      rpxbody.move_to(Xalign)
      rpxbody.dump_pdb('body_I.pdb')
      for i, x in enumerate(symxforms):
         rpxbody.move_to(x @ Xalign)
         rpxbody.dump_pdb('body_%i.pdb' % i)

      assert 0, "must rerun with newly genrated symframes"

   symxforms = xspec.frames.copy()
   symxforms[:, :3, 3] *= celldim

   # g1 = rp.homog.hrot(axis1, (2 * np.pi / nfold1) * np.arange(0, nfold1), celldim * orig1[:3])
   # g2 = rp.homog.hrot(axis2, (2 * np.pi / nfold2) * np.arange(0, nfold2), celldim * orig2[:3])
   # # # print('g1', axis1.round(3), 360 / nfold1, (celldim * orig1[:3]).round(3))
   # # # print('g2', axis2.round(3), 360 / nfold2, (celldim * orig2[:3]).round(3))
   # if swapped: g1, g2 = g2, g1
   # g = np.concatenate([g1, g2])
   # # print('swapped', swapped)
   # redundant_point = (xpt1 + xax1) if first_is_peptide else (xpt2 + xax2)
   # # redundant_point = xpt1 if first_is_peptide else xpt2
   # # print('redundancy point', redundant_point)
   # # # rpxbody.move_to(np.eye(4))
   # # # rpxbody.dump_pdb('a_body.pdb')
   # rpxbody.move_to(Xalign)
   # # # print(0, Xalign @ rp.homog.hpoint([1, 2, 3]))
   # # rpxbody.dump_pdb('a_body_xalign.pdb')

   kw.timer.checkpoint()

   clash, tot_ncontact = False, 0
   rpxbody_pdb, ir_ic = rpxbody.str_pdb(warn_on_chain_overflow=False, use_orig_coords=False)
   body_xalign = rpxbody.copy()
   body_xalign.move_to(Xalign)
   # body_xalign.dump_pdb('body_xalign.pdb')
   prev = [np.eye(4)]
   for i, x in enumerate(symxforms):
      # rp.homog.expand_xforms(g, redundant_point=redundant_point, N=6, maxrad=30)):
      if np.allclose(x, np.eye(4), atol=1e-4): assert 0
      rpxbody.move_to(x @ Xalign)
      # rpxbody.dump_pdb('clashcheck%02i.pdb' % i)
      if debug:
         pdbstr, ir_ic = rpxbody.str_pdb(start=ir_ic, warn_on_chain_overflow=False,
                                         use_orig_coords=False)
         rpxbody_pdb += pdbstr
      if np.any(rpxbody.intersect(rpxbody,
                                  np.stack(prev) @ Xalign, x @ Xalign, mindis=clash_dis)):
         clash = True
         print('     ', xspec.spacegroup, pdb_name, aa1, aa2, 'Fail on xtal clash', f'sub{i+1}')
         return []

      ncontact = rpxbody.contact_count(body_xalign, maxdis=contact_dis)
      tot_ncontact += ncontact

      prev.append(x)

      #   if clash and debug:
      #    for xprev in prev:
      #       # print(xprev.shape, (xprev @ Xalign).shape, (x @ Xalign).shape)
      #       if rpxbody.intersect(rpxbody, xprev @ Xalign, x @ Xalign, mindis=3.0):
      #          show_body_isect(rpxbody, Xalign, maxdis=3.0)
      #          rp.util.dump_str(rpxbody_pdb, 'sym_bodies.pdb')
      #    assert 0

   if tot_ncontact < min_contacts:
      print('     ', xspec.spacegroup, pdb_name, aa1, aa2, 'Fail on ncontact', tot_ncontact)
      return []

   kw.timer.checkpoint('clash_check')

   # for i, x in enumerate(symxforms):
   #    # print('sym xform %02i' % i, rp.homog.axis_ang_cen_of(x)
   #    rpxbody.move_to(x @ Xalign)
   #    rpxbody.dump_pdb('clashframe_%02i.pdb' % i)

   # assert 0

   # print('!!!!!!!!!!!!!!!! debug clash check  !!!!!!!!!!!!!!!!!!!!!!!!!')
   # rpxbody.move_to(Xalign)
   # rpxbody.dump_pdb('body.pdb')
   # symxforms = rp.homog.expand_xforms(g, redundant_point=redundant_point, N=8, maxrad=30)
   # for i, x in enumerate(symxforms):
   #    # print('sym xform %02i' % i, rp.homog.axis_ang_cen_of(x))
   #    rpxbody.move_to(x @ Xalign)
   #    rpxbody.dump_pdb('clashcheck%02i.pdb' % i)
   #    if rpxbody.intersect(rpxbody, Xalign, x @ Xalign, mindis=3.0):
   #       util.show_body_isect(rpxbody, Xalign, maxdis=3.0)
   #       rp.util.dump_str(rpxbody_pdb, 'sym_bodies.pdb')
   # assert 0

   # assert 0, 'xtal build after clashcheck'

   # fname = f'{tag}_body_xtal.pdb'
   # print('dumping checked bodies', fname)

   ci = rt.core.io.CrystInfo()
   ci.A(celldim)  # cell dimensions
   ci.B(celldim)
   ci.C(celldim)
   ci.alpha(90)  # cell angles
   ci.beta(90)
   ci.gamma(90)
   ci.spacegroup(xspec.spacegroup)  # sace group
   pi = rt.core.pose.PDBInfo(xtal_pose)
   pi.set_crystinfo(ci)
   xtal_pose.pdb_info(pi)

   nonbonded_energy = 0
   if max_sym_score < 1000:
      sympose = xtal_pose.clone()
      rt.protocols.cryst.MakeLatticeMover().apply(sympose)
      syminfo = rt.core.pose.symmetry.symmetry_info(sympose)

      # rp.util.dump_str(rpxbody_pdb, 'symbodies.pdb')
      lj_sfxn(sympose)

      nasym = len(xtal_pose.residues)
      nchain = syminfo.subunits()  # sympose.num_chains()
      bonded_subunits = []
      nterm = sympose.residue(1).xyz('N')
      cterm = sympose.residue(nasym).xyz('C')
      for i in range(1, nchain):
         nres = i * nasym + 1
         cres = i * nasym + nasym
         if 2 > cterm.distance(sympose.residue(nres).xyz('N')):
            bonded_subunits.append(i + 1)
         if 2 > nterm.distance(sympose.residue(cres).xyz('C')):
            bonded_subunits.append(i + 1)

      energy_graph = sympose.energies().energy_graph()
      eweights = sympose.energies().weights()
      nonbonded_energy = 0
      for ichain in range(1, nchain):
         if ichain + 1 in bonded_subunits: continue
         for i in range(nasym):
            ir = ichain + i + 1
            for j in range(nasym):
               jr = j + 1
               edge = energy_graph.find_edge(ir, jr)
               if not edge:
                  continue
               nonbonded_energy += edge.dot(eweights)

      # print('nonbonded_energy', nonbonded_energy)
      if nonbonded_energy > max_sym_score:
         print('     ', xspec.spacegroup, pdb_name, aa1, aa2,
               'Fail on nonbonded_energy(max_sym_score)', nonbonded_energy)
         return []

   kw.timer.checkpoint('make sympose and "nonbonded" score')

   znpos = Xalign @ metal_origin
   znres = make_residue('VZN')
   xtal_pose.append_residue_by_jump(znres, 1)
   znresi = len(xtal_pose.residues)
   znpos = xyzVec(*znpos[:3])
   zndelta = znpos - xtal_pose.residue(znresi).xyz(1)
   for ia in range(1, xtal_pose.residue(znresi).natoms() + 1):
      newxyz = zndelta + xtal_pose.residue(znresi).xyz(ia)
      # print(xtal_pose.residue(znresi).name(), ia, xtal_pose.residue(znresi).atom_name(ia), newxyz)
      xtal_pose.set_xyz(AtomID(ia, znresi), newxyz)
   # xtal_pose.dump_pdb('a_xtal_pose.pdb')
   # assert 0
   # rp.util.dump_str(rpxbody_pdb, 'a_symframes.pdb')
   # assert 0

   return [(Xalign, xtal_pose, rpxbody_pdb, tot_ncontact, nonbonded_energy, solv_frac)]
예제 #9
0
def minimize_mof_xtal(sfxn, xspec, pose, debug=False, **kw):
    kw = rp.Bunch(kw)
    #    try:
    #       print('''
    # minimize.py score initial....................      687.825
    # minimize.py: score before chem bonds.........      687.825
    # minimize.py: score after chem bonds..........      166.551
    # minimize.py: score after chainbreaks.........      166.551
    # minimize.py: score after metal olap .........      166.551
    # minimize.py: score after metal dist .........      176.766
    # minimize.py: score after metal dir...........      275.546
    # minimize.py: score after lig angle added.....      290.724
    # minimize.py: score after min no scale........      111.465
    # ==========================================================
    # '''.strip())
    #       os.remove('before.pdb')
    #       os.remove('zafter.pdb')
    #    except:
    #       pass

    nresasym = pose.size()
    beg = 1
    end = nresasym - 1
    metalres = rts.name_map('ZN')
    metalname = 'ZN'
    metalresnos = [nresasym, 2 * nresasym]  # TODO.. make not stupid
    metalnbonds = 4

    metalaid = AtomID(1, metalresnos[0])

    # cst_ang_metal = 109.47
    # cst_dis_metal = 2.2
    # cst_sd_metal_olap = 0.01
    # cst_sd_metal_dir = 0.4
    # cst_sd_metal_lig_dist = 0.2
    # cst_sd_metal_lig_ang = 0.4
    # cst_sd_metal_coo = 0.5
    # cst_sd_cut_dis = 0.01
    # cst_sd_cut_ang = 0.01
    # cst_sd_cut_dih = 0.1

    pose = pose.clone()
    r.core.pose.remove_lower_terminus_type_from_pose_residue(pose, beg)
    r.core.pose.remove_upper_terminus_type_from_pose_residue(pose, end)
    for ir in range(1, pose.size() + 1):
        if 'HIS' in pose.residue(ir).name():
            newname = pose.residue(ir).name().replace('HIS', 'HIS_D')
            newname = newname.replace('_D_D', '')
            r.core.pose.replace_pose_residue_copying_existing_coordinates(
                pose, ir, rts.name_map(newname))

    if False:
        tmp = pose.clone()
        r.core.pose.replace_pose_residue_copying_existing_coordinates(
            tmp, metalresnos[0], metalres)
        makelattice(tmp)
        tmp.dump_pdb('before.pdb')
    makelattice(pose)
    if debug:
        print(
            f'minimize.py score initial.................... {sfxn(pose):10.3f}'
        )
    # print_nonzero_energies(sfxn, pose)

    syminfo = r.core.pose.symmetry.symmetry_info(pose)
    symdofs = syminfo.get_dofs()
    allowed_jumps = list()
    # for jid, dofinfo in symdofs.items():
    #    # if dofinfo.allow_dof(1) and not any(dofinfo.allow_dof(i) for i in range(2, 7)):
    #    allowed_jumps.append(jid)
    # print('minimize_mof_xtal allowed jumps:', allowed_jumps)
    nxyz = pose.residue(beg).xyz('N')
    cxyz = pose.residue(end).xyz('C')
    nac, cac = None, None  # (N/C)-(a)djacent (c)hain
    for isub in range(1, syminfo.subunits()):
        othern = pose.residue((isub + 0) * nresasym + 1).xyz('N')
        otherc = pose.residue((isub + 1) * nresasym - 1).xyz('C')
        if nxyz.distance(otherc) < 2.0: cac = (isub + 1) * nresasym - 1
        if cxyz.distance(othern) < 2.0: nac = (isub + 0) * nresasym + 1
    assert nac and cac, 'backbone is weird?'
    if debug: print('peptide connection 1:', cac, beg)
    if debug: print('peptide_connection 2:', end, nac)
    # pose.dump_pdb('check_cuts.pdb')
    # assert 0

    f_metal_lig_dist = r.core.scoring.func.HarmonicFunc(
        kw.cst_dis_metal, kw.cst_sd_metal_lig_dist)
    f_metal_lig_ang = r.core.scoring.func.HarmonicFunc(
        np.radians(kw.cst_ang_metal), kw.cst_sd_metal_lig_ang)
    f_metal_olap = r.core.scoring.func.HarmonicFunc(0.0, kw.cst_sd_metal_olap)
    f_point_at_metal = r.core.scoring.func.HarmonicFunc(
        0.0, kw.cst_sd_metal_dir)
    f_metal_coo = r.core.scoring.func.CircularHarmonicFunc(
        0.0, kw.cst_sd_metal_coo)
    f_cut_dis = r.core.scoring.func.HarmonicFunc(1.328685, kw.cst_sd_cut_dis)
    f_cut_ang_cacn = r.core.scoring.func.HarmonicFunc(2.028, kw.cst_sd_cut_ang)
    f_cut_ang_cnca = r.core.scoring.func.HarmonicFunc(2.124, kw.cst_sd_cut_ang)
    f_cut_dih = r.core.scoring.func.CircularHarmonicFunc(
        np.pi, kw.cst_sd_cut_dih)
    f_cut_dihO = r.core.scoring.func.CircularHarmonicFunc(
        0.00, kw.cst_sd_cut_dih)

    ################### check cutpoint ##################

    conf = pose.conformation().clone()
    assert r.core.conformation.symmetry.is_symmetric(conf)
    # print(pose.pdb_info().crystinfo())
    pi = pose.pdb_info()
    # conf.detect_bonds()
    conf.declare_chemical_bond(cac, 'C', beg, 'N')
    # conf.declare_chemical_bond(end, 'N', nac, 'N')
    pose.set_new_conformation(conf)
    pose.set_new_energies_object(r.core.scoring.symmetry.SymmetricEnergies())
    pose.pdb_info(pi)
    if debug:
        print(
            f'minimize.py: score after chem bonds.......... {sfxn(pose):10.3f}'
        )

    #############################################3

    cst_cut, cst_lig_dis, cst_lig_ang, cst_lig_ori = list(), list(), list(
    ), list()

    ############### chainbreaks ################3

    # this doesn't behave well...
    # # 39 C / 1 OVU1
    # # 39 OVL1 / 1 N
    # # 29 OVL2 / CA
    # r.core.pose.add_variant_type_to_pose_residue(pose, 'CUTPOINT_UPPER', beg)
    # r.core.pose.add_variant_type_to_pose_residue(pose, 'CUTPOINT_LOWER', end)
    # cres1 = pose.residue(cac)
    # nres1 = pose.residue(1)
    # cres2 = pose.residue(end)
    # nres2 = pose.residue(nac)
    # # Apc = r.core.scoring.constraints.AtomPairConstraint
    # # getaid = lambda p, n, i: AtomID(p.residue(i).atom_index(n.strip()), i)
    # for cst in [
    #       Apc(getaid(pose, 'C   ', cac), getaid(pose, 'OVU1', beg), f_cut),
    #       Apc(getaid(pose, 'OVL1', cac), getaid(pose, 'N   ', beg), f_cut),
    #       Apc(getaid(pose, 'OVL2', cac), getaid(pose, 'CA  ', beg), f_cut),
    #       Apc(getaid(pose, 'C   ', end), getaid(pose, 'OVU1', nac), f_cut),
    #       Apc(getaid(pose, 'OVL1', end), getaid(pose, 'N   ', nac), f_cut),
    #       Apc(getaid(pose, 'OVL2', end), getaid(pose, 'CA  ', nac), f_cut),
    # ]:
    #    pose.add_constraint(cst)

    cst_cut.append(addcst_dis(pose, cac, 'C ', beg, 'N', f_cut_dis))
    cst_cut.append(addcst_dis(pose, end, 'C ', nac, 'N', f_cut_dis))
    if debug:
        print(
            f'minimize.py: score after chainbreak dis...... {sfxn(pose):10.3f}'
        )
    cst_cut.append(
        addcst_ang(pose, cac, 'CA', cac, 'C', beg, 'N ', f_cut_ang_cacn))
    cst_cut.append(
        addcst_ang(pose, cac, 'C ', beg, 'N', beg, 'CA', f_cut_ang_cnca))
    cst_cut.append(
        addcst_ang(pose, end, 'CA', end, 'C', nac, 'N ', f_cut_ang_cacn))
    cst_cut.append(
        addcst_ang(pose, end, 'C ', nac, 'N', nac, 'CA', f_cut_ang_cnca))
    if debug:
        print(
            f'minimize.py: score after chainbreak ang...... {sfxn(pose):10.3f}'
        )
    # print(r.numeric.dihedral(
    #       pose.residue(cac).xyz('CA'),
    #       pose.residue(cac).xyz('C'),
    #       pose.residue(beg).xyz('N'),
    #       pose.residue(beg).xyz('CA'),
    #    ))
    cst_cut.append(
        addcst_dih(pose, cac, 'CA', cac, 'C', beg, 'N ', beg, 'CA', f_cut_dih))
    cst_cut.append(
        addcst_dih(pose, end, 'CA', end, 'C', nac, 'N ', nac, 'CA', f_cut_dih))
    cst_cut.append(
        addcst_dih(pose, cac, 'O ', cac, 'C', beg, 'N ', beg, 'CA',
                   f_cut_dihO))
    cst_cut.append(
        addcst_dih(pose, end, 'O ', end, 'C', nac, 'N ', nac, 'CA',
                   f_cut_dihO))
    if debug:
        print(
            f'minimize.py: score after chainbreak dihedral. {sfxn(pose):10.3f}'
        )

    ############## metal constraints ################

    for i, j in [(i, j) for i in metalresnos for j in metalresnos if i < j]:
        addcst_dis(pose, i, metalname, j, metalname, f_metal_olap)
    if debug:
        print(
            f'minimize.py: score after metal olap ......... {sfxn(pose):10.3f}'
        )

    allowed_elems = 'NOS'
    znpos = pose.residue(metalresnos[0]).xyz(1)
    znbonded = list()
    for ir in range(1, len(pose.residues) + 1):
        res = pose.residue(ir)
        if not res.is_protein(): continue
        for ia in range(5, res.nheavyatoms() + 1):
            aid = AtomID(ia, ir)
            elem = res.atom_name(ia).strip()[0]
            if elem in allowed_elems:
                xyz = pose.xyz(aid)
                dist = xyz.distance(znpos)
                if dist < 3.5:
                    if res.atom_name(ia) in (
                            ' OD2', ' OE2'):  # other COO O sometimes closeish
                        continue
                    znbonded.append(aid)
    if len(znbonded) != metalnbonds:
        print('WRONG NO OF LIGANDING ATOMS', len(znbonded))
        for aid in znbonded:
            print(
                pose.residue(aid.rsd()).name(),
                pose.residue(aid.rsd()).atom_name(aid.atomno()))
            pose.dump_pdb('WRONG_NO_OF_LIGANDING_ATOMS.pdb')
            return None, None
        # raise ValueError(f'WRONG NO OF LIGANDING ATOMS {len(znbonded)}')

    # metal/lig distance constraints
    for i, aid in enumerate(znbonded):
        cst = r.core.scoring.constraints.AtomPairConstraint(
            metalaid, aid, f_metal_lig_dist)
        cst_lig_dis.append(cst)
        pose.add_constraint(cst)

    if debug:
        print(
            f'minimize.py: score after metal dist ......... {sfxn(pose):10.3f}'
        )

    # for aid in znbonded:
    #    print(aid.rsd(), aid.atomno(),
    #          pose.residue(aid.rsd()).name(),
    #          pose.residue(aid.rsd()).atom_name(aid.atomno()))
    # assert 0

    # lig/metal/lig angle constraints (or dihedral in-place constraint for COO)
    # TODO kinda hacky... will need to be more general?
    for i, aid in enumerate(znbonded):
        ir, res = aid.rsd(), pose.residue(aid.rsd())
        if all(_ not in res.name() for _ in 'ASP CYS HIS GLU'.split()):
            assert 0, f'unrecognized res {res.name()}'
        if any(_ in res.name() for _ in 'ASP GLU'.split()):
            # metal comes off of OD1/OE1
            ir, coo = aid.rsd(), ('OD1 CG OD2' if 'ASP' in res.name() else
                                  'OE1 CD OE2').split()
            cst_lig_ori.append(
                addcst_dih(pose, ir, coo[0], ir, coo[1], ir, coo[2],
                           metalaid.rsd(), metalname, f_metal_coo))
        else:
            if 'HIS' in res.name(): aname = 'HD1' if res.has('HD1') else 'HE2'
            if 'CYS' in res.name(): aname = 'HG'
            cst_lig_ori.append(
                addcst_ang(pose, ir, res.atom_name(aid.atomno()),
                           metalaid.rsd(), metalname, ir, aname,
                           f_point_at_metal))
            # cst = r.core.scoring.constraints.AngleConstraint(aid, metalaid, aid2, f_point_at_metal)
            # pose.add_constraint(cst)
    if debug:
        print(
            f'minimize.py: score after metal dir........... {sfxn(pose):10.3f}'
        )

    for i, iaid in enumerate(znbonded):
        for j, jaid in enumerate(znbonded[:i]):
            # pripnt(i, j)
            cst = r.core.scoring.constraints.AngleConstraint(
                iaid, metalaid, jaid, f_metal_lig_ang)
            cst_lig_ang.append(cst)
            pose.add_constraint(cst)

    if debug:
        print(
            f'minimize.py: score after lig angle added..... {sfxn(pose):10.3f}'
        )

    ################ minimization #########################

    movemap = r.core.kinematics.MoveMap()
    movemap.set_bb(True)
    movemap.set_chi(True)
    movemap.set_jump(False)
    for i in allowed_jumps:
        movemap.set_jump(True, i)
    minimizer = r.protocols.minimization_packing.symmetry.SymMinMover(
        movemap, sfxn, 'lbfgs_armijo_nonmonotone', 0.01, True)  # tol, nblist
    if sfxn.has_nonzero_weight(r.core.scoring.ScoreType.cart_bonded):
        minimizer.cartesian(True)
    minimizer.apply(pose)
    if debug:
        print(
            f'minimize.py: score after min no scale........ {sfxn(pose):10.3f}'
        )

    # printscores(sfxn, pose)

    kw.timer.checkpoint(f'min scale 1.0')

    asym = r.core.pose.Pose()
    r.core.pose.symmetry.extract_asymmetric_unit(pose, asym, False)
    r.core.pose.replace_pose_residue_copying_existing_coordinates(
        asym, metalresnos[0], metalres)
    # asym.dump_pdb('asym.pdb')

    # for ir in metalresnos:
    #    r.core.pose.replace_pose_residue_copying_existing_coordinates(pose, ir, metalres)
    # pose.dump_pdb('zafter.pdb')

    if debug: print(kw.timer)

    info = rp.Bunch()
    info.score = sfxn(pose)

    ############### score component stuff ################
    st = r.core.scoring.ScoreType
    etot = pose.energies().total_energies()
    info.score_fa_atr = (etot[st.fa_atr])
    info.score_fa_rep = (etot[st.fa_rep])
    info.score_fa_sol = (etot[st.fa_sol])
    info.score_lk_ball = (etot[st.lk_ball] + etot[st.lk_ball_iso] +
                          etot[st.lk_ball_bridge] +
                          etot[st.lk_ball_bridge_uncpl])
    info.score_fa_elec = (etot[st.fa_elec] + etot[st.fa_intra_elec])
    info.score_hbond_sr_bb = (etot[st.hbond_sr_bb] + etot[st.hbond_lr_bb] +
                              etot[st.hbond_bb_sc] + etot[st.hbond_sc])
    info.score_dslf_fa13 = (etot[st.dslf_fa13])
    info.score_atom_pair_constraint = (etot[st.atom_pair_constraint])
    info.score_angle_constraint = (etot[st.angle_constraint])
    info.score_dihedral_constraint = (etot[st.dihedral_constraint])
    info.score_omega = (etot[st.omega])
    info.score_rotamer = (etot[st.fa_dun] + etot[st.fa_dun_dev] +
                          etot[st.fa_dun_rot] + etot[st.fa_dun_semi] +
                          etot[st.fa_intra_elec] + etot[st.fa_intra_rep] +
                          etot[st.fa_intra_atr_xover4] +
                          etot[st.fa_intra_rep_xover4] +
                          etot[st.fa_intra_sol_xover4])
    info.score_ref = (etot[st.ref])
    info.score_rama_prepro = (etot[st.rama_prepro])
    info.score_cart_bonded = (etot[st.cart_bonded])
    info.score_gen_bonded = (etot[st.gen_bonded])

    ############### cst stuff ################
    pose.remove_constraints()
    info.score_wo_cst = sfxn(pose)

    [pose.add_constraint(cst) for cst in cst_cut]
    info.score_cst_cut = sfxn(pose) - info.score_wo_cst
    pose.remove_constraints()

    [pose.add_constraint(cst) for cst in cst_lig_dis]
    [pose.add_constraint(cst) for cst in cst_lig_ang]
    [pose.add_constraint(cst) for cst in cst_lig_ori]
    info.score_cst_lig_ori = sfxn(pose) - info.score_wo_cst
    pose.remove_constraints()

    [pose.add_constraint(cst) for cst in cst_lig_dis]
    info.score_cst_lig_dis = sfxn(pose) - info.score_wo_cst
    pose.remove_constraints()

    [pose.add_constraint(cst) for cst in cst_lig_ang]
    info.score_cst_lig_ang = sfxn(pose) - info.score_wo_cst
    pose.remove_constraints()

    [pose.add_constraint(cst) for cst in cst_lig_ori]
    info.score_cst_lig_ori = sfxn(pose) - info.score_wo_cst
    pose.remove_constraints()

    return asym, info
예제 #10
0
def xtal_search_two_residues(
      search_spec,
      pose,
      rotcloud1base,
      rotcloud2base,
      err_tolerance,
      dist_err_tolerance,
      angle_err_tolerance,
      min_dist_to_z_axis,
      sym_axes_angle_tolerance,
      angle_to_cart_err_ratio,
      debug=False,
      **kw,
):
   kw = rp.Bunch(kw)
   if not kw.timer: kw.timer = rp.Timer().start()
   kw.timer.checkpoint()

   spec = search_spec
   xspec = spec.xtal_spec
   aa1 = rotcloud1base.amino_acid
   aa2 = rotcloud2base.amino_acid

   results = list()

   dont_replace_these_aas = [spec.rts.name_map('CYS'), spec.rts.name_map('PRO')]

   farep_orig = search_spec.sfxn_sterics(pose)

   p_n = pose.pdb_info().name().split('/')[-1]
   # gets rid of the ".pdb" at the end of the pdb name
   pdb_name = p_n[:-4]

   print(f'  {pdb_name} searching', aa1, aa2)

   # check the symmetry type of the pdb
   last_res = rt.core.pose.chain_end_res(pose).pop()
   total_res = int(last_res)

   sym_num = 3  # pose.chain(last_res)
   sym = 3  # int(sym_num)
   if sym_num < 2:
      print('bad pdb', p_n)
      return list()
   asym_nres = int(total_res / sym)
   peptide_sym = "C%i" % sym_num

   rpxbody = rp.Body(pose)

   for ires1 in range(1, asym_nres + 1):
      # if pose.residue_type(ires1) not in (spec.rts.name_map('ALA'), spec.rts.name_map('DALA')):
      if pose.residue_type(ires1) in dont_replace_these_aas: continue
      stub1 = rpxbody.stub[ires1 - 1]

      kw.timer.checkpoint('xtal_search')
      rots1ok = min_dist_to_z_axis < np.linalg.norm(
         (stub1 @ rotcloud1base.rotframes)[:, :2, 3], axis=1)
      if 0 == np.sum(rots1ok): continue
      rotcloud1 = rotcloud1base.subset(rots1ok)
      rotframes1 = stub1 @ rotcloud1.rotframes
      # rotcloud1.dump_pdb(f'cloud_a_{ires1:02}.pdb', position=stub1)

      kw.timer.checkpoint('position rotcloud')

      range2 = range(1, int(total_res) + 1)
      if rotcloud1base is rotcloud2base: range2 = range(ires1 + 1, int(total_res) + 1)
      for ires2 in range2:
         if ires1 == ((ires2 - 1) % asym_nres + 1): continue
         if pose.residue_type(ires2) in dont_replace_these_aas:
            continue
         stub2 = rpxbody.stub[ires2 - 1]
         # rotcloud2.dump_pdb(f'cloud_b_{ires2:02}.pdb', position=stub2)

         kw.timer.checkpoint('xtal_search')
         rots2ok = min_dist_to_z_axis < np.linalg.norm(
            (stub2 @ rotcloud2base.rotframes)[:, :2, 3], axis=1)
         if 0 == np.sum(rots2ok): continue
         rotcloud2 = rotcloud2base.subset(rots2ok)
         rotframes2 = stub2 @ rotcloud2.rotframes

         kw.timer.checkpoint('rotcloud positioning')

         dist = rotframes1[:, :, 3].reshape(-1, 1, 4) - rotframes2[:, :, 3].reshape(1, -1, 4)
         dist = np.linalg.norm(dist, axis=2)

         kw.timer.checkpoint('rotcloud dist')

         # if np.min(dist) < 1.0:
         # print(f'{ires1:02} {ires2:02} {np.sort(dist.flat)[:5]}')
         dot = np.sum(
            rotframes1[:, :, 0].reshape(-1, 1, 4) * rotframes2[:, :, 0].reshape(1, -1, 4), axis=2)
         ang = np.degrees(np.arccos(np.clip(dot, -1, 1)))
         ang_delta = np.abs(ang - 109.4712206)

         kw.timer.checkpoint('rotcloud ang')

         err = np.sqrt((ang_delta / angle_to_cart_err_ratio)**2 + dist**2)
         rot1err2 = np.min(err, axis=1)
         bestrot2 = np.argmin(err, axis=1)
         disterr = dist[np.arange(len(bestrot2)), bestrot2]
         angerr = ang_delta[np.arange(len(bestrot2)), bestrot2]
         ok = (rot1err2 < err_tolerance)
         ok *= (angerr < angle_err_tolerance)
         ok *= (disterr < dist_err_tolerance)
         # ok = rot1err2 < err_tolerance
         # ok = disterr < dist_err_tolerance
         # ok = angerr < angle_err_tolerance
         hits1 = np.argwhere(ok).reshape(-1)

         kw.timer.checkpoint('rotcloud match check')

         # hits = (ang_delta < angle_err_tolerance) * (dist < dist_err_tolerance)
         if len(hits1):
            hits2 = bestrot2[hits1]
            hits = np.stack([hits1, hits2], axis=1)
            # print(
            # f'stats {ires1:2} {ires2:2} {np.sum(ang_delta < 10):7} {np.sum(dist < 1.0):5} {np.sum(hits):3}'
            # )
            for ihit, hit in enumerate(hits):
               frame1 = rotframes1[hit[0]]
               frame2 = rotframes2[hit[1]]

               kw.timer.checkpoint('xtal_search')

               parl = (frame1[:, 0] + frame2[:, 0]) / 2.0
               perp = rp.homog.hcross(frame1[:, 0], frame2[:, 0])
               metalaxis1 = rp.homog.hrot(parl, +45) @ perp
               metalaxis2 = rp.homog.hrot(parl, -45) @ perp
               symang1 = rp.homog.line_angle(metalaxis1, spec.pept_axis)
               symang2 = rp.homog.line_angle(metalaxis2, spec.pept_axis)
               match1 = np.abs(np.degrees(symang1) - xspec.dihedral) < sym_axes_angle_tolerance
               match2 = np.abs(np.degrees(symang2) - xspec.dihedral) < sym_axes_angle_tolerance
               if not (match1 or match2): continue
               matchsymang = symang1 if match1 else symang2
               metal_axis = metalaxis1 if match1 else metalaxis2
               if rp.homog.angle(metal_axis, spec.pept_axis) > np.pi / 2:
                  metal_axis[:3] = -metal_axis[:3]
               metal_pos = (rotframes1[hit[0], :, 3] + rotframes2[hit[1], :, 3]) / 2.0

               correction_axis = rp.homog.hcross(metal_axis, spec.pept_axis)
               correction_angle = np.abs(matchsymang - np.radians(xspec.dihedral))
               # print('target', xspec.dihedral, '---------------------')
               # print(np.degrees(correction_angle))
               # print(np.degrees(matchsymang))
               # print('before', rp.homog.angle_degrees(metal_axis, spec.pept_axis))

               for why_do_i_need_this in (-correction_angle, correction_angle):
                  metal_axis_try = rp.homog.hrot(correction_axis, why_do_i_need_this) @ metal_axis
                  if np.allclose(rp.homog.angle_degrees(metal_axis_try, spec.pept_axis),
                                 xspec.dihedral, atol=0.001):
                     metal_axis = metal_axis_try
                     break
               # print('after ', rp.homog.angle_degrees(metal_axis, spec.pept_axis))

               assert np.allclose(rp.homog.angle_degrees(metal_axis, spec.pept_axis),
                                  xspec.dihedral, atol=0.001)

               kw.timer.checkpoint('axes geom checks')

               # pose.dump_pdb('before.pdb')
               pose2mut = mof.util.mutate_two_res(pose, ires1, aa1, rotcloud1.rotchi[hit[0]],
                                                  ires2, aa2, rotcloud2.rotchi[hit[1]], sym_num)
               # pose2mut.dump_pdb('after.pdb')

               search_spec.sfxn_sterics(pose2mut)
               sc_2res = (pose2mut.energies().residue_total_energy(ires1) +
                          pose2mut.energies().residue_total_energy(ires2))
               sc_2res_orig = (pose.energies().residue_total_energy(ires1) +
                               pose.energies().residue_total_energy(ires2))

               kw.timer.checkpoint('mut_two_res')

               # print('scores', sc_2res, sc_2res_orig)

               # if sc_2res > kw.max_2res_score: continue
               if sc_2res - sc_2res_orig > kw.max_2res_score: continue

               tag = ('hit_%s_%s_%i_%i_%i' % (aa1, aa2, ires1, ires2, ihit))

               kw.timer.checkpoint('xtal_search')

               xtal_poses = mof.xtal_build.xtal_build(
                  pdb_name,
                  xspec,
                  aa1,
                  aa2,
                  pose2mut,
                  peptide_sym,
                  spec.pept_orig,
                  spec.pept_axis,
                  'C2',
                  metal_pos,
                  metal_axis,
                  rpxbody,
                  tag,
                  **kw,
               )
               if not xtal_poses: continue

               # for Xalign, xtal_pose, rpxbody_pdb in xtal_poses:
               # xtal_pose.dump_pdb(tag + '_xtal.pdb')
               # rp.util.dump_str(rpxbody_pdb, tag + '_clashcheck.pdb')
               # assert 0

               kw.timer.checkpoint('xtal_search')

               for ixtal, (xalign, xtal_pose, body_pdb, ncontact, enonbonded,
                           solv_frac) in enumerate(xtal_poses):

                  xtal_pose_min, mininfo = mof.minimize.minimize_mof_xtal(
                     spec.sfxn_minimize,
                     xspec,
                     xtal_pose,
                     **kw,
                  )
                  if not xtal_pose_min:
                     continue
                  if kw.max_score_minimized < mininfo.score:
                     continue
                     print('     ', xspec.spacegroup, pdb_name, aa1, aa2, 'a on minimzied score',
                           mininfo.score)
                     continue
                  celldim = xtal_pose.pdb_info().crystinfo().A()
                  label = f"{pdb_name}_{xspec.spacegroup.replace(' ','_')}_{tag}_cell{int(celldim):03}_ncontact{ncontact:02}_score{int(enonbonded):03}"

                  info = mininfo.sub(  # adding to mininfo
                     label=label,
                     xalign=xalign,
                     ncontact=ncontact,
                     enonbonded=enonbonded,
                     sequence=','.join(r.name() for r in xtal_pose.residues),
                     solv_frac=solv_frac,
                     celldim=celldim,
                     spacegroup=xspec.spacegroup,
                     nsubunits=xspec.nsubs,
                     nres=xtal_pose_min.size() - 1,
                  )
                  bbcoords = np.array(
                     [(v[0], v[1], v[2]) for v in [[r.xyz(n)
                                                    for n in ('N', 'CA', 'C')]
                                                   for r in xtal_pose_min.residues[:-1]]])
                  bbpad = np.zeros(shape=(kw.max_pept_size - xtal_pose_min.size() + 1, 3, 3))
                  info['bbcoords'] = np.concatenate([bbcoords, bbpad])

                  results.append(
                     rp.Bunch(
                        xspec=xspec,
                        # rpxbody=rpxbody,
                        # asym_pose=xtal_pose,
                        asym_pose_min=xtal_pose_min,
                        info=info,
                     ))
                  ### debug crap
                  if results:
                     print('  * HIT %10s %7s %7s %3i %3i %9s %-7.3f %5.3f %s' % (
                        xspec.spacegroup.replace(' ', '_'),
                        aa1,
                        aa2,
                        ires1,
                        ires2,
                        xtal_pose_min.sequence(),
                        info.score,
                        info.solv_frac,
                        pdb_name,
                     ))
                  # rotcloud1.dump_pdb(fn + '_a.pdb', stub1, which=hit[0])
                  # rotcloud2.dump_pdb(fn + '_b.pdb', stub2, which=hit[1])
                  # rpxbody2.dump_pdb(fn + '_sym.pdb')
                  # metalaxispos = metal_pos[:3] + metal_axis[:3] + metal_axis[:3] + metal_axis[:3]
                  # pose2mut.dump_pdb(tag + '_before.pdb')
                  # hokey_position_atoms(pose2mut, ires1, ires2, metal_pos, metalaxispos)
                  # pose2mut.dump_pdb(tag + '_after.pdb')
                  # assert 0
                  ### end debug crap

               kw.timer.checkpoint('build_result')

   kw.timer.checkpoint('xtal_search')

   return results
예제 #11
0
def xtal_search_single_residue(search_spec, pose, **kw):
   raise NotImplemntedError('xtal_search_single_residue needs updating')
   kw = rp.Bunch(kw)

   spec = search_spec
   xspec = spec.xtal_spec

   results = list()

   p_n = pose.pdb_info().name().split('/')[-1]
   # gets rid of the ".pdb" at the end of the pdb name
   pdb_name = p_n[:-4]

   print(f'{pdb_name} searching')

   # check the symmetry type of the pdb
   last_res = rt.core.pose.chain_end_res(pose).pop()
   total_res = int(last_res)
   sym_num = pose.chain(last_res)
   if sym_num < 2:
      print('bad pdb', p_n)
      return list()
   sym = int(sym_num)
   peptide_sym = "C%i" % sym_num

   for ires in range(1, int(total_res / sym) + 1):
      if pose.residue_type(ires) not in (spec.rts.name_map('GLY'), spec.rts.name_map('ALA'),
                                         spec.rts.name_map('DALA')):
         continue
      lig_poses = util.mut_to_ligand(pose, ires, spec.ligands, spec.sym_of_ligand)
      bad_rots = 0
      for ilig, lig_pose in enumerate(lig_poses):
         mut_res_name, lig_sym = lig_poses[lig_pose]

         rotamers = lig_pose.residue(ires).get_rotamers()
         rotamers = util.extra_rotamers(rotamers, lb=-20, ub=21, bs=20)

         pose_num = 1
         for irot, rotamer in enumerate(rotamers):
            #for i in range(1, len(rotamer)+1): # if I want to sample the metal-axis too
            for i in range(len(rotamer)):
               lig_pose.residue(ires).set_chi(i + 1, rotamer[i])
            rot_pose = rt.protocols.grafting.return_region(lig_pose, 1, lig_pose.size())

            if kw.debug:
               rot_pose.set_xyz(AtomID(rot_pose.residue(ires).atom_index('1HB'), ires),
                                rVec(0, 0, -2))
               rot_pose.set_xyz(AtomID(rot_pose.residue(ires).atom_index('CB'), ires),
                                rVec(0, 0, +0.0))
               rot_pose.set_xyz(AtomID(rot_pose.residue(ires).atom_index('2HB'), ires),
                                rVec(0, 0, +2))

            spec.sfxn_rotamer(rot_pose)
            dun_score = rot_pose.energies().residue_total_energy(ires)
            if dun_score >= spec.max_dun_score:
               bad_rots += 1
               continue
            rpxbody = rp.Body(rot_pose)

            ############ fix this

            metal_orig = hm.hpoint(util.coord_find(rot_pose, ires, 'VZN'))
            hz = hm.hpoint(util.coord_find(rot_pose, ires, 'HZ'))
            ne = hm.hpoint(util.coord_find(rot_pose, ires, 'VNE'))
            metal_his_bond = hm.hnormalized(metal_orig - ne)
            metal_sym_axis0 = hm.hnormalized(hz - metal_orig)
            dihedral = xspec.dihedral

            ############# ...

            rots_around_nezn = hm.xform_around_dof_for_vector_target_angle(
               fix=spec.pept_axis, mov=metal_sym_axis0, dof=metal_his_bond,
               target_angle=np.radians(dihedral))

            for idof, rot_around_nezn in enumerate(rots_around_nezn):
               metal_sym_axis = rot_around_nezn @ metal_sym_axis0
               assert np.allclose(hm.line_angle(metal_sym_axis, spec.pept_axis),
                                  np.radians(dihedral))

               newhz = util.coord_find(rot_pose, ires, 'VZN') + 2 * metal_sym_axis[:3]

               aid = rt.core.id.AtomID(rot_pose.residue(ires).atom_index('HZ'), ires)
               xyz = rVec(newhz[0], newhz[1], newhz[2])
               rot_pose.set_xyz(aid, xyz)

               tag = f'{pdb_name}_{ires}_{lig_poses[lig_pose][0]}_{idof}_{pose_num}'
               xtal_poses = mof.xtal_build.xtal_build(
                  pdb_name,
                  xspec,
                  aa1,
                  aa2,
                  rot_pose,
                  peptide_sym,
                  spec.pept_orig,
                  spec.pept_axis,
                  lig_sym,
                  metal_orig,
                  metal_sym_axis,
                  rpxbody,
                  tag,
               )

               if False and xtal_poses:
                  print('hoaktolfhtoia')
                  print(rot_pose)
                  print(pdb_name)
                  print(xspec)
                  rot_pose.dump_pdb('test_xtal_build_p213.pdb')
                  print(ires)
                  print(peptide_sym)
                  print(spec.pept_orig)
                  print(spec.pept_axis)
                  print(lig_sym)
                  print(metal_orig)
                  print(metal_sym_axis)
                  print('rp.Body(pose)')

                  xalign, xpose, bodypdb = xtal_poses[0]
                  print(xalign)
                  xpose.dump_pdb('xtal_pose.pdb')

                  assert 0

               for ixtal, (xalign, xtal_pose, body_pdb) in enumerate(xtal_poses):
                  celldim = xtal_pose.pdb_info().crystinfo().A()
                  fname = f"{xspec.spacegroup.replace(' ','_')}_cell{int(celldim):03}_{tag}"
                  results.append(
                     mof.result.Result(
                        xspec,
                        fname,
                        xalign,
                        rpxbody,
                        xtal_pose,
                        body_pdb,
                     ))

            pose_num += 1
      # print(pdb_name, 'res', ires, 'bad rots:', bad_rots)

   return results
예제 #12
0
def xtal_search_two_residues(
    search_spec,
    pose,
    rotcloud1base,
    rotcloud2base,
    err_tolerance=1.5,
    min_dist_to_z_axis=6.0,
    sym_axes_angle_tolerance=3.0,
    **arg,
):
    arg = rp.Bunch(arg)

    spec = search_spec
    xspec = spec.xtal_spec

    results = list()

    farep_orig = search_spec.rep_sfxn(pose)

    p_n = pose.pdb_info().name().split('/')[-1]
    # gets rid of the ".pdb" at the end of the pdb name
    pdb_name = p_n[:-4]

    print(f'{pdb_name} searching')

    # check the symmetry type of the pdb
    last_res = rt.core.pose.chain_end_res(pose).pop()
    total_res = int(last_res)

    sym_num = pose.chain(last_res)
    sym = int(sym_num)
    if sym_num < 2:
        print('bad pdb', p_n)
        return list()
    asym_nres = int(total_res / sym)
    peptide_sym = "C%i" % sym_num

    rpxbody = rp.Body(pose)

    for ires1 in range(1, asym_nres + 1):
        # if pose.residue_type(ires1) not in (spec.rts.name_map('ALA'), spec.rts.name_map('DALA')):
        if pose.residue_type(ires1) != spec.rts.name_map('ALA'):
            continue
        stub1 = rpxbody.stub[ires1 - 1]

        rots1ok = min_dist_to_z_axis < np.linalg.norm(
            (stub1 @ rotcloud1base.rotframes)[:, :2, 3], axis=1)
        if 0 == np.sum(rots1ok): continue
        rotcloud1 = rotcloud1base.subset(rots1ok)
        rotframes1 = stub1 @ rotcloud1.rotframes
        # rotcloud1.dump_pdb(f'cloud_a_{ires1:02}.pdb', position=stub1)

        range2 = range(1, int(total_res) + 1)
        if rotcloud1base is rotcloud2base:
            range2 = range(ires1 + 1, int(total_res) + 1)
        for ires2 in range2:
            if ires1 == ires2 % asym_nres: continue
            if pose.residue_type(ires2) != spec.rts.name_map('ALA'):
                continue
            stub2 = rpxbody.stub[ires2 - 1]
            # rotcloud2.dump_pdb(f'cloud_b_{ires2:02}.pdb', position=stub2)

            rots2ok = min_dist_to_z_axis < np.linalg.norm(
                (stub2 @ rotcloud2base.rotframes)[:, :2, 3], axis=1)
            if 0 == np.sum(rots2ok): continue
            rotcloud2 = rotcloud2base.subset(rots2ok)
            rotframes2 = stub2 @ rotcloud2.rotframes

            dist = rotframes1[:, :, 3].reshape(
                -1, 1, 4) - rotframes2[:, :, 3].reshape(1, -1, 4)
            dist = np.linalg.norm(dist, axis=2)
            # if np.min(dist) < 1.0:
            # print(f'{ires1:02} {ires2:02} {np.sort(dist.flat)[:5]}')
            dot = np.sum(rotframes1[:, :, 0].reshape(-1, 1, 4) *
                         rotframes2[:, :, 0].reshape(1, -1, 4),
                         axis=2)
            ang = np.degrees(np.arccos(dot))
            angerr = np.abs(ang - 107)
            err = angerr / 15.0 + dist
            rot1err = np.min(err, axis=1)
            bestrot2 = np.argmin(err, axis=1)
            hits1 = np.argwhere(rot1err < err_tolerance).reshape(-1)

            # hits = (angerr < angle_err_tolerance) * (dist < dist_err_tolerance)
            if len(hits1):
                # print(rotcloud1.amino_acid, rotcloud2.amino_acid, ires1, ires2)
                hits2 = bestrot2[hits1]
                hits = np.stack([hits1, hits2], axis=1)
                # print(
                # f'stats {ires1:2} {ires2:2} {np.sum(angerr < 10):7} {np.sum(dist < 1.0):5} {np.sum(hits):3}'
                # )
                for ihit, hit in enumerate(hits):
                    frame1 = rotframes1[hit[0]]
                    frame2 = rotframes2[hit[1]]

                    parl = (frame1[:, 0] + frame2[:, 0]) / 2.0
                    perp = rp.homog.hcross(frame1[:, 0], frame2[:, 0])
                    metalaxis1 = rp.homog.hrot(parl, +45) @ perp
                    metalaxis2 = rp.homog.hrot(parl, -45) @ perp
                    symang1 = rp.homog.line_angle(metalaxis1, spec.pept_axis)
                    symang2 = rp.homog.line_angle(metalaxis2, spec.pept_axis)
                    match11 = np.abs(np.degrees(symang1) -
                                     35.26) < sym_axes_angle_tolerance
                    match12 = np.abs(np.degrees(symang2) -
                                     35.26) < sym_axes_angle_tolerance
                    match21 = np.abs(np.degrees(symang1) -
                                     54.735) < sym_axes_angle_tolerance
                    match22 = np.abs(np.degrees(symang2) -
                                     54.735) < sym_axes_angle_tolerance
                    if not (match11 or match12 or match12 or match22): continue
                    matchsymang = symang1 if (match11 or match21) else symang2
                    metalaxis = metalaxis1 if (match11
                                               or match21) else metalaxis2

                    metal_pos = (rotframes1[hit[0], :3, 3] +
                                 rotframes2[hit[1], :3, 3]) / 2.0
                    metalaxispos = metal_pos + metalaxis[:3] + metalaxis[:3]
                    # metal_dist_z = np.sqrt(metal_pos[0]**2 + metal_pos[1]**2)
                    # if metal_dist_z < 4.0: continue
                    pose2 = mof.util.mutate_two_res(
                        pose,
                        ires1,
                        rotcloud1.amino_acid,
                        rotcloud1.rotchi[hit[0]],
                        ires2,
                        rotcloud2.amino_acid,
                        rotcloud2.rotchi[hit[1]],
                    )
                    if pose2.residue(ires1).has('VZN'):
                        pose2.set_xyz(
                            AtomID(
                                pose2.residue(ires1).atom_index('VZN'), ires1),
                            rVec(metal_pos[0], metal_pos[1], metal_pos[2]))
                        pose2.set_xyz(
                            AtomID(
                                pose2.residue(ires1).atom_index('HZ'), ires1),
                            rVec(metalaxispos[0], metalaxispos[1],
                                 metalaxispos[2]))

                    elif pose2.residue(ires2).has('VZN'):
                        pose2.set_xyz(
                            AtomID(
                                pose2.residue(ires2).atom_index('VZN'), ires2),
                            rVec(metal_pos[0], metal_pos[1], metal_pos[2]))
                        pose2.set_xyz(
                            AtomID(
                                pose2.residue(ires2).atom_index('HZ'), ires2),
                            rVec(metalaxispos[0], metalaxispos[1],
                                 metalaxispos[2]))
                    farep_delta = search_spec.rep_sfxn(pose2) - farep_orig
                    if farep_delta > 1.0: continue
                    print(
                        "HIT",
                        rotcloud1.amino_acid,
                        rotcloud2.amino_acid,
                        ires1,
                        ires2,
                        np.round(np.degrees(matchsymang), 3),
                        hit,
                        rotcloud1.rotchi[hit[0]],
                        rotcloud2.rotchi[hit[1]],
                        # farep_delta,
                        np.round(dist[tuple(hit)], 3),
                        np.round(angerr[tuple(hit)], 3),
                    )
                    fn = ('hit_%s_%s_%i_%i_%i.pdb' %
                          (rotcloud1.amino_acid, rotcloud2.amino_acid, ires1,
                           ires2, ihit))
                    rotcloud1.dump_pdb(fn + '_a.pdb', stub1, which=hit[0])
                    rotcloud2.dump_pdb(fn + '_b.pdb', stub2, which=hit[1])
                    pose2.dump_pdb(fn)

    return results