Example #1
0
def setup_fah_run(destination_path,
                  protein_pdb_filename,
                  oemol=None,
                  cache=None,
                  restrain_rmsd=False,
                  biounit='monomer'):
    """
    Prepare simulation

    Parameters
    ----------
    destination_path : str
        The path to the RUN to be created
    protein_pdb_filename : str
        Path to protein PDB file
    oemol : openeye.oechem.OEMol, optional, default=None
        The molecule to parameterize, with SDData attached
        If None, don't include the small molecule
    restrain_rmsd : bool, optional, default=False
        If True, restrain RMSD during first equilibration phase
    biounit : str, optional, default='monomer'
        'monomer' or 'dimer'
    """
    # Parameters
    from simtk import unit, openmm
    protein_forcefield = 'amber14/protein.ff14SB.xml'
    solvent_forcefield = 'amber14/tip3p.xml'
    small_molecule_forcefield = 'openff-1.3.0'
    water_model = 'tip3p'
    solvent_padding = 10.0 * unit.angstrom
    ionic_strength = 70 * unit.millimolar  # assay buffer: 20 mM HEPES pH 7.3, 1 mM TCEP, 50 mM NaCl, 0.01% Tween-20, 10% glycerol
    pressure = 1.0 * unit.atmospheres
    collision_rate = 1.0 / unit.picoseconds
    temperature = 300.0 * unit.kelvin
    timestep = 4.0 * unit.femtoseconds
    iterations = 1000  # 1 ns equilibration
    nsteps_per_iteration = 250
    nsteps_per_snapshot = 250000  # 1 ns
    nsnapshots_per_wu = 20  # number of snapshots per WU

    # Prepare phases
    import os
    system_xml_filename = os.path.join(destination_path, 'system.xml.bz2')
    integrator_xml_filename = os.path.join(destination_path,
                                           'integrator.xml.bz2')
    state_xml_filename = os.path.join(destination_path, 'state.xml.bz2')

    # Check if we can skip setup
    openmm_files_exist = os.path.exists(
        system_xml_filename) and os.path.exists(
            state_xml_filename) and os.path.exists(integrator_xml_filename)
    if openmm_files_exist:
        return

    # Create barostat
    barostat = openmm.MonteCarloBarostat(pressure, temperature)

    # Create RUN directory if it does not yet exist
    os.makedirs(destination_path, exist_ok=True)

    # Load any molecule(s)
    molecule = None
    molecules = []
    if oemol is not None:
        from openforcefield.topology import Molecule
        molecule = Molecule.from_openeye(oemol, allow_undefined_stereo=True)
        molecule.name = 'MOL'  # Ensure residue is MOL
        print([res for res in molecule.to_topology().to_openmm().residues()])
        molecules = [molecule]

    # Create SystemGenerator
    import os
    from simtk.openmm import app
    forcefield_kwargs = {
        'removeCMMotion': False,
        'hydrogenMass': 3.0 * unit.amu,
        'constraints': app.HBonds,
        'rigidWater': True
    }
    periodic_kwargs = {
        'nonbondedMethod': app.PME,
        'ewaldErrorTolerance': 2.5e-04
    }
    forcefields = [protein_forcefield, solvent_forcefield]
    from openmmforcefields.generators import SystemGenerator
    openmm_system_generator = SystemGenerator(
        forcefields=forcefields,
        molecules=molecules,
        small_molecule_forcefield=small_molecule_forcefield,
        cache=cache,
        barostat=barostat,
        forcefield_kwargs=forcefield_kwargs,
        periodic_forcefield_kwargs=periodic_kwargs)

    # Read protein
    print(f'Reading protein from {protein_pdb_filename}...')
    pdbfile = app.PDBFile(protein_pdb_filename)
    modeller = app.Modeller(pdbfile.topology, pdbfile.positions)

    if oemol is not None:
        # Add small molecule to the system
        modeller.add(molecule.to_topology().to_openmm(),
                     molecule.conformers[0])

    # Extract protein and molecule chains and indices before adding solvent
    import mdtraj as md
    mdtop = md.Topology.from_openmm(
        modeller.topology)  # excludes solvent and ions
    protein_atom_indices = mdtop.select('protein and (mass > 1)')
    molecule_atom_indices = mdtop.select(
        '(not protein) and (not water) and (mass > 1)')
    protein_chainids = list(
        set([
            atom.residue.chain.index for atom in mdtop.atoms
            if atom.index in protein_atom_indices
        ]))
    n_protein_chains = len(protein_chainids)
    protein_chain_atom_indices = dict()
    for chainid in protein_chainids:
        protein_chain_atom_indices[chainid] = mdtop.select(
            f'protein and chainid {chainid}')

    # Add solvent
    print('Adding solvent...')
    kwargs = {'padding': solvent_padding}
    modeller.addSolvent(openmm_system_generator.forcefield,
                        model='tip3p',
                        ionicStrength=ionic_strength,
                        **kwargs)

    # Write initial model and select atom subsets and chains
    import bz2
    with bz2.open(os.path.join(destination_path, 'initial-model.pdb.bz2'),
                  'wt') as outfile:
        app.PDBFile.writeFile(modeller.topology,
                              modeller.positions,
                              outfile,
                              keepIds=True)

    # Create an OpenMM system
    print('Creating OpenMM system...')
    system = openmm_system_generator.create_system(modeller.topology)

    #
    # Add virtual bonds to ensure protein subunits and ligand are imaged together
    #

    virtual_bond_force = openmm.CustomBondForce('0')
    system.addForce(virtual_bond_force)

    # Add a virtual bond between protein chains
    if (n_protein_chains > 1):
        chainid = protein_chainids[0]
        iatom = protein_chain_atom_indices[chainid][0]
        for chainid in protein_chainids[1:]:
            jatom = protein_chain_atom_indices[chainid][0]
            print(f'Creating virtual bond between atoms {iatom} and {jatom}')
            virtual_bond_force.addBond(int(iatom), int(jatom), [])

    # Add a virtual bond between protein and ligand to make sure they are not imaged separately
    if oemol is not None:
        ligand_atom_indices = mdtop.select(
            '((resname MOL) and (mass > 1))')  # ligand heavy atoms
        protein_atom_index = int(protein_atom_indices[0])
        ligand_atom_index = int(ligand_atom_indices[0])
        print(
            f'Creating virtual bond between atoms {protein_atom_index} and {ligand_atom_index}'
        )
        virtual_bond_force.addBond(int(protein_atom_index),
                                   int(ligand_atom_index), [])

    # Add RMSD restraints if requested
    if restrain_rmsd:
        print('Adding RMSD restraint...')
        kB = unit.AVOGADRO_CONSTANT_NA * unit.BOLTZMANN_CONSTANT_kB
        kT = kB * temperature
        rmsd_atom_indices = mdtop.select(
            '(protein and (name CA)) or ((resname MOL) and (mass > 1))'
        )  # CA atoms and ligand heavy atoms
        rmsd_atom_indices = [int(index) for index in rmsd_atom_indices]
        custom_cv_force = openmm.CustomCVForce('(K_RMSD/2)*RMSD^2')
        custom_cv_force.addGlobalParameter('K_RMSD', kT / unit.angstrom**2)
        rmsd_force = openmm.RMSDForce(modeller.positions, rmsd_atom_indices)
        custom_cv_force.addCollectiveVariable('RMSD', rmsd_force)
        force_index = system.addForce(custom_cv_force)

    # Create OpenM Context
    platform = openmm.Platform.getPlatformByName('OpenCL')
    platform.setPropertyDefaultValue('Precision', 'mixed')
    from openmmtools import integrators
    integrator = integrators.LangevinIntegrator(temperature, collision_rate,
                                                timestep)
    context = openmm.Context(system, integrator, platform)
    context.setPositions(modeller.positions)

    # Report initial potential energy
    state = context.getState(getEnergy=True)
    print(
        f'Initial potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol'
    )

    # Store snapshots in MDTraj trajectory to examine RMSD
    import mdtraj as md
    import numpy as np
    mdtop = md.Topology.from_openmm(pdbfile.topology)
    atom_indices = mdtop.select('all')  # all solute atoms
    protein_atom_indices = mdtop.select(
        'protein and (mass > 1)')  # heavy solute atoms
    if oemol is not None:
        ligand_atom_indices = mdtop.select(
            '(resname MOL) and (mass > 1)')  # ligand heavy atoms
    trajectory = md.Trajectory(
        np.zeros([iterations + 1, len(atom_indices), 3], np.float32), mdtop)
    trajectory.xyz[0, :, :] = context.getState(getPositions=True).getPositions(
        asNumpy=True)[atom_indices] / unit.nanometers

    # Minimize
    print('Minimizing...')
    openmm.LocalEnergyMinimizer.minimize(context)

    # Equilibrate (with RMSD restraint if needed)
    import numpy as np
    from rich.progress import track
    import time
    initial_time = time.time()
    for iteration in track(range(iterations), 'Equilibrating...'):
        integrator.step(nsteps_per_iteration)
        trajectory.xyz[iteration + 1, :, :] = context.getState(
            getPositions=True).getPositions(
                asNumpy=True)[atom_indices] / unit.nanometers
    elapsed_time = (time.time() - initial_time) * unit.seconds
    ns_per_day = (context.getState().getTime() /
                  elapsed_time) / (unit.nanoseconds / unit.day)
    print(f'Performance: {ns_per_day:8.3f} ns/day')

    if restrain_rmsd:
        # Disable RMSD restraint
        context.setParameter('K_RMSD', 0.0)

        print('Minimizing...')
        openmm.LocalEnergyMinimizer.minimize(context)

        for iteration in track(range(iterations),
                               'Equilibrating without RMSD restraint...'):
            integrator.step(nsteps_per_iteration)

    # Retrieve state
    state = context.getState(getPositions=True,
                             getVelocities=True,
                             getEnergy=True,
                             getForces=True)
    system.setDefaultPeriodicBoxVectors(*state.getPeriodicBoxVectors())
    modeller.topology.setPeriodicBoxVectors(state.getPeriodicBoxVectors())
    print(
        f'Final potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol'
    )

    # Equilibrate again if we restrained the RMSD
    if restrain_rmsd:
        print('Removing RMSD restraint from system...')
        system.removeForce(force_index)

    #if oemol is not None:
    #    # Check final RMSD
    #    print('checking RMSD...')
    #    trajectory.superpose(trajectory, atom_indices=protein_atom_indices)
    #    protein_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=protein_atom_indices)[-1] * 10 # Angstroms
    #    oechem.OESetSDData(oemol, 'equil_protein_rmsd', f'{protein_rmsd:.2f} A')
    #    ligand_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=ligand_atom_indices)[-1] * 10 # Angstroms
    #    oechem.OESetSDData(oemol, 'equil_ligand_rmsd', f'{ligand_rmsd:.2f} A')
    #    print('RMSD after equilibration: protein {protein_rmsd:8.2f} A | ligand {ligand_rmsd:8.3f} A')

    # Save as OpenMM
    print('Exporting for OpenMM FAH simulation...')
    import bz2
    with bz2.open(integrator_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(integrator))
    with bz2.open(state_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(state))
    with bz2.open(system_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(system))
    with bz2.open(os.path.join(destination_path, 'equilibrated-all.pdb.bz2'),
                  'wt') as f:
        app.PDBFile.writeFile(modeller.topology,
                              state.getPositions(),
                              f,
                              keepIds=True)
    with open(os.path.join(destination_path, 'equilibrated-solute.pdb'),
              'wt') as f:
        import mdtraj
        mdtraj_topology = mdtraj.Topology.from_openmm(modeller.topology)
        mdtraj_trajectory = mdtraj.Trajectory(
            [state.getPositions(asNumpy=True) / unit.nanometers],
            mdtraj_topology)
        selection = mdtraj_topology.select('not water')
        mdtraj_trajectory = mdtraj_trajectory.atom_slice(selection)
        app.PDBFile.writeFile(mdtraj_trajectory.topology.to_openmm(),
                              mdtraj_trajectory.openmm_positions(0),
                              f,
                              keepIds=True)
    with open(os.path.join(destination_path, 'core.xml'), 'wt') as f:
        f.write(f'<config>\n')
        f.write(
            f'  <numSteps>{nsteps_per_snapshot * nsnapshots_per_wu}</numSteps>\n'
        )
        f.write(f'  <xtcFreq>{nsteps_per_snapshot}</xtcFreq>\n')
        f.write(f'  <precision>mixed</precision>\n')
        f.write(
            f'  <xtcAtoms>{",".join([str(index) for index in selection])}</xtcAtoms>\n'
        )
        f.write(f'</config>\n')
    if oemol is not None:
        # Write molecule as SDF, SMILES, and mol2
        for extension in ['sdf', 'mol2', 'smi', 'csv']:
            filename = os.path.join(destination_path, f'molecule.{extension}')
            with oechem.oemolostream(filename) as ofs:
                oechem.OEWriteMolecule(ofs, oemol)

    # Clean up
    del context, integrator
