def test_debug_ffxml(self):
     """Test that debug ffxml file is created when requested"""
     with tempfile.TemporaryDirectory() as tmpdirname:
         debug_ffxml_filename = os.path.join(tmpdirname, 'molecule.ffxml')
         cache = os.path.join(tmpdirname, 'db.json')
         # Create a generator that only knows about one molecule
         molecule = self.molecules[0]
         generator = self.TEMPLATE_GENERATOR(molecules=molecule, cache=cache)
         # Create a ForceField
         from simtk.openmm.app import ForceField
         forcefield = ForceField()
         # Register the template generator
         forcefield.registerTemplateGenerator(generator.generator)
         # Ensure no file is created
         from simtk.openmm.app import NoCutoff
         openmm_topology = molecule.to_topology().to_openmm()
         system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
         assert not os.path.exists(debug_ffxml_filename)
         # Enable debug file output creation
         forcefield = ForceField()
         forcefield.registerTemplateGenerator(generator.generator)
         generator.debug_ffxml_filename = debug_ffxml_filename
         # Ensure that an ffxml file is created
         system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
         assert os.path.exists(debug_ffxml_filename)
         # Ensure we can use that file to create a new force field
         forcefield_from_ffxml = ForceField()
         if hasattr(generator, 'gaff_xml_filename'):
             forcefield_from_ffxml.loadFile(generator.gaff_xml_filename)
         forcefield_from_ffxml.loadFile(debug_ffxml_filename)
         system2 = forcefield_from_ffxml.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
         # TODO: Test that systems are equivalent
         assert system.getNumParticles() == system2.getNumParticles()
 def test_parameterize(self):
     """Test parameterizing molecules with template generator for all supported force fields"""
     # Test all supported small molecule force fields
     for small_molecule_forcefield in self.TEMPLATE_GENERATOR.INSTALLED_FORCEFIELDS:
         print(f'Testing {small_molecule_forcefield}')
         # Create a generator that knows about a few molecules
         # TODO: Should the generator also load the appropriate force field files into the ForceField object?
         generator = self.TEMPLATE_GENERATOR(molecules=self.molecules, forcefield=small_molecule_forcefield)
         # Check that we have loaded the right force field
         assert generator.forcefield == small_molecule_forcefield
         # Create a ForceField with the appropriate small molecule force field
         from simtk.openmm.app import ForceField
         forcefield = ForceField()
         # Register the template generator
         forcefield.registerTemplateGenerator(generator.generator)
         # Parameterize some molecules
         from simtk.openmm.app import NoCutoff
         from openmmforcefields.utils import Timer
         for molecule in self.molecules:
             openmm_topology = molecule.to_topology().to_openmm()
             with Timer() as t1:
                 system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
             assert system.getNumParticles() == molecule.n_atoms
             # Molecule should now be cached
             with Timer() as t2:
                 system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
             assert system.getNumParticles() == molecule.n_atoms
             assert (t2.interval() < t1.interval())
    def test_cache(self):
        """Test template generator cache capability"""
        from simtk.openmm.app import ForceField, NoCutoff
        with tempfile.TemporaryDirectory() as tmpdirname:
            # Create a generator that also has a database cache
            cache = os.path.join(tmpdirname, 'db.json')
            generator = self.TEMPLATE_GENERATOR(molecules=self.molecules,
                                                cache=cache)
            # Create a ForceField
            forcefield = ForceField()
            # Register the template generator
            forcefield.registerTemplateGenerator(generator.generator)
            # Parameterize the molecules
            for molecule in self.molecules:
                openmm_topology = molecule.to_topology().to_openmm()
                forcefield.createSystem(openmm_topology,
                                        nonbondedMethod=NoCutoff)

            # Check database contents
            def check_cache(generator, n_expected):
                """
                Check database contains number of expected records

                Parameters
                ----------
                generator : SmallMoleculeTemplateGenerator
                    The generator whose cache should be examined
                n_expected : int
                    Number of expected records
                """
                from tinydb import TinyDB
                db = TinyDB(generator._cache)
                table = db.table(generator._database_table_name)
                db_entries = table.all()
                db.close()
                n_entries = len(db_entries)
                assert (n_entries == n_expected), \
                    "Expected {} entries but database has {}\n db contents: {}".format(n_expected, n_entries, db_entries)

            check_cache(generator, len(self.molecules))

            # Clean up, forcing closure of database
            del forcefield, generator

            # Create a generator that also uses the database cache but has no molecules
            print('Creating new generator with just cache...')
            generator = self.TEMPLATE_GENERATOR(cache=cache)
            # Check database still contains the molecules we expect
            check_cache(generator, len(self.molecules))
            # Create a ForceField
            forcefield = ForceField()
            # Register the template generator
            forcefield.registerTemplateGenerator(generator.generator)
            # Parameterize the molecules; this should succeed
            for molecule in self.molecules:
                openmm_topology = molecule.to_topology().to_openmm()
                forcefield.createSystem(openmm_topology,
                                        nonbondedMethod=NoCutoff)
Ejemplo n.º 4
0
    def _prep_sim(self, coords, external_forces=[]):

        try:
            from simtk.openmm import Platform, LangevinIntegrator, Vec3
            from simtk.openmm.app import Modeller, ForceField, \
                CutoffNonPeriodic, PME, Simulation, HBonds
            from simtk.unit import angstrom, nanometers, picosecond, \
                kelvin, Quantity, molar
        except ImportError:
            raise ImportError(
                'Please install PDBFixer and OpenMM in order to use ClustENM.')

        positions = Quantity([Vec3(*xyz) for xyz in coords], angstrom)
        modeller = Modeller(self._topology, positions)

        if self._sol == 'imp':
            forcefield = ForceField(*self._force_field)

            system = forcefield.createSystem(modeller.topology,
                                             nonbondedMethod=CutoffNonPeriodic,
                                             nonbondedCutoff=1.0 * nanometers,
                                             constraints=HBonds)

        if self._sol == 'exp':
            forcefield = ForceField(*self._force_field)

            modeller.addSolvent(forcefield,
                                padding=self._padding * nanometers,
                                ionicStrength=self._ionicStrength * molar)

            system = forcefield.createSystem(modeller.topology,
                                             nonbondedMethod=PME,
                                             nonbondedCutoff=1.0 * nanometers,
                                             constraints=HBonds)

        for force in external_forces:
            system.addForce(force)

        integrator = LangevinIntegrator(self._temp * kelvin, 1 / picosecond,
                                        0.002 * picosecond)

        # precision could be mixed, but single is okay.
        platform = self._platform if self._platform is None else Platform.getPlatformByName(
            self._platform)
        properties = None

        if self._platform is None:
            properties = {'Precision': 'single'}
        elif self._platform in ['CUDA', 'OpenCL']:
            properties = {'Precision': 'single'}

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

        simulation.context.setPositions(modeller.positions)

        return simulation
    def test_jacs_ligands(self):
        """Use template generator to parameterize the Schrodinger JACS set of ligands"""
        from simtk.openmm.app import ForceField, NoCutoff
        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']
            # Load 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)
            # Ensure this is a list
            try:
                nmolecules = len(molecules)
            except TypeError:
                molecules = [molecules]

            print(f'Read {len(molecules)} molecules from {ligand_sdf_filename}')
            #molecules = self.filter_molecules(molecules)
            MAX_MOLECULES = len(molecules)
            if 'TRAVIS' in os.environ:
                MAX_MOLECULES = 3
            molecules = molecules[:MAX_MOLECULES]
            print(f'{len(molecules)} molecules remain after filtering')

            # 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
            forcefield = ForceField()
            # Register the template generator
            forcefield.registerTemplateGenerator(generator.generator)

            # Parameterize all molecules
            print(f'Caching all molecules for {system_name} at {cache} ...')
            n_success = 0
            n_failure = 0
            for molecule in molecules:
                openmm_topology = molecule.to_topology().to_openmm()
                try:
                    forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
                    n_success += 1
                except Exception as e:
                    n_failure += 1
                    print(e)
            print(f'{n_failure}/{n_success+n_failure} ligands failed to parameterize for {system_name}')
