Ejemplo n.º 1
0
def build_softcore_system(reference_system,
                          receptor_atoms,
                          ligand_atoms,
                          valence_lambda,
                          coulomb_lambda,
                          vdw_lambda,
                          annihilate=False):
    """
    Build alchemically-modified system where ligand is decoupled or annihilated using *SoftcoreForce classes.
    
    """

    # Create new system.
    system = openmm.System()

    # Set periodic box vectors.
    [a, b, c] = reference_system.getDefaultPeriodicBoxVectors()
    system.setDefaultPeriodicBoxVectors(a, b, c)

    # Add atoms.
    for atom_index in range(reference_system.getNumParticles()):
        mass = reference_system.getParticleMass(atom_index)
        system.addParticle(mass)

    # Add constraints
    for constraint_index in range(reference_system.getNumConstraints()):
        [iatom, jatom,
         r0] = reference_system.getConstraintParameters(constraint_index)
        system.addConstraint(iatom, jatom, r0)

    # Perturb force terms.
    for force_index in range(reference_system.getNumForces()):
        reference_force = reference_system.getForce(force_index)
        # Dispatch forces
        if isinstance(reference_force, openmm.HarmonicBondForce):
            # HarmonicBondForce
            force = openmm.HarmonicBondForce()
            for bond_index in range(reference_force.getNumBonds()):
                # Retrieve parameters.
                [iatom, jatom, r0,
                 K] = reference_force.getBondParameters(bond_index)
                # Annihilate if directed.
                if annihilate and (iatom
                                   in ligand_atoms) and (jatom
                                                         in ligand_atoms):
                    K *= valence_lambda
                # Add bond parameters.
                force.addBond(iatom, jatom, r0, K)
            # Add force to new system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.HarmonicAngleForce):
            # HarmonicAngleForce
            force = openmm.HarmonicAngleForce()
            for angle_index in range(reference_force.getNumAngles()):
                # Retrieve parameters.
                [iatom, jatom, katom, theta0,
                 Ktheta] = reference_force.getAngleParameters(angle_index)
                # Annihilate if directed:
                if annihilate and (iatom in ligand_atoms) and (
                        jatom in ligand_atoms) and (katom in ligand_atoms):
                    Ktheta *= valence_lambda
                # Add parameters.
                force.addAngle(iatom, jatom, katom, theta0, Ktheta)
            # Add force to system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.PeriodicTorsionForce):
            # PeriodicTorsionForce
            force = openmm.PeriodicTorsionForce()
            for torsion_index in range(reference_force.getNumTorsions()):
                # Retrieve parmaeters.
                [
                    particle1, particle2, particle3, particle4, periodicity,
                    phase, k
                ] = reference_force.getTorsionParameters(torsion_index)
                # Annihilate if directed:
                if annihilate and (particle1 in ligand_atoms) and (
                        particle2 in ligand_atoms) and (
                            particle3 in ligand_atoms) and (particle4
                                                            in ligand_atoms):
                    k *= valence_lambda
                # Add parameters.
                force.addTorsion(particle1, particle2, particle3, particle4,
                                 periodicity, phase, k)
            # Add force to system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.NonbondedForce):
            # NonbondedForce
            force = openmm.NonbondedSoftcoreForce()
            for particle_index in range(reference_force.getNumParticles()):
                # Retrieve parameters.
                [charge, sigma, epsilon
                 ] = reference_force.getParticleParameters(particle_index)
                # Alchemically modify parameters.
                if particle_index in ligand_atoms:
                    charge *= coulomb_lambda
                    epsilon *= vdw_lambda
                    # Add modified particle parameters.
                    force.addParticle(charge, sigma, epsilon, vdw_lambda)
                else:
                    # Add unmodified particle parameters.
                    force.addParticle(charge, sigma, epsilon, 1.0)
            for exception_index in range(reference_force.getNumExceptions()):
                # Retrieve parameters.
                [iatom, jatom, chargeprod, sigma, epsilon
                 ] = reference_force.getExceptionParameters(exception_index)
                # Alchemically modify epsilon and chargeprod.
                if (iatom in ligand_atoms) and (jatom in ligand_atoms):
                    if annihilate:
                        epsilon *= vdw_lambda
                        chargeprod *= coulomb_lambda
                    # Add modified exception parameters.
                    force.addException(iatom, jatom, chargeprod, sigma,
                                       epsilon, vdw_lambda)
                else:
                    # Add unmodified exception parameters.
                    force.addException(iatom, jatom, chargeprod, sigma,
                                       epsilon, 1.0)
            # Set parameters.
            force.setNonbondedMethod(reference_force.getNonbondedMethod())
            force.setCutoffDistance(reference_force.getCutoffDistance())
            force.setReactionFieldDielectric(
                reference_force.getReactionFieldDielectric())
            force.setEwaldErrorTolerance(
                reference_force.getEwaldErrorTolerance())
            # Add force to new system.
            #system.addForce(force)

        elif isinstance(reference_force, openmm.GBSAOBCForce):
            # GBSAOBCForce
            force = openmm.GBSAOBCSoftcoreForce()

            force.setSolventDielectric(reference_force.getSolventDielectric())
            force.setSoluteDielectric(reference_force.getSoluteDielectric())

            for particle_index in range(reference_force.getNumParticles()):
                # Retrieve parameters.
                [charge, radius, scaling_factor
                 ] = reference_force.getParticleParameters(particle_index)
                # Alchemically modify parameters.
                if particle_index in ligand_atoms:
                    # Scale charge and contribution to GB integrals.
                    force.addParticle(charge * coulomb_lambda, radius,
                                      scaling_factor, coulomb_lambda)
                else:
                    # Don't modulate GB.
                    force.addParticle(charge, radius, scaling_factor, 1.0)

            # Add force to new system.
            #system.addForce(force)
        else:
            # Don't add unrecognized forces.
            pass

    return system