Example #2
0
    def __init__(self,
                 protein_pdb_filename,
                 ligand_file,
                 old_ligand_index,
                 new_ligand_index,
                 forcefield_files,
                 pressure=1.0 * unit.atmosphere,
                 temperature=300.0 * unit.kelvin,
                 solvent_padding=9.0 * unit.angstroms):
        """
        Initialize a NonequilibriumFEPSetup object

        Parameters
        ----------
        protein_pdb_filename : str
            The name of the protein pdb file
        ligand_file : str
            the name of the ligand file (any openeye supported format)
        ligand_smiles : list of two str
            The SMILES strings representing the two ligands
        forcefield_files : list of str
            The list of ffxml files that contain the forcefields that will be used
        pressure : Quantity, units of pressure
            Pressure to use in the barostat
        temperature : Quantity, units of temperature
            Temperature to use for the Langevin integrator
        solvent_padding : Quantity, units of length
            The amount of padding to use when adding solvent
        """
        self._protein_pdb_filename = protein_pdb_filename
        self._pressure = pressure
        self._temperature = temperature
        self._barostat_period = 50
        self._padding = solvent_padding

        self._ligand_file = ligand_file
        self._old_ligand_index = old_ligand_index
        self._new_ligand_index = new_ligand_index

        self._old_ligand_oemol = self.load_sdf(self._ligand_file,
                                               index=self._old_ligand_index)
        self._new_ligand_oemol = self.load_sdf(self._ligand_file,
                                               index=self._new_ligand_index)

        self._old_ligand_positions = extractPositionsFromOEMOL(
            self._old_ligand_oemol)

        ffxml = forcefield_generators.generateForceFieldFromMolecules(
            [self._old_ligand_oemol, self._new_ligand_oemol])

        self._old_ligand_oemol.SetTitle("MOL")
        self._new_ligand_oemol.SetTitle("MOL")

        self._new_ligand_smiles = oechem.OECreateSmiString(
            self._new_ligand_oemol,
            oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)
        #self._old_ligand_smiles = '[H]c1c(c(c(c(c1N([H])c2nc3c(c(n2)OC([H])([H])C4(C(C(C(C(C4([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])nc(n3[H])[H])[H])[H])S(=O)(=O)C([H])([H])[H])[H]'
        self._old_ligand_smiles = oechem.OECreateSmiString(
            self._old_ligand_oemol,
            oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)

        print(self._new_ligand_smiles)
        print(self._old_ligand_smiles)

        self._old_ligand_topology = forcefield_generators.generateTopologyFromOEMol(
            self._old_ligand_oemol)
        self._old_ligand_md_topology = md.Topology.from_openmm(
            self._old_ligand_topology)
        self._new_ligand_topology = forcefield_generators.generateTopologyFromOEMol(
            self._new_ligand_oemol)
        self._new_liands_md_topology = md.Topology.from_openmm(
            self._new_ligand_topology)

        protein_pdbfile = open(self._protein_pdb_filename, 'r')
        pdb_file = app.PDBFile(protein_pdbfile)
        protein_pdbfile.close()

        self._protein_topology_old = pdb_file.topology
        self._protein_md_topology_old = md.Topology.from_openmm(
            self._protein_topology_old)
        self._protein_positions_old = pdb_file.positions
        self._forcefield = app.ForceField(*forcefield_files)
        self._forcefield.loadFile(StringIO(ffxml))

        print("Generated forcefield")

        self._complex_md_topology_old = self._protein_md_topology_old.join(
            self._old_ligand_md_topology)
        self._complex_topology_old = self._complex_md_topology_old.to_openmm()

        n_atoms_complex_old = self._complex_topology_old.getNumAtoms()
        n_atoms_protein_old = self._protein_topology_old.getNumAtoms()

        self._complex_positions_old = unit.Quantity(np.zeros(
            [n_atoms_complex_old, 3]),
                                                    unit=unit.nanometers)
        self._complex_positions_old[:
                                    n_atoms_protein_old, :] = self._protein_positions_old
        self._complex_positions_old[
            n_atoms_protein_old:, :] = self._old_ligand_positions

        if pressure is not None:
            barostat = openmm.MonteCarloBarostat(self._pressure,
                                                 self._temperature,
                                                 self._barostat_period)
            self._system_generator = SystemGenerator(
                forcefield_files,
                barostat=barostat,
                forcefield_kwargs={'nonbondedMethod': app.PME})
        else:
            self._system_generator = SystemGenerator(forcefield_files)

        #self._complex_proposal_engine = TwoMoleculeSetProposalEngine(self._old_ligand_smiles, self._new_ligand_smiles, self._system_generator, residue_name="MOL")
        self._complex_proposal_engine = TwoMoleculeSetProposalEngine(
            self._old_ligand_oemol,
            self._new_ligand_oemol,
            self._system_generator,
            residue_name="MOL")
        self._geometry_engine = FFAllAngleGeometryEngine()

        self._complex_topology_old_solvated, self._complex_positions_old_solvated, self._complex_system_old_solvated = self._solvate_system(
            self._complex_topology_old, self._complex_positions_old)
        self._complex_md_topology_old_solvated = md.Topology.from_openmm(
            self._complex_topology_old_solvated)
        print(self._complex_proposal_engine._smiles_list)

        beta = 1.0 / (kB * temperature)

        self._complex_topology_proposal = self._complex_proposal_engine.propose(
            self._complex_system_old_solvated,
            self._complex_topology_old_solvated)
        self._complex_positions_new_solvated, _ = self._geometry_engine.propose(
            self._complex_topology_proposal,
            self._complex_positions_old_solvated, beta)

        #now generate the equivalent objects for the solvent phase. First, generate the ligand-only topologies and atom map
        self._solvent_topology_proposal, self._old_solvent_positions = self._generate_ligand_only_topologies(
            self._complex_positions_old_solvated,
            self._complex_positions_new_solvated)
        self._new_solvent_positions, _ = self._geometry_engine.propose(
            self._solvent_topology_proposal, self._old_solvent_positions, beta)
Example #3
0
    def simulationSpawner(self, protocol, label='NPT', kind='equilibration', index=0):
        
        
        self.energy=self.simulation.context.getState(getEnergy=True).getTotalEnergy()

        print(f'Spwaning new simulation:')
        print(f'\tSystem total energy: {self.energy}')
        
        
        if kind == 'minimization':
            
            self.simulation.minimizeEnergy()
            self.structures['minimization']=self.writePDB(self.topology, self.positions, name='minimization')
            print(f'\tPerforming energy minimization: {Ei}')
        
        else:
            
            name=f'{kind}_{label}'
            trj_file=f'{self.workdir}/{kind}_{label}'
        
            #If there are user defined costum forces
            try:
                if protocol['restrained_sets']:
                    self.system=self.setRestraints(protocol['restrained_sets'])

            except KeyError:    
                pass

            if label == 'NPT':
            
                #TODO: frequency is hardcoded to 25, make it go away. Check units throughout!
                print(f'\tAdding MC barostat for {name} ensemble')      
                self.system.addForce(omm.MonteCarloBarostat(self.pressure, self.temperature, 25)) 
        
            self.simulation.context.setPositions(self.positions)
        
            if index == 1 and kind == 'equilibration':
                print(f'\tFirst equilibration run {name}. Assigning velocities to {self.temperature}')
                self.simulation.context.setVelocitiesToTemperature(self.temperature)
        
            # Define reporters
            self.simulation.reporters.append(DCDReporter(f'{trj_file}.dcd', protocol['report']))           
            self.simulation.reporters.append(HDF5Reporter(f'{trj_file}.h5', protocol['report'], atomSubset=self.trj_indices))
            self.simulation.reporters.append(app.StateDataReporter(f'{trj_file}.csv', 
                                                          protocol['report'], 
                                                          step=True, 
                                                          totalEnergy=True, 
                                                          temperature=True,
                                                          density=True,
                                                          progress=True, 
                                                          remainingTime=True, 
                                                          speed=True, 
                                                          totalSteps=protocol['step'], 
                                                          separator='\t'))
        
            positions_first = self.simulation.context.getState(getPositions=True).getPositions()
        
            self.structures['f{name}_ref']=self.writePDB(self.simulation.topology, positions_first, name=f'{name}_0')
        
            #############
            ## WARNIN ##
            #############
        
            trj_time=protocol['step']*self.dt
            print(f'\t{kind} simulation in {label} ensemble ({trj_time})...')
            self.simulation.step(protocol['step'])
        
            
            #############
            ## WARNOUT ##
            #############

            print(f'\t{kind} simulation in {label} ensemble ({trj_time}) completed.')
            self.structures[f'{name}']=self.writePDB(self.simulation.topology, self.positions, name='{name}')

        state=self.simulation.context.getState(getPositions=True, getVelocities=True, getEnergy=True)
        self.positions = state.getPositions()
        self.velocities = state.getVelocities()
        self.energy=state.getPotentialEnergy()


        

        
        #Remove Costum forces (always initialized in next run)
        if label == 'NPT':
            self.system=self.forceHandler(self.system, kinds=['CustomExternalForce', 'MonteCarloBarostat'])
        elif label == 'NVT':
            self.system=self.forceHandler(self.system, kinds=['CustomExternalForce'])
            
        return self.simulation