def test_gaffResidueTemplateGenerator():
    """
    Test the GAFF residue template generator.
    """

    #
    # Test where we generate parameters for only a ligand.
    #

    # Load the PDB file.
    from simtk.openmm.app import PDBFile

    pdb_filename = utils.get_data_filename("chemicals/imatinib/imatinib.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator

    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    # Check potential is finite.
    check_potential_is_finite(system, pdb.positions)
    # Check energy matches prmtop route.
    check_energy_components_vs_prmtop(
        prmtop=utils.get_data_filename("chemicals/imatinib/imatinib.prmtop"),
        inpcrd=utils.get_data_filename("chemicals/imatinib/imatinib.inpcrd"),
        system=system,
    )

    #
    # Test where we generate parameters for only a ligand in a protein.
    #

    # Load the PDB file.
    from simtk.openmm.app import PDBFile

    pdb_filename = utils.get_data_filename("chemicals/proteins/T4-lysozyme-L99A-p-xylene-implicit.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField("amber99sb.xml", gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator

    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    # Check potential is finite.
    check_potential_is_finite(system, pdb.positions)
def test_generateResidueTemplate():
    """
    Test GAFF residue template generation from OEMol molecules.
    """
    from openeye import oechem, oeiupac

    from pkg_resources import resource_filename

    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")

    # Test independent ForceField instances.
    for molecule_name in IUPAC_molecule_names:
        mol = createOEMolFromIUPAC(molecule_name)
        # Generate an ffxml residue template.
        from openmoltools.forcefield_generators import generateResidueTemplate

        [template, ffxml] = generateResidueTemplate(mol)
        # Create a ForceField object.
        forcefield = ForceField(gaff_xml_filename)
        # Add the additional parameters and template to the forcefield.
        forcefield.registerResidueTemplate(template)
        forcefield.loadFile(StringIO(ffxml))
        # Create a Topology from the molecule.
        from openmoltools.forcefield_generators import generateTopologyFromOEMol

        topology = generateTopologyFromOEMol(mol)
        # Parameterize system.
        system = forcefield.createSystem(topology, nonbondedMethod=NoCutoff)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(mol)
        check_potential_is_finite(system, positions)

    # Test adding multiple molecules to a single ForceField instance.
    forcefield = ForceField(gaff_xml_filename)
    for molecule_name in IUPAC_molecule_names:
        mol = createOEMolFromIUPAC(molecule_name)
        # Generate an ffxml residue template.
        from openmoltools.forcefield_generators import generateResidueTemplate

        [template, ffxml] = generateResidueTemplate(mol)
        # Add the additional parameters and template to the forcefield.
        forcefield.registerResidueTemplate(template)
        forcefield.loadFile(StringIO(ffxml))
        # Create a Topology from the molecule.
        from openmoltools.forcefield_generators import generateTopologyFromOEMol

        topology = generateTopologyFromOEMol(mol)
        # Parameterize system.
        system = forcefield.createSystem(topology, nonbondedMethod=NoCutoff)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(mol)
        check_potential_is_finite(system, positions)
Ejemplo n.º 8
0
def test_xtc_reporter_append(tmpdir, get_fn):
    pdb = PDBFile(get_fn('native.pdb'))
    forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml')
    # NO PERIODIC BOUNDARY CONDITIONS
    system = forcefield.createSystem(pdb.topology,
                                     nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers,
                                     constraints=HBonds,
                                     rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds,
                                    2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)

    simulation.context.setVelocitiesToTemperature(300 * kelvin)

    tmpdir = str(tmpdir)
    xtcfile = os.path.join(tmpdir, 'traj.xtc')
    xtcfile_cp = os.path.join(tmpdir, 'traj_cp.xtc')
    checkpoint = os.path.join(tmpdir, 'checkpoint.chk')
    reporter = XTCReporter(xtcfile, 2)
    simulation.reporters.append(reporter)
    simulation.reporters.append(CheckpointReporter(checkpoint, 10))
    simulation.step(10)
    reporter.close()
    shutil.copyfile(xtcfile, xtcfile_cp)
    system = forcefield.createSystem(pdb.topology,
                                     nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers,
                                     constraints=HBonds,
                                     rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds,
                                    2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.loadCheckpoint(checkpoint)
    reporter = XTCReporter(xtcfile, 2, append=True)
    simulation.reporters.append(reporter)
    simulation.step(10)
    reporter.close()
    xtc_traj = md.load(xtcfile, top=get_fn('native.pdb'))
    xtc_traj_cp = md.load(xtcfile_cp, top=get_fn('native.pdb'))
    eq(xtc_traj.xyz[:5], xtc_traj_cp.xyz)
    eq(xtc_traj.n_frames, 10)
    eq(xtc_traj_cp.n_frames, 5)
    eq(xtc_traj.time[:5], xtc_traj_cp.time)
Ejemplo n.º 9
0
def test_gaffResidueTemplateGenerator():
    """
    Test the GAFF residue template generator.
    """

    #
    # Test where we generate parameters for only a ligand.
    #

    # Load the PDB file.
    from simtk.openmm.app import PDBFile
    pdb_filename = utils.get_data_filename("chemicals/imatinib/imatinib.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator
    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    # Check potential is finite.
    check_potential_is_finite(system, pdb.positions)
    # Check energy matches prmtop route.
    check_energy_components_vs_prmtop(
        prmtop=utils.get_data_filename('chemicals/imatinib/imatinib.prmtop'),
        inpcrd=utils.get_data_filename('chemicals/imatinib/imatinib.inpcrd'),
        system=system)

    #
    # Test where we generate parameters for only a ligand in a protein.
    #

    # Load the PDB file.
    from simtk.openmm.app import PDBFile
    pdb_filename = utils.get_data_filename(
        "chemicals/proteins/T4-lysozyme-L99A-p-xylene-implicit.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField('amber99sb.xml', gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator
    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    # Check potential is finite.
    check_potential_is_finite(system, pdb.positions)
    def test_charge(self):
        """Test that charges are nonzero after charging if the molecule does not contain user charges"""
        # Create a generator that does not know about any molecules
        generator = self.TEMPLATE_GENERATOR()
        # Create a ForceField
        from simtk.openmm.app import ForceField
        forcefield = ForceField()
        # Register the template generator
        forcefield.registerTemplateGenerator(generator.generator)

        # Check that parameterizing a molecule using user-provided charges produces expected charges
        import numpy as np
        from simtk import unit
        molecule = self.molecules[0]
        # Ensure partial charges are initially zero
        assert np.all(molecule.partial_charges / unit.elementary_charge == 0)
        # Add the molecule
        generator.add_molecules(molecule)
        # Create the System
        from simtk.openmm.app import NoCutoff
        openmm_topology = molecule.to_topology().to_openmm()
        system = forcefield.createSystem(openmm_topology,
                                         nonbondedMethod=NoCutoff)
        # Ensure charges are no longer zero
        assert not np.all(
            self.charges_from_system(system) ==
            0), "System has zero charges despite molecule not being charged"
Ejemplo n.º 11
0
def test_porin_membrane_system():
    """Test the addition of a ligand to a solvated porin"""
    # pdb file corresponding to a solvated porin
    pdb = PDBFile(
        os.path.join(os.path.dirname(__file__),
                     '../data/porin/solvated-porin.pdb'))
    modeller = app.Modeller(pdb.topology, pdb.positions)
    forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
    platform = mm.Platform.getPlatformByName('CPU')
    modeller.addHydrogens(forcefield=forcefield)
    # rigidWater False is required for ParMed to access water paramters
    system_md = forcefield.createSystem(modeller.topology,
                                        nonbondedMethod=app.PME,
                                        rigidWater=False,
                                        nonbondedCutoff=1 * unit.nanometer)
    ligand_system = PorinMembraneSystem('comp7',
                                        system_md,
                                        modeller.topology,
                                        modeller.positions,
                                        platform,
                                        tolerance=1 * unit.kilojoule /
                                        unit.mole,
                                        max_iterations=200)
    integrator = mm.LangevinIntegrator(300 * unit.kelvin,
                                       1.0 / unit.picoseconds,
                                       2 * unit.femtosecond)
    simulation = app.Simulation(ligand_system.structure.topology,
                                ligand_system.system, integrator, platform)
    simulation.context.setPositions(ligand_system.structure.positions)
    state = simulation.context.getState(getEnergy=True)
    pe = state.getPotentialEnergy()._value
    assert pe < 0.0
def test_membraneModeller():
    # pdb file containing a solvated single lipid molecule
    pdb = PDBFile('solvated-lipid.pdb')
    modeller = Modeller(pdb.topology,pdb.positions)
    modeller.modifyTopology()
    forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
    modeller.addHydrogens(forcefield=forcefield)

    system = forcefield.createSystem(modeller.topology,
                                     nonbondedMethod=app.PME,
                                     rigidWater=True,
                                     nonbondedCutoff=1*unit.nanometer)
    integrator = mm.VerletIntegrator(0.5*unit.femtoseconds)
    platform = mm.Platform.getPlatformByName('Reference')
    simulation = app.Simulation(modeller.topology, system, integrator, platform)
    simulation.context.setPositions(modeller.positions)
    simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
    # Minimize the system after adding hydrogens
    tolerance = 0.1*unit.kilojoules_per_mole/unit.angstroms
    simulation.minimizeEnergy(tolerance=tolerance,maxIterations=200)
    simulation.reporters.append(app.StateDataReporter('relax-hydrogens.log',
                                                       1000,
                                                       step=True,
                                                       potentialEnergy=True))
    simulation.step(1000)
def imatinib_timing():
    print("Loading imatinib...")
    # Load the PDB file.
    from simtk.openmm.app import PDBFile
    pdb_filename = utils.get_data_filename("chemicals/imatinib/imatinib.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator
    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    integrator = openmm.LangevinIntegrator(300 * unit.kelvin,
                                           5.0 / unit.picoseconds,
                                           1.0 * unit.femtoseconds)
    # Create Context
    context = openmm.Context(system, integrator)
    context.setPositions(pdb.positions)
    integrator.step(100)

    import time
    nsteps = 10000000
    initial_time = time.time()
    integrator.step(nsteps)
    state = context.getState().getPeriodicBoxVectors()  # force dynamics
    final_time = time.time()
    elapsed_time = final_time / initial_time
    time_per_step = elapsed_time / float(nsteps)
    print('time per force evaluation is %.3f us' % (time_per_step * 1e6))
def test_generate_ffxml_from_molecules():
    """
    Test generation of single ffxml file from a list of molecules
    """
    # Create a test set of molecules.
    molecules = [createOEMolFromIUPAC(name) for name in IUPAC_molecule_names]
    # Create an ffxml file.
    from openmoltools.forcefield_generators import generateForceFieldFromMolecules

    ffxml = generateForceFieldFromMolecules(molecules)
    # Create a ForceField.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    try:
        forcefield.loadFile(StringIO(ffxml))
    except Exception as e:
        msg = str(e)
        msg += "ffxml contents:\n"
        for (index, line) in enumerate(ffxml.split("\n")):
            msg += "line %8d : %s\n" % (index, line)
        raise Exception(msg)

    # Parameterize the molecules.
    from openmoltools.forcefield_generators import generateTopologyFromOEMol

    for molecule in molecules:
        # Create topology from molecule.
        topology = generateTopologyFromOEMol(molecule)
        # Create system with forcefield.
        system = forcefield.createSystem(topology)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(molecule)
        check_potential_is_finite(system, positions)
    def test_charge_from_molecules(self):
        """Test that user-specified partial charges are used if requested"""
        # Create a generator that does not know about any molecules
        generator = self.TEMPLATE_GENERATOR()
        # Create a ForceField
        from simtk.openmm.app import ForceField
        forcefield = ForceField()
        # Register the template generator
        forcefield.registerTemplateGenerator(generator.generator)

        # Check that parameterizing a molecule using user-provided charges produces expected charges
        import numpy as np
        from simtk import unit
        molecule = self.molecules[0]
        charges = np.random.random([molecule.n_particles])
        charges += (molecule.total_charge - charges.sum()) / molecule.n_particles
        molecule.partial_charges = unit.Quantity(charges, unit.elementary_charge)
        assert not np.all(molecule.partial_charges / unit.elementary_charge == 0)
        # Add the molecule
        generator.add_molecules(molecule)
        # Create the System
        from simtk.openmm.app import NoCutoff
        openmm_topology = molecule.to_topology().to_openmm()
        system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
        assert self.charges_are_equal(system, molecule)
def imatinib_timing():
    print("Loading imatinib...")
    # Load the PDB file.
    from simtk.openmm.app import PDBFile
    pdb_filename = utils.get_data_filename("chemicals/imatinib/imatinib.pdb")
    pdb = PDBFile(pdb_filename)
    # Create a ForceField object.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    # Add the residue template generator.
    from openmoltools.forcefield_generators import gaffTemplateGenerator
    forcefield.registerTemplateGenerator(gaffTemplateGenerator)
    # Parameterize system.
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=NoCutoff)
    integrator = openmm.LangevinIntegrator(300 * unit.kelvin, 5.0 / unit.picoseconds, 1.0 * unit.femtoseconds)
    # Create Context
    context = openmm.Context(system, integrator)
    context.setPositions(pdb.positions)
    integrator.step(100)

    import time
    nsteps = 10000000
    initial_time = time.time()
    integrator.step(nsteps)
    state = context.getState().getPeriodicBoxVectors() # force dynamics
    final_time = time.time()
    elapsed_time = final_time / initial_time
    time_per_step = elapsed_time / float(nsteps)
    print('time per force evaluation is %.3f us' % (time_per_step*1e6))
Ejemplo n.º 17
0
def test_membrane_modeller():
    """Test the addition of hydrogens to a solvated DPPC molecule"""
    # pdb file corresponding to a solvated lipid molecule
    pdb = PDBFile(os.path.join(os.path.dirname(__file__), '../data/dppc/solvated-dppc.pdb'))
    modeller = MembraneModeller(pdb.topology,pdb.positions)
    modeller.modify_topology()
    forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
    modeller.addHydrogens(forcefield=forcefield)

    system = forcefield.createSystem(modeller.topology,
                                     nonbondedMethod=app.PME,
                                     rigidWater=True,
                                     nonbondedCutoff=1*unit.nanometer)
    integrator = mm.VerletIntegrator(0.5*unit.femtoseconds)
    platform = mm.Platform.getPlatformByName('Reference')
    simulation = app.Simulation(modeller.topology, system, integrator, platform)
    simulation.context.setPositions(modeller.positions)
    simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
    # Minimize the system after adding hydrogens
    simulation.minimizeEnergy(maxIterations=200)
    # Run a few MD steps to check the system has no overlaps
    simulation.step(1000)
    state = simulation.context.getState(getEnergy=True)
    pe = state.getPotentialEnergy()._value
    assert pe < 0.0
Ejemplo n.º 18
0
def test_generate_ffxml_from_molecules():
    """
    Test generation of single ffxml file from a list of molecules
    """
    # Create a test set of molecules.
    molecules = [createOEMolFromIUPAC(name) for name in IUPAC_molecule_names]
    # Create an ffxml file.
    from openmoltools.forcefield_generators import generateForceFieldFromMolecules
    ffxml = generateForceFieldFromMolecules(molecules)
    # Create a ForceField.
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")
    forcefield = ForceField(gaff_xml_filename)
    try:
        forcefield.loadFile(StringIO(ffxml))
    except Exception as e:
        msg = str(e)
        msg += "ffxml contents:\n"
        for (index, line) in enumerate(ffxml.split('\n')):
            msg += 'line %8d : %s\n' % (index, line)
        raise Exception(msg)

    # Parameterize the molecules.
    from openmoltools.forcefield_generators import generateTopologyFromOEMol
    for molecule in molecules:
        # Create topology from molecule.
        topology = generateTopologyFromOEMol(molecule)
        # Create system with forcefield.
        system = forcefield.createSystem(topology)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(molecule)
        check_potential_is_finite(system, positions)
Ejemplo n.º 19
0
def test_generateResidueTemplate():
    """
    Test GAFF residue template generation from OEMol molecules.
    """
    from openeye import oechem, oeiupac

    from pkg_resources import resource_filename
    gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml")

    # Test independent ForceField instances.
    for molecule_name in IUPAC_molecule_names:
        mol = createOEMolFromIUPAC(molecule_name)
        # Generate an ffxml residue template.
        from openmoltools.forcefield_generators import generateResidueTemplate
        [template, ffxml] = generateResidueTemplate(mol)
        # Create a ForceField object.
        forcefield = ForceField(gaff_xml_filename)
        # Add the additional parameters and template to the forcefield.
        forcefield.registerResidueTemplate(template)
        forcefield.loadFile(StringIO(ffxml))
        # Create a Topology from the molecule.
        from openmoltools.forcefield_generators import generateTopologyFromOEMol
        topology = generateTopologyFromOEMol(mol)
        # Parameterize system.
        system = forcefield.createSystem(topology, nonbondedMethod=NoCutoff)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(mol)
        check_potential_is_finite(system, positions)

    # Test adding multiple molecules to a single ForceField instance.
    forcefield = ForceField(gaff_xml_filename)
    for molecule_name in IUPAC_molecule_names:
        mol = createOEMolFromIUPAC(molecule_name)
        # Generate an ffxml residue template.
        from openmoltools.forcefield_generators import generateResidueTemplate
        [template, ffxml] = generateResidueTemplate(mol)
        # Add the additional parameters and template to the forcefield.
        forcefield.registerResidueTemplate(template)
        forcefield.loadFile(StringIO(ffxml))
        # Create a Topology from the molecule.
        from openmoltools.forcefield_generators import generateTopologyFromOEMol
        topology = generateTopologyFromOEMol(mol)
        # Parameterize system.
        system = forcefield.createSystem(topology, nonbondedMethod=NoCutoff)
        # Check potential is finite.
        positions = extractPositionsFromOEMOL(mol)
        check_potential_is_finite(system, positions)
    def test_add_molecules(self):
        """Test that molecules can be added to template generator after its creation"""
        # Create a generator that does not know about any molecules
        generator = self.TEMPLATE_GENERATOR()
        # Create a ForceField
        from simtk.openmm.app import ForceField
        forcefield = ForceField()
        # Register the template generator
        forcefield.registerTemplateGenerator(generator.generator)

        # Check that parameterizing a molecule fails
        molecule = self.molecules[0]
        from simtk.openmm.app import NoCutoff
        try:
            # This should fail with an exception
            openmm_topology = molecule.to_topology().to_openmm()
            system = forcefield.createSystem(openmm_topology,
                                             nonbondedMethod=NoCutoff)
        except ValueError as e:
            # Exception 'No template found...' is expected
            assert str(e).startswith('No template found')

        # Now add the molecule to the generator and ensure parameterization passes
        generator.add_molecules(molecule)
        openmm_topology = molecule.to_topology().to_openmm()
        try:
            system = forcefield.createSystem(openmm_topology,
                                             nonbondedMethod=NoCutoff)
        except Exception as e:
            print(forcefield._atomTypes.keys())
            from simtk.openmm.app import PDBFile
            PDBFile.writeFile(openmm_topology, molecule.conformers[0])
            raise e
        assert system.getNumParticles() == molecule.n_atoms

        # Add multiple molecules, including repeats
        generator.add_molecules(self.molecules)

        # Ensure all molecules can be parameterized
        for molecule in self.molecules:
            openmm_topology = molecule.to_topology().to_openmm()
            system = forcefield.createSystem(openmm_topology,
                                             nonbondedMethod=NoCutoff)
            assert system.getNumParticles() == molecule.n_atoms
Ejemplo n.º 21
0
def test_xtc_reporter_append(tmpdir, get_fn):
    pdb = PDBFile(get_fn('native.pdb'))
    forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml')
    # NO PERIODIC BOUNDARY CONDITIONS
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)

    simulation.context.setVelocitiesToTemperature(300 * kelvin)

    tmpdir = str(tmpdir)
    xtcfile = os.path.join(tmpdir, 'traj.xtc')
    xtcfile_cp = os.path.join(tmpdir, 'traj_cp.xtc')
    checkpoint = os.path.join(tmpdir, 'checkpoint.chk')
    reporter = XTCReporter(xtcfile, 2)
    simulation.reporters.append(reporter)
    simulation.reporters.append(CheckpointReporter(checkpoint, 10))
    simulation.step(10)
    reporter.close()
    shutil.copyfile(xtcfile, xtcfile_cp)
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.loadCheckpoint(checkpoint)
    reporter = XTCReporter(xtcfile, 2, append=True)
    simulation.reporters.append(reporter)
    simulation.step(10)
    reporter.close()
    xtc_traj = md.load(xtcfile, top=get_fn('native.pdb'))
    xtc_traj_cp = md.load(xtcfile_cp, top=get_fn('native.pdb'))
    eq(xtc_traj.xyz[:5], xtc_traj_cp.xyz)
    eq(xtc_traj.n_frames, 10)
    eq(xtc_traj_cp.n_frames, 5)
    eq(xtc_traj.time[:5], xtc_traj_cp.time)
Ejemplo n.º 22
0
def createSystemFromIUPAC(iupac_name):
    """
    Create an openmm system out of an oemol

    Parameters
    ----------
    iupac_name : str
        IUPAC name

    Returns
    -------
    molecule : openeye.OEMol
        OEMol molecule
    system : openmm.System object
        OpenMM system
    positions : [n,3] np.array of floats
        Positions
    topology : openmm.app.Topology object
        Topology
    """
    from perses.utils.data import get_data_filename
    from perses.utils.openeye import extractPositionsFromOEMol
    # Create OEMol
    molecule = iupac_to_oemol(iupac_name)

    # Generate a topology.
    from openmoltools.forcefield_generators import generateTopologyFromOEMol
    topology = generateTopologyFromOEMol(molecule)

    # Initialize a forcefield with GAFF.
    # TODO: Fix path for `gaff.xml` since it is not yet distributed with OpenMM
    from simtk.openmm.app import ForceField
    gaff_xml_filename = get_data_filename('data/gaff.xml')
    forcefield = ForceField(gaff_xml_filename)

    # Generate template and parameters.
    from openmoltools.forcefield_generators import generateResidueTemplate
    [template, ffxml] = generateResidueTemplate(molecule)

    # Register the template.
    forcefield.registerResidueTemplate(template)

    # Add the parameters.
    forcefield.loadFile(StringIO(ffxml))

    # Create the system.
    system = forcefield.createSystem(topology, removeCMMotion=False)

    # Extract positions
    positions = extractPositionsFromOEMol(molecule)

    return (molecule, system, positions, topology)
Ejemplo n.º 23
0
def createSystemFromIUPAC(iupac_name):
    """
    Create an openmm system out of an oemol

    Parameters
    ----------
    iupac_name : str
        IUPAC name

    Returns
    -------
    molecule : openeye.OEMol
        OEMol molecule
    system : openmm.System object
        OpenMM system
    positions : [n,3] np.array of floats
        Positions
    topology : openmm.app.Topology object
        Topology
    """

    # Create OEMol
    molecule = createOEMolFromIUPAC(iupac_name)

    # Generate a topology.
    from openmoltools.forcefield_generators import generateTopologyFromOEMol
    topology = generateTopologyFromOEMol(molecule)

    # Initialize a forcefield with GAFF.
    # TODO: Fix path for `gaff.xml` since it is not yet distributed with OpenMM
    from simtk.openmm.app import ForceField
    gaff_xml_filename = get_data_filename('data/gaff.xml')
    forcefield = ForceField(gaff_xml_filename)

    # Generate template and parameters.
    from openmoltools.forcefield_generators import generateResidueTemplate
    [template, ffxml] = generateResidueTemplate(molecule)

    # Register the template.
    forcefield.registerResidueTemplate(template)

    # Add the parameters.
    forcefield.loadFile(StringIO(ffxml))

    # Create the system.
    system = forcefield.createSystem(topology)

    # Extract positions
    positions = extractPositionsFromOEMOL(molecule)

    return (molecule, system, positions, topology)
Ejemplo n.º 24
0
def calculate_fragment_energetics(frag_no=1):
    """
    * Create an OpenMM system with a fragment.
    * Calculate the energy of the system and print.
    :param frag_no: The number of the fragment being analysed (used to access files).
    """
    os.chdir(f'group2/frag{frag_no}')
    # Necessary due to size of calculation
    sys.setrecursionlimit(15000)

    pdb = PDBFile(f'QUBE_pro_frag{frag_no}.pdb')
    forcefield = ForceField(f'QUBE_pro_frag{frag_no}_plus.xml')

    system = forcefield.createSystem(
        pdb.topology,
        nonbondedMethod=NoCutoff,
    )

    system = apply_opls_combo(system)

    with open(f'QUBE_pro_frag{frag_no}_out.xml', 'w') as outfile:
        serialized_system = XmlSerializer.serialize(system)
        outfile.write(serialized_system)

    # Create the integrator to do Langevin dynamics
    integrator = LangevinIntegrator(
        298.15 * unit.kelvin,  # Temperature of heat bath
        1.0 / unit.picoseconds,  # Friction coefficient
        2.0 * unit.femtoseconds,  # Time step
    )

    platform = Platform.getPlatformByName('CPU')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)
    print('energy from openmm library')
    print(simulation.context.getState(getEnergy=True).getPotentialEnergy())

    structure = parmed.load_file(f'QUBE_pro_frag{frag_no}.pdb')
    energy_comps = parmed.openmm.energy_decomposition_system(structure, system)

    total_energy = 0.0
    for comp in energy_comps:
        total_energy += comp[1]
        print(*comp)

    print(f'Total energy {total_energy: 6.6f}')
    def test_multiple_registration(self):
        """Test registering the template generator with multiple force fields"""
        generator = self.TEMPLATE_GENERATOR(molecules=self.molecules)
        from simtk.openmm.app import ForceField
        NUM_FORCEFIELDS = 2 # number of force fields to test
        forcefields = list()
        for index in range(NUM_FORCEFIELDS):
            forcefield = ForceField()
            forcefield.registerTemplateGenerator(generator.generator)
            forcefields.append(forcefield)

        # Parameterize a molecule in each force field instance
        molecule = self.molecules[0]
        openmm_topology = molecule.to_topology().to_openmm()
        from simtk.openmm.app import NoCutoff
        for forcefield in forcefields:
            system = forcefield.createSystem(openmm_topology, nonbondedMethod=NoCutoff)
            assert system.getNumParticles() == molecule.n_atoms
Ejemplo n.º 26
0
def setup(args: ListOfArgs) -> Tuple[PDBFile, int, Simulation]:
    print("Initialization...")
    if args.SIM_RANDOM_SEED == 0:
        random_seed = np.random.randint(2147483647)
    else:
        random_seed = args.SIM_RANDOM_SEED
    print(f"   Loading initial structure: {args.INITIAL_STRUCTURE_PATH}")
    pdb = PDBFile(args.INITIAL_STRUCTURE_PATH)
    print(f"   Loading forcefield file:  {args.FORCEFIELD_PATH}")
    forcefield = ForceField(args.FORCEFIELD_PATH)
    print("   Building system...")
    system = forcefield.createSystem(pdb.topology)
    add_forces_to_system(system, args)
    integrator = get_integrator(random_seed, args)
    print("   Setting up simulation...")
    simulation = Simulation(pdb.topology, system, integrator)
    simulation.context.setPositions(pdb.positions)
    return pdb, random_seed, simulation
Ejemplo n.º 27
0
                        model='tip3p',
                        positiveIon='Na+',
                        negativeIon='Cl-',
                        ionicStrength=0 * unit.molar)
    print("Done adding solvent.")
    PDBxFile.writeFile(molecule.topology,
                       molecule.positions,
                       open(f'{pdbid}_chain{chain}.pdbx', 'w'),
                       keepIds=True)
    PDBFile.writeFile(molecule.topology,
                      molecule.positions,
                      open(f'{pdbid}_chain{chain}_solvated.pdb', 'w'),
                      keepIds=True)
    print("Done outputing pdbx and solvated pdb.")
    system = forcefield.createSystem(molecule.topology,
                                     nonbondedMethod=PME,
                                     rigidWater=True,
                                     nonbondedCutoff=1 * unit.nanometer)

    # specify the rest of the context for minimization
    integrator = mm.VerletIntegrator(0.5 * unit.femtoseconds)
    print("Done specifying integrator.")
    platform = mm.Platform.getPlatformByName('CUDA')
    print("Done specifying platform.")
    platform.setPropertyDefaultValue('Precision', 'mixed')
    print("Done setting the precision to mixed.")
    minimize = Simulation(molecule.topology, system, integrator, platform)
    print("Done specifying simulation.")
    minimize.context.setPositions(molecule.positions)
    print("Done recording a context for positions.")
    minimize.context.setVelocitiesToTemperature(310.15 * unit.kelvin)
    print("Done assigning velocities.")
Ejemplo n.º 28
0
                                2.91151942, 2.917109761, 2.922520161,
                                2.927750286, 2.932799813, 2.937668432,
                                2.942355841, 2.946861752, 2.951185887,
                                2.955327978, 2.959287772, 2.963065022,
                                2.966659496, 2.970070973, 2.973299242,
                                2.976344104, 2.979205371, 2.981882866,
                                2.984376425, 2.986685894, 2.988811129,
                                2.990752001, 2.992508389, 2.994080185,
                                2.995467292, 2.996669625, 2.997687109,
                                2.998519681, 2.999167291, 2.999629897,
                                2.999907473, 3
                            ]])

