示例#1
0
                        vdw_lambda=vdw_lambda,
                        annihilate_coulomb=True,
                        annihilate_vdw=True))

# Create alchemical states where we turn on charges with full Lennard-Jones.
for coulomb_lambda in coulomb_lambdas:
    alchemical_states.append(
        AlchemicalState(coulomb_lambda=coulomb_lambda,
                        vdw_lambda=1.0,
                        annihilate_coulomb=True,
                        annihilate_vdw=True))

alchemical_factory = AbsoluteAlchemicalFactory(
    reference_system, alchemical_atoms=alchemical_atoms)
systems = alchemical_factory.createPerturbedSystems(
    alchemical_states
)  # systems[istate] will be the System object corresponding to alchemical intermediate state index 'istate'
nstates = len(systems)

#==============================================================================
# Run simulation.
#==============================================================================

# Initialize NetCDF file to store data.
import netCDF4 as netcdf
ncfile = netcdf.Dataset(filename, 'w', version='NETCDF4')
ncfile.createDimension('iteration', 0)  # unlimited number of iterations
ncfile.createDimension('state', nstates)  # number of replicas
ncfile.createDimension(
    'atom', reference_system.getNumParticles())  # number of atoms in system
ncfile.createDimension('spatial', 3)  # number of spatial dimensions
示例#2
0
文件: yank.py 项目: kmvisscher/yank
    def _create_phase(self, phase, reference_system, positions, atom_indices, thermodynamic_state, protocols=None, options=None, mpicomm=None):
        """
        Create a repex object for a specified phase.

        Parameters
        ----------
        phase : str
           The phase being initialized (one of ['complex', 'solvent', 'vacuum'])
        reference_system : simtk.openmm.System
           The reference system object from which alchemical intermediates are to be construcfted.
        positions : list of simtk.unit.Qunatity objects containing (natoms x 3) positions (as np or lists)
           The list of positions to be used to seed replicas in a round-robin way.
        atom_indices : dict
           atom_indices[phase][component] is the set of atom indices associated with component, where component is ['ligand', 'receptor']
        thermodynamic_state : ThermodynamicState
           Thermodynamic state from which reference temperature and pressure are to be taken.
        protocols : dict of list of AlchemicalState, optional, default=None
           If specified, the alchemical protocol protocols[phase] will be used for phase 'phase' instead of the default.
        options : dict of str, optional, default=None
           If specified, these options will override default repex simulation options.

        """

        # Make sure positions argument is a list of coordinate snapshots.
        if hasattr(positions, 'unit'):
            # Wrap in list.
            positions = [positions]

        # Check the dimensions of positions.
        for index in range(len(positions)):
            # Make sure it is recast as a np array.
            positions[index] = unit.Quantity(np.array(positions[index] / positions[index].unit), positions[index].unit)

            [natoms, ndim] = (positions[index] / positions[index].unit).shape
            if natoms != reference_system.getNumParticles():
                raise Exception("positions argument must be a list of simtk.unit.Quantity of (natoms,3) lists or np array with units compatible with nanometers.")

        # Create metadata storage.
        metadata = dict()

        # Make a deep copy of the reference system so we don't accidentally modify it.
        reference_system = copy.deepcopy(reference_system)

        # TODO: Use more general approach to determine whether system is periodic.
        is_periodic = self._is_periodic(reference_system)

        # Make sure pressure is None if not periodic.
        if not is_periodic: thermodynamic_state.pressure = None

        # Compute standard state corrections for complex phase.
        metadata['standard_state_correction'] = 0.0
        # TODO: Do we need to include a standard state correction for other phases in periodic boxes?
        if phase == 'complex-implicit':
            # Impose restraints for complex system in implicit solvent to keep ligand from drifting too far away from receptor.
            if self.verbose: print "Creating receptor-ligand restraints..."
            reference_positions = positions[0]
            if self.restraint_type == 'harmonic':
                restraints = HarmonicReceptorLigandRestraint(thermodynamic_state, reference_system, reference_positions, atom_indices['receptor'], atom_indices['ligand'])
            elif self.restraint_type == 'flat-bottom':
                restraints = FlatBottomReceptorLigandRestraint(thermodynamic_state, reference_system, reference_positions, atom_indices['receptor'], atom_indices['ligand'])
            else:
                raise Exception("restraint_type of '%s' is not supported." % self.restraint_type)

            force = restraints.getRestraintForce() # Get Force object incorporating restraints
            reference_system.addForce(force)
            metadata['standard_state_correction'] = restraints.getStandardStateCorrection() # standard state correction in kT
        elif phase == 'complex-explicit':
            # For periodic systems, we do not use a restraint, but must add a standard state correction for the box volume.
            # TODO: What if the box volume fluctuates during the simulation?
            box_vectors = reference_system.getDefaultPeriodicBoxVectors()
            box_volume = thermodynamic_state._volume(box_vectors)
            STANDARD_STATE_VOLUME = 1660.53928 * unit.angstrom**3
            metadata['standard_state_correction'] = np.log(STANDARD_STATE_VOLUME / box_volume) # TODO: Check sign.

        # Use default alchemical protocols if not specified.
        if not protocols:
            protocols = self.default_protocols

        # Create alchemically-modified states using alchemical factory.
        if self.verbose: print "Creating alchemically-modified states..."
        factory = AbsoluteAlchemicalFactory(reference_system, ligand_atoms=atom_indices['ligand'])
        systems = factory.createPerturbedSystems(protocols[phase])

        # Randomize ligand position if requested, but only for implicit solvent systems.
        if self.randomize_ligand and (phase == 'complex-implicit'):
            if self.verbose: print "Randomizing ligand positions and excluding overlapping configurations..."
            randomized_positions = list()
            nstates = len(systems)
            for state_index in range(nstates):
                positions_index = np.random.randint(0, len(positions))
                current_positions = positions[positions_index]
                new_positions = ModifiedHamiltonianExchange.randomize_ligand_position(current_positions,
                                                                                      atom_indices['receptor'], atom_indices['ligand'],
                                                                                      self.randomize_ligand_sigma_multiplier * restraints.getReceptorRadiusOfGyration(),
                                                                                      self.randomize_ligand_close_cutoff)
                randomized_positions.append(new_positions)
            positions = randomized_positions
        if self.randomize_ligand and (phase == 'complex-explicit'):
            print "WARNING: Ligand randomization requested, but will not be performed for explicit solvent simulations."

        # Identify whether any atoms will be displaced via MC.
        mc_atoms = list()
        if 'ligand' in atom_indices:
            mc_atoms = atom_indices['ligand']

        # Combine simulation options with defaults.
        options = dict(self.default_options.items() + options.items())

        # Set up simulation.
        # TODO: Support MPI initialization?
        if self.verbose: print "Creating replica exchange object..."
        store_filename = os.path.join(self._store_directory, phase + '.nc')
        self._store_filenames[phase] = store_filename
        simulation = ModifiedHamiltonianExchange(store_filename, mpicomm=mpicomm)
        simulation.create(thermodynamic_state, systems, positions,
                          displacement_sigma=self.mc_displacement_sigma, mc_atoms=mc_atoms,
                          options=options, metadata=metadata)
        simulation.verbose = self.verbose

        # Initialize simulation.
        # TODO: Use the right scheme for initializing the simulation without running.
        #if self.verbose: print "Initializing simulation..."
        #simulation.run(0)

        # TODO: Process user-supplied options.

        # Clean up simulation.
        del simulation

        return