for x in range(RUNSid):
    # prepare system and integrator
    system = prmtop.createSystem(nonbondedMethod=app.PME,
                                 nonbondedCutoff=1.0 * unit.nanometers,
                                 constraints=app.HBonds,
                                 rigidWater=True,
                                 ewaldErrorTolerance=0.0005)
    integrator = mm.LangevinIntegrator(TEMPid * unit.kelvin,
                                       1.0 / unit.picoseconds,
                                       2.0 * unit.femtoseconds)
    integrator.setConstraintTolerance(0.00001)
    thermostat = mm.AndersenThermostat(TEMPid * unit.kelvin,
                                       1 / unit.picosecond)
    system.addForce(thermostat)
    barostat = mm.MonteCarloBarostat(1.0 * unit.bar, TEMPid * unit.kelvin, 25)
    system.addForce(barostat)

    # prepare simulation
    platform = mm.Platform.getPlatformByName('CUDA')
    properties = {'CudaPrecision': 'mixed', 'DeviceIndex': '0'}
    simulation = app.Simulation(prmtop.topology, system, integrator, platform,
                                properties)
    simulation.context.setPositions(inpcrd.positions)

    # minimize
    print('Minimizing...')
    simulation.minimizeEnergy()

    # equilibrate for 100 steps
    simulation.context.setVelocitiesToTemperature(TEMPid * unit.kelvin)
Example #5
0
# Get the coordinates from the PDB
crd = app.CharmmCrdFile('ubi_cubi.crd') # in case a crd file instead of pdb is used

# Load the parameter set.
lib = '/home/xuyou/toppar/' # FULL path of force field topology and parameter files
params = app.CharmmParameterSet(lib+'top_all36_prot.rtf', lib+'par_all36m_prot.prm', lib+'toppar_water_ions.str')

platform = mm.Platform.getPlatformByName('CUDA') # make sure the GPU is used. Others: Reference, CPU & OpenCL

system = psf.createSystem(params, nonbondedMethod=app.LJPME, nonbondedCutoff=0.9*nanometer, ewaldErrorTolerance = 0.0001, constraints=app.HBonds) 
# The error tolerance is roughly equal to the fractional error in the forces due to truncating the Ewald summation. Default 0.0005. 
# The default vdwCutoff is as nonbondedCutof, so fswitch or fshift?

system.addForce(mm.AndersenThermostat(temp*kelvin, 1/picosecond)) # thermostat: temperature and collision frequency
system.addForce(mm.MonteCarloBarostat(pressure*bar, temp*kelvin)) # The barostat does not itself do anything to regulate the temperature
integrator = mm.VerletIntegrator(0.002*picoseconds)        # 2 fs time step

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

# simulation.context.setPositions(pdb.getPositions()) # speicify the initial positions
simulation.context.setPositions(crd.positions) # in case the crd file is used 

simulation.minimizeEnergy(maxIterations = 100) # default tolerance=10*kJ/mol, maxIterations: until converged

if start > 0: # restart from the positions and velocities
    restart=str(start-1)
    with open(trjPath+jobname+'.'+restart+'.rst', 'r') as f:  # the .rst file should only be used if .chk restart file cannot be loaded
        simulation.context.setState(mm.XmlSerializer.deserialize(f.read()))

nsavcrd=50000 # save coordinates every 100 ps
Example #6
0
def generate_solvated_hybrid_test_topology(current_mol_name="naphthalene",
                                           proposed_mol_name="benzene",
                                           current_mol_smiles=None,
                                           proposed_mol_smiles=None,
                                           vacuum=False,
                                           render_atom_mapping=False,
                                           atom_expression=['Hybridization'],
                                           bond_expression=['Hybridization']):
    """
    This function will generate a topology proposal, old positions, and new positions with a geometry proposal (either vacuum or solvated) given a set of input iupacs or smiles.
    The function will (by default) read the iupac names first.  If they are set to None, then it will attempt to read a set of current and new smiles.
    An atom mapping pdf will be generated if specified.
    Arguments
    ----------
    current_mol_name : str, optional
        name of the first molecule
    proposed_mol_name : str, optional
        name of the second molecule
    current_mol_smiles : str (default None)
        current mol smiles
    proposed_mol_smiles : str (default None)
        proposed mol smiles
    vacuum: bool (default False)
        whether to render a vacuum or solvated topology_proposal
    render_atom_mapping : bool (default False)
        whether to render the atom map of the current_mol_name and proposed_mol_name
    atom_expression : list(str), optional
        list of atom mapping criteria
    bond_expression : list(str), optional
        list of bond mapping criteria

    Returns
    -------
    topology_proposal : perses.rjmc.topology_proposal
        The topology proposal representing the transformation
    current_positions : np.array, unit-bearing
        The positions of the initial system
    new_positions : np.array, unit-bearing
        The positions of the new system
    """
    import simtk.openmm.app as app
    from openmoltools import forcefield_generators

    from openeye import oechem
    from openmoltools.openeye import iupac_to_oemol, generate_conformers, smiles_to_oemol
    from openmoltools import forcefield_generators
    import perses.utils.openeye as openeye
    from perses.utils.data import get_data_filename
    from perses.rjmc.topology_proposal import TopologyProposal, SmallMoleculeSetProposalEngine
    import simtk.unit as unit
    from perses.rjmc.geometry import FFAllAngleGeometryEngine
    from perses.utils.openeye import generate_expression
    from openmmforcefields.generators import SystemGenerator
    from openforcefield.topology import Molecule

    atom_expr = generate_expression(atom_expression)
    bond_expr = generate_expression(bond_expression)

    if current_mol_name != None and proposed_mol_name != None:
        try:
            old_oemol, new_oemol = iupac_to_oemol(
                current_mol_name), iupac_to_oemol(proposed_mol_name)
            old_smiles = oechem.OECreateSmiString(
                old_oemol,
                oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)
            new_smiles = oechem.OECreateSmiString(
                new_oemol,
                oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)
        except:
            raise Exception(
                f"either {current_mol_name} or {proposed_mol_name} is not compatible with 'iupac_to_oemol' function!"
            )
    elif current_mol_smiles != None and proposed_mol_smiles != None:
        try:
            old_oemol, new_oemol = smiles_to_oemol(
                current_mol_smiles), smiles_to_oemol(proposed_mol_smiles)
            old_smiles = oechem.OECreateSmiString(
                old_oemol,
                oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)
            new_smiles = oechem.OECreateSmiString(
                new_oemol,
                oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens)
        except:
            raise Exception(f"the variables are not compatible")
    else:
        raise Exception(
            f"either current_mol_name and proposed_mol_name must be specified as iupacs OR current_mol_smiles and proposed_mol_smiles must be specified as smiles strings."
        )

    old_oemol, old_system, old_positions, old_topology = openeye.createSystemFromSMILES(
        old_smiles, title="MOL")

    #correct the old positions
    old_positions = openeye.extractPositionsFromOEMol(old_oemol)
    old_positions = old_positions.in_units_of(unit.nanometers)

    new_oemol, new_system, new_positions, new_topology = openeye.createSystemFromSMILES(
        new_smiles, title="NEW")

    ffxml = forcefield_generators.generateForceFieldFromMolecules(
        [old_oemol, new_oemol])

    old_oemol.SetTitle('MOL')
    new_oemol.SetTitle('MOL')

    old_topology = forcefield_generators.generateTopologyFromOEMol(old_oemol)
    new_topology = forcefield_generators.generateTopologyFromOEMol(new_oemol)

    if not vacuum:
        nonbonded_method = app.PME
        barostat = openmm.MonteCarloBarostat(1.0 * unit.atmosphere,
                                             300.0 * unit.kelvin, 50)
    else:
        nonbonded_method = app.NoCutoff
        barostat = None

    forcefield_files = ['amber14/protein.ff14SB.xml', 'amber14/tip3p.xml']
    forcefield_kwargs = {
        'removeCMMotion': False,
        'ewaldErrorTolerance': 1e-4,
        'constraints': app.HBonds,
        'hydrogenMass': 4 * unit.amus
    }
    periodic_forcefield_kwargs = {'nonbondedMethod': nonbonded_method}
    small_molecule_forcefield = 'gaff-2.11'

    system_generator = SystemGenerator(
        forcefields=forcefield_files,
        barostat=barostat,
        forcefield_kwargs=forcefield_kwargs,
        periodic_forcefield_kwargs=periodic_forcefield_kwargs,
        small_molecule_forcefield=small_molecule_forcefield,
        molecules=[
            Molecule.from_openeye(mol) for mol in [old_oemol, new_oemol]
        ],
        cache=None)

    proposal_engine = SmallMoleculeSetProposalEngine([old_oemol, new_oemol],
                                                     system_generator,
                                                     residue_name='MOL',
                                                     atom_expr=atom_expr,
                                                     bond_expr=bond_expr,
                                                     allow_ring_breaking=True)
    geometry_engine = FFAllAngleGeometryEngine(metadata=None,
                                               use_sterics=False,
                                               n_bond_divisions=1000,
                                               n_angle_divisions=180,
                                               n_torsion_divisions=360,
                                               verbose=True,
                                               storage=None,
                                               bond_softening_constant=1.0,
                                               angle_softening_constant=1.0,
                                               neglect_angles=False)

    if not vacuum:
        #now to solvate
        modeller = app.Modeller(old_topology, old_positions)
        hs = [
            atom for atom in modeller.topology.atoms()
            if atom.element.symbol in ['H']
            and atom.residue.name not in ['MOL', 'OLD', 'NEW']
        ]
        modeller.delete(hs)
        modeller.addHydrogens(forcefield=system_generator.forcefield)
        modeller.addSolvent(system_generator.forcefield,
                            model='tip3p',
                            padding=9.0 * unit.angstroms)
        solvated_topology = modeller.getTopology()
        solvated_positions = modeller.getPositions()
        solvated_positions = unit.quantity.Quantity(value=np.array([
            list(atom_pos) for atom_pos in
            solvated_positions.value_in_unit_system(unit.md_unit_system)
        ]),
                                                    unit=unit.nanometers)
        solvated_system = system_generator.create_system(solvated_topology)

        #now to create proposal
        top_proposal = proposal_engine.propose(
            current_system=solvated_system,
            current_topology=solvated_topology,
            current_mol_id=0,
            proposed_mol_id=1)
        new_positions, _ = geometry_engine.propose(top_proposal,
                                                   solvated_positions, beta)

        if render_atom_mapping:
            from perses.utils.smallmolecules import render_atom_mapping
            print(
                f"new_to_old: {proposal_engine.non_offset_new_to_old_atom_map}"
            )
            render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol,
                                new_oemol,
                                proposal_engine.non_offset_new_to_old_atom_map)

        return top_proposal, solvated_positions, new_positions

    else:
        vacuum_system = system_generator.create_system(old_topology)
        top_proposal = proposal_engine.propose(current_system=vacuum_system,
                                               current_topology=old_topology,
                                               current_mol_id=0,
                                               proposed_mol_id=1)
        new_positions, _ = geometry_engine.propose(top_proposal, old_positions,
                                                   beta)
        if render_atom_mapping:
            from perses.utils.smallmolecules import render_atom_mapping
            print(f"new_to_old: {top_proposal._new_to_old_atom_map}")
            render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol,
                                new_oemol, top_proposal._new_to_old_atom_map)
        return top_proposal, old_positions, new_positions