Ejemplo n.º 2
0
def build_alchemically_modified_system(reference_system,
                                       receptor_atoms,
                                       ligand_atoms,
                                       annihilate=True):
    """
    Build alchemically-modified system where ligand is decoupled or annihilated.
    
    """

    # Create new system.
    system = openmm.System()

    # Add atoms.
    for atom_index in range(reference_system.getNumParticles()):
        mass = reference_system.getParticleMass(atom_index)
        system.addParticle(mass)

    # Add constraints
    for constraint_index in range(reference_system.getNumConstraints()):
        [iatom, jatom,
         r0] = reference_system.getConstraintParameters(constraint_index)
        system.addConstraint(iatom, jatom, r0)

    # Perturb force terms.
    for force_index in range(reference_system.getNumForces()):
        reference_force = reference_system.getForce(force_index)
        # Dispatch forces
        if isinstance(reference_force, openmm.HarmonicBondForce):
            # HarmonicBondForce
            force = openmm.HarmonicBondForce()
            for bond_index in range(reference_force.getNumBonds()):
                # Retrieve parameters.
                [iatom, jatom, r0,
                 K] = reference_force.getBondParameters(bond_index)
                # Annihilate if directed.
                if annihilate and (iatom
                                   in ligand_atoms) and (jatom
                                                         in ligand_atoms):
                    K *= 0.0
                # Add bond parameters.
                force.addBond(iatom, jatom, r0, K)
            # Add force to new system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.HarmonicAngleForce):
            # HarmonicAngleForce
            force = openmm.HarmonicAngleForce()
            for angle_index in range(reference_force.getNumAngles()):
                # Retrieve parameters.
                [iatom, jatom, katom, theta0,
                 Ktheta] = reference_force.getAngleParameters(angle_index)
                # Annihilate if directed:
                if annihilate and (iatom in ligand_atoms) and (
                        jatom in ligand_atoms) and (katom in ligand_atoms):
                    Ktheta *= 0.0
                # Add parameters.
                force.addAngle(iatom, jatom, katom, theta0, Ktheta)
            # Add force to system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.PeriodicTorsionForce):
            # PeriodicTorsionForce
            force = openmm.PeriodicTorsionForce()
            for torsion_index in range(reference_force.getNumTorsions()):
                # Retrieve parmaeters.
                [
                    particle1, particle2, particle3, particle4, periodicity,
                    phase, k
                ] = reference_force.getTorsionParameters(torsion_index)
                # Annihilate if directed:
                if annihilate and (particle1 in ligand_atoms) and (
                        particle2 in ligand_atoms) and (
                            particle3 in ligand_atoms) and (particle4
                                                            in ligand_atoms):
                    k *= 0.0
                # Add parameters.
                force.addTorsion(particle1, particle2, particle3, particle4,
                                 periodicity, phase, k)
            # Add force to system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.NonbondedForce):
            # NonbondedForce
            force = openmm.NonbondedSoftcoreForce()
            for particle_index in range(reference_force.getNumParticles()):
                # Retrieve parameters.
                [charge, sigma, epsilon
                 ] = reference_force.getParticleParameters(particle_index)
                # Alchemically modify parameters.
                alchemical_lambda = 1.0
                if particle_index in ligand_atoms:
                    alchemical_lambda = 0.0
                    charge *= 0.0
                    if annihilate:
                        epsilon *= 0.0
                # Add modified particle parameters.
                force.addParticle(charge, sigma, epsilon, alchemical_lambda)
            for exception_index in range(reference_force.getNumExceptions()):
                # Retrieve parameters.
                [iatom, jatom, chargeprod, sigma, epsilon
                 ] = reference_force.getExceptionParameters(exception_index)
                # TODO: Alchemically modify parameters.
                if (iatom in ligand_atoms) and (jatom in ligand_atoms):
                    chargeprod *= 0.0
                    if annihilate:
                        epsilon *= 0.0
                # Add modified exception parameters.
                force.addException(iatom, jatom, chargeprod, sigma, epsilon)
            # Set parameters.
            force.setNonbondedMethod(reference_force.getNonbondedMethod())
            force.setCutoffDistance(reference_force.getCutoffDistance())
            force.setReactionFieldDielectric(
                reference_force.getReactionFieldDielectric())
            force.setEwaldErrorTolerance(
                reference_force.getEwaldErrorTolerance())
            # Add force to new system.
            system.addForce(force)
        elif isinstance(reference_force, openmm.GBSAOBCForce):
            # GBSAOBCForce
            force = openmm.GBSAOBCSoftcoreForce()
            for particle_index in range(reference_force.getNumParticles()):
                # Retrieve parameters.
                [charge, radius, scaling_factor
                 ] = reference_force.getParticleParameters(particle_index)
                # Alchemically modify parameters.
                nonpolar_scaling_factor = 1.0
                if particle_index in ligand_atoms:
                    charge *= 0.0
                    #radius *= 0.0
                    #scaling_factor *= 0.0
                    nonpolar_scaling_factor = 0.0
                    pass
                # Add parameters.
                force.addParticle(charge, radius, scaling_factor,
                                  nonpolar_scaling_factor)
            force.setSolventDielectric(reference_force.getSolventDielectric())
            force.setSoluteDielectric(reference_force.getSoluteDielectric())
            #force.setCutoffDistance( reference_force.getCutoffDistance() )
            #force.setNonbondedMethod( reference_force.getNonbondedMethod() )
            # Add force to new system.
            system.addForce(force)
        else:
            # Don't add unrecognized forces.
            pass

    return system