Example #1
0
    def set_Structure(config):
        """
        Load the input/reference files (.prmtop, .inpcrd) into a parmed.Structure. If a `restart` (.rst7)
        file is given, overwrite the reference positions, velocities, and box vectors on the Structure.

        Parameters
        -----------
        filename: str, filepath to input (.prmtop)
        restart: str, file path to Amber restart file (.rst7)
        logger: logging.Logger object, records information

        Notes
        -----
        Reference for parmed.load_Structure *args and **kwargs
        https://parmed.github.io/ParmEd/html/structobj/parmed.formats.registry.load_file.html#parmed.formats.registry.load_file
        """
        if 'restart' in config['structure'].keys():
            rst7 = config['structure']['restart']
            config['Logger'].info('Restarting simulation from {}'.format(rst7))
            restart = parmed.amber.Rst7(rst7)
            config['structure'].pop('restart')

            structure = parmed.load_file(**config['structure'])
            structure.positions = restart.positions
            structure.velocities = restart.velocities
            structure.box = restart.box
        else:
            structure = parmed.load_file(**config['structure'])

        config['Structure'] = structure
        return config
Example #2
0
 def testMoleculeCombine(self):
     """ Tests selective molecule combination in Gromacs topology files """
     warnings.filterwarnings('ignore', category=GromacsWarning)
     parm = load_file(os.path.join(get_fn('12.DPPC'), 'topol3.top'))
     fname = get_fn('combined.top', written=True)
     # Make sure that combining non-adjacent molecules fails
     self.assertRaises(ValueError, lambda:
             parm.write(fname, combine=[[1, 3]]))
     self.assertRaises(ValueError, lambda:
             parm.write(fname, combine='joey'))
     self.assertRaises(ValueError, lambda:
             parm.write(fname, combine=[1, 2, 3]))
     self.assertRaises(TypeError, lambda:
             parm.write(fname, combine=1))
     parm.write(fname, combine=[[3, 4], [126, 127, 128, 129, 130]])
     with open(fname, 'r') as f:
         for line in f:
             if line.startswith('[ molecules ]'):
                 break
         molecule_list = []
         for line in f:
             if line[0] == ';': continue
             words = line.split()
             molecule_list.append((words[0], int(words[1])))
     parm2 = load_file(fname)
     self.assertEqual(molecule_list, [('DPPC', 3), ('system1', 1),
                      ('SOL', 121), ('system2', 1), ('SOL', 121)])
     self.assertEqual(len(parm2.atoms), len(parm.atoms))
     self.assertEqual(len(parm2.residues), len(parm2.residues))
     for a1, a2 in zip(parm.atoms, parm2.atoms):
         self._equal_atoms(a1, a2)
     for r1, r2 in zip(parm.residues, parm2.residues):
         self.assertEqual(len(r1), len(r2))
         for a1, a2 in zip(r1, r2):
             self._equal_atoms(a1, a2)
    def test_geometric_combining_rule_energy(self):
        """ Tests converting geom. comb. rule energy from Gromacs to Amber """
        top = load_file(os.path.join(get_fn('05.OPLS'), 'topol.top'),
                        xyz=os.path.join(get_fn('05.OPLS'), 'conf.gro'))
        self.assertEqual(top.combining_rule, 'geometric')
        del top.rb_torsions[:]
        parm = load_file(get_saved_fn('opls.parm7'),
                         xyz=os.path.join(get_fn('05.OPLS'), 'conf.gro'))
        self.assertEqual(parm.combining_rule, 'geometric')
        self.assertFalse(parm.has_NBFIX())

        sysg = top.createSystem()
        sysa = parm.createSystem()

        cong = mm.Context(sysg, mm.VerletIntegrator(0.001), CPU)
        cona = mm.Context(sysa, mm.VerletIntegrator(0.001), CPU)

        cong.setPositions(top.positions)
        cona.setPositions(top.positions)

        self._check_energies(top, cong, parm, cona)

        # Make an NBFIX
        self.assertFalse(parm.has_NBFIX())
        parm.parm_data['LENNARD_JONES_ACOEF'][-4] = 10.0
        self.assertTrue(parm.has_NBFIX())
        parm.createSystem()
Example #4
0
    def testCharmmParameterSetConversion(self):
        """ Tests CharmmParameterSet.from_parameterset and from_structure """
        params1 = ParameterSet.from_structure(
                load_file(get_fn('benzene_cyclohexane_10_500.prmtop'))
        )
        params2 = load_file(os.path.join(get_fn('03.AlaGlu'), 'topol.top')).parameterset

        chparams1 = parameters.CharmmParameterSet.from_parameterset(params1)
        chparams2 = parameters.CharmmParameterSet.from_parameterset(params2, copy=True)
        chparams3 = parameters.CharmmParameterSet.from_structure(
                load_file(get_fn('benzene_cyclohexane_10_500.prmtop'))
        )

        self.assertIsInstance(chparams1, parameters.CharmmParameterSet)
        self.assertIsInstance(chparams2, parameters.CharmmParameterSet)
        self.assertIsInstance(chparams3, parameters.CharmmParameterSet)

        self._compare_paramsets(chparams1, params1, copy=False)
        self._compare_paramsets(chparams2, params2, copy=True)
        self._compare_paramsets(chparams1, chparams3, copy=True)

        self._check_uppercase_types(chparams1)
        self._check_uppercase_types(chparams2)
        self._check_uppercase_types(chparams3)

        # GAFF atom types, as in the first parameter set, are all lower-case.
        # Check that name decoration is the established pattern
        for name in chparams1.atom_types:
            self.assertTrue(name.endswith('LTU'))
        for name in chparams3.atom_types:
            self.assertTrue(name.endswith('LTU'))
Example #5
0
    def patch(self, top_string, crd_string):
        INTOP = 'in.top'
        INRST = 'in.rst'
        OUTTOP = 'out.top'
        OUTRST = 'out.rst'

        with util.in_temp_dir():
            with open(INTOP, 'wt') as outfile:
                outfile.write(top_string)
            with open(INRST, 'wt') as outfile:
                outfile.write(crd_string)

            topol = pmd.load_file(INTOP)
            crd = pmd.load_file(INRST)
            topol.coordinates = crd.coordinates

            self._add_particles(topol)

            topol.write_parm(OUTTOP)
            topol.write_rst7(OUTRST)
            with open(OUTTOP, 'rt') as infile:
                top_string = infile.read()
            with open(OUTRST, 'rt') as infile:
                crd_string = infile.read()
        return top_string, crd_string
Example #6
0
 def test_xyz(self):
     """ Tests parsing Tinker XYZ files """
     self.assertTrue(tinkerfiles.XyzFile.id_format(get_fn('nma.xyz')))
     self.assertTrue(tinkerfiles.XyzFile.id_format(get_fn('2igd_924wat.xyz')))
     xyz = tinkerfiles.XyzFile(get_fn('nma.xyz'))
     np.testing.assert_allclose(xyz.box, [30.735, 30.876, 28.485, 90.0, 90.0, 90.0])
     self.assertEqual(len(xyz.atoms), 2466)
     self.assertEqual(xyz.atoms[0].name, 'C')
     self.assertEqual(xyz.atoms[0].type, '221')
     self.assertEqual(len(xyz.atoms[0].bond_partners), 4)
     self.assertEqual(xyz.atoms[-1].name, 'H')
     self.assertEqual(xyz.atoms[-1].atomic_number, 1)
     self.assertEqual(xyz.atoms[-1].type, '248')
     xyz = pmd.load_file(get_fn('2igd_924wat.xyz'), get_fn('2igd_924wat.pdb'))
     pdb = pmd.load_file(get_fn('2igd_924wat.pdb'))
     xyz2 = pmd.load_file(get_fn('2igd_924wat.xyz'))
     self.assertEqual(len(pdb.atoms), len(xyz.atoms))
     self.assertEqual(len(pdb.residues), len(xyz.residues))
     for r1, r2 in zip(pdb.residues, xyz.residues):
         self.assertEqual(len(r1), len(r2))
         self.assertEqual(r1.chain, r2.chain)
         self.assertEqual(r1.name, r2.name)
         self.assertEqual(r1.insertion_code, r2.insertion_code)
     # Make sure NA ions are atomic number of sodium
     for atom in xyz.view['NA',:].atoms:
         self.assertEqual(atom.atomic_number, pmd.periodic_table.AtomicNum['Na'])
     # Now make sure that NA ions are atomic number of sodium even if we
     # don't load a PDB file
     for atom in xyz2.view[:,'Na+']:
         self.assertEqual(atom.atomic_number, pmd.periodic_table.AtomicNum['Na'])
Example #7
0
 def testSimple(self):
     """ Tests converting standard Gromacs system into Amber prmtop """
     top = load_file(get_fn(os.path.join('03.AlaGlu', 'topol.top')))
     self.assertEqual(top.combining_rule, 'lorentz')
     parm = amber.AmberParm.from_structure(top)
     parm.write_parm(get_fn('ala_glu.parm7', written=True))
     parm = load_file(get_fn('ala_glu.parm7', written=True))
     self.assertIsInstance(parm, amber.AmberParm)
     self.assertEqual(len(top.atoms), len(parm.atoms))
     self.assertEqual(len(top.bonds), len(parm.bonds))
     self.assertEqual(len(top.angles), len(parm.angles))
     self.assertEqual(len(top.residues), len(parm.residues))
     for a1, a2 in zip(top.atoms, parm.atoms):
         self.assertEqual(a1.name, a2.name)
         self.assertEqual(a1.type, a2.type)
         self.assertEqual(a1.atomic_number, a2.atomic_number)
         self.assertEqual(a1.residue.name, a2.residue.name)
         self.assertEqual(a1.residue.idx, a2.residue.idx)
         self.assertAlmostEqual(a1.mass, a2.mass)
         self.assertIs(type(a1), type(a2))
         self.assertAlmostEqual(a1.charge, a2.charge)
         self.assertEqual(set([a.idx for a in a1.bond_partners]),
                          set([a.idx for a in a2.bond_partners]))
         self.assertEqual(set([a.idx for a in a1.angle_partners]),
                          set([a.idx for a in a2.angle_partners]))
         self.assertEqual(set([a.idx for a in a1.dihedral_partners]),
                          set([a.idx for a in a2.dihedral_partners]))
Example #8
0
    def testDPPC(self):
        """ Tests non-standard Gromacs force fields and nonbonded exceptions """
        # We know what we're doing
        warnings.filterwarnings('ignore', category=GromacsWarning)
        top = load_file(os.path.join(get_fn('12.DPPC'), 'topol.top'))
        gro = load_file(os.path.join(get_fn('12.DPPC'), 'conf.gro'))
        top.box = gro.box[:]

        # Create the system and context, then calculate the energy decomposition
        system = top.createSystem()
        with open('system.xml', 'w') as f:
            f.write(mm.XmlSerializer.serialize(system))
        context = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        context.setPositions(gro.positions)
        energies = energy_decomposition(top, context, nrg=u.kilojoules_per_mole)

        # Compare with Lee-Ping's answers.
        self.assertAlmostEqual(energies['bond'], 0)
        self.assertAlmostEqual(energies['angle'], 1405.7354199, places=4)
        self.assertAlmostEqual(energies['dihedral'], 236.932663255, places=4)
        self.assertAlmostEqual(energies['improper'], 33.201541811, places=4)
        self.assertAlmostEqual(energies['rb_torsion'], 428.0550599, places=4)
        self.assertRelativeEqual(energies['nonbonded'], -16432.8092955, places=4)
        gmxfrc = get_forces_from_xvg(os.path.join(get_fn('12.DPPC'), 'force.xvg'))
        ommfrc = context.getState(getForces=True).getForces().value_in_unit(
                    u.kilojoules_per_mole/u.nanometer)
        zero_ep_frc(ommfrc, top)
        max_diff = get_max_diff(gmxfrc, ommfrc)
        self.assertLess(max_diff, 5)
Example #9
0
    def testRoundTrip(self):
        """ Test ParmEd -> OpenMM round trip with Gromacs system """
        # Use DPPC to get RB-torsions tested. Also check that it initially fails
        # with the CustomNonbondedForce
        warnings.filterwarnings('ignore', category=GromacsWarning)
        top = load_file(os.path.join(get_fn('12.DPPC'), 'topol.top'))
        gro = load_file(os.path.join(get_fn('12.DPPC'), 'conf.gro'))
        top.box = gro.box[:]

        system = top.createSystem()
        def bad_system():
            return openmm.load_topology(top.topology, system).createSystem()
        warnings.filterwarnings('error', category=OpenMMWarning)
        self.assertRaises(OpenMMWarning, lambda:
                openmm.load_topology(top.topology, system)
        )
        warnings.filterwarnings('ignore', category=OpenMMWarning)
        self.assertRaises(ParmedError, bad_system)
        for i in range(len(system.getForces())):
            if isinstance(system.getForce(i), mm.CustomNonbondedForce):
                system.removeForce(i)
                break
        system2 = openmm.load_topology(top.topology, system).createSystem()
        con1 = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        con2 = mm.Context(system2, mm.VerletIntegrator(0.001), CPU)
        con1.setPositions(gro.positions)
        con2.setPositions(gro.positions)
        ene1 = energy_decomposition(top, con1)
        ene2 = energy_decomposition(top, con2)
        self.assertAlmostEqual(ene1['bond'], ene2['bond'])
        self.assertAlmostEqual(ene1['angle'], ene2['angle'])
        self.assertAlmostEqual(ene1['dihedral'], ene2['dihedral'])
        self.assertAlmostEqual(ene1['improper'], ene2['improper'])
        self.assertAlmostEqual(ene1['rb_torsion'], ene2['rb_torsion'])
        self.assertAlmostEqual(ene1['nonbonded'], ene2['nonbonded'])