Example #7
0
import pandas as pd
import lb_loader
import simtk.openmm.app as app
import numpy as np
import simtk.openmm as mm
from simtk import unit as u
from openmmtools import hmc_integrators, testsystems
pd.set_option('display.width', 1000)

collision_rate = 10000.0 / u.picoseconds
temperature = 25. * u.kelvin

testsystem = testsystems.LennardJonesFluid()

system, positions = testsystem.system, testsystem.positions
system.addForce(mm.MonteCarloBarostat(1.0 * u.atmospheres, temperature, 50))

integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds,
                                   0.5 * u.femtoseconds)
context = mm.Context(system, integrator)
context.setPositions(positions)
context.setPeriodicBoxVectors(*boxes)
context.setVelocitiesToTemperature(temperature)
integrator.step(25000)
positions = context.getState(getPositions=True).getPositions()

x = []
for i in range(1000):
    state = context.getState(getParameters=True, getPositions=True)
    positions = state.getPositions(asNumpy=True) / u.nanometers
    boxes = state.getPeriodicBoxVectors(asNumpy=True) / u.nanometers
Example #8
0
kB = unit.BOLTZMANN_CONSTANT_kB * unit.AVOGADRO_CONSTANT_NA
temperature = 300.0 * unit.kelvin
pressure = 1.0 * unit.atmosphere

#### Integrator

friction = 1.0 / unit.picosecond
step_size = 2.0 * unit.femtoseconds
integrator = LangevinIntegrator(temperature, friction, step_size)
integrator.setConstraintTolerance(0.00001)

#### Barostat

barostat_interval = 25
barostat = mm.MonteCarloBarostat(pressure, temperature, barostat_interval)
system.addForce(barostat)

#### Platform

platform = mm.Platform.getPlatformByName('CUDA')
properties = {'CudaPrecision': 'mixed'}

#### Simulation

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

#### Initial Conditions

positions = m3t.get(pdb, coordinates=True)
simulation.context.setPositions(positions)
Example #9
0
    def apply(self, thermodynamic_state, sampler_state, platform=None):
        """
        Apply the MCMC move.

        Parameters
        ----------
        thermodynamic_state : ThermodynamicState
           The thermodynamic state to use when applying the MCMC move
        sampler_state : SamplerState
           The sampler state to apply the move to
        platform : simtk.openmm.Platform, optional, default = None
           If not None, the specified platform will be used.

        Returns
        -------
        updated_sampler_state : SamplerState
           The updated sampler state

        Examples
        --------

        >>> # Create a test system
        >>> from openmmtools import testsystems
        >>> test = testsystems.LennardJonesFluid()
        >>> # Create a sampler state.
        >>> sampler_state = SamplerState(system=test.system, positions=test.positions, box_vectors=test.system.getDefaultPeriodicBoxVectors())
        >>> # Create a thermodynamic state.
        >>> from thermodynamics import ThermodynamicState
        >>> thermodynamic_state = ThermodynamicState(system=test.system, temperature=298*u.kelvin, pressure=1*u.atmospheres)
        >>> # Create a Monte Carlo Barostat move.
        >>> move = MonteCarloBarostatMove(nattempts=5)
        >>> # Perform one update of the sampler state.
        >>> updated_sampler_state = move.apply(thermodynamic_state, sampler_state)

        """

        timer = Timer()

        # Make sure system contains a barostat.
        system = sampler_state.system
        forces = {
            system.getForce(index).__class__.__name__: system.getForce(index)
            for index in range(system.getNumForces())
        }
        old_barostat_frequency = None
        if 'MonteCarloBarostat' in forces:
            force = forces['MonteCarloBarostat']
            force.setTemperature(thermodynamic_state.temperature)
            old_barostat_frequency = force.getFrequency()
            force.setFrequency(1)
            parameter_name = force.Pressure()
        else:
            # Add MonteCarloBarostat.
            force = mm.MonteCarloBarostat(thermodynamic_state.pressure,
                                          thermodynamic_state.temperature, 1)
            system.addForce(force)
            parameter_name = force.Pressure()

        # Create integrator.
        integrator = integrators.DummyIntegrator()

        # Random number seed.
        seed = np.random.randint(_RANDOM_SEED_MAX)
        force.setRandomNumberSeed(seed)

        # Create context.
        timer.start("Context Creation")
        context = sampler_state.createContext(integrator, platform=platform)
        timer.stop("Context Creation")

        # Set pressure.
        context.setParameter(parameter_name, thermodynamic_state.pressure)

        # Run update.
        # Note that ONE step of this integrator is equal to self.nsteps of velocity Verlet dynamics followed by Metropolis accept/reject.
        timer.start("step(1)")
        integrator.step(self.nattempts)
        timer.stop("step(1)")

        # Get sampler state.
        timer.start("update_sampler_state")
        updated_sampler_state = SamplerState.createFromContext(context)
        timer.stop("update_sampler_state")

        # DEBUG
        #print thermodynamics.volume(updated_sampler_state.box_vectors)

        # Clean up.
        del context

        # Restore frequency of barostat.
        if old_barostat_frequency:
            force.setFrequency(old_barostat_frequency)

        timer.report_timing()

        # Return updated sampler state.
        return updated_sampler_state
temperature = 300. 
pressure = 1.0 * u.atmospheres
ionicStrength = 0.05 * u.molar

pdb = app.PDBFile("./%s_fixed.pdb" % code)

modeller = app.Modeller(pdb.topology, pdb.positions)
modeller.addSolvent(ff, padding=padding, ionicStrength=ionicStrength)

topology = modeller.topology
positions = modeller.positions

system = ff.createSystem(topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=app.HBonds)

integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds, 1.0 * u.femtoseconds)
system.addForce(mm.MonteCarloBarostat(pressure, temperature, 25))
simulation = app.Simulation(topology, system, integrator)
simulation.context.setPositions(positions)
print('Minimizing...')
simulation.minimizeEnergy()

simulation.context.setVelocitiesToTemperature(temperature)
print('Equilibrating...')
simulation.step(50000)
state = simulation.context.getState(getPositions=True, getParameters=True)

positions = state.getPositions()
vectors = state.getPeriodicBoxVectors()
vectors = tuple([v[i] / u.nanometers for (i,v) in enumerate(vectors)])
vectors = u.Quantity(vectors, u.nanometer)
topology.setUnitCellDimensions(vectors)
Example #11
0
def solvate_and_minimize(topology, positions, phase=''):
    """
    Solvate the given system and minimize.

    Parameters
    ----------
    topology : simtk.openmm.Topology
        The topology
    positions : simtk.unit.Quantity of numpy.array of (natoms,3) with units compatible with nanometer.
        The positions
    phase : string, optional, default=''
        The phase prefix to prepend to written files.

    Returns
    -------
    topology : simtk.openmm.app.Topology
        The new Topology object
    system : simtk.openm.System
        The solvated system.
    positions : simtk.unit.Quantity of dimension natoms x 3 with units compatible with angstroms
        The minimized positions.

    """

    # Solvate (if desired) and create system.
    logger.info("Solvating...")
    forcefield = app.ForceField(*ffxmls)
    modeller = app.Modeller(topology, positions)
    modeller.addHydrogens(forcefield=forcefield, pH=pH)  # DEBUG
    if is_periodic:
        # Add solvent if in a periodic box.
        modeller.addSolvent(forcefield, padding=padding, model=water_name)
    system = forcefield.createSystem(modeller.topology,
                                     nonbondedMethod=nonbonded_method,
                                     nonbondedCutoff=nonbonded_cutoff,
                                     constraints=constraints)
    if is_periodic:
        system.addForce(
            openmm.MonteCarloBarostat(pressure, temperature,
                                      barostat_frequency))
    logger.info("System has %d atoms." % system.getNumParticles())

    # DEBUG
    print "modeller.topology.chains(): %s" % str(
        [chain.id for chain in modeller.topology.chains()])

    # Serialize to XML files.
    logger.info("Serializing to XML...")
    system_filename = os.path.join(workdir, 'system.xml')
    write_file(system_filename, openmm.XmlSerializer.serialize(system))

    if minimize:
        # Create simulation.
        logger.info("Creating simulation...")
        errorTol = 0.001
        integrator = openmm.VariableLangevinIntegrator(temperature,
                                                       collision_rate,
                                                       errorTol)
        simulation = app.Simulation(modeller.topology, system, integrator)
        simulation.context.setPositions(modeller.positions)

        # Print potential energy.
        potential = simulation.context.getState(
            getEnergy=True).getPotentialEnergy()
        logger.info("Potential energy is %12.3f kcal/mol" %
                    (potential / unit.kilocalories_per_mole))

        # Write modeller positions.
        logger.info("Writing modeller output...")
        filename = os.path.join(workdir, phase + 'modeller.pdb')
        app.PDBFile.writeFile(simulation.topology, modeller.positions,
                              open(filename, 'w'))

        # Minimize energy.
        logger.info("Minimizing energy...")
        simulation.minimizeEnergy(maxIterations=max_minimization_iterations)
        #integrator.step(max_minimization_iterations)
        state = simulation.context.getState(getEnergy=True)
        potential_energy = state.getPotentialEnergy()
        if np.isnan(potential_energy / unit.kilocalories_per_mole):
            raise Exception("Potential energy is NaN after minimization.")
        logger.info("Potential energy after minimiziation: %.3f kcal/mol" %
                    (potential_energy / unit.kilocalories_per_mole))
        modeller.positions = simulation.context.getState(
            getPositions=True).getPositions()

        # Print potential energy.
        potential = simulation.context.getState(
            getEnergy=True).getPotentialEnergy()
        logger.info("Potential energy is %12.3f kcal/mol" %
                    (potential / unit.kilocalories_per_mole))

        # Write minimized positions.
        filename = os.path.join(workdir, phase + 'minimized.pdb')
        app.PDBFile.writeFile(simulation.topology, modeller.positions,
                              open(filename, 'w'))

        # Clean up
        del simulation

    # Return the modeller instance.
    return [modeller.topology, system, modeller.positions]