pdb = PDBFile('initial_structure.pdb')
forcefield = ForceField('polymer_ff.xml')
system = forcefield.createSystem(pdb.topology, nonbondedCutoff=1 * u.nanometer)
integrator = mm.LangevinIntegrator(100 * u.kelvin, 0.2, 1 * u.femtoseconds)

# Distance constraint
for i in range(system.getNumParticles() - 1):
    system.addConstraint(i, i + 1, 0.1 * u.nanometer)

# Pinning ends with rubber
pin_force = mm.CustomExternalForce("k*((x-x0)^2+(y-y0)^2+(z-z0)^2)")
pin_force.addGlobalParameter("k",
                             50 * u.kilocalories_per_mole / u.angstroms**2)
pin_force.addPerParticleParameter("x0")
pin_force.addPerParticleParameter("y0")
pin_force.addPerParticleParameter("z0")
pin_force.addParticle(0, [15 * u.angstrom, 0 * u.angstrom, 0 * u.angstrom])
pin_force.addParticle(system.getNumParticles() - 1,
Ejemplo n.º 29
0
def test_reporter(tmpdir, get_fn):
    pdb = PDBFile(get_fn('native.pdb'))
    forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml')
    # NO PERIODIC BOUNDARY CONDITIONS
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)

    simulation.context.setVelocitiesToTemperature(300 * kelvin)

    tmpdir = str(tmpdir)
    hdf5file = os.path.join(tmpdir, 'traj.h5')
    ncfile = os.path.join(tmpdir, 'traj.nc')
    dcdfile = os.path.join(tmpdir, 'traj.dcd')
    xtcfile = os.path.join(tmpdir, 'traj.xtc')

    reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True,
                            cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True,
                            velocities=True)
    reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True)
    reporter3 = DCDReporter(dcdfile, 2)
    reporter4 = XTCReporter(xtcfile, 2)

    simulation.reporters.append(reporter)
    simulation.reporters.append(reporter2)
    simulation.reporters.append(reporter3)
    simulation.reporters.append(reporter4)
    simulation.step(100)

    reporter.close()
    reporter2.close()
    reporter3.close()
    reporter4.close()

    with HDF5TrajectoryFile(hdf5file) as f:
        got = f.read()
        eq(got.temperature.shape, (50,))
        eq(got.potentialEnergy.shape, (50,))
        eq(got.kineticEnergy.shape, (50,))
        eq(got.coordinates.shape, (50, 22, 3))
        eq(got.velocities.shape, (50, 22, 3))
        eq(got.cell_lengths, None)
        eq(got.cell_angles, None)
        eq(got.time, 0.002 * 2 * (1 + np.arange(50)))
        assert f.topology == md.load(get_fn('native.pdb')).top

    with NetCDFTrajectoryFile(ncfile) as f:
        xyz, time, cell_lengths, cell_angles = f.read()
        eq(cell_lengths, None)
        eq(cell_angles, None)
        eq(time, 0.002 * 2 * (1 + np.arange(50)))

    hdf5_traj = md.load(hdf5file)
    dcd_traj = md.load(dcdfile, top=get_fn('native.pdb'))
    netcdf_traj = md.load(ncfile, top=get_fn('native.pdb'))
    xtc_traj = md.load(xtcfile, top=get_fn('native.pdb'))

    # we don't have to convert units here, because md.load already
    # handles that
    assert hdf5_traj.unitcell_vectors is None
    eq(hdf5_traj.xyz, netcdf_traj.xyz)
    eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors)
    eq(hdf5_traj.time, netcdf_traj.time)
    eq(xtc_traj.time, netcdf_traj.time)

    eq(dcd_traj.xyz, hdf5_traj.xyz)
    eq(xtc_traj.xyz, dcd_traj.xyz, decimal=3)