Example #10
0
    def testJACPMESwitch(self):
        """ Tests the DHFR Gromacs system nrg and force (PME w/ switch) """
        # Load the top and gro files
        top = load_file(os.path.join(get_fn('10.DHFR-PME-Switch'), 'topol.top'))
        gro = load_file(os.path.join(get_fn('10.DHFR-PME-Switch'), 'conf.gro'))
        top.box = gro.box[:]

        # Create the system and context, then calculate the energy decomposition
        system = top.createSystem(nonbondedMethod=app.PME,
                                  constraints=app.HBonds,
                                  nonbondedCutoff=0.9*u.nanometers,
                                  ewaldErrorTolerance=1.0e-5)
        context = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        context.setPositions(gro.positions)
        energies = energy_decomposition(top, context, nrg=u.kilojoules_per_mole)

        # Compare with Lee-Ping's answers. Make sure we zero-out forces for
        # virtual sites, since OMM doesn't do this and Gromacs does.
        self.assertAlmostEqual(energies['bond'], 1628.54739, places=3)
        self.assertAlmostEqual(energies['angle'], 3604.58751, places=3)
        self.assertAlmostEqual(energies['dihedral'], 6490.00844, delta=0.002)
        self.assertRelativeEqual(energies['nonbonded'], 23616.457584, places=3)
        gmxfrc = get_forces_from_xvg(
                os.path.join(get_fn('10.DHFR-PME-Switch'), 'force.xvg'))
        ommfrc = context.getState(getForces=True).getForces().value_in_unit(
                    u.kilojoules_per_mole/u.nanometer)
        zero_ep_frc(ommfrc, top)
        max_diff = get_max_diff(gmxfrc, ommfrc)
        self.assertLess(max_diff, 5)
Example #11
0
    def testJAC(self):
        """ Tests the JAC benchmark Gromacs system nrg and force (no PBC) """
        # Load the top and gro files
        top = load_file(os.path.join(get_fn('07.DHFR-Liquid-NoPBC'), 'topol.top'))
        gro = load_file(os.path.join(get_fn('07.DHFR-Liquid-NoPBC'), 'conf.gro'))

        # Create the system and context, then calculate the energy decomposition
        system = top.createSystem()
        context = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        context.setPositions(gro.positions)
        energies = energy_decomposition(top, context, nrg=u.kilojoules_per_mole)

        # Compare with Lee-Ping's answers. Make sure we zero-out forces for
        # virtual sites, since OMM doesn't do this and Gromacs does.
        self.assertAlmostEqual(energies['bond'], 35.142565, places=3)
        self.assertAlmostEqual(energies['angle'], 3735.514669, places=3)
        self.assertAlmostEqual(energies['dihedral'], 7277.741635, delta=0.002)
        self.assertRelativeEqual(energies['nonbonded'], -288718.981405, places=4)
        gmxfrc = get_forces_from_xvg(
                os.path.join(get_fn('07.DHFR-Liquid-NoPBC'), 'force.xvg'))
        ommfrc = context.getState(getForces=True).getForces().value_in_unit(
                    u.kilojoules_per_mole/u.nanometer)
        zero_ep_frc(ommfrc, top)
        max_diff = get_max_diff(gmxfrc, ommfrc)
        self.assertLess(max_diff, 0.5)
Example #12
0
def test_ring_count():
    # Two rings
    fused = pmd.load_file(get_fn('fused.mol2'), structure=True)
    top, _ = generate_topology(fused)
    rule = SMARTSGraph(name='test', parser=PARSER,
                       smarts_string='[#6;R2]')

    match_indices = list(rule.find_matches(top))
    for atom_idx in (3, 4):
        assert atom_idx in match_indices
    assert len(match_indices) == 2

    rule = SMARTSGraph(name='test', parser=PARSER,
                       smarts_string='[#6;R1]')
    match_indices = list(rule.find_matches(top))
    for atom_idx in (0, 1, 2, 5, 6, 7, 8, 9):
        assert atom_idx in match_indices
    assert len(match_indices) == 8

    # One ring
    ring = pmd.load_file(get_fn('ring.mol2'), structure=True)
    top, _ = generate_topology(ring)

    rule = SMARTSGraph(name='test', parser=PARSER,
                       smarts_string='[#6;R1]')
    match_indices = list(rule.find_matches(top))
    for atom_idx in range(6):
        assert atom_idx in match_indices
    assert len(match_indices) == 6
Example #13
0
 def testWriteCharmm27Top(self):
     """ Tests writing a Gromacs topology file with CHARMM 27 FF """
     top = load_file(get_fn('1aki.charmm27.top'))
     self.assertEqual(top.combining_rule, 'lorentz')
     GromacsTopologyFile.write(top,
             get_fn('1aki.charmm27.top', written=True))
     top2 = load_file(get_fn('1aki.charmm27.top', written=True))
     self._charmm27_checks(top)
Example #14
0
def test_ringness():
    ring = pmd.load_file(get_fn('ring.mol2'), structure=True)
    top, _ = generate_topology(ring)
    _rule_match(top, '[#6]1[#6][#6][#6][#6][#6]1', True)

    not_ring = pmd.load_file(get_fn('not_ring.mol2'), structure=True)
    top, _ = generate_topology(not_ring)
    _rule_match(top, '[#6]1[#6][#6][#6][#6][#6]1', False)
 def test_write_amber99SBILDN(self):
     """ Tests writing a Gromacs topology with multiple molecules """
     top = load_file(get_fn('ildn.solv.top'))
     self.assertEqual(top.combining_rule, 'lorentz')
     fn = get_fn('ildn.solv.top', written=True)
     GromacsTopologyFile.write(top, fn, combine=None)
     top2 = load_file(fn)
     self._check_ff99sbildn(top2)
     self._check_equal_structures(top, top2)
Example #16
0
 def test_load_topology_error(self):
     """ Test error handling in load_topology """
     parm = load_file(get_fn("ash.parm7"), get_fn("ash.rst7"))
     parm2 = load_file(get_fn("solv2.parm7"), get_fn("solv2.rst7"))
     self.assertRaises(TypeError, lambda: openmm.load_topology(parm.topology, system=get_fn("integrator.xml")))
     self.assertRaises(TypeError, lambda: openmm.load_topology(parm2.topology, system=parm.createSystem()))
     system = parm.createSystem()
     system.addForce(mm.CustomTorsionForce("theta**2"))
     self.assertRaises(exceptions.OpenMMWarning, lambda: openmm.load_topology(parm.topology, system))
Example #17
0
 def testDuplicateSystemNames(self):
     """ Tests that Gromacs topologies never have duplicate moleculetypes """
     parm = load_file(get_fn('phenol.prmtop'))
     parm = parm * 20 + load_file(get_fn('biphenyl.prmtop')) * 20
     top = GromacsTopologyFile.from_structure(parm)
     self.assertEqual(top.combining_rule, 'lorentz')
     top.write(get_fn('phenol_biphenyl.top', written=True))
     top2 = GromacsTopologyFile(get_fn('phenol_biphenyl.top', written=True))
     self.assertEqual(len(top.residues), 40)
Example #18
0
 def testOPLS(self):
     """ Tests the geometric combining rules in Gromacs with OPLS/AA """
     parm = load_file(os.path.join(get_fn('05.OPLS'), 'topol.top'),
                      xyz=os.path.join(get_fn('05.OPLS'), 'conf.gro'))
     self.assertEqual(parm.combining_rule, 'geometric')
     self.assertEqual(parm.defaults.comb_rule, 3)
     parm.write(get_fn('test.topol', written=True), combine='all')
     parm2 = load_file(get_fn('test.topol', written=True))
     self.assertEqual(len(parm.atoms), len(parm2.atoms))
 def test_OPLS(self):
     """ Tests the geometric combining rules in Gromacs with OPLS/AA """
     parm = load_file(os.path.join(get_fn('05.OPLS'), 'topol.top'),
                      xyz=os.path.join(get_fn('05.OPLS'), 'conf.gro'))
     self.assertEqual(parm.combining_rule, 'geometric')
     self.assertEqual(parm.defaults.comb_rule, 3)
     parm.write(get_fn('test.topol', written=True), combine='all')
     parm2 = load_file(get_fn('test.topol', written=True))
     self.assertEqual(len(parm.atoms), len(parm2.atoms))
     # Check that the charge attribute is read correctly
     self.assertEqual(parm.parameterset.atom_types['opls_001'].charge, 0.5)
 def test_write_gro_file_nobox(self):
     """ Test GROMACS GRO file writing without a box """
     parm = load_file(get_fn('trx.prmtop'), get_fn('trx.inpcrd'))
     self.assertIs(parm.box, None)
     fn = get_fn('test.gro', written=True)
     parm.save(fn)
     # Make sure it has a box
     gro = load_file(fn)
     self.assertIsNot(gro.box, None)
     parm.save(fn, nobox=True, overwrite=True)
     gro = load_file(fn)
     self.assertIs(gro.box, None)
Example #21
0
 def testMoleculeOrdering(self):
     """ Tests non-contiguous atoms in Gromacs topology file writes """
     warnings.filterwarnings('ignore', category=GromacsWarning)
     parm = load_file(os.path.join(get_fn('12.DPPC'), 'topol3.top'))
     parm.write(get_fn('topol3.top', written=True))
     parm2 = load_file(get_fn('topol3.top', written=True))
     self.assertEqual(len(parm.atoms), len(parm2.atoms))
     self.assertEqual(len(parm.residues), len(parm2.residues))
     for r1, r2 in zip(parm.residues, parm2.residues):
         self.assertEqual(r1.name, r2.name)
         for a1, a2 in zip(r1.atoms, r2.atoms):
             self.assertEqual(a1.name, a2.name)
             self.assertEqual(a1.type, a2.type)
Example #22
0
 def test_atomtyping(self, mol_name, testfiles_dir=OPLS_TESTFILES_DIR):
     files = glob.glob(os.path.join(testfiles_dir, mol_name, '*'))
     for mol_file in files:
         _, ext = os.path.splitext(mol_file)
         if ext == '.top':
             top_filename = '{}.top'.format(mol_name)
             gro_filename = '{}.gro'.format(mol_name)
             top_path = os.path.join(testfiles_dir, mol_name, top_filename)
             gro_path = os.path.join(testfiles_dir, mol_name, gro_filename)
             structure = pmd.load_file(top_path, xyz=gro_path, parametrize=False)
         elif ext == '.mol2':
             mol2_path = os.path.join(testfiles_dir, mol_name, mol_file)
             structure = pmd.load_file(mol2_path, structure=True)
     atomtype(structure, OPLSAA)
Example #23
0
 def test_atomtyping(self, mol_name, testfiles_dir=TRAPPE_TESTFILES_DIR):
     files = glob.glob(os.path.join(testfiles_dir, mol_name, '*'))
     for mol_file in files:
         _, ext = os.path.splitext(mol_file)
         mol2_path = os.path.join(testfiles_dir, mol_name, mol_file)
         structure = pmd.load_file(mol2_path, structure=True)
     atomtype(structure, TRAPPE_UA, non_atomistic=True)
Example #24
0
 def test_box_from_system(self):
     """ Tests loading box from System """
     parm = load_file(get_fn('solv2.parm7'), get_fn('solv2.rst7'))
     system = parm.createSystem(nonbondedMethod=app.PME,
                                nonbondedCutoff=8*u.angstroms)
     top = openmm.load_topology(parm.topology, system)
     np.testing.assert_allclose(parm.box, top.box)
Example #25
0
 def testWriteCrd(self):
     """ Test CHARMM coordinate writing capabilities """
     struct = load_file(get_fn('4lzt.pdb'))
     charmmcrds.CharmmCrdFile.write(struct, get_fn('test.crd', written=True))
     crd = charmmcrds.CharmmCrdFile(get_fn('test.crd', written=True))
     np.testing.assert_allclose(struct.coordinates,
                                crd.coordinates.reshape((len(struct.atoms), 3)))
Example #26
0
def test_coordinates_meta():
    from mdtraj.testing import get_fn
    fn, tn = [get_fn('frame0.pdb'),] * 2
    trajs = [pt.load(fn, tn), md.load(fn, top=tn), pmd.load_file(tn, fn)]

    N_FRAMES = trajs[0].n_frames

    from MDAnalysis import Universe
    u = Universe(tn, fn)
    trajs.append(Universe(tn, fn))

    views = [nv.show_pytraj(trajs[0]), nv.show_mdtraj(trajs[1]), nv.show_parmed(trajs[2])]
    views.append(nv.show_mdanalysis(trajs[3]))

    for index, (view, traj) in enumerate(zip(views, trajs)):
        view.frame = 3
        
        nt.assert_equal(view.trajlist[0].n_frames, N_FRAMES)
        nt.assert_equal(len(view.trajlist[0].get_coordinates_dict().keys()), N_FRAMES)

        if index in [0, 1]:
            # pytraj, mdtraj
            if index == 0:
                aa_eq(view.coordinates[0], traj.xyz[3], decimal=4)
            else:
                aa_eq(view.coordinates[0],10*traj.xyz[3], decimal=4)
            view.coordinates = traj.xyz[2]