Example #12
0
    def _build_sim(self):

        #set step length
        if self.hmr:
            self.step_length = 0.004 * unit.picoseconds
        else:
            self.step_length = 0.002 * unit.picoseconds

        if self.constraints in ['HBonds', 'HAngles', 'Allbonds']:
            print('setting {} constraints'.format(self.constraints))
            constraints_object = eval("app.%s" % self.constraints)
        else:
            print('did not set any constraints')
            constraints_object = None

        self.system = self.parmed_structure.createSystem(
            nonbondedMethod=self.nonbonded_method,
            nonbondedCutoff=self.nonbonded_cutoff * unit.angstroms,
            constraints=constraints_object,
            hydrogenMass=4.0 * unit.amu if self.hmr else None)

        if self.implicit_solvent_model:
            self.set_implicit_solvent_model(self.implicit_solvent_model,
                                            self.nonbonded_cutoff)

        if self.pressure:
            if self.membrane:
                barostat_force = mm.MonteCarloMembraneBarostat(
                    1 * unit.bar, 200 * unit.bar * unit.nanometer,
                    self.temperature * unit.kelvin,
                    mm.MonteCarloMembraneBarostat.XYIsotropic,
                    mm.MonteCarloMembraneBarostat.ZFree)
            else:
                barostat_force = mm.MonteCarloBarostat(
                    self.pressure * unit.atmospheres,
                    self.temperature * unit.kelvin, 25)
            self.system.addForce(barostat_force)

        if self.atoms_to_restrain is not None:
            self.set_positional_restraints(self.atoms_to_restrain)

        if self.atoms_to_freeze is not None:
            self.freeze_atom_selection(self.atoms_to_freeze)

        #get integrator
        if self.integrator not in ['Langevin', 'Verlet']:
            raise ValueError('{} integrator type not supported'.format(
                self.integrator))

        if self.integrator == 'Langevin':
            self.integrator = mm.LangevinIntegrator(
                self.temperature * unit.kelvin, 1 / unit.picoseconds,
                self.step_length)

        if self.integrator == 'Verlet':
            integrator = mm.VerletIntegrator(self.step_length)

        if self.platform:
            self.platform = mm.Platform.getPlatformByName(self.platform)
            self.simulation = app.Simulation(self.parmed_structure.topology,
                                             self.system,
                                             self.integrator,
                                             platform=self.platform)
        else:
            self.simulation = app.Simulation(self.parmed_structure.topology,
                                             self.system, self.integrator)

        self.simulation.context.setPositions(self.positions)

        if self.box_vectors is not None:
            self.simulation.context.setPeriodicBoxVectors(
                self.box_vectors[0], self.box_vectors[1], self.box_vectors[2])

        if self.velocities is not None:
            print('found velocities, restarting from previous simulation')
            self.simulation.context.setVelocities(self.velocities)
        else:
            print('assigning random velocity distribution with temperature {}'.
                  format(self.temperature))
            self.simulation.context.setVelocitiesToTemperature(
                self.temperature * unit.kelvin)