示例#3
0
    def _create_phase(self,
                      phase,
                      reference_system,
                      positions,
                      atom_indices,
                      thermodynamic_state,
                      protocols=None,
                      options=None,
                      mpicomm=None):
        """
        Create a repex object for a specified phase.

        Parameters
        ----------
        phase : str
           The phase being initialized (one of ['complex', 'solvent', 'vacuum'])
        reference_system : simtk.openmm.System
           The reference system object from which alchemical intermediates are to be construcfted.
        positions : list of simtk.unit.Qunatity objects containing (natoms x 3) positions (as np or lists)
           The list of positions to be used to seed replicas in a round-robin way.
        atom_indices : dict
           atom_indices[phase][component] is the set of atom indices associated with component, where component is ['ligand', 'receptor']
        thermodynamic_state : ThermodynamicState
           Thermodynamic state from which reference temperature and pressure are to be taken.
        protocols : dict of list of AlchemicalState, optional, default=None
           If specified, the alchemical protocol protocols[phase] will be used for phase 'phase' instead of the default.
        options : dict of str, optional, default=None
           If specified, these options will override default repex simulation options.

        """

        # Make sure positions argument is a list of coordinate snapshots.
        if hasattr(positions, 'unit'):
            # Wrap in list.
            positions = [positions]

        # Check the dimensions of positions.
        for index in range(len(positions)):
            # Make sure it is recast as a np array.
            positions[index] = unit.Quantity(
                np.array(positions[index] / positions[index].unit),
                positions[index].unit)

            [natoms, ndim] = (positions[index] / positions[index].unit).shape
            if natoms != reference_system.getNumParticles():
                raise Exception(
                    "positions argument must be a list of simtk.unit.Quantity of (natoms,3) lists or np array with units compatible with nanometers."
                )

        # Create metadata storage.
        metadata = dict()

        # Make a deep copy of the reference system so we don't accidentally modify it.
        reference_system = copy.deepcopy(reference_system)

        # TODO: Use more general approach to determine whether system is periodic.
        is_periodic = self._is_periodic(reference_system)

        # Make sure pressure is None if not periodic.
        if not is_periodic: thermodynamic_state.pressure = None

        # Compute standard state corrections for complex phase.
        metadata['standard_state_correction'] = 0.0
        # TODO: Do we need to include a standard state correction for other phases in periodic boxes?
        if phase == 'complex-implicit':
            # Impose restraints for complex system in implicit solvent to keep ligand from drifting too far away from receptor.
            if self.verbose: print "Creating receptor-ligand restraints..."
            reference_positions = positions[0]
            if self.restraint_type == 'harmonic':
                restraints = HarmonicReceptorLigandRestraint(
                    thermodynamic_state, reference_system, reference_positions,
                    atom_indices['receptor'], atom_indices['ligand'])
            elif self.restraint_type == 'flat-bottom':
                restraints = FlatBottomReceptorLigandRestraint(
                    thermodynamic_state, reference_system, reference_positions,
                    atom_indices['receptor'], atom_indices['ligand'])
            else:
                raise Exception("restraint_type of '%s' is not supported." %
                                self.restraint_type)

            force = restraints.getRestraintForce(
            )  # Get Force object incorporating restraints
            reference_system.addForce(force)
            metadata[
                'standard_state_correction'] = restraints.getStandardStateCorrection(
                )  # standard state correction in kT
        elif phase == 'complex-explicit':
            # For periodic systems, we do not use a restraint, but must add a standard state correction for the box volume.
            # TODO: What if the box volume fluctuates during the simulation?
            box_vectors = reference_system.getDefaultPeriodicBoxVectors()
            box_volume = thermodynamic_state._volume(box_vectors)
            STANDARD_STATE_VOLUME = 1660.53928 * unit.angstrom**3
            metadata['standard_state_correction'] = np.log(
                STANDARD_STATE_VOLUME / box_volume)  # TODO: Check sign.

        # Use default alchemical protocols if not specified.
        if not protocols:
            protocols = self.default_protocols

        # Create alchemically-modified states using alchemical factory.
        if self.verbose: print "Creating alchemically-modified states..."
        factory = AbsoluteAlchemicalFactory(
            reference_system, ligand_atoms=atom_indices['ligand'])
        systems = factory.createPerturbedSystems(protocols[phase])

        # Randomize ligand position if requested, but only for implicit solvent systems.
        if self.randomize_ligand and (phase == 'complex-implicit'):
            if self.verbose:
                print "Randomizing ligand positions and excluding overlapping configurations..."
            randomized_positions = list()
            nstates = len(systems)
            for state_index in range(nstates):
                positions_index = np.random.randint(0, len(positions))
                current_positions = positions[positions_index]
                new_positions = ModifiedHamiltonianExchange.randomize_ligand_position(
                    current_positions, atom_indices['receptor'],
                    atom_indices['ligand'],
                    self.randomize_ligand_sigma_multiplier *
                    restraints.getReceptorRadiusOfGyration(),
                    self.randomize_ligand_close_cutoff)
                randomized_positions.append(new_positions)
            positions = randomized_positions

        # Identify whether any atoms will be displaced via MC.
        mc_atoms = list()
        if 'ligand' in atom_indices:
            mc_atoms = atom_indices['ligand']

        # Combine simulation options with defaults.
        options = dict(self.default_options.items() + options.items())

        # Set up simulation.
        # TODO: Support MPI initialization?
        if self.verbose: print "Creating replica exchange object..."
        store_filename = os.path.join(self._store_directory, phase + '.nc')
        self._store_filenames[phase] = store_filename
        simulation = ModifiedHamiltonianExchange(store_filename,
                                                 mpicomm=mpicomm)
        simulation.create(thermodynamic_state,
                          systems,
                          positions,
                          displacement_sigma=self.mc_displacement_sigma,
                          mc_atoms=mc_atoms,
                          options=options,
                          metadata=metadata)
        simulation.verbose = self.verbose

        # Initialize simulation.
        # TODO: Use the right scheme for initializing the simulation without running.
        #if self.verbose: print "Initializing simulation..."
        #simulation.run(0)

        # TODO: Process user-supplied options.

        # Clean up simulation.
        del simulation

        return