def main(argdict):
    """ Main function for entry point checking.

    Expects a dictionary of command line arguments.
    """

    # load configuration from logfile:
    with open(argdict["log"], 'r') as f:
        argdict = json.load(f)

    # load system initial configuration:
    pdb = pdb_file_nonstandard_bonds(argdict["pdb"])
    print("--> input topology: ", end="")
    print(pdb.topology)

    # physical parameters of simulation:
    sim_temperature = argdict["temperature"] * kelvin
    sim_andersen_coupling = 1 / picosecond
    sim_pressure = (
        (argdict["pressure"], argdict["pressure"], argdict["pressure"]) * bar)
    sim_scale_x = True
    sim_scale_y = True
    sim_scale_z = True

    # simulation control parameters:
    sim_timestep = argdict["timestep"] * femtoseconds

    # restraints parameters:
    sim_restr_fc = argdict["restr_fc"] * kilojoule_per_mole / nanometer**2

    # create force field object:
    ff = ForceField(*argdict["ff"])

    # build a simulation system from topology and force field:
    # (note that AMOEBA is intended to be run without constraints)
    # (note that mutualInducedtargetEpsilon defaults to 0.01 unlike what is
    # specified in the documentation which claims 0.00001)
    system = ff.createSystem(
        pdb.topology,
        nonbondedMethod=PME,
        nonbondedCutoff=argdict["nonbonded_cutoff"] * nanometer,
        vdwCutoff=argdict["vdw_cutoff"] * nanometer,
        ewaldErrorTolerance=argdict["ewald_error_tolerance"],
        polarisation=argdict["polarisation"],
        mutualInducedTargetEpsilon=argdict["mutual_induced_target_epsilon"],
        constraints=None,
        rigidWater=False,
        removeCMMotion=True  # removes centre of mass motion
    )

    # overwrite the polarisation method set at system creation; this is
    # necessary as openMM always sets polarisation method to "mutual" of the
    # target epsilon is specified at system creation; this way, target epsilon
    # is ignored for all but the mutual method
    multipole_force = [
        f for f in system.getForces() if isinstance(f, AmoebaMultipoleForce)
    ][0]
    print("--> using polarisation method " + str(argdict["polarisation"]))
    if argdict["polarisation"] == "mutual":
        multipole_force.setPolarizationType(multipole_force.Mutual)
    if argdict["polarisation"] == "extrapolated":
        multipole_force.setPolarizationType(multipole_force.Extrapolated)
    if argdict["polarisation"] == "direct":
        multipole_force.setPolarizationType(multipole_force.Direct)

    # will use Andersen thermostat here:
    # (Inhibits particle dynamics somewhat, but little or no ergodicity
    # issues (from Gromacs documenation). However, only alternative is full
    #  Langevin dynamics, which is even worse wrt dynamics. Bussi/v-rescale is
    # not available at the moment, it seems (it is available in tinker, but
    # without GPU acceleration))
    system.addForce(AndersenThermostat(sim_temperature, sim_andersen_coupling))

    # use anisotropic barostat:
    # (note that this corresponds to semiisotropic pressure coupling in Gromacs
    # if the pressure is identical for the x- and y/axes)
    # (note that by default this attempts an update every 25 steps)
    system.addForce(
        MonteCarloAnisotropicBarostat(sim_pressure, sim_temperature,
                                      sim_scale_x, sim_scale_y, sim_scale_z))

    # prepare harmonic restraining potential:
    # (note that periodic distance is absolutely necessary here to prevent
    # system from blowing up, as otherwise periodic image position may be used
    # resulting in arbitrarily large forces)
    force = CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2")
    force.addGlobalParameter("k", sim_restr_fc)
    force.addPerParticleParameter("x0")
    force.addPerParticleParameter("y0")
    force.addPerParticleParameter("z0")

    # apply harmonic restraints to C-alphas:
    if argdict["restr"] == "capr":
        print("--> applying harmonic positional restraints to CA atoms")
        for atm in pdb.topology.atoms():
            if atm.name == "CA":
                force.addParticle(atm.index, pdb.positions[atm.index])
    elif argdict["restr"] == "hapr":
        sys.exit("Restraints mode " + str(argdict["restr"]) +
                 "is not implemented.")
    elif argdict["restr"] == "none":
        print("--> applying no harmonic positional restraints to any atom")
    else:
        sys.exit("Restraints mode " + str(argdict["restr"]) +
                 "is not implemented.")

    # add restraining force to system:
    system.addForce(force)

    # make special group for nonbonded forces:
    for f in system.getForces():
        if (isinstance(f, AmoebaMultipoleForce)
                or isinstance(f, AmoebaVdwForce)
                or isinstance(f, AmoebaGeneralizedKirkwoodForce)
                or isinstance(f, AmoebaWcaDispersionForce)):
            f.setForceGroup(1)

    # select integrator:
    if argdict["integrator"] == "mts":
        # use multiple timestep RESPA integrator:
        print("--> using RESPA/MTS integrator")
        integrator = MTSIntegrator(sim_timestep,
                                   [(0, argdict["inner_ts_frac"]), (1, 1)])
    if argdict["integrator"] == "verlet":
        # use Leapfrog Verlet integrator here:
        print("--> using Verlet integrator")
        integrator = VerletIntegrator(sim_timestep)

    # select a platform (should be CUDA, otherwise VERY slow):
    platform = Platform.getPlatformByName(argdict["platform"])
    properties = {
        "CudaPrecision": argdict["precision"],
        "CudaDeviceIndex": "0"
    }

    # create simulation system:
    sim = Simulation(pdb.topology, system, integrator, platform, properties)

    # unit conversion factors:
    ang2nm = 0.1

    # create MDA universe:
    u = mda.Universe(args.s, args.f)

    # selection for overall system will be needed to set OpenMM positions
    # accordingt to trajectory:
    allsystem = u.select_atoms("all")

    # get parameters to define cylinder around protein center of geometry:
    # (the cylinder spans the entire box in the z-direction)
    protein = u.select_atoms("protein")
    radius = str(args.r)
    z_margin = args.z_margin
    z_min = str(protein.bbox()[0, 2] - protein.center_of_geometry()[2] -
                z_margin)
    z_max = str(protein.bbox()[1, 2] - protein.center_of_geometry()[2] +
                z_margin)

    # select all solvent atoms, note that AMOEBA residue name is HOH:
    # (these must be updating, as water may move in and out of pore!)
    solvent = u.select_atoms("byres (resname HOH SOL) and cyzone " + radius +
                             " " + z_max + " " + z_min + " protein",
                             updating=True)
    solvent_ow = solvent.select_atoms("name O OW", updating=True)

    # lambda function for converting atomic dipoles to molecular dipoles:
    # (this only works on 1D arrays, hence use apply_along_axis if quantity is
    # vector-valued, e.g. positions and dipoles)
    def atomic2molecular_sum(arr):
        return np.bincount(allsystem.resindices, arr)

    def atomic2molecular_avg(arr):
        return np.bincount(allsystem.resindices, arr) / np.bincount(
            allsystem.resindices)

    # create lambda function for obtaining charges in vectorisable way:
    # (units are elementary_charge)
    get_atomic_charges = np.vectorize(
        lambda index: multipole_force.getMultipoleParameters(int(index))[
            0].value_in_unit(elementary_charge))

    # obtain atomic charges:
    # (charges are static, so need this only once; units are elementary charge)
    atomic_charges = get_atomic_charges(allsystem.ix)

    # obtain start and end time as will as time step:
    dt = float(args.dt)
    t_start = float(args.b)
    t_end = float(args.e)

    # prepare results dictionary:
    res = {
        "t": [],
        "x": [],
        "y": [],
        "z": [],
        "indu_rho": [],
        "indu_costheta": [],
        "indu_cosphi": [],
        "perm_rho": [],
        "perm_costheta": [],
        "perm_cosphi": [],
        "mono_rho": [],
        "mono_costheta": [],
        "mono_cosphi": [],
        "total_rho": [],
        "total_costheta": [],
        "total_cosphi": []
    }

    # loop over trajectory:
    for ts in u.trajectory:

        # skip all frames before starting frame:
        if ts.time < t_start:
            continue

        # only analyse relevant time frames:
        if round(ts.time, 4) % dt == 0:

            # inform user:
            print("analysing frame: " + str(ts.frame) + " at time: " +
                  str(ts.time))
            print("number of selected solvent molecules in this frame: " +
                  str(solvent.n_residues))

            # convert mda positions to OpenMM positions and set context:
            omm_positions = Quantity(
                [tuple(pos) for pos in list(allsystem.positions)],
                unit=angstrom)
            sim.context.setPositions(omm_positions)

            # calculate molecular positions (or molecular centre of geometry) by
            # averaging over all atomic positions within a residue:
            # (units are Angstrom in MDAnalysis!)
            molecular_positions = np.apply_along_axis(
                atomic2molecular_avg, 0, allsystem.positions) * ang2nm

            # calculate charge-weighted positions by multiplying the relative
            # atomic positions with the atomic charges (relative positions are
            # necessary to account for charged residues/molecules, where the
            # dipole moment is calculated relative to the center of geometry of
            # the residue):
            # (units are elementary charge * nanometer)
            atomic_charge_weighted_positions = (
                allsystem.positions -
                molecular_positions[allsystem.resindices])
            atomic_charge_weighted_positions *= (atomic_charges[np.newaxis].T *
                                                 ang2nm)

            # obtain induced and permanent atomic dipoles from OpenMM:
            # (units are elementary charge * nm)
            atomic_dipoles_indu = np.array(
                multipole_force.getInducedDipoles(sim.context))
            atomic_dipoles_perm = np.array(
                multipole_force.getLabFramePermanentDipoles(sim.context))

            # convert atomic to molecular quantities and calculate total dipole:
            molecular_dipoles_indu = np.apply_along_axis(
                atomic2molecular_sum, 0, atomic_dipoles_indu)
            molecular_dipoles_perm = np.apply_along_axis(
                atomic2molecular_sum, 0, atomic_dipoles_perm)
            molecular_dipoles_mono = np.apply_along_axis(
                atomic2molecular_sum, 0, atomic_charge_weighted_positions)
            molecular_dipoles_total = (molecular_dipoles_indu +
                                       molecular_dipoles_perm +
                                       molecular_dipoles_mono)

            # convert to spherical coordinates:
            molecular_dipoles_indu = cartesian2spherical(
                molecular_dipoles_indu)
            molecular_dipoles_perm = cartesian2spherical(
                molecular_dipoles_perm)
            molecular_dipoles_mono = cartesian2spherical(
                molecular_dipoles_mono)
            molecular_dipoles_total = cartesian2spherical(
                molecular_dipoles_total)

            # insert into results dictionary:
            res["t"].append(np.repeat(ts.time, solvent.n_residues))
            res["x"].append(molecular_positions[solvent_ow.resindices, 0])
            res["y"].append(molecular_positions[solvent_ow.resindices, 1])
            res["z"].append(molecular_positions[solvent_ow.resindices, 2])
            res["indu_rho"].append(
                molecular_dipoles_indu[solvent_ow.resindices, 0])
            res["indu_costheta"].append(
                molecular_dipoles_indu[solvent_ow.resindices, 1])
            res["indu_cosphi"].append(
                molecular_dipoles_indu[solvent_ow.resindices, 2])
            res["perm_rho"].append(
                molecular_dipoles_perm[solvent_ow.resindices, 0])
            res["perm_costheta"].append(
                molecular_dipoles_perm[solvent_ow.resindices, 1])
            res["perm_cosphi"].append(
                molecular_dipoles_perm[solvent_ow.resindices, 2])
            res["mono_rho"].append(
                molecular_dipoles_mono[solvent_ow.resindices, 0])
            res["mono_costheta"].append(
                molecular_dipoles_mono[solvent_ow.resindices, 1])
            res["mono_cosphi"].append(
                molecular_dipoles_mono[solvent_ow.resindices, 2])
            res["total_rho"].append(
                molecular_dipoles_total[solvent_ow.resindices, 0])
            res["total_costheta"].append(
                molecular_dipoles_total[solvent_ow.resindices, 1])
            res["total_cosphi"].append(
                molecular_dipoles_total[solvent_ow.resindices, 2])

        # stop iterating through trajectory after end time:
        if ts.time > t_end:
            break

    # convert lists of arrays to arrays:
    for k in res.keys():
        res[k] = np.concatenate(res[k])

    # convert units of dipole magnitude to Debye:
    eNm2debye = 48.03205
    res["indu_rho"] = eNm2debye * res["indu_rho"]
    res["perm_rho"] = eNm2debye * res["perm_rho"]
    res["mono_rho"] = eNm2debye * res["mono_rho"]
    res["total_rho"] = eNm2debye * res["total_rho"]

    # load spline curve data:
    with open(args.j, "r") as f:
        chap_data = json.load(f)

    # create spline curve from CHAP data:
    spline_curve = BSplineCurve(chap_data)

    # calculate s-coordinate from z-coordinate:
    res["s"] = spline_curve.z2s(res["z"])

    # convert results to data frame:
    df_res = pd.DataFrame(res)

    # loop over various numbers of bins:
    df = []
    for nbins in args.nbins:

        # create a temporary data frame:
        tmp = df_res

        # drop positional coordinates:
        tmp = tmp.drop(["x", "y", "z", "t"], axis=1)

        # bin by value of s-coordinate:
        tmp = tmp.groupby(pd.cut(tmp.s, nbins))

        # aggregate variables:
        tmp = tmp.agg([np.mean, np.std, sem, np.size, np.median, qlo,
                       qhi]).reset_index()

        # rename columns (combines variable name with aggregation method):
        tmp.columns = ["_".join(x) for x in tmp.columns.ravel()]

        # remove grouping key:
        tmp = tmp.drop("s_", axis=1)

        # add column wit number of bins:
        tmp["nbins"] = nbins

        # append to list of data frames:
        df.append(tmp)

    # combine list of data frames into single data frame:
    df = pd.concat(df)

    # write to JSON file:
    df.to_json(args.o, orient="records")

    # need to add newline for POSIX compliance:
    with open(args.o, "a") as f:
        f.write("\n")