Example #13
0
def openmm_simulate_amber_npt(pdb_file, top_file, 
        check_point=None, GPU_index=0,
        output_traj="output.dcd", output_log="output.log", output_cm=None,
        temperature=300, 
        report_time=10*u.picoseconds, sim_time=10*u.nanoseconds):
    """
    Start and run an OpenMM NVT simulation with Langevin integrator at 2 fs 
    time step and 300 K. The cutoff distance for nonbonded interactions were 
    set at 1.0 nm, which commonly used along with Amber force field. Long-range
    nonbonded interactions were handled with PME. 

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

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

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

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

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

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

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

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

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

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

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

    simulation.context.setPositions(top.positions)

    simulation.minimizeEnergy()

    report_freq = int(report_time/dt)
    simulation.context.setVelocitiesToTemperature(10*u.kelvin, random.randint(1, 10000))
    simulation.reporters.append(app.DCDReporter(output_traj, report_freq))
    if output_cm:
        simulation.reporters.append(ContactMapReporter(output_cm, report_freq))
    simulation.reporters.append(app.StateDataReporter(output_log,
            report_freq, step=True, time=True, speed=True,
            potentialEnergy=True, temperature=True, totalEnergy=True))
    simulation.reporters.append(app.CheckpointReporter('checkpnt.chk', report_freq))

    if check_point:
        simulation.loadCheckpoint(check_point)
    nsteps = int(sim_time/dt)
    simulation.step(nsteps)
Example #14
0
P = 1 * u.atmosphere
ts = 0.002 * u.picoseconds

sstep = 100
nstep = 1000000

prmtop = app.AmberPrmtopFile('../complex.prmtop')
inpcrd = app.AmberInpcrdFile('../complex.inpcrd')

system = prmtop.createSystem(nonbondedMethod=app.PME,
                             nonbondedCutoff=10 * u.angstrom,
                             switchDistance=9 * u.angstrom,
                             constraints=app.HBonds)

integrator = mm.LangevinIntegrator(T_i, 1 / u.picosecond, ts)
barostat = mm.MonteCarloBarostat(P, T)

simulation = app.Simulation(prmtop.topology, system, integrator)

simulation.reporters.append(app.DCDReporter('output.dcd', 1000))
simulation.reporters.append(
    app.StateDataReporter('state.out',
                          1000,
                          step=True,
                          potentialEnergy=True,
                          temperature=True))

simulation.context.setPositions(inpcrd.positions)
simulation.context.setPeriodicBoxVectors(*inpcrd.boxVectors)

simulation.minimizeEnergy()
Example #15
0
# Thermodynamic and simulation control parameters
temperature = 300.0 * unit.kelvin
collision_rate = 90.0 / unit.picoseconds
pressure = 1.0 * unit.atmospheres
timestep = 2.0 * unit.femtoseconds
equil_steps = 1500

# Load AMBER files
prmtop = app.AmberPrmtopFile('prmtop')
inpcrd = app.AmberInpcrdFile('inpcrd')

# Initialize system, including a barostat
system = prmtop.createSystem(nonbondedMethod=app.CutoffPeriodic,
                             nonbondedCutoff=1.0 * unit.nanometer,
                             constraints=app.HBonds)
system.addForce(openmm.MonteCarloBarostat(pressure, temperature))
box_vectors = inpcrd.getBoxVectors(asNumpy=True)
system.setDefaultPeriodicBoxVectors(box_vectors[0], box_vectors[1],
                                    box_vectors[2])

# Create the integrator and context
integrator = openmm.LangevinIntegrator(temperature, collision_rate, timestep)
context = openmm.Context(system, integrator)
context.setPositions(inpcrd.positions)

# Minimize the system
openmm.LocalEnergyMinimizer.minimize(context)

# Briefly thermalize.
integrator.step(equil_steps)
Example #16
0
def generate_atp(phase='vacuum'):
    """
    modify the AlanineDipeptideVacuum test system to be parametrized with amber14ffsb in vac or solvent (tip3p)
    """
    import openmmtools.testsystems as ts
    from openmmforcefields.generators import SystemGenerator
    atp = ts.AlanineDipeptideVacuum(constraints=app.HBonds,
                                    hydrogenMass=4 * unit.amus)

    forcefield_files = [
        'gaff.xml', 'amber14/protein.ff14SB.xml', 'amber14/tip3p.xml'
    ]

    if phase == 'vacuum':
        barostat = None
        system_generator = SystemGenerator(
            forcefield_files,
            barostat=barostat,
            forcefield_kwargs={
                'removeCMMotion': False,
                'ewaldErrorTolerance': 1e-4,
                'constraints': app.HBonds,
                'hydrogenMass': 4 * unit.amus
            },
            nonperiodic_forcefield_kwargs={'nonbondedMethod': app.NoCutoff},
            small_molecule_forcefield='gaff-2.11',
            molecules=None,
            cache=None)

        atp.system = system_generator.create_system(
            atp.topology)  #update the parametrization scheme to amberff14sb

    elif phase == 'solvent':
        barostat = openmm.MonteCarloBarostat(1.0 * unit.atmosphere,
                                             300 * unit.kelvin, 50)

        system_generator = SystemGenerator(
            forcefield_files,
            barostat=barostat,
            forcefield_kwargs={
                'removeCMMotion': False,
                'ewaldErrorTolerance': 1e-4,
                'nonbondedMethod': app.PME,
                'constraints': app.HBonds,
                'hydrogenMass': 4 * unit.amus
            },
            small_molecule_forcefield='gaff-2.11',
            molecules=None,
            cache=None)

    if phase == 'solvent':
        modeller = app.Modeller(atp.topology, atp.positions)
        modeller.addSolvent(system_generator._forcefield,
                            model='tip3p',
                            padding=9 * unit.angstroms,
                            ionicStrength=0.15 * unit.molar)
        solvated_topology = modeller.getTopology()
        solvated_positions = modeller.getPositions()

        # canonicalize the solvated positions: turn tuples into np.array
        atp.positions = unit.quantity.Quantity(value=np.array([
            list(atom_pos) for atom_pos in
            solvated_positions.value_in_unit_system(unit.md_unit_system)
        ]),
                                               unit=unit.nanometers)
        atp.topology = solvated_topology

        atp.system = system_generator.create_system(atp.topology)

    return atp, system_generator
Example #17
0
print('\n=== Periodic Box ===')
periodic_box_vectors = [[box_L, 0., 0.], [0., box_L, 0.], [0., 0., box_L]]
print(periodic_box_vectors)
top.setPeriodicBoxVectors(periodic_box_vectors * unit.nanometer)

print('\n=== Making System ===')
system = forcefield.createSystem(top,
                                 nonbondedMethod=nonbonded_method,
                                 nonbondedCutoff=nonbonded_cutoff,
                                 ewaldErrorTolerance=ewald_tol,
                                 rigidWater=True,
                                 constraints=None)

integrator = mm.LangevinIntegrator(temperature * unit.kelvin, friction,
                                   dt * unit.picosecond)
barostat = mm.MonteCarloBarostat(pressure * unit.bar,
                                 temperature * unit.kelvin, barostatfreq)
#barostat = mm.MonteCarloBarostat( pressure, temperature, barostatfreq )
if run_npt:
    system.addForce(barostat)

if use_gpu:
    platform = mm.Platform.getPlatformByName('OpenCL')
    properties = {'DeviceIndex': '1', 'Precision': 'mixed'}
else:
    platform = mm.Platform.getPlatformByName('CPU')
    properties = {'Threads': '1'}

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

# === Get initial configuration ===
out_pdb_filename = PackMol(nMols, chainPDBs, box_L, box_L, box_L)
Example #18
0
def main():

    prmtop_filename = '/lustre/atlas/scratch/farkaspall/chm126/inspire-data/nilotinib/e255k/build/e255k-complex.top'
    crd_filename = '/lustre/atlas/scratch/farkaspall/chm126/inspire-data/nilotinib/e255k/build/e255k-complex.inpcrd'

    prmtop = AmberParm(prmtop_filename, crd_filename)

    system = prmtop.createSystem(nonbondedMethod=app.PME,
                                 nonbondedCutoff=10 * unit.angstrom,
                                 constraints=app.HBonds,
                                 switchDistance=8 * unit.angstrom)

    temperature = 300 * unit.kelvin
    pressure = 1 * unit.atmosphere
    collision_rate = 5 / unit.picosecond
    timestep = 2 * unit.femtosecond

    integrator = openmm.LangevinIntegrator(temperature, collision_rate,
                                           timestep)
    barostat = openmm.MonteCarloBarostat(temperature, pressure)
    system.addForce(barostat)

    restrain = True

    if restrain:
        restrained_atoms = mdtraj.Topology.from_openmm(
            prmtop.topology).select("protein and not type H").tolist()
        K = 4.0 * unit.kilocalorie / (unit.angstrom**2 * unit.mole)
        energy_expression = '(K/2)*periodicdistance(x, y, z, x0, y0, z0)^2'
        restraint_force = openmm.CustomExternalForce(energy_expression)
        restraint_force.addGlobalParameter('K', K)
        restraint_force.addPerParticleParameter('x0')
        restraint_force.addPerParticleParameter('y0')
        restraint_force.addPerParticleParameter('z0')
        for index in restrained_atoms:
            parameters = prmtop.positions[index].value_in_unit_system(
                unit.md_unit_system)
            restraint_force.addParticle(index, parameters)

        system.addForce(restraint_force)

    system.setDefaultPeriodicBoxVectors(*prmtop.box_vectors)

    simulation = app.Simulation(prmtop.topology, system, integrator)

    simulation.context.setPositions(prmtop.positions)
    simulation.context.setVelocitiesToTemperature(temperature)

    print('System contains {} atoms.'.format(system.getNumParticles()))
    print('Using platform "{}".'.format(
        simulation.context.getPlatform().getName()))

    print('Minimizing energy to avoid clashes.')
    simulation.minimizeEnergy(maxIterations=100)

    print('Initial potential energy is {}'.format(
        simulation.context.getState(getEnergy=True).getPotentialEnergy()))

    # Warm up the integrator to compile kernels, etc
    print('Warming up integrator to trigger kernel compilation...')
    simulation.step(10)

    # Time integration
    print('Time: {}'.format(time.strftime('%H:%M:%S')))
    print('Benchmarking...')
    nsteps = 20000
    initial_time = time.time()
    integrator.step(nsteps)
    final_time = time.time()
    elapsed_time = (final_time - initial_time) * unit.seconds
    simulated_time = nsteps * timestep
    performance = (simulated_time / elapsed_time)
    print('Time: {}'.format(time.strftime('%H:%M:%S')))
    print('Completed {} steps in {}.'.format(nsteps, elapsed_time))
    print('Performance is {} ns/day'.format(performance /
                                            (unit.nanoseconds / unit.day)))
    print('Final potential energy is {}'.format(
        simulation.context.getState(getEnergy=True).getPotentialEnergy()))
    def __init__(
            self,
            receptor_filename,
            ligand_filename,
            mutation_chain_id,
            mutation_residue_id,
            proposed_residue,
            phase='complex',
            conduct_endstate_validation=False,
            ligand_index=0,
            forcefield_files=[
                'amber14/protein.ff14SB.xml', 'amber14/tip3p.xml'
            ],
            barostat=openmm.MonteCarloBarostat(1.0 * unit.atmosphere,
                                               temperature, 50),
            forcefield_kwargs={
                'removeCMMotion': False,
                'ewaldErrorTolerance': 1e-4,
                'constraints': app.HBonds,
                'hydrogenMass': 4 * unit.amus
            },
            periodic_forcefield_kwargs={'nonbondedMethod': app.PME},
            small_molecule_forcefields='gaff-2.11',
            **kwargs):
        """
        arguments
            receptor_filename : str
                path to receptor; .pdb
            ligand_filename : str
                path to ligand of interest; .sdf or .pdb
            mutation_chain_id : str
                name of the chain to be mutated
            mutation_residue_id : str
                residue id to change
            proposed_residue : str
                three letter code of the residue to mutate to
            phase : str, default complex
                if phase == vacuum, then the complex will not be solvated with water; else, it will be solvated with tip3p
            conduct_endstate_validation : bool, default True
                whether to conduct an endstate validation of the hybrid topology factory
            ligand_index : int, default 0
                which ligand to use
            forcefield_files : list of str, default ['amber14/protein.ff14SB.xml', 'amber14/tip3p.xml']
                forcefield files for proteins and solvent
            barostat : openmm.MonteCarloBarostat, default openmm.MonteCarloBarostat(1.0 * unit.atmosphere, 300 * unit.kelvin, 50)
                barostat to use
            forcefield_kwargs : dict, default {'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'nonbondedMethod': app.NoCutoff, 'constraints' : app.HBonds, 'hydrogenMass' : 4 * unit.amus}
                forcefield kwargs for system parametrization
            periodic_forcefield_kwargs : dict default {'nonbondedMethod':app.PME}
            small_molecule_forcefields : str, default 'gaff-2.11'
                the forcefield string for small molecule parametrization

        TODO : allow argument for separate apo structure if it exists separately
               allow argument for specator ligands besides the 'ligand_filename'
        """
        from openforcefield.topology import Molecule
        from openmmforcefields.generators import SystemGenerator

        # first thing to do is make a complex and apo...
        pdbfile = open(receptor_filename, 'r')
        pdb = app.PDBFile(pdbfile)
        pdbfile.close()
        receptor_positions, receptor_topology, receptor_md_topology = pdb.positions, pdb.topology, md.Topology.from_openmm(
            pdb.topology)
        receptor_topology = receptor_md_topology.to_openmm()
        receptor_n_atoms = receptor_md_topology.n_atoms

        molecules = []
        ligand_mol = createOEMolFromSDF(ligand_filename, index=ligand_index)
        ligand_mol = generate_unique_atom_names(ligand_mol)
        molecules.append(
            Molecule.from_openeye(ligand_mol, allow_undefined_stereo=False))
        ligand_positions, ligand_topology = extractPositionsFromOEMol(
            ligand_mol), forcefield_generators.generateTopologyFromOEMol(
                ligand_mol)
        ligand_md_topology = md.Topology.from_openmm(ligand_topology)
        ligand_n_atoms = ligand_md_topology.n_atoms

        #now create a complex
        complex_md_topology = receptor_md_topology.join(ligand_md_topology)
        complex_topology = complex_md_topology.to_openmm()
        complex_positions = unit.Quantity(np.zeros(
            [receptor_n_atoms + ligand_n_atoms, 3]),
                                          unit=unit.nanometers)
        complex_positions[:receptor_n_atoms, :] = receptor_positions
        complex_positions[receptor_n_atoms:, :] = ligand_positions

        #now for a system_generator
        self.system_generator = SystemGenerator(
            forcefields=forcefield_files,
            barostat=barostat,
            forcefield_kwargs=forcefield_kwargs,
            periodic_forcefield_kwargs=periodic_forcefield_kwargs,
            small_molecule_forcefield=small_molecule_forcefields,
            molecules=molecules,
            cache=None)

        #create complex and apo inputs...
        complex_topology, complex_positions, complex_system = self._solvate(
            complex_topology, complex_positions, 'tip3p', phase=phase)
        apo_topology, apo_positions, apo_system = self._solvate(
            receptor_topology, receptor_positions, 'tip3p', phase='phase')

        geometry_engine = FFAllAngleGeometryEngine(
            metadata=None,
            use_sterics=False,
            n_bond_divisions=100,
            n_angle_divisions=180,
            n_torsion_divisions=360,
            verbose=True,
            storage=None,
            bond_softening_constant=1.0,
            angle_softening_constant=1.0,
            neglect_angles=False,
            use_14_nonbondeds=True)

        #run pipeline...
        htfs = []
        for (top, pos, sys) in zip([complex_topology, apo_topology],
                                   [complex_positions, apo_positions],
                                   [complex_system, apo_system]):
            point_mutation_engine = PointMutationEngine(
                wildtype_topology=top,
                system_generator=self.system_generator,
                chain_id=
                mutation_chain_id,  #denote the chain id allowed to mutate (it's always a string variable)
                max_point_mutants=1,
                residues_allowed_to_mutate=[
                    mutation_residue_id
                ],  #the residue ids allowed to mutate
                allowed_mutations=[
                    (mutation_residue_id, proposed_residue)
                ],  #the residue ids allowed to mutate with the three-letter code allowed to change
                aggregate=True)  #always allow aggregation

            topology_proposal = point_mutation_engine.propose(sys, top)

            new_positions, logp_proposal = geometry_engine.propose(
                topology_proposal, pos, beta)
            logp_reverse = geometry_engine.logp_reverse(
                topology_proposal, new_positions, pos, beta)

            forward_htf = HybridTopologyFactory(
                topology_proposal=topology_proposal,
                current_positions=pos,
                new_positions=new_positions,
                use_dispersion_correction=False,
                functions=None,
                softcore_alpha=None,
                bond_softening_constant=1.0,
                angle_softening_constant=1.0,
                soften_only_new=False,
                neglected_new_angle_terms=[],
                neglected_old_angle_terms=[],
                softcore_LJ_v2=True,
                softcore_electrostatics=True,
                softcore_LJ_v2_alpha=0.85,
                softcore_electrostatics_alpha=0.3,
                softcore_sigma_Q=1.0,
                interpolate_old_and_new_14s=False,
                omitted_terms=None)

            if not topology_proposal.unique_new_atoms:
                assert geometry_engine.forward_final_context_reduced_potential == None, f"There are no unique new atoms but the geometry_engine's final context reduced potential is not None (i.e. {self._geometry_engine.forward_final_context_reduced_potential})"
                assert geometry_engine.forward_atoms_with_positions_reduced_potential == None, f"There are no unique new atoms but the geometry_engine's forward atoms-with-positions-reduced-potential in not None (i.e. { self._geometry_engine.forward_atoms_with_positions_reduced_potential})"
                vacuum_added_valence_energy = 0.0
            else:
                added_valence_energy = geometry_engine.forward_final_context_reduced_potential - geometry_engine.forward_atoms_with_positions_reduced_potential

            if not topology_proposal.unique_old_atoms:
                assert geometry_engine.reverse_final_context_reduced_potential == None, f"There are no unique old atoms but the geometry_engine's final context reduced potential is not None (i.e. {self._geometry_engine.reverse_final_context_reduced_potential})"
                assert geometry_engine.reverse_atoms_with_positions_reduced_potential == None, f"There are no unique old atoms but the geometry_engine's atoms-with-positions-reduced-potential in not None (i.e. { self._geometry_engine.reverse_atoms_with_positions_reduced_potential})"
                subtracted_valence_energy = 0.0
            else:
                subtracted_valence_energy = geometry_engine.reverse_final_context_reduced_potential - geometry_engine.reverse_atoms_with_positions_reduced_potential

            if conduct_endstate_validation:
                zero_state_error, one_state_error = validate_endstate_energies(
                    forward_htf._topology_proposal,
                    forward_htf,
                    added_valence_energy,
                    subtracted_valence_energy,
                    beta=beta,
                    ENERGY_THRESHOLD=ENERGY_THRESHOLD)
            else:
                pass

            htfs.append(forward_htf)

        self.complex_htf = htfs[0]
        self.apo_htf = htfs[1]
Example #20
0
#box = complex_solv.box;
#print("Starting with new velocities ....");
printfile = sys.stdout;

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

# Add Force Barostat to the system
if simType == 'npt':
   system.addForce(mm.MonteCarloBarostat(pressureAtm*u.atmospheres, tempK*u.kelvin, 25))

# Apply restraints
if restraints :
    print("RESTRAINT mask applied to: {}"
                       "\tRestraint weight: {}".format(restraintAtom,
                                                       restraintWt*
                                                       u.kilocalories_per_mole/u.angstroms**2))
    # Select atom to restraint
    print("Type of restraint atoms: {}".format(restraintType))
    # define the custom force to restrain atoms to their starting positions
    force_restr = mm.CustomExternalForce('k_restr*periodicdistance(x, y, z, x0, y0, z0)^2')
    # Add the restraint weight as a global parameter in kcal/mol/A^2
    force_restr.addGlobalParameter("k_restr", restraintWt*u.kilocalories_per_mole/u.angstroms**2)
    # Define the target xyz coords for the restraint as per-atom (per-particle) parameters
    force_restr.addPerParticleParameter("x0")
    print(pdb_filename)

    if os.path.exists(output_pdb):
        continue    

    ff = app.ForceField('%s.xml' % ff_name, '%s.xml' % water_name)
    
    pdb = app.PDBFile(pdb_filename)
    modeller = app.Modeller(pdb.topology, pdb.positions)
    modeller.addSolvent(ff, model=base_waters[water_name], padding=padding)
    topology = modeller.getTopology()
    positions = modeller.getPositions()
    
    system = ff.createSystem(topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=app.HBonds)
    integrator = mm.LangevinIntegrator(temperature, friction, timestep)
    system.addForce(mm.MonteCarloBarostat(pressure, temperature, barostat_frequency))

    simulation = app.Simulation(topology, system, integrator)
    simulation.context.setPositions(positions)
    
    print('Minimizing...')
    simulation.minimizeEnergy()

    simulation.context.setVelocitiesToTemperature(temperature)
    print('Running.')
    simulation.reporters.append(app.PDBReporter(output_pdb, equilibrate_output_frequency))
    simulation.reporters.append(app.DCDReporter(output_dcd, equilibrate_output_frequency))
    simulation.step(n_equil_steps)
    del simulation
    del system
    t = md.load(output_dcd, top=output_pdb)
Example #22
0
from __future__ import print_function
from simtk.openmm import app
import simtk.openmm as mm
from simtk import unit
from sys import stdout

prmtop = app.AmberPrmtopFile('../equib/ade_D_ala.prmtop')
inpcrd = app.AmberInpcrdFile('../equib/ade_D_ala.inpcrd')

system = prmtop.createSystem(nonbondedMethod=app.PME, 
    nonbondedCutoff=1.0*unit.nanometers, constraints=app.HBonds, rigidWater=True, 
    ewaldErrorTolerance=0.0005)
integrator = mm.LangevinIntegrator(300*unit.kelvin, 1.0/unit.picoseconds, 
    2.0*unit.femtoseconds)
integrator.setConstraintTolerance(0.00001)
system.addForce(mm.MonteCarloBarostat(1*unit.atmospheres, 300*unit.kelvin, 25))

platform = mm.Platform.getPlatformByName('CUDA')
properties = {'CudaPrecision': 'mixed', 'CudaDeviceIndex': '0'}
simulation = app.Simulation(prmtop.topology, system, integrator, platform, 
    properties)
simulation.loadState('../equib/equilibrated.xml')
simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
total_steps = 500000000
simulation.reporters.append(app.DCDReporter('trajectory002.dcd', 5000))
simulation.reporters.append(app.StateDataReporter('prod002.dat', 50000, step=True,
    time=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, 
    temperature=True, volume=True, density=True, progress=True, 
    remainingTime=True, speed=True, totalSteps=total_steps, separator=','))
simulation.reporters.append(app.CheckpointReporter('checkpnt002.chk', 50000))
Example #23
0
ff = app.ForceField(which_forcefield, which_water)

pdb = app.PDBFile(pdb_filename)

topology = pdb.topology
positions = pdb.positions

system = ff.createSystem(topology,
                         nonbondedMethod=app.PME,
                         nonbondedCutoff=cutoff,
                         constraints=app.HBonds)

integrator = mm.LangevinIntegrator(temperature, equil_friction, equil_timestep)
system.addForce(
    mm.MonteCarloBarostat(pressure, temperature, barostat_frequency))

simulation = app.Simulation(topology, system, integrator)
simulation.context.setPositions(positions)
print('Minimizing...')
simulation.minimizeEnergy()

simulation.context.setVelocitiesToTemperature(temperature)
print('Equilibrating...')

simulation.step(discard_steps)  # Don't even save the first XXX ps

simulation.reporters.append(app.DCDReporter(dcd_filename, output_frequency))
simulation.reporters.append(app.PDBReporter(out_pdb_filename, n_steps - 1))
simulation.reporters.append(
    app.StateDataReporter(open(log_filename, 'w'),
Example #24
0
 def apply_barostat(self):
     if not self.system.usesPeriodicBoundaryConditions():
         raise ValueError('Barostat can only be used with PBC conditions.')
     self.system.addForce(mm.MonteCarloBarostat(self.pressure*u.bar,
                                                self.temperature*u.kelvin,
                                                self.barostat_interval))
Example #25
0
# Create output directory
output_prefix = "./output/" + chosen_ligand
os.makedirs(output_prefix, exist_ok=True)
print("--> Directory ", output_prefix, " created ")

# Set file names
integrator_xml_filename = "integrator_2fs.xml"
state_xml_filename = "pr_output_state.xml"
state_pdb_filename = "pr_output_state.pdb"
system_xml_filename = "pr_output_system.xml"
checkpoint_filename = "pr_output_checkpoint.chk"
traj_output_filename = "pr_output_traj.xtc"

# Define the barostat for the system
barostat = mm.MonteCarloBarostat(pressure, temperature)

# Read in equilibrated system (PDB)
pdb = PDBFile(input_pdb)

# Deserialize system file and load system
with open(input_system, 'r') as f:
    system = XmlSerializer.deserialize(f.read())

# Make and serialize integrator - Langevin dynamics
print("Serializing integrator to %s" %
      os.path.join(output_prefix, integrator_xml_filename))
integrator = mm.LangevinIntegrator(
    temperature,
    collision_rate,
    timestep  # Friction coefficient
Example #26
0
def generate_solvated_hybrid_test_topology(current_mol_name="naphthalene", proposed_mol_name="benzene"):
    """
    Generate a test solvated topology proposal, current positions, and new positions triplet
    from two IUPAC molecule names.

    Parameters
    ----------
    current_mol_name : str, optional
        name of the first molecule
    proposed_mol_name : str, optional
        name of the second molecule

    Returns
    -------
    topology_proposal : perses.rjmc.topology_proposal
        The topology proposal representing the transformation
    current_positions : np.array, unit-bearing
        The positions of the initial system
    new_positions : np.array, unit-bearing
        The positions of the new system
    """
    import simtk.openmm.app as app
    from openmoltools import forcefield_generators
    from openeye import oechem
    from perses.rjmc.topology_proposal import SystemGenerator, SmallMoleculeSetProposalEngine
    from perses.rjmc import geometry

    from perses.utils.data import get_data_filename

    current_mol, unsolv_old_system, pos_old, top_old = createSystemFromIUPAC(current_mol_name)

    proposed_mol = iupac_to_oemol(proposed_mol_name)
    proposed_mol.SetTitle("MOL")

    initial_smiles = oechem.OEMolToSmiles(current_mol)
    final_smiles = oechem.OEMolToSmiles(proposed_mol)

    gaff_xml_filename = get_data_filename("data/gaff.xml")
    forcefield = app.ForceField(gaff_xml_filename, 'tip3p.xml')
    forcefield.registerTemplateGenerator(forcefield_generators.gaffTemplateGenerator)

    modeller = app.Modeller(top_old, pos_old)
    modeller.addSolvent(forcefield, model='tip3p', padding=9.0*unit.angstrom)
    solvated_topology = modeller.getTopology()
    solvated_positions = modeller.getPositions()
    solvated_system = forcefield.createSystem(solvated_topology, nonbondedMethod=app.PME, removeCMMotion=False)
    barostat = openmm.MonteCarloBarostat(1.0*unit.atmosphere, temperature, 50)

    solvated_system.addForce(barostat)

    gaff_filename = get_data_filename('data/gaff.xml')

    system_generator = SystemGenerator([gaff_filename, 'amber99sbildn.xml', 'tip3p.xml'], barostat=barostat, forcefield_kwargs={'removeCMMotion': False},periodic_forcefield_kwargs={'nonbondedMethod': app.PME})
    geometry_engine = geometry.FFAllAngleGeometryEngine()
    canonicalized_smiles_list = [SmallMoleculeSetProposalEngine.canonicalize_smiles(smiles) for smiles in [initial_smiles, final_smiles]]
    proposal_engine = SmallMoleculeSetProposalEngine(
        canonicalized_smiles_list, system_generator, residue_name="MOL")

    #generate topology proposal
    topology_proposal = proposal_engine.propose(solvated_system, solvated_topology)

    #generate new positions with geometry engine
    new_positions, _ = geometry_engine.propose(topology_proposal, solvated_positions, beta)

    return topology_proposal, solvated_positions, new_positions
Example #27
0
#now run the simulations
for k in range(nstates):
    print("*******************Lambda %.2f*******************" % lambdas[k])
    #create the lambda folderse if it does not exist
    if not os.path.exists("lambda-%.2f" % lambdas[k]):
            os.makedirs("lambda-%.2f" % lambdas[k])
    simfile = open("lambda-%.2f/simfile.csv" % lambdas[k],"w")

    if (k==0):
        #at lambda 0.0 initialize the system 
        #when we are at the very first iteration of lambda 0, create all the initial system
        #create an alchemical system
        alchemical_system = set_lambda_electrostatics(reference_system,[0],lambdas[k])
        #add barostat
        alchemical_barostat = openmm.MonteCarloBarostat(pressure, temperature, 25)
        alchemical_system.addForce(alchemical_barostat)
        #add the thermostat
        alchemical_thermostat = openmm.AndersenThermostat(temperature, collision_rate)
        alchemical_system.addForce(alchemical_thermostat)
        #define the Verlet integrator
        alchemical_integrator = openmm.VerletIntegrator(timestep)
        #set the simulation
        alchemical_simulation = app.Simulation(base.topology, alchemical_system,alchemical_integrator,platform,properties)
        #set the positions based on the coordinate files
        alchemical_simulation.context.setPositions(base.positions)
        alchemical_simulation.context.setVelocitiesToTemperature(temperature)
    else:
        #if we are doing the other iterations or lambdas, recrate the system, based on the temporary/previous
        #alchemical system
        alchemical_system = set_lambda_electrostatics(reference_system,[0],lambdas[k])
Example #28
0
def equilibrateSystem(pdbfile,
                      psffile,
                      outpdb,
                      numsteps=30000,
                      minimplatform='CPU',
                      equilplatform='CUDA',
                      device=0,
                      temp=300,
                      minimize=500000,
                      minimizetol=100,
                      charmmfolder=None):
    pdb = Molecule(pdbfile)
    watcoo = pdb.get('coords', 'water')
    celld = unit.Quantity((watcoo.max(axis=0) - watcoo.min(axis=0)).squeeze(),
                          unit=unit.angstrom)

    psf = app.CharmmPsfFile(psffile)
    pdb = app.PDBFile(pdbfile)
    psf.setBox(celld[0], celld[1], celld[2])

    params = _readCharmmParameters(charmmfolder, defaultCharmmFiles)

    system = psf.createSystem(params,
                              nonbondedMethod=app.PME,
                              nonbondedCutoff=1 * unit.nanometer,
                              constraints=app.HBonds)
    system.addForce(
        mm.MonteCarloBarostat(1 * unit.atmospheres, temp * unit.kelvin, 25))

    platform, prop = _getPlatform(minimplatform, device)
    integrator = mm.LangevinIntegrator(temp * unit.kelvin, 1 / unit.picosecond,
                                       0.002 * unit.picoseconds)
    simulation = app.Simulation(psf.topology, system, integrator, platform,
                                prop)
    simulation.context.setPositions(pdb.positions)

    # Perform minimization
    _printEnergies(simulation, 'Energy before minimization')
    simulation.minimizeEnergy(tolerance=minimizetol * unit.kilojoule /
                              unit.mole,
                              maxIterations=minimize)
    _printEnergies(simulation, 'Energy after minimization')

    # Copy coordinates from miminization context to equilibration context
    state = simulation.context.getState(getPositions=True)
    pos = state.getPositions()

    # Set up the equilibration simulation
    platform, prop = _getPlatform(equilplatform, device)
    integrator = mm.LangevinIntegrator(temp * unit.kelvin, 1 / unit.picosecond,
                                       0.002 * unit.picoseconds)
    simulation = app.Simulation(psf.topology, system, integrator, platform,
                                prop)
    simulation.context.setPositions(pos)

    # Generate initial velocities
    simulation.context.setVelocitiesToTemperature(temp)

    from htmd.membranebuilder.pdbreporter import PDBReporter
    simulation.reporters.append(
        PDBReporter(outpdb, numsteps, enforcePeriodicBox=False))
    simulation.reporters.append(
        app.StateDataReporter(stdout,
                              int(numsteps / 10),
                              step=True,
                              potentialEnergy=True,
                              kineticEnergy=True,
                              totalEnergy=True,
                              temperature=True,
                              progress=True,
                              speed=True,
                              remainingTime=True,
                              totalSteps=numsteps,
                              separator='\t'))
    simulation.step(numsteps)
Example #29
0
    def equilibration_NPT(self, protocol, index=0):      
            
        eq_trj=f'{self.workdir}/equilibration_NPT'

        if protocol['restrained_sets']:

            #call to setRestraints, returns updated system. Check protocol['restrained_sets'] definitions on setSimulation.            
            self.system=self.setRestraints(protocol['restrained_sets'])

        # add MC barostat for NPT     
        self.system.addForce(omm.MonteCarloBarostat(self.pressure, 
                                                    self.temperature, 
                                                    25)) 
        #TODO: force is hardcoded, make it go away. Check units throughout!
        
        
        self.simulation.context.setPositions(self.positions)
        
        if index == 0:
        
            self.simulation.context.setVelocitiesToTemperature(self.temperature)
        
        # Define reporters
        self.simulation.reporters.append(DCDReporter(f'{eq_trj}.dcd', protocol['report']))           
        self.simulation.reporters.append(HDF5Reporter(f'{eq_trj}.h5', protocol['report'], atomSubset=self.trj_indices))
        self.simulation.reporters.append(app.StateDataReporter(f'{eq_trj}.csv', 
                                                          protocol['report'], 
                                                          step=True, 
                                                          totalEnergy=True, 
                                                          temperature=True,
                                                          density=True,
                                                          progress=True, 
                                                          remainingTime=True, 
                                                          speed=True, 
                                                          totalSteps=protocol['step'], 
                                                          separator='\t'))
        
        positions_first = self.simulation.context.getState(getPositions=True).getPositions()
        
        self.writePDB(self.simulation.topology, positions_first, name='equilibration_NPT_0')
        
        #############
        ## WARNIN ##
        #############
        
        trj_time=protocol['step']*self.dt
        print(f"Restrained NPT equilibration ({trj_time})...")
        
        self.simulation.step(protocol['step'])
        
        #############
        ## WARNOUT ##
        #############

        state=self.simulation.context.getState(getPositions=True, getVelocities=True, getEnergy=True)
        self.positions = state.getPositions()
        self.velocities = state.getVelocities()
        self.energy=state.getPotentialEnergy()

        print('NPT equilibration finished.')
        
        self.EQ_NPT_PDB=self.writePDB(self.simulation.topology, self.positions, name='equilibration_NPT')
         
        self.system=self.forceHandler(self.system, kinds=['CustomExternalForce', 'MonteCarloBarostat'])         
            
        return self.simulation
Example #30
0
#-----------------------------------------------------------------------------

# Load up custom residue definitions. This is necessary for OpenMM to recognize
# the unnnatural amino acid that I'm using.
app.Topology.loadBondDefinitions('../residues-nle.xml')
pdb = app.PDBFile(NATIVE)
forcefield = app.ForceField('amber99sbildn.xml', 'tip3p.xml', '../amber99sbildn-nle.xml')

modeller = app.Modeller(pdb.topology, pdb.positions)
modeller.addSolvent(forcefield, model='tip3p', boxSize=BOX_SIZE, ionicStrength=40*unit.millimolar)

system = forcefield.createSystem(modeller.topology, nonbondedMethod=app.PME, 
                                 nonbondedCutoff=9.5*unit.angstroms,
                                 constraints=app.HBonds, rigidWater=True, 
                                 ewaldErrorTolerance=0.0005)
system.addForce(mm.MonteCarloBarostat(1*unit.atmosphere, TEMPERATURE, 25))

integrator = mm.LangevinIntegrator(TEMPERATURE, 1.0/unit.picoseconds, TIMESTEP)
integrator.setConstraintTolerance(0.00001)

platform = mm.Platform.getPlatformByName('CUDA')
properties = {'CudaPrecision': 'mixed'}
simulation = app.Simulation(modeller.topology, system, integrator, platform, properties)
simulation.context.setPositions(modeller.positions)

print 'Setting Velocities'
simulation.context.setVelocitiesToTemperature(TEMPERATURE)

print 'Adding reporters'
simulation.reporters.append(HDF5Reporter(OUT_FN, REPORT_INTERVAL))
simulation.reporters.append(ProgressReporter(sys.stdout, REPORT_INTERVAL, N_STEPS))