示例#4
0
    #
    # Create alchemical intermediates.
    #

    print "Creating alchemical intermediates..."

    # Create a factory to produce alchemical intermediates.
    ligand_atoms = range(0, 2)  # NaCl
    from alchemy import AbsoluteAlchemicalFactory
    factory = AbsoluteAlchemicalFactory(reference_system,
                                        ligand_atoms=ligand_atoms)
    # Get the default protocol for 'denihilating' in complex in explicit solvent.
    protocol = factory.defaultComplexProtocolImplicit()
    # Create the perturbed systems using this protocol.
    systems = factory.createPerturbedSystems(protocol, verbose=True)

    #
    # Set up replica exchange simulation.
    #

    print "Setting up replica-exchange simulation..."

    # Create reference state.
    from thermodynamics import ThermodynamicState
    reference_state = ThermodynamicState(reference_system,
                                         temperature=temperature,
                                         pressure=pressure)
    # Create simulation.
    from repex import HamiltonianExchange
    simulation = HamiltonianExchange(reference_state, systems, positions,
示例#5
0
print "Creating alchemical intermediates..."
alchemical_atoms = range(nfixed) # atoms to be alchemically modified

alchemical_states = list() # alchemical_states[istate] is the alchemical state lambda specification for alchemical state 'istate'

# Create alchemical states where we turn on Lennard-Jones (via softcore) with zero charge.
for vdw_lambda in vdw_lambdas:
    alchemical_states.append( AlchemicalState(coulomb_lambda=0.0, vdw_lambda=vdw_lambda, annihilate_coulomb=True, annihilate_vdw=True) )

# Create alchemical states where we turn on charges with full Lennard-Jones.
for coulomb_lambda in coulomb_lambdas:
    alchemical_states.append( AlchemicalState(coulomb_lambda=coulomb_lambda, vdw_lambda=1.0, annihilate_coulomb=True, annihilate_vdw=True) )

alchemical_factory = AbsoluteAlchemicalFactory(reference_system, alchemical_atoms=alchemical_atoms)
systems = alchemical_factory.createPerturbedSystems(alchemical_states) # systems[istate] will be the System object corresponding to alchemical intermediate state index 'istate'
nstates = len(systems)

#==============================================================================
# Run simulation.
#==============================================================================

# Initialize NetCDF file to store data.
import netCDF4 as netcdf 
ncfile = netcdf.Dataset(filename, 'w', version='NETCDF4')
ncfile.createDimension('iteration', 0) # unlimited number of iterations
ncfile.createDimension('state', nstates) # number of replicas
ncfile.createDimension('atom', reference_system.getNumParticles()) # number of atoms in system
ncfile.createDimension('spatial', 3) # number of spatial dimensions
ncfile.createVariable('positions', 'f', ('iteration','state','atom','spatial')) # positions (in A)
ncfile.createVariable('box_vectors', 'f', ('iteration','state','spatial','spatial')) # box vectors (in A)
#!/usr/bin/env python

"""
Create alchemical intermediates for default alchemical protocol for p-xylene in T4 lysozyme L99A in GBSA.

"""

from alchemy import AbsoluteAlchemicalFactory
from openmmtools import testsystems

# Create a reference system.
print "Creating a reference T4 lysozyme L99A system..."
complex = testsystems.LysozymeImplicit()
[reference_system, positions] = [complex.system, complex.positions]

# Create a factory to produce alchemical intermediates.
print "Creating an alchemical factory..."
receptor_atoms = range(0,2603) # T4 lysozyme L99A
ligand_atoms = range(2603,2621) # p-xylene
factory = AbsoluteAlchemicalFactory(reference_system, ligand_atoms=ligand_atoms)

# Get the default protocol for 'denihilating' in complex in explicit solvent.
protocol = factory.defaultComplexProtocolImplicit()

# Create the perturbed systems using this protocol.
print "Creating a perturbed system..."
systems = factory.createPerturbedSystems(protocol)
print "Done."