def main(pdblist, pdb_pattern, force=False):
    for code in pdblist:
        try:
            print("trying to make {} folder".format(code))
            os.mkdir(code)
        except OSError:
            pass
        with temp_change_dir(code):
            print('processing {}'.format(code))
            print(os.getcwd())
            try:
                pdbfiles = glob(PDB_PATTERN.format(code=code))
                assert len(pdbfiles) > 0, "can not find any pdb file"
                for pdbfile in pdbfiles:
                    basename = os.path.basename(pdbfile)
                    try:
                        parm = pmd.load_file(pdbfile)
                        ok = True
                    except ValueError:
                        print('ParmEd failed: {}'.format(pdbfile))
                        ok = False
                    pdbfile_root = basename.replace('.pdb', '')
                    fn = 'NoH_' + basename
                    if os.path.exists(fn) and not force:
                        print('skip {}'.format(fn))
                    else:
                        if ok:
                            new_parm = parm[[index for index, atom in enumerate(
                                parm.atoms) if atom.atomic_number != 1]]
                            new_parm.save(fn, overwrite=True)
                            run_tleap(code, pdbfile_root, TLEAP_TEMPLATE)
            except TypeError:
                print('type error: ', code)
            except IndexError:
                print('index error: ', code)
 def test_chamber_expanded_exclusions(self):
     """ Tests converting Gromacs to Chamber parm w/ modified exceptions """
     # Now let's modify an exception parameter so that it needs type
     # expansion, and ensure that it is handled correctly
     top = load_file(get_fn('1aki.charmm27.solv.top'),
                     xyz=get_fn('1aki.charmm27.solv.gro'))
     gsystem1 = top.createSystem(nonbondedCutoff=8*u.angstroms,
                                 nonbondedMethod=app.PME)
     gcon1 = mm.Context(gsystem1, mm.VerletIntegrator(1*u.femtosecond),
                        Reference)
     gcon1.setPositions(top.positions)
     top.adjust_types.append(to.NonbondedExceptionType(0, 0, 1))
     top.adjust_types.claim()
     top.adjusts[10].type = top.adjust_types[-1]
     gsystem2 = top.createSystem(nonbondedCutoff=8*u.angstroms,
                                 nonbondedMethod=app.PME)
     gcon2 = mm.Context(gsystem2, mm.VerletIntegrator(1*u.femtosecond),
                        Reference)
     gcon2.setPositions(top.positions)
     e1 = gcon1.getState(getEnergy=True).getPotentialEnergy()
     e1 = e1.value_in_unit(u.kilocalories_per_mole)
     e2 = gcon2.getState(getEnergy=True).getPotentialEnergy()
     e2 = e2.value_in_unit(u.kilocalories_per_mole)
     self.assertGreater(abs(e2 - e1), 1e-2)
     # Convert to chamber now
     parm = amber.ChamberParm.from_structure(top)
     asystem = parm.createSystem(nonbondedCutoff=8*u.angstroms,
                                 nonbondedMethod=app.PME)
     acon = mm.Context(asystem, mm.VerletIntegrator(1*u.femtosecond),
                       Reference)
     acon.setPositions(top.positions)
     e3 = acon.getState(getEnergy=True).getPotentialEnergy()
     e3 = e3.value_in_unit(u.kilocalories_per_mole)
     self.assertLess(abs(e2 - e3), 1e-2)
    def test_simple(self):
        """ Test OpenMM System/Topology -> Amber prmtop conversion """
        parm = load_file(get_fn('ash.parm7'), get_fn('ash.rst7'))
        self.assertEqual(parm.combining_rule, 'lorentz')
        system = parm.createSystem()
        amber.AmberParm.from_structure(
                openmm.load_topology(parm.topology, system)
        ).write_parm(get_fn('ash_from_omm.parm7', written=True))
        parm2 = load_file(get_fn('ash_from_omm.parm7', written=True))
        system2 = parm2.createSystem()
        con1 = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        con2 = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        con1.setPositions(parm.positions)
        con2.setPositions(parm.positions)

        self._check_energies(parm, con1, parm2, con2)
def check_energy_components_vs_prmtop(prmtop=None, inpcrd=None, system=None, MAX_ALLOWED_DEVIATION=5.0):
    """
    """
    import parmed as pmd

    structure = pmd.load_file(prmtop, inpcrd)
    prmtop_components = dict(
        pmd.openmm.energy_decomposition_system(structure, structure.createSystem(nonbondedMethod=NoCutoff))
    )
    system_components = dict(pmd.openmm.energy_decomposition_system(structure, system))

    msg = "\n"
    msg += "Energy components:\n"
    test_pass = True
    msg += "%20s %12s %12s : %12s\n" % ("component", "prmtop (kcal/mol)", "system (kcal/mol)", "deviation")
    for key in prmtop_components:
        e1 = prmtop_components[key]
        e2 = system_components[key]
        deviation = abs(e1 - e2)
        if deviation > MAX_ALLOWED_DEVIATION:
            test_pass = False
        msg += "%20s %20.6f %20.6f : %20.6f\n" % (key, e1, e2, deviation)

    if not test_pass:
        msg += "Maximum allowed deviation (%f) exceeded.\n" % MAX_ALLOWED_DEVIATION
        # raise Exception(msg) # TODO: Re-enable when we have force tag merging sorted out in simtk.openmm.app.ForceField
        print(msg)  # DEBUG
Example #31
0
 def test_save_resnames_single(self, c3, n4):
     system = mb.Compound([c3, n4])
     system.save('resnames_single.gro', residues=['C3', 'N4'])
     struct = pmd.load_file('resnames_single.gro')
     assert struct.residues[0].number == 1
     assert struct.residues[1].number == 2
Example #32
0
# Script that converts an Amber formatted topology file and a coordinate file to a Orca force field parameter file and a Orca-readable xyz file.
# Written by Åsmund Røhr Kjendseth (2019)
# 
# Input:  
# parm7 topology file named: prmtop  
# coordinate file named: inpcrd
# These files are written by the AmberTools program tleap using the command: saveamberparm mol prmtop inpcrd
#
# More input/output options will be included.
#
# =============================================================================

import parmed as pmd

# Read Amber topology and coordinate files
parm = pmd.load_file('prmtop', xyz='inpcrd')


# Non bonded LJ 1-4 scaling factor
scnb = 2.0


# Colomb conversion factors (not used below) but may be the cause of slight differences in ee-terms.
CC_AMBER = 332.0522173 
CC_CHARMM = 332.054
CC_NAMD = 332.0636



# Write Amber formatted frcmod file (force constants). This file can be useful but is not used further below.
pmd.tools.writeFrcmod(parm, 'amber.frcmod').execute()
Example #33
0
from __future__ import division, print_function

import sys

# OpenMM Imports
import openmm as mm
import openmm.app as app

# ParmEd Imports
from parmed import load_file
from parmed.openmm.reporters import NetCDFReporter
from parmed import unit as u

# Load the Gromacs files
print('Loading Gromacs files...')
top = load_file('dhfr_pme.top', xyz='dhfr_pme.gro')

# Create the OpenMM system
print('Creating OpenMM System')
system = top.createSystem(nonbondedMethod=app.PME,
                          nonbondedCutoff=8.0*u.angstroms,
                          constraints=app.HBonds,
)

# Create the integrator to do Langevin dynamics
integrator = mm.LangevinIntegrator(
                        300*u.kelvin,       # Temperature of heat bath
                        1.0/u.picoseconds,  # Friction coefficient
                        2.0*u.femtoseconds, # Time step
)
Example #34
0
if not (len(sys.argv) == 5 or len(sys.argv) == 6):

    print "Usage: strip_random.py [-O] <prmtop> <inpcrd> <first_strippable_water> <remaining_wats>"
    exit(1)

overwrite = False
arg_shift = 0
if sys.argv[1] == "-O":
    overwrite = True
    arg_shift = 1
prmtop = sys.argv[1 + arg_shift]
inpcrd = sys.argv[2 + arg_shift]
first_wat = int(sys.argv[3 + arg_shift])
remaining_wats = int(sys.argv[4 + arg_shift])

p = pmd.load_file(prmtop)
p.load_rst7(inpcrd)
wats = p[":WAT"]

prmtop_watcnt = len(wats.residues)

if prmtop_watcnt <= remaining_wats:

    print "Warning: Number of Remaining wates lower than present waters."
    exit(1)

wat_list = list()
no_strip = list()
# Get water resids
for wat_idx in range(prmtop_watcnt):
Example #35
0
 def test_preserve_resname(self, oplsaa):
     untyped_ethane = pmd.load_file(get_fn("ethane.mol2"), structure=True)
     untyped_resname = untyped_ethane.residues[0].name
     typed_ethane = oplsaa.apply(untyped_ethane)
     typed_resname = typed_ethane.residues[0].name
     assert typed_resname == untyped_resname
    def test_jacs_complexes(self):
        """Use template generator to parameterize the Schrodinger JACS set of complexes"""
        # TODO: Uncomment working systems when we have cleaned up the input files
        jacs_systems = {
            #'bace'     : { 'prefix' : 'Bace' },
            #'cdk2'     : { 'prefix' : 'CDK2' },
            #'jnk1'     : { 'prefix' : 'Jnk1' },
            'mcl1'     : { 'prefix' : 'MCL1' },
            #'p38'      : { 'prefix' : 'p38' },
            #'ptp1b'    : { 'prefix' : 'PTP1B' },
            #'thrombin' : { 'prefix' : 'Thrombin' },
            #'tyk2'     : { 'prefix' : 'Tyk2' },
        }
        for system_name in jacs_systems:
            prefix = jacs_systems[system_name]['prefix']
            # Read molecules
            ligand_sdf_filename = get_data_filename(os.path.join('perses_jacs_systems', system_name, prefix + '_ligands.sdf'))
            print(f'Reading molecules from {ligand_sdf_filename} ...')
            from openforcefield.topology import Molecule
            molecules = Molecule.from_file(ligand_sdf_filename, allow_undefined_stereo=True)
            try:
                nmolecules = len(molecules)
            except TypeError:
                molecules = [molecules]
            print(f'Read {len(molecules)} molecules from {ligand_sdf_filename}')

            # Read ParmEd Structures
            import parmed
            from simtk import unit
            protein_pdb_filename = get_data_filename(os.path.join('perses_jacs_systems', system_name, prefix + '_protein.pdb'))
            from simtk.openmm.app import PDBFile
            print(f'Reading protein from {protein_pdb_filename} ...')
            #protein_structure = parmed.load_file(protein_pdb_filename) # NOTE: This mis-interprets distorted geometry and sequentially-numbered residues that span chain breaks
            pdbfile = PDBFile(protein_pdb_filename)
            protein_structure = parmed.openmm.load_topology(pdbfile.topology, xyz=pdbfile.positions.value_in_unit(unit.angstroms))
            ligand_structures = parmed.load_file(ligand_sdf_filename)
            try:
                nmolecules = len(ligand_structures)
            except TypeError:
                ligand_structures = [ligand_structures]
            assert len(ligand_structures) == len(molecules)

            # Filter molecules
            MAX_MOLECULES = 6 if not CI else 3
            molecules = molecules[:MAX_MOLECULES]
            ligand_structures = ligand_structures[:MAX_MOLECULES]
            print(f'{len(molecules)} molecules remain after filtering')

            # Create complexes
            complex_structures = [ (protein_structure + ligand_structure) for ligand_structure in ligand_structures ]

            # Create template generator with local cache
            cache = os.path.join(get_data_filename(os.path.join('perses_jacs_systems', system_name)), 'cache.json')
            generator = self.TEMPLATE_GENERATOR(molecules=molecules, cache=cache)

            # Create a ForceField
            from simtk.openmm.app import ForceField
            forcefield = ForceField(*self.amber_forcefields)
            # Register the template generator
            forcefield.registerTemplateGenerator(generator.generator)

            # Parameterize all complexes
            print(f'Caching all molecules for {system_name} at {cache} ...')
            for ligand_index, complex_structure in enumerate(complex_structures):
                openmm_topology = complex_structure.topology
                molecule = molecules[ligand_index]

                # Delete hydrogens from terminal protein residues
                # TODO: Fix the input files so we don't need to do this
                from simtk.openmm import app
                modeller = app.Modeller(complex_structure.topology, complex_structure.positions)
                residues = [residue for residue in modeller.topology.residues() if residue.name != 'UNL']
                termini_ids = [residues[0].id, residues[-1].id]
                #hs = [atom for atom in modeller.topology.atoms() if atom.element.symbol in ['H'] and atom.residue.name != 'UNL']
                hs = [atom for atom in modeller.topology.atoms() if atom.element.symbol in ['H'] and atom.residue.id in termini_ids]
                modeller.delete(hs)
                from simtk.openmm.app import PDBFile
                modeller.addHydrogens(forcefield)

                # Parameterize protein:ligand complex in vacuum
                print(f' Parameterizing {system_name} : {molecule.to_smiles()} in vacuum...')
                from simtk.openmm.app import NoCutoff
                forcefield.createSystem(modeller.topology, nonbondedMethod=NoCutoff)

                # Parameterize protein:ligand complex in solvent
                print(f' Parameterizing {system_name} : {molecule.to_smiles()} in explicit solvent...')
                from simtk.openmm.app import PME
                modeller.addSolvent(forcefield, padding=0*unit.angstroms, ionicStrength=300*unit.millimolar)
                forcefield.createSystem(modeller.topology, nonbondedMethod=PME)