Ejemplo n.º 31
0
class MoleculeUtil(object):
    """
    A class for managing a molecule defined by a PDB file
    """
    np.random.seed(20)

    def __init__(self, pdb_path, offset_size=2):
        # OpenMM init
        self.pdb_path = pdb_path
        self.pdb = PDBFile(self.pdb_path)
        self.forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
        self.modeller = Modeller(self.pdb.topology, self.pdb.positions)

        # Remove any water that might be present in the PDB file
        self.modeller.deleteWater()

        # Add any hydrogens not present
        self.modeller.addHydrogens(self.forcefield)
        self.system = self.forcefield.createSystem(self.modeller.topology,
                                                   nonbondedMethod=PME,
                                                   nonbondedCutoff=1 *
                                                   u.nanometer,
                                                   constraints=HBonds)
        self.integrator = LangevinIntegrator(300 * u.kelvin, 1 / u.picosecond,
                                             0.002 * u.picoseconds)
        self.simulation = Simulation(self.modeller.topology, self.system,
                                     self.integrator)
        self.pdb_positions = self.modeller.getPositions()

        # Initialize bond dictionary and positions for chemcoord
        self.cc_bonds = {}
        self.offset_size = offset_size
        self._init_pdb_bonds()
        self.set_cc_positions(self.pdb_positions)

        # Perform initial minimization, which updates self.pdb_positions
        min_energy, min_positions = self.run_simulation()

        # Reset the positions after the minimization
        self.set_cc_positions(self.pdb_positions)
        self.torsion_indices = self._get_torsion_indices()
        self.starting_positions = min_positions
        self.starting_torsions = np.array([
            self.zmat.loc[self.torsion_indices[:, 0], 'dihedral'],
            self.zmat.loc[self.torsion_indices[:, 1], 'dihedral']
        ]).T
        self.seed_offsets()

    def _add_backbone_restraint(self):
        # https://github.com/ParmEd/ParmEd/wiki/OpenMM-Tricks-and-Recipes#positional-restraints
        positions = self.modeller.getPositions()
        force = CustomExternalForce('k*((x-x0)^2+(y-y0)^2+(z-z0)^2)')
        force.addGlobalParameter(
            'k', 5.0 * u.kilocalories_per_mole / u.angstroms**2)
        force.addPerParticleParameter('x0')
        force.addPerParticleParameter('y0')
        force.addPerParticleParameter('z0')

        for index, atom in enumerate(self.modeller.topology.atoms()):
            if atom.name in ('CA', 'C', 'N'):
                coord = positions[index]
                force.addParticle(index, coord.value_in_unit(u.nanometers))

        self.restraint_force_id = self.system.addForce(force)

    def _remove_backbone_restraint(self):
        self.system.removeForce(self.restraint_force_id)

    def _fix_backbone(self):
        for index, atom in enumerate(self.modeller.topology.atoms()):
            if atom.name in ('CA', 'C', 'N'):
                self.system.setParticleMass(index, 0)

    def seed_offsets(self):
        self.offsets = np.random.choice([0, 0, -1, 1],
                                        self.starting_torsions.shape)

    def get_torsions(self):
        return np.array([
            self.zmat.loc[self.torsion_indices[:, 0], 'dihedral'],
            self.zmat.loc[self.torsion_indices[:, 1], 'dihedral']
        ]).T

    def set_torsions(self, new_torsions):
        self.zmat.safe_loc[self.torsion_indices[:, 0],
                           'dihedral'] = new_torsions[:, 0]
        self.zmat.safe_loc[self.torsion_indices[:, 1],
                           'dihedral'] = new_torsions[:, 1]

    def get_offset_torsions(self, scale_factor):
        """
        Calculates and returns new torsion angles based on randomly generated
        offsets.

        Args:
            scale_factor: the relative scale of the offset relative to
                          self.offset_size
        Returns:
            The new torsion angles
        """
        total_offset = self.offset_size * scale_factor
        new_torsions = np.zeros(shape=self.starting_torsions.shape)
        new_torsions[:, 0] = self.starting_torsions[:, 0] + \
            (self.offsets[:, 0] * total_offset)
        new_torsions[:, 1] = self.starting_torsions[:, 1] + \
            (self.offsets[:, 1] * total_offset)
        return new_torsions

    def run_simulation(self):
        """
        Run a simulation to calculate the current configuration's energy level.
        Note that the atoms will likely move somewhat during the calculation,
        since energy minimization is used.

        Returns:
            A tuple of the form (potential_energy, updated_positions)
        """
        # Delete solvent that's based on previous positions
        cartesian = self.zmat.get_cartesian().sort_index()
        self.simulation.context.setPositions([
            Vec3(x, y, z)
            for x, y, z in zip(cartesian['x'], cartesian['y'], cartesian['z'])
        ])

        # self._add_backbone_restraint()
        # self._fix_backbone()

        self.modeller.addSolvent(self.forcefield, padding=1.0 * u.nanometer)
        self.simulation.minimizeEnergy(maxIterations=200)
        state = self.simulation.context.getState(getEnergy=True,
                                                 getPositions=True)
        p_energy = state.getPotentialEnergy()
        positions = state.getPositions(asNumpy=True)

        # Clean up - remove solvent and backbone restraint (for next iteration)
        self.modeller.deleteWater()

        # self._remove_backbone_restraint()

        return p_energy, positions

    def _init_pdb_bonds(self):
        """Construct a dictionary describing the PDB's bonds for chemcoord use"""
        for index in range(self.modeller.topology.getNumAtoms()):
            self.cc_bonds[index] = set()

        for bond in self.modeller.topology.bonds():
            self.cc_bonds[bond[0].index].add(bond[1].index)
            self.cc_bonds[bond[1].index].add(bond[0].index)

    def set_cc_positions(self, positions):
        """
        Calculates the zmat from an OpenMM modeller

        Args:
            positions (list): A list 
        """
        cc_df = self._get_cartesian_df(positions)
        self.cartesian = cc.Cartesian(cc_df)
        self.cartesian.set_bonds(self.cc_bonds)
        self.cartesian._give_val_sorted_bond_dict(use_lookup=True)
        self.zmat = self.cartesian.get_zmat(use_lookup=True)

    def _get_cartesian_df(self, positions):
        cc_positions = np.zeros((3, self.modeller.topology.getNumAtoms()))
        atom_names = []
        for index, atom in enumerate(self.modeller.topology.atoms()):
            pos = positions[index] / u.nanometer
            atom_names.append(atom.name)
            cc_positions[:, index] = pos

        cc_df = pd.DataFrame({
            'atom': atom_names,
            'x': cc_positions[0, :],
            'y': cc_positions[1, :],
            'z': cc_positions[2, :]
        })
        return cc_df

    def _get_torsion_indices(self):
        """
        Calculates indices into the zmatrix which correspond to phi
        and psi angles.

        Args:
            zmat: the zmatrix specifying the molecule
        Returns:
            a numpy.array, with first column as phi_indices, second column
            as psi_indices
        """
        phi_indices = []
        psi_indices = []

        for i in range(len(self.zmat.index)):
            b_index = self.zmat.loc[i, 'b']
            a_index = self.zmat.loc[i, 'a']
            d_index = self.zmat.loc[i, 'd']

            # If this molecule references a magic string (origin, e_x, e_y, e_z, etc)
            if isinstance(b_index, str) or isinstance(
                    a_index, str) or isinstance(d_index, str):
                continue

            # Psi angles
            if (self.zmat.loc[i, 'atom'] == 'N') & \
                    (self.zmat.loc[b_index, 'atom'] == 'CA') & \
                    (self.zmat.loc[a_index, 'atom'] == 'C') & \
                    (self.zmat.loc[d_index, 'atom'] == 'N'):
                psi_indices.append(i)

            elif (self.zmat.loc[i, 'atom'] == 'N') & \
                    (self.zmat.loc[b_index, 'atom'] == 'C') & \
                    (self.zmat.loc[a_index, 'atom'] == 'CA') & \
                    (self.zmat.loc[d_index, 'atom'] == 'N'):
                psi_indices.append(i)

            elif (self.zmat.loc[i, 'atom'] == 'C') & \
                    (self.zmat.loc[b_index, 'atom'] == 'N') & \
                    (self.zmat.loc[a_index, 'atom'] == 'CA') & \
                    (self.zmat.loc[d_index, 'atom'] == 'C'):
                phi_indices.append(i)

            elif (self.zmat.loc[i, 'atom'] == 'C') & \
                    (self.zmat.loc[b_index, 'atom'] == 'CA') & \
                    (self.zmat.loc[a_index, 'atom'] == 'N') & \
                    (self.zmat.loc[d_index, 'atom'] == 'C'):
                phi_indices.append(i)

        return np.array([phi_indices, psi_indices]).T