Example #37
0
    def __init__(self, options):

        super(OpenMM, self).__init__(options)

        # get simulation from options if it exists
        #self.options['job_data']['simulation'] = self.options['job_data'].get('simulation',None)
        self.simulation = self.options['job_data'].get('simulation', None)

        if self.lot_inp_file is not None and self.simulation is None:

            # Now go through the logic of determining which FILE options are activated.
            self.file_options.set_active('use_crystal', False, bool,
                                         "Use crystal unit parameters")
            self.file_options.set_active(
                'use_pme', False, bool, '',
                "Use particle mesh ewald-- requires periodic boundary conditions"
            )
            self.file_options.set_active('cutoff',
                                         1.0,
                                         float,
                                         '',
                                         depend=(self.file_options.use_pme),
                                         msg="Requires PME")
            self.file_options.set_active('prmtopfile', None, str,
                                         "parameter file")
            self.file_options.set_active('inpcrdfile', None, str,
                                         "inpcrd file")
            self.file_options.set_active('restrain_torfile', None, str,
                                         "list of torsions to restrain")
            self.file_options.set_active('restrain_tranfile', None, str,
                                         "list of translations to restrain")

            for line in self.file_options.record():
                print(line)

            # set all active values to self for easy access
            for key in self.file_options.ActiveOptions:
                setattr(self, key, self.file_options.ActiveOptions[key])

            nifty.printcool(" Options for OpenMM")
            for val in [self.prmtopfile, self.inpcrdfile]:
                assert val != None, "Missing prmtop or inpcrdfile"

            # Integrator will never be used (Simulation requires one)
            integrator = openmm.VerletIntegrator(1.0)

            # create simulation object
            if self.use_crystal:
                crystal = load_file(self.prmtopfile, self.inpcrdfile)
                if self.use_pme:
                    system = crystal.createSystem(
                        nonbondedMethod=openmm_app.PME,
                        nonbondedCutoff=self.cutoff * openmm_units.nanometer,
                    )
                else:
                    system = crystal.createSystem(
                        nonbondedMethod=openmm_app.NoCutoff, )

                # Torsion restraint
                if self.restrain_torfile is not None:
                    nifty.printcool(" Adding torsional restraints!")

                    # Harmonic constraint
                    tforce = openmm.CustomTorsionForce(
                        "0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535"
                    )
                    tforce.addPerTorsionParameter("k")
                    tforce.addPerTorsionParameter("theta0")
                    system.addForce(tforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_torfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            b = int(columns[1])
                            c = int(columns[2])
                            d = int(columns[3])
                            k = float(columns[4])
                            dih = Dihedral(a, b, c, d)
                            theta0 = dih.value(xyz)
                            tforce.addTorsion(a, b, c, d, [k, theta0])

                # Translation restraint
                if self.restrain_tranfile is not None:
                    nifty.printcool(" Adding translational restraints!")
                    trforce = openmm.CustomExternalForce(
                        "k*periodicdistance(x, y, z, x0, y0, z0)^2")
                    trforce.addPerParticleParameter("k")
                    trforce.addPerParticleParameter("x0")
                    trforce.addPerParticleParameter("y0")
                    trforce.addPerParticleParameter("z0")
                    system.addForce(trforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_tranfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            k = float(columns[1])
                            x0 = xyz[a, 0] * 0.1  # Units are in nm
                            y0 = xyz[a, 1] * 0.1  # Units are in nm
                            z0 = xyz[a, 2] * 0.1  # Units are in nm
                            trforce.addParticle(a, [k, x0, y0, z0])

                self.simulation = openmm_app.Simulation(
                    crystal.topology, system, integrator)
                # set the box vectors
                inpcrd = openmm_app.AmberInpcrdFile(self.inpcrdfile)
                if inpcrd.boxVectors is not None:
                    print(" setting box vectors")
                    print(inpcrd.boxVectors)
                    self.simulation.context.setPeriodicBoxVectors(
                        *inpcrd.boxVectors)
            else:  # Do not use crystal parameters
                prmtop = openmm_app.AmberPrmtopFile(self.prmtopfile)
                if self.use_pme:
                    system = prmtop.createSystem(
                        nonbondedMethod=openmm_app.PME,
                        nonbondedCutoff=self.cutoff * openmm_units.nanometer,
                    )
                else:
                    system = prmtop.createSystem(
                        nonbondedMethod=openmm_app.NoCutoff, )
                self.simulation = openmm_app.Simulation(
                    prmtop.topology,
                    system,
                    integrator,
                )
Example #38
0
import sys
import numpy as np
from scipy.spatial import distance
import parmed as pmd

if len(sys.argv) != 4:
    print "Usage: filter_clashes.py <target.pdb> <query-filter-structure.pdb> <cutoff-distance> "
    exit(1)

mol_ref_path = sys.argv[1]
mol_cut_path = sys.argv[2]
cutoff = sys.argv[3]
cutoff = float(cutoff)**2

mol_ref = pmd.load_file(mol_ref_path)["!@H="]
mol_cut = pmd.load_file(mol_cut_path)["!@H="]

dists_ref = distance.cdist(mol_ref.coordinates,
                           mol_cut.coordinates,
                           metric="sqeuclidean")
dists_self = distance.cdist(mol_cut.coordinates,
                            mol_cut.coordinates,
                            metric="sqeuclidean")

filter_ref = np.where(dists_ref < cutoff)
filter_self = np.where(dists_self < cutoff)

filter_list = list()
filter_block = list()
        #resnames = ['HIP', 'HIE', 'HID', 'GLY']
        #resnames = []
    for resa, resb in itertools.permutations(resnames, 2):
        if (folder, (resa, resb)) in malformed_tripeptides:
            print(
                f'Skipping {folder}/{resa}_{resb} because it is known to be mis-formatted'
            )
            continue

        resname = f'{resa}_{resb}'
        prefix = os.path.join(folder, resname, resname)
        print()
        print()
        print(prefix)
        # Prepare AMBER system
        amber_struct = ParmEd.load_file(prefix + '.prmtop', prefix + '.inpcrd')
        #print(pmd_struct.atoms)
        amber_system = amber_struct.createSystem(
            nonbondedMethod=NoCutoff,
            #nonbondedCutoff=9.0*unit.angstrom,
            #constraints=HBonds,
            removeCMMotion=False)
        with open('amb_sys.xml', 'w') as of:
            of.write(XmlSerializer.serialize(amber_system))
        amber_top = amber_struct.topology

        amber_energy = calc_energy(amber_system, amber_top,
                                   amber_struct.positions)
        print(amber_energy)

        # prepare openff system
Example #40
0
 def test_missing_type_definitions(self):
     with pytest.raises(FoyerError):
         FF = Forcefield()
         ethane = pmd.load_file(get_fn("ethane.mol2"), structure=True)
         FF.apply(ethane)
Example #41
0
    def test_write_xml(self, filename, oplsaa):
        mol = pmd.load_file(get_fn(filename), structure=True)
        typed = oplsaa.apply(mol)

        typed.write_foyer(
            filename="opls-snippet.xml",
            name="oplsaa-snippet",
            version="0.1.0",
            forcefield=oplsaa,
            unique=True,
        )
        oplsaa_partial = Forcefield("opls-snippet.xml")
        assert oplsaa_partial.name == "oplsaa-snippet"
        assert oplsaa_partial.version == "0.1.0"
        assert oplsaa_partial.combining_rule == "geometric"
        typed_by_partial = oplsaa_partial.apply(mol)

        for adj in typed.adjusts:
            type1 = adj.atom1.atom_type
            type2 = adj.atom1.atom_type
            sigma_factor_pre = adj.type.sigma / (
                (type1.sigma + type2.sigma) / 2)
            epsilon_factor_pre = adj.type.epsilon / (
                (type1.epsilon * type2.epsilon)**0.5)

        for adj in typed_by_partial.adjusts:
            type1 = adj.atom1.atom_type
            type2 = adj.atom1.atom_type
            sigma_factor_post = adj.type.sigma / (
                (type1.sigma + type2.sigma) / 2)
            epsilon_factor_post = adj.type.epsilon / (
                (type1.epsilon * type2.epsilon)**0.5)

        assert sigma_factor_pre == sigma_factor_post
        assert epsilon_factor_pre == epsilon_factor_post

        # Do it again but with an XML including periodic dihedrals
        mol = pmd.load_file(get_fn(filename), structure=True)
        oplsaa = Forcefield(get_fn("oplsaa-periodic.xml"))
        typed = oplsaa.apply(mol)

        typed.write_foyer(filename="opls-snippet.xml",
                          forcefield=oplsaa,
                          unique=True)
        oplsaa_partial = Forcefield("opls-snippet.xml")
        typed_by_partial = oplsaa_partial.apply(mol)

        for adj in typed.adjusts:
            type1 = adj.atom1.atom_type
            type2 = adj.atom1.atom_type
            sigma_factor_pre = adj.type.sigma / (
                (type1.sigma + type2.sigma) / 2)
            epsilon_factor_pre = adj.type.epsilon / (
                (type1.epsilon * type2.epsilon)**0.5)

        for adj in typed_by_partial.adjusts:
            type1 = adj.atom1.atom_type
            type2 = adj.atom1.atom_type
            sigma_factor_post = adj.type.sigma / (
                (type1.sigma + type2.sigma) / 2)
            epsilon_factor_post = adj.type.epsilon / (
                (type1.epsilon * type2.epsilon)**0.5)

        assert sigma_factor_pre == sigma_factor_post
        assert epsilon_factor_pre == epsilon_factor_post
Example #42
0
 def test_pmd_loop(self, top, request):
     write_top(request.getfixturevalue(top), 'system.top')
     pmd.load_file('system.top')
Example #43
0
def get_indices(itp_name):
    itp = parmed.load_file(itp_name)
    #indices
    bond_indices = []
    angle_indices = []
    dihedral_indices = []
    improper_indices = []
    #equivalent parameters
    bond_symmetries = []
    angle_symmetries = []
    dihedral_symmetries = []
    #other stuff
    dihedral_multiplicities = []
    dihedral_types = []
    for bond in itp.bonds:
        if bond.funct == 1:
            bond_indices.append([bond.atom1.idx, bond.atom2.idx])
        else:
            raise NotImplementedError('Unknown bond function type')
    for angle in itp.angles:
        if angle.funct == 1:
            angle_indices.append(
                [angle.atom1.idx, angle.atom2.idx, angle.atom3.idx])
        else:
            raise NotImplementedError('Unknown angle function type')
    for dihedral in itp.dihedrals:
        dihedral_types.append(dihedral.funct)
        if dihedral.funct == 1:
            dihedral_indices.append([
                dihedral.atom1.idx, dihedral.atom2.idx, dihedral.atom3.idx,
                dihedral.atom4.idx
            ])
            dihedral_multiplicities.append(dihedral.type.per)
        elif dihedral.funct == 4:
            improper_indices.append([
                dihedral.atom1.idx, dihedral.atom2.idx, dihedral.atom3.idx,
                dihedral.atom4.idx
            ])
        else:
            raise NotImplementedError('Unknown dihedral function type')

    for bond_type in itp.bond_types:
        symmetry = []
        for index, bond in enumerate(itp.bonds):
            if bond.type == bond_type:
                symmetry.append(index)
        bond_symmetries.append(symmetry)

    for angle_type in itp.angle_types:
        symmetry = []
        for index, angle in enumerate(itp.angles):
            if angle.type == angle_type:
                symmetry.append(index)
        angle_symmetries.append(symmetry)

    for dihedral_type in itp.dihedral_types:
        symmetry = []
        for index, dihedral in enumerate(itp.dihedrals):
            if dihedral.type == dihedral_type:
                symmetry.append(index)
        dihedral_symmetries.append(symmetry)
    return bond_indices, angle_indices, dihedral_indices, improper_indices, dihedral_multiplicities, bond_symmetries, angle_symmetries, dihedral_symmetries, dihedral_types
Example #44
0
    Make an rtp file based on model0_1 and qout
"""
import argparse

import parmed

if __name__ == '__main__':

    argparser = argparse.ArgumentParser(description="Script to parse optimal charges")
    argparser.add_argument('-f','--file',help="the PDB file")
    argparser.add_argument('-q','--qout',help="the output charges",default="qout")
    argparser.add_argument('-o','--out',help="the output RTP file")
    argparser.add_argument('-t','--types',help="a file with atom types")
    args = argparser.parse_args()

    struct = parmed.load_file(args.file)

    qline = ""
    with open(args.qout, "r") as f :
        line = f.readline()
        while line :
            qline += line.strip() + " "
            line = f.readline()
    charges = map(float,qline.strip().split())

    for atom, charge in zip(struct.atoms, charges) :
        print "%4s%10.6f"%(atom.name, charge)

    if args.out is not None :
        atype = {}
        with open(args.types, "r") as f :
Example #45
0
def create_data(pdb_path):
    """
    Parse the protein data bank (PDB) file to generate
    input modelData

    @param pdb_path
    Name of the biomolecular structure file in PDB format

    """

    # Create local copy of temp file
    copy2(pdb_path, './tmp.pdb')

    # Use parmed to read the bond information from temp file
    top = pmd.load_file('tmp.pdb')

    # Remove the created temp file
    os.remove('tmp.pdb')

    # Read PDB file to create atom/bond information
    with open(pdb_path, 'r') as infile:
        # store only non-empty lines
        lines = [l.strip() for l in infile if l.strip()]

    # Initialize all variables
    var_nchains = []
    serial = []
    atm_name = []
    res_name = []
    chain = []
    res_id = []
    positions = []
    occupancy = []
    temp_factor = []
    atom_type = []
    ct = 0

    datb = {'atoms': [], 'bonds': []}

    # Variables that store the character positions of different
    # parameters from the molecule PDB file
    serialpos = [6, 11]
    atm_namepos = [12, 16]
    r_namepos = [17, 20]
    chainpos = [21, 22]
    r_idpos = [22, 26]
    xpos = [30, 38]
    ypos = [38, 46]
    zpos = [46, 54]
    occupos = [54, 60]
    bfacpos = [60, 66]
    atm_typepos = [77, 79]

    for l in lines:
        line = l.split()
        if "ATOM" in line[0] or "HETATM" in line[0]:
            serial.append(int(l[serialpos[0]:serialpos[1]]))
            atm_name.append(l[atm_namepos[0]:atm_namepos[1]].strip())
            val_r_name = l[r_namepos[0]:r_namepos[1]].strip()
            res_name.append(val_r_name)
            chain_val = l[chainpos[0]:chainpos[1]].strip()
            chain.append(chain_val)
            if chain_val not in var_nchains:
                var_nchains.append(chain_val)
            val_r_id = int(l[r_idpos[0]:r_idpos[1]])
            res_id.append(val_r_id)
            x = float(l[xpos[0]:xpos[1]])
            y = float(l[ypos[0]:ypos[1]])
            z = float(l[zpos[0]:zpos[1]])
            positions.append([x, y, z])
            occupancy.append(l[occupos[0]:occupos[1]].strip())
            temp_factor.append(l[bfacpos[0]:bfacpos[1]].strip())
            atom_type.append(l[atm_typepos[0]:atm_typepos[1]].strip())
            ct += 1

    # Create list of atoms
    tmp_res = res_id[0]
    resct = 1
    for i in range(len(chain)):
        if tmp_res != res_id[i]:
            tmp_res = res_id[i]
            resct += 1
        datb['atoms'].append({
            "name": atm_name[i],
            "chain": chain[i],
            "positions": positions[i],
            "residue_index": resct,
            "element": atom_type[i],
            "residue_name": res_name[i] + str(res_id[i]),
            "serial": i,
        })

    # Create list of bonds using the parmed module
    for i in range(len(top.bonds)):
        bondpair = top.bonds[i].__dict__
        atom1 = re.findall(r"\[(\d+)\]", str(bondpair['atom1']))
        atom2 = re.findall(r"\[(\d+)\]", str(bondpair['atom2']))
        datb['bonds'].append({
            'atom2_index': int(atom1[0]),
            'atom1_index': int(atom2[0])
        })

    return json.dumps(datb)
Example #46
0
def ante_charges(molecule, charge_style, net_charge=0.0,
                           multiplicity=1):
    """Calculates partial charges by calling antechamber

    Parameters
    ----------
    molecule : parmed.Structure or mbuild.Compound
        Molecular structure to perform atomtyping on
    charge_style : str
        Style of partial charges calculation. Options include
        'bcc', 'gas', and 'mul'. See antechamber documentation
        by running 'antechamber -L' for details.
    net_charge : float, optional, default=0.0
        Net charge of the molecule
    multiplicity : int, optional, default=1
        Spin multiplicity, 2S + 1

    Returns
    -------
    molecule : parmed.Structure
        The molecule with charges applied
    """
    _check_antechamber(ANTECHAMBER)

    # Check valid atomtype name
    supported_chargetypes = ['bcc', 'gas', 'mul']
    if charge_style not in supported_chargetypes:
        raise FoyerError( 'Unsupported charge style requested. '
            'Please select from {}'.format(supported_chargetypes))

    # Check for parmed.Structure. Convert from mbuild.Compound if possible
    molecule = _check_structure(molecule)
    # Confirm single connected molecule
    _check_single_molecule(molecule)

    # Get current directory to write any error logs
    workdir = os.getcwd()
    # Work within a temporary directory
    # to clean up after antechamber
    with temporary_directory() as tmpdir:
        with temporary_cd(tmpdir):
            # Save the existing molecule to file
            _write_pdb(molecule,'ante_in.pdb')
            # Call antechamber
            command = ( 'antechamber -i ante_in.pdb -fi pdb '
                         '-o ante_out.mol2 -fo mol2 ' +
                         '-c ' + charge_style + ' ' +
                         '-nc ' + str(net_charge) + ' ' +
                         '-m ' + str(multiplicity) +  ' ' +
                         '-s 2' )

            proc = Popen(command, stdout=PIPE, stderr=PIPE,
                         universal_newlines=True, shell=True)

            out, err = proc.communicate()

            # Error handling here
            if 'Fatal Error' in err or proc.returncode != 0:
                _antechamber_error(out,err,workdir)

            # Now read in the mol2 file with atomtyping
            charges = pmd.load_file('ante_out.mol2',structure=True)

    # Combine charge information with existing molecule structure
    assert len(molecule.atoms) == len(charges.atoms)
    for atom_idx in range(len(molecule.atoms)):
        assert molecule.atoms[atom_idx].element == \
                charges.atoms[atom_idx].element
        molecule.atoms[atom_idx].charge = charges.atoms[atom_idx].charge
    return molecule
Example #47
0
)
attach_fractions = [float(i) / 100 for i in attach_string.split()]

pull_string = (
    "0.00 0.40 0.80 1.20 1.60 2.00 2.40 2.80 3.20 3.60 4.00 4.40 4.80 5.20 5.60 6.00 6.40 6.80 7.20 7.60 8.00 8.40 8.80 9.20 9.60 10.00 10.40 10.80 11.20 11.60 12.00 12.40 12.80 13.20 13.60 14.00 14.40 14.80 15.20 15.60 16.00 16.40 16.80 17.20 17.60 18.00"
)
pull_distances = [float(i) + 6.00 for i in pull_string.split()]

release_fractions = attach_fractions[::-1]

windows = [len(attach_fractions), len(pull_distances), 0]


structure = pmd.load_file(
    os.path.join("systems", system, "smirnoff", "smirnoff.prmtop"),
    os.path.join("systems", system, "smirnoff", "smirnoff.inpcrd"),
    structure=True,
)

anchor_atoms = grep_anchor_atoms(system)
static_restraints = setup_static_restraints(
    anchor_atoms, windows, structure, distance_fc=5.0, angle_fc=100.0
)

guest_restraints = setup_guest_restraints(
    anchor_atoms,
    windows,
    structure,
    attach_fractions,
    distance_fc=5.0,
    angle_fc=100.0,
Example #48
0
import sys
import parmed as pmd
from paprika.io as import load_restraints
from paprika.analysis import fe_calc
from paprika.restraints.utils import extract_guest_restraints

# Filenames etc.
structure_file = 'vac-dum'
guest_resname = 'AMT'
restraint_file = 'restraints.json'

# Extract restraints
structure = pmd.load_file(f'{structure_file}.prmtop', f'{structure_file}.rst7')
restraints = load_restraints(filepath=restraint_file)
guest_restraints = extract_guest_restraints(structure, guest_resname, restraints)

# Calculate ref state work
FE = fe_calc()
FE.compute_ref_state_work(guest_restraints, calc='ddm')
print(f"Ref state work: {FE.results['ref_state_work']:.2f} kcal/mol")
Example #49
0
def solvate(complex,
            params=None,
            box_length=8,
            shell=0,
            neutralise=True,
            ion_conc=0.154,
            centre=True,
            work_dir=None,
            filebase="complex"):
    """
    Uses gmx solvate and gmx genion to solvate the system and (optionally) add NaCl ions. This function preserves the
    crystal water molecules.

    Parameters
    ----------
    complex : BioSimSpace.System or parmed.structure.Structure
        The input unsolvated system.
    params : ProtoCaller.Parametrise.Params
        The input force field parameters.
    box_length : float, iterable
        Size of the box in nm.
    shell : float
        Places a layer of water of the specified thickness in nm around the solute.
    neutralise : bool
        Whether to add counterions to neutralise the system.
    ion_conc : float
        Ion concentration of NaCl in mol/L.
    centre : bool
        Whether to centre the system.
    work_dir : str
        Work directory. Default: current directory.
    filebase : str
        Output base name of the file.

    Returns
    -------
    complex : BioSimSpace.System or parmed.structure.Structure
        The solvated system.
    """
    if params is None:
        params = _parametrise.Params()

    if isinstance(complex, _pmd.Structure):
        centrefunc = _pmdwrap.centre
        chargefunc = lambda x: round(sum([atom.charge for atom in x.atoms]))
        readfunc = _pmdwrap.openFilesAsParmed
    elif _PC.BIOSIMSPACE and isinstance(complex,
                                        (_BSS._SireWrappers._molecule.Molecule,
                                         _BSS._SireWrappers._system.System)):
        if isinstance(complex, _BSS._SireWrappers._molecule.Molecule):
            complex = complex.toSystem()
        centrefunc = _BSSwrap.centre
        chargefunc = lambda x: round(x.charge().magnitude())
        readfunc = _BSS.IO.readMolecules
    else:
        raise TypeError("Cannot solvate object of type %s" % type(complex))

    if not isinstance(box_length, _Iterable):
        box_length = 3 * [box_length]

    if work_dir is None:
        work_dir = _os.path.basename(_tempfile.TemporaryDirectory().name)
        temp = True
    else:
        temp = False

    with _fileio.Dir(dirname=work_dir, temp=temp):
        # centre
        if centre:
            complex, box_length, _ = centrefunc(complex, box_length)

        # solvate with gmx solvate and load unparametrised waters into memory
        files = _PC.IO.GROMACS.saveAsGromacs(filebase, complex)
        # reloading the complex fixes some problems with ParmEd
        if isinstance(complex, _pmd.Structure):
            complex = _pmdwrap.openFilesAsParmed(files)
        new_gro = filebase + "_solvated.gro"
        command = "{0} solvate -shell {1} -box {2[0]} {2[1]} {2[2]} -cp \"{3}\" -o \"{4}\"".format(
            _PC.GROMACSEXE, shell, box_length, files[1], new_gro)
        if params.water_points == 4:
            command += " -cs tip4p.gro"
        _runexternal.runExternal(command, procname="gmx solvate")
        complex_solvated = _pmd.load_file(new_gro, skip_bonds=True)
        waters = complex_solvated[":SOL"]

        # prepare waters for tleap and parametrise
        for residue in waters.residues:
            residue.name = "WAT"
        for i, atom in enumerate(waters.atoms):
            if "H" in atom.name:
                atom.name = atom.name[0] + atom.name[2]
            elif "O" in atom.name:
                atom.name = "O"
            else:
                atom.name = "EPW"

        # here we only parametrise a single water molecule in order to gain performance
        waters_prep_filenames = [
            filebase + "_waters.top", filebase + "_waters.gro"
        ]
        waters[":1"].save(filebase + "_single_wat.pdb")
        water = _parametrise.parametriseAndLoadPmd(
            params, filebase + "_single_wat.pdb", "water")
        _pmdwrap.saveFilesFromParmed(waters, [waters_prep_filenames[1]],
                                     combine="all")
        _pmdwrap.saveFilesFromParmed(water, [waters_prep_filenames[0]])
        for line in _fileinput.input(waters_prep_filenames[0], inplace=True):
            line_new = line.split()
            if len(line_new) == 2 and line_new == ["WAT", "1"]:
                line = line.replace(
                    "1",
                    "{}".format(len(waters.positions) // params.water_points))
            print(line, end="")
        waters_prep = _pmdwrap.openFilesAsParmed(waters_prep_filenames)

        waters_prep.box = _pmd.load_file(files[1], skip_bonds=True).box
        if any([neutralise, ion_conc, shell]):
            for residue in waters_prep.residues:
                residue.name = "SOL"
        _pmdwrap.saveFilesFromParmed(waters_prep, waters_prep_filenames)

        # add ions
        if any([neutralise, ion_conc, shell]):
            # write an MDP file
            _protocol.Protocol(use_preset="default").write("GROMACS", "ions")

            # neutralise if needed
            charge = chargefunc(complex) if neutralise else 0
            volume = box_length[0] * box_length[1] * box_length[2] * 10**-24
            n_Na, n_Cl = [
                int(volume * 6.022 * 10**23 * ion_conc) - abs(charge) // 2
            ] * 2
            if neutralise:
                if charge < 0:
                    n_Na -= charge
                else:
                    n_Cl += charge

            # add ions with gmx genion
            ions_prep_filenames = [
                filebase + "_ions.top", filebase + "_ions.gro"
            ]
            command = "{0} grompp -f ions.mdp -p {1} -c {2} -o \"{3}_solvated.tpr\"".format(
                _PC.GROMACSEXE, *waters_prep_filenames, filebase)
            _runexternal.runExternal(command, procname="gmx grompp")

            command = "{{ echo 2; }} | {0} genion -s \"{1}_solvated.tpr\" -o \"{2}\" -nn {3} -np {4}".format(
                _PC.GROMACSEXE, filebase, ions_prep_filenames[1], n_Cl, n_Na)
            _runexternal.runExternal(command, procname="gmx genion")

            # prepare waters for tleap
            ions = _pmd.load_file(ions_prep_filenames[1], skip_bonds=True)
            for residue in ions.residues:
                if residue.name == "SOL":
                    residue.name = "WAT"

            # here we only parametrise single ions to gain performance
            ion = ions[":WAT"][":1"] + ions[":NA"][":1"] + ions[":CL"][":1"]
            max_len = len(ion.residues)
            ion.save(filebase + "_single_ion.pdb")
            ion = _parametrise.parametriseAndLoadPmd(
                params, filebase + "_single_ion.pdb", "water")
            _pmdwrap.saveFilesFromParmed(ions, [ions_prep_filenames[1]],
                                         combine="all")
            _pmdwrap.saveFilesFromParmed(ion, [ions_prep_filenames[0]])
            mol_dict = {}
            for line in _fileinput.input(ions_prep_filenames[0], inplace=True):
                line_new = line.split()
                if len(line_new) == 2 and line_new[0] in [
                        "WAT", "NA", "CL"
                ] and line_new[1] == "1":
                    n_mols = len(ions[":{}".format(line_new[0])].positions)
                    if line_new[0] == "WAT":
                        n_mols //= params.water_points
                    line = line.replace("1", "{}".format(n_mols))
                    mol_dict[line_new[0]] = line
                    # preserve the order of water, sodium and chloride
                    if len(mol_dict) == max_len:
                        for x in ["WAT", "NA", "CL"]:
                            if x in mol_dict.keys():
                                print(mol_dict[x], end="")
                        mol_dict = {}
                else:
                    print(line, end="")

            return complex + readfunc(ions_prep_filenames)
        else:
            complex + readfunc(waters_prep_filenames)
Example #50
0
    def add_droplet(
        self,
        topology: md.Topology,
        coordinates: unit.quantity.Quantity,
        diameter: unit.quantity.Quantity = (30.0 * unit.angstrom),
        restrain_hydrogen_bonds: bool = True,
        restrain_hydrogen_angles: bool = False,
        top_file: str = "",
    ) -> md.Trajectory:
        """
        Adding a droplet with a given diameter around a small molecule.

        Parameters
        ----------
        topology: md.Topology
            topology of the molecule
        coordinates: np.array, unit'd
        diameter: float, unit'd
        top_file: str
            if top_file is provided the final droplet pdb is either kept and can be reused or if
            top_file already exists it will be used to create the same droplet.
        Returns
        ----------
        A mdtraj.Trajectory object with the ligand centered in the solvent for inspection.
        """

        assert type(diameter) == unit.Quantity
        assert type(topology) == md.Topology
        assert type(coordinates) == unit.Quantity
        if restrain_hydrogen_bonds:
            logger.debug("Hydrogen bonds are restraint.")

        if restrain_hydrogen_angles:
            logger.warning("HOH angles are restraint.")

        # get topology from mdtraj to PDBfixer via pdb file
        radius = diameter.value_in_unit(unit.angstrom) / 2
        center = np.array([radius, radius, radius])

        # if no solvated pdb file is provided generate one
        if top_file:
            # read in the file with the defined droplet
            pdb_filepath = top_file
        else:
            # generage a one time droplet
            pdb_filepath = f"tmp{random.randint(1,10000000)}.pdb"

        if not os.path.exists(pdb_filepath):
            logger.info(f"Generating droplet for {pdb_filepath}...")

            # mdtraj works with nanomter
            md.Trajectory(coordinates.value_in_unit(unit.nanometer),
                          topology).save_pdb(pdb_filepath)
            pdb = PDBFixer(filename=pdb_filepath)
            os.remove(pdb_filepath)

            # put the ligand in the center
            l_in_nanometer = diameter.value_in_unit(unit.nanometer)
            pdb.positions = np.array(
                pdb.positions.value_in_unit(
                    unit.nanometer)) + (l_in_nanometer / 2)
            # add water
            pdb.addSolvent(boxVectors=(
                Vec3(l_in_nanometer, 0.0, 0.0),
                Vec3(0.0, l_in_nanometer, 0.0),
                Vec3(0.0, 0.0, l_in_nanometer),
            ))
            # get topology from PDBFixer to mdtraj # NOTE: a second tmpfile - not happy about this
            from simtk.openmm.app import PDBFile

            PDBFile.writeFile(pdb.topology, pdb.positions,
                              open(pdb_filepath, "w"))
            # load pdb in parmed
            logger.debug("Load with parmed ...")
            structure = pm.load_file(pdb_filepath)
            os.remove(pdb_filepath)

            # search for residues that are outside of the cutoff and delete them
            to_delete = []
            logger.debug("Flag residues ...")

            for residue in structure.residues:
                for atom in residue:
                    p1 = np.array([atom.xx, atom.xy, atom.xz])
                    p2 = center
                    squared_dist = np.sum((p1 - p2)**2, axis=0)
                    dist = np.sqrt(squared_dist)
                    if (
                            dist > radius + 1
                    ):  # NOTE: distance must be greater than radius + 1 Angstrom
                        to_delete.append(residue)

            # only delete water molecules
            for residue in list(set(to_delete)):
                if residue.name == "HOH":
                    logger.debug(f"Remove: {residue}")
                    structure.residues.remove(residue)
                else:
                    logger.warning(
                        f"Residue {residue} reaches outside the droplet")
                    print(f"Residue {residue} reaches outside the droplet")

            structure.write_pdb(pdb_filepath)

        # load pdb with mdtraj
        traj = md.load(pdb_filepath)
        if not top_file:
            os.remove(pdb_filepath)

        # set coordinates #NOTE: note the xyz[0]
        self._ligand_in_water_coordinates = traj.xyz[0] * unit.nanometer

        # generate atom string
        atom_list = []
        for atom in traj.topology.atoms:
            atom_list.append(atom.element.symbol)

        # set atom string
        self.ligand_in_water_atoms = "".join(atom_list)
        # set mdtraj topology
        self.ligand_in_water_topology = traj.topology

        # set FlattBottomRestraintToCenter on each oxygen
        self.solvent_restraints = []
        for residue in traj.topology.residues:
            if residue.is_water:
                for atom in residue.atoms:
                    if str(atom.element.symbol) == "O":
                        self.solvent_restraints.append(
                            CenterFlatBottomRestraint(
                                sigma=0.1 * unit.angstrom,
                                point=center * unit.angstrom,
                                radius=(diameter / 2),
                                atom_idx=atom.index,
                                active_at=-1,
                            ))
                        logger.debug("Adding restraint to center to {}".format(
                            atom.index))

        if restrain_hydrogen_bonds or restrain_hydrogen_angles:
            for residue in traj.topology.residues:
                if residue.is_water:
                    oxygen_idx = -1
                    hydrogen_idxs = []
                    for atom in residue.atoms:
                        if str(atom.element.symbol) == "O":
                            oxygen_idx = atom.index
                        elif str(atom.element.symbol) == "H":
                            hydrogen_idxs.append(atom.index)
                        else:
                            raise RuntimeError(
                                "Water should only consist of O and H atoms.")
                    if restrain_hydrogen_bonds:
                        self.solvent_restraints.append(
                            BondFlatBottomRestraint(
                                sigma=0.2 * unit.angstrom,
                                atom_i_idx=oxygen_idx,
                                atom_j_idx=hydrogen_idxs[0],
                                atoms=self.ligand_in_water_atoms,
                            ))
                        self.solvent_restraints.append(
                            BondFlatBottomRestraint(
                                sigma=0.2 * unit.angstrom,
                                atom_i_idx=oxygen_idx,
                                atom_j_idx=hydrogen_idxs[1],
                                atoms=self.ligand_in_water_atoms,
                            ))
                    if restrain_hydrogen_angles:
                        self.solvent_restraints.append(
                            AngleHarmonicRestraint(
                                sigma=0.1 * unit.radian,
                                atom_i_idx=hydrogen_idxs[0],
                                atom_j_idx=oxygen_idx,
                                atom_k_idx=hydrogen_idxs[1],
                            ))
        # return a mdtraj object for visual check
        return md.Trajectory(
            self._ligand_in_water_coordinates.value_in_unit(unit.nanometer),
            self.ligand_in_water_topology,
        )
Example #51
0
def runNCMC(platform_name, nstepsNC, nprop, outfname):

    #Generate the ParmEd Structure
    prmtop = utils.get_data_filename('blues', 'tests/data/eqToluene.prmtop')  #
    inpcrd = utils.get_data_filename('blues', 'tests/data/eqToluene.inpcrd')
    struct = parmed.load_file(prmtop, xyz=inpcrd)
    print('Structure: %s' % struct.topology)

    #Define some options
    opt = {
        'temperature': 300.0,
        'friction': 1,
        'dt': 0.002,
        'nIter': 100,
        'nstepsNC': nstepsNC,
        'nstepsMD': 5000,
        'nprop': nprop,
        'nonbondedMethod': 'PME',
        'nonbondedCutoff': 10,
        'constraints': 'HBonds',
        'freeze_distance': 5.0,
        'trajectory_interval': 1000,
        'reporter_interval': 1000,
        'ncmc_traj': None,
        'write_move': True,
        'platform': platform_name,
        'outfname': 't4-tol',
        'verbose': False
    }

    #Define the 'model' object we are perturbing here.
    # Calculate particle masses of object to be moved
    ligand = RandomLigandRotationMove(struct, 'LIG')
    ligand.calculateProperties()

    # Initialize object that proposes moves.
    ligand_mover = MoveEngine(ligand)

    # Generate the MD, NCMC, ALCHEMICAL Simulation objects
    simulations = SimulationFactory(struct, ligand_mover, **opt)
    simulations.createSimulationSet()

    # Add reporters to MD simulation.
    traj_reporter = openmm.app.DCDReporter(
        outfname + '-nc{}.dcd'.format(nstepsNC), opt['trajectory_interval'])
    progress_reporter = openmm.app.StateDataReporter(
        sys.stdout,
        separator="\t",
        reportInterval=opt['reporter_interval'],
        step=True,
        totalSteps=opt['nIter'] * opt['nstepsMD'],
        time=True,
        speed=True,
        progress=True,
        remainingTime=True)
    simulations.md.reporters.append(traj_reporter)
    simulations.md.reporters.append(progress_reporter)

    # Run BLUES Simulation
    blues = Simulation(simulations, ligand_mover, **opt)
    blues.run(opt['nIter'])
def openmm_simulate_amber_explicit(
    pdb_file,
    top_file=None,
    check_point=None,
    GPU_index=0,
    output_traj="output.dcd",
    output_log="output.log",
    output_cm=None,
    report_time=10 * u.picoseconds,
    sim_time=10 * u.nanoseconds,
    reeval_time=None,
):
    """
    Start and run an OpenMM NPT simulation with Langevin integrator at 2 fs 
    time step and 300 K. The cutoff distance for nonbonded interactions were 
    set at 1.0 nm, which commonly used along with Amber force field. Long-range
    nonbonded interactions were handled with PME. 

    Parameters
    ----------
    top_file : topology file (.top, .prmtop, ...)
        This is the topology file discribe all the interactions within the MD 
        system. 

    pdb_file : coordinates file (.gro, .pdb, ...)
        This is the molecule configuration file contains all the atom position
        and PBC (periodic boundary condition) box in the system. 

    GPU_index : Int or Str 
        The device # of GPU to use for running the simulation. Use Strings, '0,1'
        for example, to use more than 1 GPU

    output_traj : the trajectory file (.dcd)
        This is the file stores all the coordinates information of the MD 
        simulation results. 

    output_log : the log file (.log) 
        This file stores the MD simulation status, such as steps, time, potential
        energy, temperature, speed, etc.

    report_time : 10 ps
        The program writes its information to the output every 10 ps by default 

    sim_time : 10 ns
        The timespan of the simulation trajectory
    """

    # set up save dir for simulation results
    work_dir = os.getcwd()
    time_label = int(time.time())
    omm_path = create_md_path(time_label)
    print(f"Running simulation at {omm_path}")

    # setting up running path
    os.chdir(omm_path)

    top = pmd.load_file(top_file, xyz=pdb_file)

    system = top.createSystem(nonbondedMethod=app.PME,
                              nonbondedCutoff=1 * u.nanometer,
                              constraints=app.HBonds)
    dt = 0.002 * u.picoseconds
    integrator = omm.LangevinIntegrator(300 * u.kelvin, 1 / u.picosecond, dt)
    system.addForce(omm.MonteCarloBarostat(1 * u.bar, 300 * u.kelvin))

    try:
        platform = omm.Platform_getPlatformByName("CUDA")
        properties = {'DeviceIndex': str(GPU_index), 'CudaPrecision': 'mixed'}
    except Exception:
        platform = omm.Platform_getPlatformByName("OpenCL")
        properties = {'DeviceIndex': str(GPU_index)}

    simulation = app.Simulation(top.topology, system, integrator, platform,
                                properties)

    # simulation.context.setPositions(top.positions)
    if pdb.get_coordinates().shape[0] == 1:
        simulation.context.setPositions(pdb.positions)
        shutil.copy2(pdb_file, './')
    else:
        positions = random.choice(pdb.get_coordinates())
        simulation.context.setPositions(positions / 10)
        #parmed \AA to OpenMM nm
        pdb.write_pdb('start.pdb', coordinates=positions)

    simulation.minimizeEnergy()
    simulation.context.setVelocitiesToTemperature(300 * u.kelvin,
                                                  random.randint(1, 10000))
    simulation.step(int(100 * u.picoseconds / (2 * u.femtoseconds)))

    report_freq = int(report_time / dt)
    simulation.reporters.append(app.DCDReporter(output_traj, report_freq))
    if output_cm:
        simulation.reporters.append(ContactMapReporter(output_cm, report_freq))
    simulation.reporters.append(
        app.StateDataReporter(output_log,
                              report_freq,
                              step=True,
                              time=True,
                              speed=True,
                              potentialEnergy=True,
                              temperature=True,
                              totalEnergy=True))
    simulation.reporters.append(
        app.CheckpointReporter('checkpnt.chk', report_freq))

    if check_point:
        simulation.loadCheckpoint(check_point)
    nsteps = int(sim_time / dt)
    simulation.step(nsteps)

    if reeval_time:
        nsteps = int(reeval_time / dt)
        niter = int(sim_time / reeval_time)
        for i in range(niter):
            if os.path.exists('../halt'):
                return
            elif os.path.exists('new_pdb'):
                print("Found new.pdb, starting new sim...")

                # cleaning up old runs
                del simulation
                # starting new simulation with new pdb
                with open('new_pdb', 'r') as fp:
                    new_pdb = fp.read().split()[0]
                os.chdir(work_dir)
                openmm_simulate_amber_explicit(
                    new_pdb,
                    top_file=top_file,
                    check_point=None,
                    GPU_index=GPU_index,
                    output_traj=output_traj,
                    output_log=output_log,
                    output_cm=output_cm,
                    report_time=report_time,
                    sim_time=sim_time,
                    reeval_time=reeval_time,
                )
            else:
                simulation.step(nsteps)
    else:
        nsteps = int(sim_time / dt)
        simulation.step(nsteps)

    os.chdir(work_dir)
    if not os.path.exists('../halt'):
        openmm_simulate_amber_explicit(
            pdb_file,
            top_file=top_file,
            check_point=None,
            GPU_index=GPU_index,
            output_traj=output_traj,
            output_log=output_log,
            output_cm=output_cm,
            report_time=report_time,
            sim_time=sim_time,
            reeval_time=reeval_time,
        )
    else:
        return
Example #53
0
def structure():
    # Load the waterbox with toluene into a structure.
    prmtop = utils.get_data_filename('blues', 'tests/data/TOL-parm.prmtop')
    inpcrd = utils.get_data_filename('blues', 'tests/data/TOL-parm.inpcrd')
    structure = parmed.load_file(prmtop, xyz=inpcrd)
    return structure
Example #54
0
from parmed.exceptions import CharmmWarning, ParameterError
from parmed.openmm.utils import energy_decomposition
from parmed import unit as u, openmm, load_file, UreyBradley
from parmed.utils.six.moves import range
from copy import copy
from math import sqrt
import unittest
from utils import get_fn, TestCaseRelative, mm, app, has_openmm, CPU
import warnings

# Suppress warning output from bad psf file... sigh.
warnings.filterwarnings('ignore', category=CharmmWarning)

# System
charmm_gas = CharmmPsfFile(get_fn('ala_ala_ala.psf'))
charmm_gas_crds = load_file(get_fn('ala_ala_ala.pdb'))
charmm_nbfix = CharmmPsfFile(get_fn('ala3_solv.psf'))
charmm_nbfix_crds = CharmmCrdFile(get_fn('ala3_solv.crd'))
charmm_nbfix.box = [3.271195e1, 3.299596e1, 3.300715e1, 90, 90, 90]

# Parameter sets
param22 = CharmmParameterSet(get_fn('top_all22_prot.inp'),
                             get_fn('par_all22_prot.inp'))
param36 = CharmmParameterSet(get_fn('par_all36_prot.prm'),
                             get_fn('toppar_water_ions.str'))


@unittest.skipUnless(has_openmm, "Cannot test without OpenMM")
class TestCharmmFiles(TestCaseRelative):
    def test_gas_energy(self):
        """ Compare OpenMM and CHARMM gas phase energies """
def main(args):
    #Get the structure, topology, and trajectory files from the command line
    #ParmEd accepts a wide range of file types (Amber, GROMACS, CHARMM, OpenMM... but not LAMMPS)
    try:
        topFile = args[0]
        strucFile = args[1]
        trajFile = args[2]
    except IndexError:
        print(
            "Specify topology, structure, and trajectory files from the command line."
        )
        print(Usage)
        sys.exit(2)

    #And also allow user to specify start frame, but default to zero if no input
    try:
        startFrame = int(args[3])
    except IndexError:
        startFrame = 0

    #And get information on whether or not to use a restraint
    try:
        boolstr = args[4]
        if boolstr.lower() == 'true' or boolstr.lower() == 'yes':
            restraintBool = True
        else:
            restraintBool = False
    except IndexError:
        restraintBool = False

    print("Using topology file: %s" % topFile)
    print("Using structure file: %s" % strucFile)
    print("Using trajectory file: %s" % trajFile)

    print("\nSetting up system...")

    #Load in the files for initial simulations
    top = pmd.load_file(topFile)
    struc = pmd.load_file(strucFile)

    #Transfer unit cell information to topology object
    top.box = struc.box[:]

    #Set up some global features to use in all simulations
    temperature = 298.15 * u.kelvin

    #Define the platform (i.e. hardware and drivers) to use for running the simulation
    #This can be CUDA, OpenCL, CPU, or Reference
    #CUDA is for NVIDIA GPUs
    #OpenCL is for CPUs or GPUs, but must be used for old CPUs (not SSE4.1 compatible)
    #CPU only allows single precision (CUDA and OpenCL allow single, mixed, or double)
    #Reference is a clear, stable reference for other code development and is very slow, using double precision by default
    platform = mm.Platform.getPlatformByName('CUDA')
    prop = {  #'Threads': '1', #number of threads for CPU - all definitions must be strings (I think)
        'Precision':
        'mixed',  #for CUDA or OpenCL, select the precision (single, mixed, or double)
        'DeviceIndex':
        '0',  #selects which GPUs to use - set this to zero if using CUDA_VISIBLE_DEVICES
        'DeterministicForces':
        'True'  #Makes sure forces with CUDA and PME are deterministic
    }

    #Create the OpenMM system that can be used as a reference
    systemRef = top.createSystem(
        nonbondedMethod=app.
        PME,  #Uses PME for long-range electrostatics, simple cut-off for LJ
        nonbondedCutoff=12.0 *
        u.angstroms,  #Defines cut-off for non-bonded interactions
        rigidWater=True,  #Use rigid water molecules
        constraints=app.HBonds,  #Constrains all bonds involving hydrogens
        flexibleConstraints=
        False,  #Whether to include energies for constrained DOFs
        removeCMMotion=
        True,  #Whether or not to remove COM motion (don't want to if part of system frozen)
    )

    #Set up the integrator to use as a reference
    integratorRef = mm.LangevinIntegrator(
        temperature,  #Temperature for Langevin
        1.0 / u.picoseconds,  #Friction coefficient
        2.0 * u.femtoseconds,  #Integration timestep
    )
    integratorRef.setConstraintTolerance(1.0E-08)

    #Get solute atoms and solute heavy atoms separately
    soluteIndices = []
    heavyIndices = []
    for res in top.residues:
        if res.name not in ['OTM', 'CTM', 'STM', 'NTM', 'SOL']:
            for atom in res.atoms:
                soluteIndices.append(atom.idx)
                if 'H' not in atom.name[0]:
                    heavyIndices.append(atom.idx)

    #JUST for boric acid, add a custom bonded force
    #Couldn't find a nice, compatible force field, but did find A forcefield, so using it
    #But has no angle terms on O-B-O and instead a weird bond repulsion term
    #This term also prevents out of plane bending
    #Simple in our case because boric acid is symmetric, so only need one parameter
    #Parameters come from Otkidach and Pletnev, 2001
    #Here, Ad = (A^2) / (d^6) since Ai and Aj and di and dj are all the same
    #In the original paper, B-OH bond had A = 1.72 and d = 0.354
    #Note that d is dimensionless and A should have units of (Angstrom^3)*(kcal/mol)^(1/2)
    #These units are inferred just to make things work out with kcal/mol and the given distance dependence
    bondRepulsionFunction = 'Ad*(1.0/r)^6'
    BondRepulsionForce = mm.CustomBondForce(bondRepulsionFunction)
    BondRepulsionForce.addPerBondParameter(
        'Ad')  #Units are technically kJ/mol * nm^6
    baOxInds = []
    for aind in soluteIndices:
        if top.atoms[aind].type == 'oh':
            baOxInds.append(aind)
    for i in range(len(baOxInds)):
        for j in range(i + 1, len(baOxInds)):
            BondRepulsionForce.addBond(baOxInds[i], baOxInds[j], [0.006289686])

    systemRef.addForce(BondRepulsionForce)

    #If working with expanded ensemble simulation of solute near the interface, need to include restraint to keep close
    if restraintBool:
        #Also get surface SU atoms and surface CU atoms at top and bottom of surface
        surfIndices = []
        for atom in top.atoms:
            if atom.type == 'SU':
                surfIndices.append(atom.idx)

        print("\nSolute indices: %s" % str(soluteIndices))
        print("Solute heavy atom indices: %s" % str(heavyIndices))
        print("Surface SU atom indices: %s" % str(surfIndices))

        #Will now add a custom bonded force between heavy atoms of each solute and surface SU atoms
        #Should be in units of kJ/mol*nm^2, but should check this
        #Also, note that here we are using a flat-bottom restraint to keep close to surface
        #AND to keep from penetrating into surface when it's in the decoupled state
        refZlo = 1.4 * u.nanometer  #in nm, the distance between the SU atoms and the solute centroid
        refZhi = 1.7 * u.nanometer
        restraintExpression = '0.5*k*step(refZlo - (z2 - z1))*(((z2 - z1) - refZlo)^2)'
        restraintExpression += '+ 0.5*k*step((z2 - z1) - refZhi)*(((z2 - z1) - refZhi)^2)'
        restraintForce = mm.CustomCentroidBondForce(2, restraintExpression)
        restraintForce.addPerBondParameter('k')
        restraintForce.addPerBondParameter('refZlo')
        restraintForce.addPerBondParameter('refZhi')
        restraintForce.addGroup(surfIndices, np.ones(
            len(surfIndices)))  #Don't weight with masses
        #To assign flat-bottom restraint correctly, need to know if each solute is above or below interface
        #Will need surface z-positions for this
        suZpos = np.average(struc.coordinates[surfIndices, 2])
        restraintForce.addGroup(heavyIndices, np.ones(len(heavyIndices)))
        solZpos = np.average(struc.coordinates[heavyIndices, 2])
        if (solZpos - suZpos) > 0:
            restraintForce.addBond([0, 1], [10000.0, refZlo, refZhi])
        else:
            #A little confusing, but have to negate and switch for when z2-z1 is always going to be negative
            restraintForce.addBond([0, 1], [10000.0, -refZhi, -refZlo])
        systemRef.addForce(restraintForce)

    #And define lambda states of interest
    lambdaVec = np.array(  #electrostatic lambda - 1.0 is fully interacting, 0.0 is non-interacting
        [
            [
                1.00, 0.75, 0.50, 0.25, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
                0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00
            ],
            #LJ lambdas - 1.0 is fully interacting, 0.0 is non-interacting
            [
                1.00, 1.00, 1.00, 1.00, 1.00, 0.90, 0.80, 0.70, 0.60, 0.50,
                0.40, 0.35, 0.30, 0.25, 0.20, 0.15, 0.10, 0.05, 0.00
            ]
        ])

    #We need to add a custom non-bonded force for the solute being alchemically changed
    #Will be helpful to have handle on non-bonded force handling LJ and coulombic interactions
    NBForce = None
    for frc in systemRef.getForces():
        if (isinstance(frc, mm.NonbondedForce)):
            NBForce = frc

    #Turn off dispersion correction since have interface
    NBForce.setUseDispersionCorrection(False)

    #Separate out alchemical and regular particles using set objects
    alchemicalParticles = set(soluteIndices)
    chemicalParticles = set(range(
        systemRef.getNumParticles())) - alchemicalParticles

    #Define the soft-core function for turning on/off LJ interactions
    #In energy expressions for CustomNonbondedForce, r is a special variable and refers to the distance between particles
    #All other variables must be defined somewhere in the function.
    #The exception are variables like sigma1 and sigma2.
    #It is understood that a parameter will be added called 'sigma' and that the '1' and '2' are to specify the combining rule.
    #Have also added parameter to switch the soft-core interaction to a WCA potential
    softCoreFunctionWCA = '(step(x-0.5))*(4.0*lambdaLJ*epsilon*x*(x-1.0) + (1.0-lambdaWCA)*lambdaLJ*epsilon) '
    softCoreFunctionWCA += '+ (1.0 - step(x-0.5))*lambdaWCA*(4.0*lambdaLJ*epsilon*x*(x-1.0));'
    softCoreFunctionWCA += 'x = (1.0/reff_sterics);'
    softCoreFunctionWCA += 'reff_sterics = (0.5*(1.0-lambdaLJ) + ((r/sigma)^6));'
    softCoreFunctionWCA += 'sigma=0.5*(sigma1+sigma2); epsilon = sqrt(epsilon1*epsilon2)'
    #Define the system force for this function and its parameters
    SoftCoreForceWCA = mm.CustomNonbondedForce(softCoreFunctionWCA)
    SoftCoreForceWCA.addGlobalParameter(
        'lambdaLJ', 1.0
    )  #Throughout, should follow convention that lambdaLJ=1.0 is fully-interacting state
    SoftCoreForceWCA.addGlobalParameter(
        'lambdaWCA',
        1.0)  #When 1, attractions included; setting to 0 turns off attractions
    SoftCoreForceWCA.addPerParticleParameter('sigma')
    SoftCoreForceWCA.addPerParticleParameter('epsilon')

    #Will turn off electrostatics completely in the original non-bonded force
    #In the end-state, only want electrostatics inside the alchemical molecule
    #To do this, just turn ON a custom force as we turn OFF electrostatics in the original force
    ONE_4PI_EPS0 = 138.935456  #in kJ/mol nm/e^2
    soluteCoulFunction = '(1.0-(lambdaQ^2))*ONE_4PI_EPS0*charge/r;'
    soluteCoulFunction += 'ONE_4PI_EPS0 = %.16e;' % (ONE_4PI_EPS0)
    soluteCoulFunction += 'charge = charge1*charge2'
    SoluteCoulForce = mm.CustomNonbondedForce(soluteCoulFunction)
    #Note this lambdaQ will be different than for soft core (it's also named differently, which is CRITICAL)
    #This lambdaQ corresponds to the lambda that scales the charges to zero
    #To turn on this custom force at the same rate, need to multiply by (1.0-lambdaQ**2), which we do
    SoluteCoulForce.addGlobalParameter('lambdaQ', 1.0)
    SoluteCoulForce.addPerParticleParameter('charge')

    #Also create custom force for intramolecular alchemical LJ interactions
    #Could include with electrostatics, but nice to break up
    #We could also do this with a separate NonbondedForce object, but it would be a little more work, actually
    soluteLJFunction = '4.0*epsilon*x*(x-1.0); x = (sigma/r)^6;'
    soluteLJFunction += 'sigma=0.5*(sigma1+sigma2); epsilon=sqrt(epsilon1*epsilon2)'
    SoluteLJForce = mm.CustomNonbondedForce(soluteLJFunction)
    SoluteLJForce.addPerParticleParameter('sigma')
    SoluteLJForce.addPerParticleParameter('epsilon')

    #Loop over all particles and add to custom forces
    #As we go, will also collect full charges on the solute particles
    #AND we will set up the solute-solute interaction forces
    alchemicalCharges = [[0]] * len(soluteIndices)
    for ind in range(systemRef.getNumParticles()):
        #Get current parameters in non-bonded force
        [charge, sigma, epsilon] = NBForce.getParticleParameters(ind)
        #Make sure that sigma is not set to zero! Fine for some ways of writing LJ energy, but NOT OK for soft-core!
        if sigma / u.nanometer == 0.0:
            newsigma = 0.3 * u.nanometer  #This 0.3 is what's used by GROMACS as a default value for sc-sigma
        else:
            newsigma = sigma
        #Add the particle to the soft-core force (do for ALL particles)
        SoftCoreForceWCA.addParticle([newsigma, epsilon])
        #Also add the particle to the solute only forces
        SoluteCoulForce.addParticle([charge])
        SoluteLJForce.addParticle([sigma, epsilon])
        #If the particle is in the alchemical molecule, need to set it's LJ interactions to zero in original force
        if ind in soluteIndices:
            NBForce.setParticleParameters(ind, charge, sigma, epsilon * 0.0)
            #And keep track of full charge so we can scale it right by lambda
            alchemicalCharges[soluteIndices.index(ind)] = charge

    #Now we need to handle exceptions carefully
    for ind in range(NBForce.getNumExceptions()):
        [p1, p2, excCharge, excSig,
         excEps] = NBForce.getExceptionParameters(ind)
        #For consistency, must add exclusions where we have exceptions for custom forces
        SoftCoreForceWCA.addExclusion(p1, p2)
        SoluteCoulForce.addExclusion(p1, p2)
        SoluteLJForce.addExclusion(p1, p2)

    #Only compute interactions between the alchemical and other particles for the soft-core force
    SoftCoreForceWCA.addInteractionGroup(alchemicalParticles,
                                         chemicalParticles)

    #And only compute alchemical/alchemical interactions for other custom forces
    SoluteCoulForce.addInteractionGroup(alchemicalParticles,
                                        alchemicalParticles)
    SoluteLJForce.addInteractionGroup(alchemicalParticles, alchemicalParticles)

    #Set other soft-core parameters as needed
    SoftCoreForceWCA.setCutoffDistance(12.0 * u.angstroms)
    SoftCoreForceWCA.setNonbondedMethod(mm.CustomNonbondedForce.CutoffPeriodic)
    SoftCoreForceWCA.setUseLongRangeCorrection(False)
    systemRef.addForce(SoftCoreForceWCA)

    #Set other parameters as needed - note that for the solute force would like to set no cutoff
    #However, OpenMM won't allow a bunch of potentials with cutoffs then one without...
    #So as long as the solute is smaller than the cut-off, won't have any problems!
    SoluteCoulForce.setCutoffDistance(12.0 * u.angstroms)
    SoluteCoulForce.setNonbondedMethod(mm.CustomNonbondedForce.CutoffPeriodic)
    SoluteCoulForce.setUseLongRangeCorrection(False)
    systemRef.addForce(SoluteCoulForce)

    SoluteLJForce.setCutoffDistance(12.0 * u.angstroms)
    SoluteLJForce.setNonbondedMethod(mm.CustomNonbondedForce.CutoffPeriodic)
    SoluteLJForce.setUseLongRangeCorrection(False)
    systemRef.addForce(SoluteLJForce)

    #Need to add integrator and context in order to evaluate potential energies
    #Integrator is arbitrary because won't use it
    integrator = mm.VerletIntegrator(1.0 * u.femtoseconds)
    context = mm.Context(systemRef, integrator, platform, prop)

    ##########################################################################

    print("\nStarting analysis...")

    kBT = u.AVOGADRO_CONSTANT_NA * u.BOLTZMANN_CONSTANT_kB * temperature

    #Set up arrays to hold potential energies
    #First row will be coupled, then no electrostatics, then no electrostatics with WCA, then decoupled
    allU = np.array([[]] * 4).T

    #We've now set everything up like we're going to run a simulation
    #But now we will use pytraj to load a trajectory to get coordinates
    #With those coordinates, we will evaluate the energies we want
    #Just need to figure out if we have a surface or a bulk system
    trajFiles = glob.glob('Quad*/%s' % trajFile)
    if len(trajFiles) == 0:
        trajFiles = [trajFile]

    print("Using following trajectory files: %s" % str(trajFiles))

    for aFile in trajFiles:

        trajtop = copy.deepcopy(top)
        trajtop.rb_torsions = pmd.TrackedList(
            [])  #Necessary for SAM systems so doesn't break pytraj
        trajtop = pt.load_parmed(trajtop, traj=False)
        traj = pt.iterload(aFile, top=trajtop, frame_slice=(startFrame, -1))

        thisAllU = np.zeros((len(traj), 4))

        #Loop over the lambda states of interest, looping over whole trajectory each time
        for i, lstate in enumerate([
            [1.0, 1.0, 1.0],  #Fully coupled 
            [1.0, 1.0, 0.0],  #Charge turned off
            [1.0, 0.0,
             0.0],  #Charged turned off, attractions turned off (so WCA)
            [0.0, 1.0, 0.0]
        ]):  #Decoupled (WCA still included, though doesn't matter)

            #Set the lambda state
            context.setParameter('lambdaLJ', lstate[0])
            context.setParameter('lambdaWCA', lstate[1])
            context.setParameter('lambdaQ', lstate[2])
            for k, ind in enumerate(soluteIndices):
                [charge, sig, eps] = NBForce.getParticleParameters(ind)
                NBForce.setParticleParameters(ind,
                                              alchemicalCharges[k] * lstate[2],
                                              sig, eps)
            NBForce.updateParametersInContext(context)

            #And loop over trajectory
            for t, frame in enumerate(traj):

                thisbox = np.array(frame.box.values[:3])
                context.setPeriodicBoxVectors(
                    np.array([thisbox[0], 0.0, 0.0]) * u.angstrom,
                    np.array([0.0, thisbox[1], 0.0]) * u.angstrom,
                    np.array([0.0, 0.0, thisbox[2]]) * u.angstrom)

                thispos = np.array(frame.xyz) * u.angstrom
                context.setPositions(thispos)

                thisAllU[t, i] = context.getState(
                    getEnergy=True).getPotentialEnergy() / kBT

        #Add this trajectory information
        allU = np.vstack((allU, thisAllU))

    #And that should be it, just need to save files and print information
    #avgUq = np.average(allU[0,:] - allU[1,:])
    #stdUq = np.std(allU[0,:] - allU[1,:], ddof=1)
    #avgUlj = np.average(allU[1,:] - allU[2,:])
    #stdUlj = np.std(allU[1,:] - allU[2,:], ddof=1)

    #print("\nAverage solute-water electrostatic potential energy: %f +/- %f"%(avgUq, stdUq))
    #print("Average solute-water LJ potential energy: %f +/- %f"%(avgUlj, stdUlj))

    np.savetxt(
        'pot_energy_decomp.txt',
        allU,
        header=
        'U_coupled (kBT)    U_noQ (kBT)    U_noQ_WCA (kBT)    U_decoupled (kBT) '
    )

    #Print some meaningful information
    #Just make sure we do so as accurately as possible using alchemical information
    alchFile = glob.glob('alchemical_U*.txt')[0]
    print('Using alchemical information file: %s' % alchFile)
    printInfo(allU, mbarFile='mbar_object.pkl', alchFile=alchFile)
Example #56
0
def test_amber_single_window_gbmin(clean_files):
    # Distance restraint
    restraint = restraints.DAT_restraint()
    restraint.continuous_apr = True
    restraint.amber_index = True
    restraint.topology = os.path.join(
        os.path.dirname(__file__), "../data/k-cl/k-cl.pdb"
    )
    restraint.mask1 = ":K+"
    restraint.mask2 = ":Cl-"
    restraint.attach["target"] = 4.5
    restraint.attach["fraction_list"] = [0.00, 0.04, 0.181, 0.496, 1.000]
    restraint.attach["fc_final"] = 5.0
    restraint.pull["fc"] = restraint.attach["fc_final"]
    restraint.pull["target_initial"] = restraint.attach["target"]
    restraint.pull["target_final"] = 18.5
    restraint.pull["num_windows"] = 5
    restraint.initialize()

    windows_directory = os.path.join("tmp", "k-cl", "windows")
    window_list = create_window_list([restraint])

    for window in window_list:
        os.makedirs(os.path.join(windows_directory, window))
        with open(
                os.path.join(windows_directory, window, "restraints.in"), "a"
        ) as file:
            string = amber.amber_restraint_line(restraint, window)
            file.write(string)

    for window in window_list:
        if window[0] == "a":
            structure = pmd.load_file(
                os.path.join(os.path.dirname(__file__), "../data/k-cl/k-cl-sol.prmtop"),
                os.path.join(os.path.dirname(__file__), "../data/k-cl/k-cl-sol.rst7"),
                structure=True,
            )
            for atom in structure.atoms:
                if atom.name == "Cl-":
                    atom.xz = 2.65
            structure.save(
                os.path.join(windows_directory, window, "k-cl.prmtop"), overwrite=True
            )
            structure.save(
                os.path.join(windows_directory, window, "k-cl.rst7"), overwrite=True
            )
            structure.save(
                os.path.join(windows_directory, window, "k-cl.pdb"), overwrite=True
            )

        elif window[0] == "p":
            structure = pmd.load_file(
                os.path.join(os.path.dirname(__file__), "../data/k-cl/k-cl-sol.prmtop"),
                os.path.join(os.path.dirname(__file__), "../data/k-cl/k-cl-sol.rst7"),
                structure=True,
            )
            target_difference = (
                    restraint.phase["pull"]["targets"][int(window[1:])]
                    - restraint.phase["pull"]["targets"][0]
            )

            for atom in structure.atoms:
                if atom.name == "Cl-":
                    atom.xz += target_difference
            structure.save(
                os.path.join(windows_directory, window, "k-cl.prmtop"), overwrite=True
            )
            structure.save(
                os.path.join(windows_directory, window, "k-cl.rst7"), overwrite=True
            )
            structure.save(
                os.path.join(windows_directory, window, "k-cl.pdb"), overwrite=True
            )

    gbsim = Simulation()
    gbsim.path = os.path.join("tmp", "k-cl", "windows", "a003")
    gbsim.executable = "sander"
    gbsim.topology = "k-cl.prmtop"
    gbsim.prefix = "minimize"
    gbsim.inpcrd = "k-cl.rst7"
    gbsim.config_gb_min()
    gbsim.cntrl["maxcyc"] = 1
    gbsim.cntrl["ncyc"] = 1
    gbsim.run()

    gbsim.config_gb_md()
    gbsim.prefix = "md"
    gbsim.inpcrd = "minimize.rst7"
    gbsim.cntrl["nstlim"] = 1
    gbsim.cntrl["ntwe"] = 1
    gbsim.cntrl["ntpr"] = 1
    gbsim.cntrl["ig"] = 777
    gbsim.run()

    mden = parse_mden(os.path.join("tmp", "k-cl", "windows", "a003", "md.mden"))

    assert pytest.approx(mden["Bond"][0]) == 0
    assert pytest.approx(mden["Angle"][0]) == 0
    assert pytest.approx(mden["Dihedral"][0]) == 0
    assert pytest.approx(mden["V14"][0]) == 0
    assert pytest.approx(mden["E14"][0]) == 0

    assert pytest.approx(mden["VDW"][0], 0.1) == 25956.13225
    assert pytest.approx(mden["Ele"][0], 0.1) == -18828.99631
    assert pytest.approx(mden["Total"][0], 0.1) == 7127.13594
Example #57
0
 def test_missing_definition(self, missing_overrides_ff):
     structure = pmd.load_file(get_fn("silly_chemistry.mol2"),
                               structure=True)
     with pytest.raises(FoyerError):
         missing_overrides_ff.apply(structure)
Example #58
0
### back into the omm script is left as an exercise to the reader.
### Note: If the simulation crashes, try adjusting the integrator setings
#######################

topfile = 'compound.top'
grofile = 'npt.gro'
temp = 305 * u.kelvin
pressure = 1 * u.bar
timestep = 2.0 * u.femtoseconds
sim_time = 100 * u.nanoseconds
platform = mm.Platform.getPlatformByName('OpenCL')
properties = {'DeviceIndex': 0}
n_steps = int(round(sim_time / timestep))

print("Reading grofiles")
top = pmd.load_file(topfile, xyz=grofile)

print("Creating system from topology")
system = top.createSystem(nonbondedMethod=app.PME,
                          constraints=app.HBonds,
                          nonbondedCutoff=12.0 * u.angstroms,
                          switchDistance=10.0 * u.angstroms)
barostat = mm.MonteCarloMembraneBarostat(
    pressure, 0.0 * u.bar * u.nanometer, temp,
    mm.MonteCarloMembraneBarostat.XYIsotropic,
    mm.MonteCarloMembraneBarostat.ZFree, 100)
system.addForce(barostat)
print("Creating integrator")
integrator = mm.LangevinIntegrator(temp, 1.0 / u.picoseconds, timestep)

print("Creating Simulation")
Example #59
0
# Usage : python3 step3.py

import sys

# OpenMM Imports
import simtk.openmm as mm
import simtk.openmm.app as app

# ParmEd Imports
from parmed import load_file, unit as u
from parmed.openmm import StateDataReporter, NetCDFReporter, RestartReporter

# Load the Amber files
print('Loading AMBER files...')
inpcrdName = 'rst/step2.rst.0'
gmx_solv = load_file('complex_wat.prmtop', xyz=inpcrdName)
inpcrd = app.AmberInpcrdFile(inpcrdName)

#minimization info
minStep = 4000
minimizationTrue = False
restartSim = False

#simulation info
tempK = 10
simTime = 20
#units of picoseconds
#simType = 'npt'; pressureAtm = 1;
simType = 'nvt'  # or 'min'

#restraint
Example #60
0
    window_num = int(window[1:])

    if os.path.exists(path + window + "/openmm_prod.rst7"):
        continue

    integrator = LangevinIntegrator(
        settings["temperature"],
        settings["friction"],
        settings["timestep"],
    )

    barostat = mm.MonteCarloBarostat(1.0 * unit.bar, settings["temperature"],
                                     25)

    structure = pmd.load_file(path + window + topology,
                              path + window + coordinates,
                              structure=True)
    # Set mass of Dummy atoms to 0 so they are non-interacting
    for atom in structure.atoms:
        if atom.name == "DUM":
            atom.mass = 0

    topology_0m = "/cb6-but-dum-0m.prmtop"
    coordinates_0m = "/cb6-but-dum-0m.rst7"

    structure.save(path + window + topology_0m, overwrite=True)
    structure.save(path + window + coordinates_0m, overwrite=True)

    prmtop = app.AmberPrmtopFile(path + window + topology_0m)
    inpcrd = app.AmberInpcrdFile(path + window + "/openmm_equil.rst7")