Ejemplo n.º 32
0
def test_reporter_subset(tmpdir, get_fn):
    pdb = PDBFile(get_fn('native2.pdb'))
    pdb.topology.setUnitCellDimensions([2, 2, 2])
    forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml')
    system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffPeriodic,
                                     nonbondedCutoff=1 * nanometers, constraints=HBonds, rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)

    simulation.context.setVelocitiesToTemperature(300 * kelvin)

    tmpdir = str(tmpdir)
    hdf5file = os.path.join(tmpdir, 'traj.h5')
    ncfile = os.path.join(tmpdir, 'traj.nc')
    dcdfile = os.path.join(tmpdir, 'traj.dcd')
    xtcfile = os.path.join(tmpdir, 'traj.xtc')

    atomSubset = [0, 1, 2, 4, 5]

    reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True,
                            cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True,
                            velocities=True, atomSubset=atomSubset)
    reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True,
                               cell=True, atomSubset=atomSubset)
    reporter3 = DCDReporter(dcdfile, 2, atomSubset=atomSubset)
    reporter4 = XTCReporter(xtcfile, 2, atomSubset=atomSubset)

    simulation.reporters.append(reporter)
    simulation.reporters.append(reporter2)
    simulation.reporters.append(reporter3)
    simulation.reporters.append(reporter4)
    simulation.step(100)

    reporter.close()
    reporter2.close()
    reporter3.close()
    reporter4.close()

    t = md.load(get_fn('native.pdb'))
    t.restrict_atoms(atomSubset)

    with HDF5TrajectoryFile(hdf5file) as f:
        got = f.read()
        eq(got.temperature.shape, (50,))
        eq(got.potentialEnergy.shape, (50,))
        eq(got.kineticEnergy.shape, (50,))
        eq(got.coordinates.shape, (50, len(atomSubset), 3))
        eq(got.velocities.shape, (50, len(atomSubset), 3))
        eq(got.cell_lengths, 2 * np.ones((50, 3)))
        eq(got.cell_angles, 90 * np.ones((50, 3)))
        eq(got.time, 0.002 * 2 * (1 + np.arange(50)))
        assert f.topology == md.load(get_fn('native.pdb'), atom_indices=atomSubset).topology

    with NetCDFTrajectoryFile(ncfile) as f:
        xyz, time, cell_lengths, cell_angles = f.read()
        eq(cell_lengths, 20 * np.ones((50, 3)))
        eq(cell_angles, 90 * np.ones((50, 3)))
        eq(time, 0.002 * 2 * (1 + np.arange(50)))
        eq(xyz.shape, (50, len(atomSubset), 3))

    hdf5_traj = md.load(hdf5file)
    dcd_traj = md.load(dcdfile, top=hdf5_traj)
    netcdf_traj = md.load(ncfile, top=hdf5_traj)
    xtc_traj = md.load(xtcfile, top=hdf5_traj)

    # we don't have to convert units here, because md.load already handles that
    eq(hdf5_traj.xyz, netcdf_traj.xyz)
    eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors)
    eq(hdf5_traj.time, netcdf_traj.time)
    eq(xtc_traj.time, netcdf_traj.time)

    eq(dcd_traj.xyz, hdf5_traj.xyz)
    eq(xtc_traj.xyz, hdf5_traj.xyz)
    eq(dcd_traj.unitcell_vectors, hdf5_traj.unitcell_vectors)
Ejemplo n.º 33
0
logging.root.setLevel(logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
yank.utils.config_root_logger(verbose=True, log_file_path=None)

# File from MemProt Data Base
pdb = PDBFile('atomistic-system.pdb')

modeller = Modeller(pdb.topology, pdb.positions)
modeller.changeAtomNames()
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
modeller.addHydrogens(forcefield=forcefield)
PDBxFile.writeFile(modeller.topology, modeller.positions,
                   open("atomistic-system-with-hydrogens.pdbx", 'w'))

system = forcefield.createSystem(modeller.topology,
                                 nonbondedMethod=app.PME,
                                 rigidWater=True,
                                 nonbondedCutoff=1 * unit.nanometer)
integrator = mm.VerletIntegrator(0.5 * unit.femtoseconds)
platform = mm.Platform.getPlatformByName('CUDA')
simulation = app.Simulation(modeller.topology, system, integrator, platform)
simulation.context.setPositions(modeller.positions)
simulation.context.setVelocitiesToTemperature(300 * unit.kelvin)
# Minimize the system after adding hydrogens to the membrane
tolerance = 0.1 * unit.kilojoules_per_mole / unit.angstroms
simulation.minimizeEnergy(tolerance=tolerance, maxIterations=0)
simulation.reporters.append(
    app.StateDataReporter('relax-hydrogens.log',
                          1000,
                          step=True,
                          temperature=True,
                          potentialEnergy=True,
    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
            if 'TRAVIS' in os.environ:
                MAX_MOLECULES = 3
            else:
                MAX_MOLECULES = 6
            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)
def loop_extrusion(STEPS, LE_FORCE_SCALE, MATRIX_LENGTH, STEPS_PER_CYCLE, STEPS_PER_IT):
    STATE_FNAME = '2sided-state.csv'
    #STEPS = 10000
    #LE_FORCE_SCALE = 3
    #MATRIX_LENGTH = 200
    #STEPS_PER_CYCLE = 10
    #STEPS_PER_IT = 1

#Macierz z parametrami sił wiązań
#Dodano funkcje generacji macierzy o wartościach sinusoidalnych. Funkcja ta przyjmuje dwa argumenty. Pierwszy oznacza liczbę kroków które ma posiadać macierz a drugi
#stanowi regulacje maksymalnej siły (tzn jeśli wstawimy 3 to maksymalna siła bedzie tyle wynosić)
    LE_FORCE_MATRIX = gen_sin_array(MATRIX_LENGTH,LE_FORCE_SCALE)
    LE_FORCE_MATRIX[1][0] = 0
    LE_FORCE_MATRIX[2][-1] = 0
#print(LE_FORCE_MATRIX)

    pdb = PDBFile('initial_structure.pdb')
    forcefield = ForceField('polymer_ff.xml')
    system = forcefield.createSystem(pdb.topology, nonbondedCutoff=1 * u.nanometer)
    integrator = mm.LangevinIntegrator(100 * u.kelvin, 0.2, 1 * u.femtoseconds)

# Distance constraint
    for i in range(system.getNumParticles() - 1):
        system.addConstraint(i, i + 1, 0.1 * u.nanometer)

# Pinning ends with rubber
    pin_force = mm.CustomExternalForce("k*((x-x0)^2+(y-y0)^2+(z-z0)^2)")
    pin_force.addGlobalParameter("k", 50 * u.kilocalories_per_mole / u.angstroms ** 2)
    pin_force.addPerParticleParameter("x0")
    pin_force.addPerParticleParameter("y0")
    pin_force.addPerParticleParameter("z0")
    pin_force.addParticle(0, [15 * u.angstrom, 0 * u.angstrom, 0 * u.angstrom])
    pin_force.addParticle(system.getNumParticles() - 1, [-15 * u.angstrom, 0 * u.angstrom, 0 * u.angstrom])
    system.addForce(pin_force)


# Loop extrusion force
    le_force = mm.HarmonicBondForce()
    le_force.addBond(48, 50, 1 * u.angstrom, LE_FORCE_SCALE * u.kilocalories_per_mole / u.angstroms ** 2)
    for i in range(2, 35):
        p1, p2 = 49 - i, 49 + i
        le_force.addBond(p1, p2, 1 * u.angstrom, 0.000001 * u.kilocalories_per_mole / u.angstroms ** 2)
    system.addForce(le_force)
    

    simulation = Simulation(pdb.topology, system, integrator)
    simulation.context.setPositions(pdb.positions)
    simulation.minimizeEnergy()
    simulation.reporters.append(DCDReporter('wyniki/2sided-trj.dcd', 1))
    simulation.reporters.append(StateDataReporter(stdout, 1000, step=True, potentialEnergy=True, temperature=True))
    simulation.reporters.append(StateDataReporter(STATE_FNAME, 10, step=True, potentialEnergy=True))

    simulation.step(1)

    for i in range(2, 35):
        p1, p2 = 49 - i, 49 + i
        for j in range(MATRIX_LENGTH):
            le_force_one = LE_FORCE_MATRIX[1][j] * u.kilocalories_per_mole / u.angstroms ** 2 #ROSNĄCA
            le_force_two = LE_FORCE_MATRIX[2][j] * u.kilocalories_per_mole / u.angstroms ** 2 #MALEJĄCA
            le_force.setBondParameters(i - 2, p1 + 1, p2 - 1, 1 * u.angstrom,
                                    le_force_two)
            le_force.setBondParameters(i - 1, p1, p2, 1 * u.angstrom, le_force_one)
            le_force.updateParametersInContext(simulation.context)
        #print(le_force_one)
        #print(le_force_two)
        #simulation.minimizeEnergy()
            simulation.step(STEPS_PER_IT)
#    for i in range(STEPS_PER_CYCLE):
#        simulation.step(1)
        simulation.step(200)
        plot_data(STATE_FNAME, '2sided-energy.png')

    print('#1: repr stick; color white; color red :1,100; repr sphere :1,100; vdwdefine 0.5')
    print('#1: color green :49,51; repr sphere :49,51; color #ffffa2e8a2e8 :50;')
    for i in range(1, 35):
        p1, p2 = 50 - i - 1, 50 + i + 1
        print(
            f'#{i*STEPS_PER_CYCLE+1}: color green :{p1},{p2}; repr sphere :{p1},{p2}; repr stick :{p1+1},{p2-1}; color #ffffa2e8a2e8 :{p1+1}-{p2-1};')

    print("Done")
class SystemGenerator(object):
    """
    Utility factory to generate OpenMM Systems from Topology objects.

    Parameters
    ----------
    forcefields_to_use : list of string
        List of the names of ffxml files that will be used in system creation.
    forcefield_kwargs : dict of arguments to createSystem, optional
        Allows specification of various aspects of system creation.
    use_gaff : bool, optional, default=True
        If True, will add the GAFF residue template generator.

    Examples
    --------
    >>> from simtk.openmm import app
    >>> forcefield_kwargs={ 'nonbondedMethod' : app.NoCutoff, 'implicitSolvent' : None, 'constraints' : None }
    >>> system_generator = SystemGenerator(['amber99sbildn.xml'], forcefield_kwargs=forcefield_kwargs)
    >>> from openmmtools.testsystems import AlanineDipeptideVacuum
    >>> testsystem = AlanineDipeptideVacuum()
    >>> system = system_generator.createSystem(testsystem.topology)
    """

    def __init__(self, forcefields_to_use, forcefield_kwargs=None, use_gaff=True):
        self._forcefield_xmls = forcefields_to_use
        self._forcefield_kwargs = forcefield_kwargs if forcefield_kwargs is not None else {}
        from simtk.openmm.app import ForceField
        self._forcefield = ForceField(*self._forcefield_xmls)
        if use_gaff:
            self._forcefield.registerTemplateGenerator(gaffTemplateGenerator)

    def getForceField(self):
        """
        Return the associated ForceField object.

        Returns
        -------
        forcefield : simtk.openmm.app.ForceField
            The current ForceField object.
        """
        return self._forcefield

    def createSystem(self, topology):
        """
        Build a system from specified topology object.

        Parameters
        ----------
        topology : simtk.openmm.app.Topology object
            The topology of the system to construct.

        Returns
        -------
        system : openmm.System
            A system object generated from the topology
        """
        system = self._forcefield.createSystem(topology, **self._forcefield_kwargs)
        return system

    @property
    def ffxmls(self):
        return self._forcefield_xmls

    @property
    def forcefield(self):
        return self._forcefield
Ejemplo n.º 37
0
import porinMembraneSystem
from porinMembraneSystem import PorinMembraneSystem

logger = logging.getLogger(__name__)
# Setup general logging
logging.root.setLevel(logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
yank.utils.config_root_logger(verbose=True, log_file_path=None)

forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')

pdbx = PDBxFile('atomistic-system-with-hydrogens.pdbx')

system = forcefield.createSystem(pdbx.topology,
                                 nonbondedMethod=app.PME,
                                 rigidWater=False,
                                 nonbondedCutoff=1 * unit.nanometer)

integrator = mm.VerletIntegrator(0.5 * unit.femtosecond)
platform = mm.Platform.getPlatformByName('CUDA')
simulation = app.Simulation(pdbx.topology, system, integrator, platform)
simulation.loadCheckpoint('state.chk')
positions = simulation.context.getState(getPositions=True).getPositions()

#rigidWater = False is necessary because water parameters are required by Parmed
#when loading the ligand
ligand_atomistic_system = PorinMembraneSystem('comp7',
                                              system,
                                              pdbx.topology,
                                              positions,
                                              platform,
Ejemplo n.º 38
0
class SystemGenerator(object):
    """
    Utility factory to generate OpenMM Systems from Topology objects.

    Parameters
    ----------
    forcefields_to_use : list of string
        List of the names of ffxml files that will be used in system creation.
    forcefield_kwargs : dict of arguments to createSystem, optional
        Allows specification of various aspects of system creation.
    use_gaff : bool, optional, default=True
        If True, will add the GAFF residue template generator.

    Examples
    --------
    >>> from simtk.openmm import app
    >>> forcefield_kwargs={ 'nonbondedMethod' : app.NoCutoff, 'implicitSolvent' : None, 'constraints' : None }
    >>> system_generator = SystemGenerator(['amber99sbildn.xml'], forcefield_kwargs=forcefield_kwargs)
    >>> from openmmtools.testsystems import AlanineDipeptideVacuum
    >>> testsystem = AlanineDipeptideVacuum()
    >>> system = system_generator.createSystem(testsystem.topology)
    """
    def __init__(self,
                 forcefields_to_use,
                 forcefield_kwargs=None,
                 use_gaff=True):
        self._forcefield_xmls = forcefields_to_use
        self._forcefield_kwargs = forcefield_kwargs if forcefield_kwargs is not None else {}
        from simtk.openmm.app import ForceField
        self._forcefield = ForceField(*self._forcefield_xmls)
        if use_gaff:
            self._forcefield.registerTemplateGenerator(gaffTemplateGenerator)

    def getForceField(self):
        """
        Return the associated ForceField object.

        Returns
        -------
        forcefield : simtk.openmm.app.ForceField
            The current ForceField object.
        """
        return self._forcefield

    def createSystem(self, topology):
        """
        Build a system from specified topology object.

        Parameters
        ----------
        topology : simtk.openmm.app.Topology object
            The topology of the system to construct.

        Returns
        -------
        system : openmm.System
            A system object generated from the topology
        """
        system = self._forcefield.createSystem(topology,
                                               **self._forcefield_kwargs)
        return system

    @property
    def ffxmls(self):
        return self._forcefield_xmls

    @property
    def forcefield(self):
        return self._forcefield
Ejemplo n.º 39
0
def test_reporter(tmpdir, get_fn):
    pdb = PDBFile(get_fn('native.pdb'))
    forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml')
    # NO PERIODIC BOUNDARY CONDITIONS
    system = forcefield.createSystem(pdb.topology,
                                     nonbondedMethod=CutoffNonPeriodic,
                                     nonbondedCutoff=1.0 * nanometers,
                                     constraints=HBonds,
                                     rigidWater=True)
    integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds,
                                    2.0 * femtoseconds)
    integrator.setConstraintTolerance(0.00001)

    platform = Platform.getPlatformByName('Reference')
    simulation = Simulation(pdb.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.positions)

    simulation.context.setVelocitiesToTemperature(300 * kelvin)

    tmpdir = str(tmpdir)
    hdf5file = os.path.join(tmpdir, 'traj.h5')
    ncfile = os.path.join(tmpdir, 'traj.nc')
    dcdfile = os.path.join(tmpdir, 'traj.dcd')

    reporter = HDF5Reporter(hdf5file,
                            2,
                            coordinates=True,
                            time=True,
                            cell=True,
                            potentialEnergy=True,
                            kineticEnergy=True,
                            temperature=True,
                            velocities=True)
    reporter2 = NetCDFReporter(ncfile,
                               2,
                               coordinates=True,
                               time=True,
                               cell=True)
    reporter3 = DCDReporter(dcdfile, 2)

    simulation.reporters.append(reporter)
    simulation.reporters.append(reporter2)
    simulation.reporters.append(reporter3)
    simulation.step(100)

    reporter.close()
    reporter2.close()
    reporter3.close()

    with HDF5TrajectoryFile(hdf5file) as f:
        got = f.read()
        eq(got.temperature.shape, (50, ))
        eq(got.potentialEnergy.shape, (50, ))
        eq(got.kineticEnergy.shape, (50, ))
        eq(got.coordinates.shape, (50, 22, 3))
        eq(got.velocities.shape, (50, 22, 3))
        eq(got.cell_lengths, None)
        eq(got.cell_angles, None)
        eq(got.time, 0.002 * 2 * (1 + np.arange(50)))
        assert f.topology == md.load(get_fn('native.pdb')).top

    with NetCDFTrajectoryFile(ncfile) as f:
        xyz, time, cell_lengths, cell_angles = f.read()
        eq(cell_lengths, None)
        eq(cell_angles, None)
        eq(time, 0.002 * 2 * (1 + np.arange(50)))

    hdf5_traj = md.load(hdf5file)
    dcd_traj = md.load(dcdfile, top=get_fn('native.pdb'))
    netcdf_traj = md.load(ncfile, top=get_fn('native.pdb'))

    # we don't have to convert units here, because md.load already
    # handles that
    assert hdf5_traj.unitcell_vectors is None
    eq(hdf5_traj.xyz, netcdf_traj.xyz)
    eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors)
    eq(hdf5_traj.time, netcdf_traj.time)

    eq(dcd_traj.xyz, hdf5_traj.xyz)