Exemplo n.º 1
0
def extract_dummy_atoms(structure, resname=None, serial=True):
    """
    Extract information about dummy atoms from a parmed structure and
    returns the information as a dictionary.

    Parameters
    ----------
    structure : :class:`parmed.Structure`
        The parmed structure object we want to extract from
    resname : list
        List of residue name for the dummy atoms (default: ["DM1", "DM2", "DM3"])
    serial : bool
        get indices in serial (starts from 1) or index (starts from 0)

    Returns
    -------
    dummy_atoms : dict
        A dictionary containing positions (``pos``), index (``idx``) and mass (``mass``) of dummy atoms.
    """

    if resname is None:
        resname = ["DM1", "DM2", "DM3"]

    dummy_atoms = {name: {} for name in resname}

    for dummy_atom in resname:
        residue = f":{dummy_atom}"
        dummy_atoms[dummy_atom]["pos"] = structure[residue].coordinates[0]
        dummy_atoms[dummy_atom]["mass"] = [
            atom.mass for atom in structure[residue].atoms
        ][0]
        dummy_atoms[dummy_atom]["idx"] = utils.index_from_mask(
            structure, residue, amber_index=serial)[0]
        dummy_atoms[dummy_atom]["idx_type"] = "serial" if serial else "index"

    return dummy_atoms
Exemplo n.º 2
0
    def initialize(self):
        """
        Automatically set remaining force constants and targets.

        Depending on which values are provided for each phase, a different method will
        be used to determine the list of force constants and targets (below).

        For attach and release, a ``target`` value is required and the method is determined if the
        following values are not ``None``:

            - Method 1:   num_windows, fc_initial, fc_final
            - Method 1a:  num_windows, fc_final
            - Method 2:   fc_increment, fc_initial, fc_final
            - Method 2a:  fc_increment, fc_final
            - Method 3:   fraction_list, fc_final
            - Method 4:   fraction_increment, fc_final
            - Method 5:   fc_list

        For pull, a ``fc`` value is required and the method is determined if the
        following values are not ``None``:

            - Method 1:   num_windows, target_initial, target_final
            - Method 1a:  num_windows, target_final
            - Method 2:   target_increment, target_initial, target_final
            - Method 2a:  target_increment, target_final
            - Method 3:   fraction_list, target_final
            - Method 4:   fraction_increment, target_final
            - Method 5:   target_list

        .. note ::
            This is unnecessary overengineering.
        """

        self.phase = {
            "attach": {
                "force_constants": None,
                "targets": None
            },
            "pull": {
                "force_constants": None,
                "targets": None
            },
            "release": {
                "force_constants": None,
                "targets": None
            },
        }
        # ------------------------------------ ATTACH ------------------------------------ #
        logger.debug("Calculating attach targets and force constants...")

        # Temporary variables to improve readability
        force_constants = None
        targets = None

        if (self.attach["num_windows"] is not None
                and self.attach["fc_final"] is not None):
            if self.attach["fc_initial"] is not None:
                logger.debug("Attach, Method #1")
                force_constants, targets = self._calc_method(
                    "a", self.attach, "1")
            else:
                logger.debug("Attach, Method #1a")
                force_constants, targets = self._calc_method(
                    "a", self.attach, "1a")

        elif (self.attach["fc_increment"] is not None
              and self.attach["fc_final"] is not None):
            if self.attach["fc_initial"] is not None:
                logger.debug("Attach, Method #2")
                force_constants, targets = self._calc_method(
                    "a", self.attach, "2")
            else:
                logger.debug("Attach, Method #2a")
                force_constants, targets = self._calc_method(
                    "a", self.attach, "2a")

        elif (self.attach["fraction_list"] is not None
              and self.attach["fc_final"] is not None):
            logger.debug("Attach, Method #3")
            force_constants, targets = self._calc_method("a", self.attach, "3")

        elif (self.attach["fraction_increment"] is not None
              and self.attach["fc_final"] is not None):
            logger.debug("Attach, Method #4")
            force_constants, targets = self._calc_method("a", self.attach, "4")

        elif self.attach["fc_list"] is not None:
            logger.debug("Attach, Method #5")
            force_constants, targets = self._calc_method("a", self.attach, "5")

        elif all(v is None for k, v in self.attach.items()):
            logger.debug(
                "No restraint info set for the attach phase! Skipping...")

        else:
            logger.error(
                "Attach restraint input did not match one of the supported methods..."
            )
            for k, v in self.attach.items():
                logger.debug("{} = {}".format(k, v))
            raise Exception(
                "Attach restraint input did not match one of the supported methods..."
            )

        if force_constants is not None and targets is not None:
            self.phase["attach"]["force_constants"] = force_constants
            self.phase["attach"]["targets"] = targets

        # ------------------------------------ PULL ------------------------------------ #
        logger.debug("Calculating pull targets and force constants...")

        force_constants = None
        targets = None

        if self.auto_apr and self.pull["target_final"] is not None:
            self.pull["fc"] = self.phase["attach"]["force_constants"][-1]
            self.pull["target_initial"] = self.phase["attach"]["targets"][-1]

        if (self.pull["num_windows"] is not None
                and self.pull["target_final"] is not None):
            if self.pull["target_initial"] is not None:
                logger.debug("Pull, Method #1")
                force_constants, targets = self._calc_method(
                    "p", self.pull, "1")
            else:
                logger.debug("Pull, Method #1a")
                force_constants, targets = self._calc_method(
                    "p", self.pull, "1a")

        elif (self.pull["target_increment"] is not None
              and self.pull["target_final"] is not None):
            if self.pull["target_initial"] is not None:
                logger.debug("Pull, Method #2")
                force_constants, targets = self._calc_method(
                    "p", self.pull, "2")
            else:
                logger.debug("Pull, Method #2a")
                force_constants, targets = self._calc_method(
                    "p", self.pull, "2a")

        elif (self.pull["fraction_list"] is not None
              and self.pull["target_final"] is not None):
            logger.debug("Pull, Method #3")
            force_constants, targets = self._calc_method("p", self.pull, "3")

        elif (self.pull["fraction_increment"] is not None
              and self.pull["target_final"] is not None):
            logger.debug("Pull, Method #4")
            force_constants, targets = self._calc_method("p", self.pull, "4")

        elif self.pull["target_list"] is not None:
            logger.debug("Pull, Method #5")
            force_constants, targets = self._calc_method("p", self.pull, "5")

        elif all(v is None for k, v in self.pull.items()):
            logger.debug(
                "No restraint info set for the pull phase! Skipping...")

        else:
            logger.error(
                "Pull restraint input did not match one of the supported methods..."
            )
            for k, v in self.pull.items():
                logger.debug("{} = {}".format(k, v))
            raise Exception(
                "Pull restraint input did not match one of the supported methods..."
            )

        if force_constants is not None and targets is not None:
            self.phase["pull"]["force_constants"] = force_constants
            self.phase["pull"]["targets"] = targets

        # ------------------------------------ RELEASE ------------------------------------ #
        logger.debug("Calculating release targets and force constants...")

        force_constants = None
        targets = None

        # I don't want auto_apr to make release restraints, unless I'm sure the user wants them.
        # I'm gonna assume that specifying self.attach['fc_final'] indicates you want it,
        # although this weakens the whole purpose of auto_apr.

        if self.auto_apr and self.release["fc_final"] is not None:
            self.release["target"] = self.phase["pull"]["targets"][-1]
            for key in [
                    "fc_final",
                    "fc_initial",
                    "num_windows",
                    "fc_increment",
                    "fraction_increment",
                    "fraction_list",
                    "fc_list",
            ]:
                if self.attach[key] is not None and self.release[key] is None:
                    self.release[key] = self.attach[key]

        if (self.release["num_windows"] is not None
                and self.release["fc_final"] is not None):
            if self.release["fc_initial"] is not None:
                logger.debug("Release, Method #1")
                force_constants, targets = self._calc_method(
                    "r", self.release, "1")
            else:
                logger.debug("Release, Method #1a")
                force_constants, targets = self._calc_method(
                    "r", self.release, "1a")

        elif (self.release["fc_increment"] is not None
              and self.release["fc_final"] is not None):
            if self.release["fc_initial"] is not None:
                logger.debug("Release, Method #2")
                force_constants, targets = self._calc_method(
                    "r", self.release, "2")
            else:
                logger.debug("Release, Method #2a")
                force_constants, targets = self._calc_method(
                    "r", self.release, "2a")

        elif (self.release["fraction_list"] is not None
              and self.release["fc_final"] is not None):
            logger.debug("Release, Method #3")
            force_constants, targets = self._calc_method(
                "r", self.release, "3")

        elif (self.release["fraction_increment"] is not None
              and self.release["fc_final"] is not None):
            logger.debug("Release, Method #4")
            force_constants, targets = self._calc_method(
                "r", self.release, "4")

        elif self.release["fc_list"] is not None:
            logger.debug("Release, Method #5")
            force_constants, targets = self._calc_method(
                "r", self.release, "5")

        elif all(v is None for k, v in self.release.items()):
            logger.debug(
                "No restraint info set for the release phase! Skipping...")

        else:
            logger.error(
                "Release restraint input did not match one of the supported methods..."
            )
            for k, v in self.release.items():
                logger.debug("{} = {}".format(k, v))
            raise Exception(
                "Release restraint input did not match one of the supported methods..."
            )

        if force_constants is not None and targets is not None:
            self.phase["release"]["force_constants"] = force_constants
            self.phase["release"]["targets"] = targets

        # ----------------------------------- WINDOWS ------------------------------------ #

        for phase in ["attach", "pull", "release"]:
            if self.phase[phase]["targets"] is not None:
                window_count = len(self.phase[phase]["targets"])
                logger.debug("Number of {} windows = {}".format(
                    phase, window_count))
            else:
                logger.debug(
                    "This restraint will be skipped in the {} phase".format(
                        phase))

        # ---------------------------------- ATOM MASKS ---------------------------------- #
        logger.debug("Assigning atom indices...")
        self.index1 = utils.index_from_mask(self.topology, self.mask1,
                                            self.amber_index)
        self.index2 = utils.index_from_mask(self.topology, self.mask2,
                                            self.amber_index)
        if self.mask3:
            self.index3 = utils.index_from_mask(self.topology, self.mask3,
                                                self.amber_index)
        else:
            self.index3 = None
        if self.mask4:
            self.index4 = utils.index_from_mask(self.topology, self.mask4,
                                                self.amber_index)
        else:
            self.index4 = None
        # If any `index` has more than one atom, mark it as a group restraint.
        if self.mask1 and len(self.index1) > 1:
            self.group1 = True

        if self.mask2 and len(self.index2) > 1:
            self.group2 = True

        if self.mask3 and len(self.index3) > 1:
            self.group3 = True

        if self.mask4 and len(self.index4) > 1:
            self.group4 = True
Exemplo n.º 3
0
def test_openmm_cb6but_sim(num_rests=0, guest_pos='guest_inside'):
    path = './cb6-but_test/' + guest_pos + '/'
    topology = 'cb6-but-dum.prmtop'
    coordinates = 'cb6-but-dum.rst7'

    if num_rests > 0:
        md_out = 'cb6_but_openmm_rest_{:02d}.csv'.format(num_rests)
        traj_out = 'cb6_but_openmm_rest_{:02d}.nc'.format(num_rests)
    else:
        md_out = 'cb6_but_openmm.csv'
        traj_out = 'cb6_but_openmm.nc'

    structure = pmd.load_file(path + topology,
                              path + coordinates,
                              structure=True)
    traj = pt.load(path + coordinates, path + topology)

    host = ":CB6"
    guest = ":BUT"

    H = [host + "@C7", host + "@C31", host + "@C19"]
    G = [guest + "@C", guest + "@C3"]
    D = [":DM1", ":DM2", ":DM3"]

    H_i = [0, 0, 0]
    G_i = [0, 0]
    D_i = [0, 0, 0]

    # Get indices for atom masks
    for i, mask in enumerate(H):
        H_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0]
    for i, mask in enumerate(G):
        G_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0]
    for i, mask in enumerate(D):
        D_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0]

    # Set mass of Dummy atoms to 0 so they are non-interacting
    for i, atom in enumerate(structure.atoms):
        if atom.name == 'DUM':
            atom.mass = 0.0

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

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

    prmtop = app.AmberPrmtopFile(path + topology_0m)
    inpcrd = app.AmberInpcrdFile(path + coordinates_0m)

    settings = {
        'nonbonded_method': app.NoCutoff,
        'temperature': 298.15 * unit.kelvin,
        'friction': 1 / unit.picosecond,
        'timestep': 0.002 * unit.picosecond,
        'implicit_solvent': app.HCT,
        'dist_fc': 5.0,
        'angle_fc': 100.0,
        'numsteps': 500000,
    }

    system = prmtop.createSystem(
        nonbondedMethod=settings['nonbonded_method'],
        implicitSolvent=settings['implicit_solvent'],
        removeCMMotion=False,
    )

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

    # Create Positional Restraints for Dummy atoms
    pos_restraint = mm.CustomExternalForce('k*((x-x0)^2+(y-y0)^2+(z-z0)^2)')
    pos_restraint.addGlobalParameter(
        'k', 50.0 * unit.kilocalories_per_mole / unit.angstroms**2)

    pos_restraint.addPerParticleParameter('x0')
    pos_restraint.addPerParticleParameter('y0')
    pos_restraint.addPerParticleParameter('z0')

    for i, atom in enumerate(structure.positions):
        if structure.atoms[i].name == 'DUM':
            pos_restraint.addParticle(i, atom.value_in_unit(unit.nanometers))

    static_restraints = []

    # Create Distance Restraint
    static_distance_rest = [D[0], H[0]]
    static_init_dist = pt.distance(traj, D[0] + ' ' + H[0])[0]

    dist_restraint = mm.CustomBondForce('k*(r-r0)^2')
    dist_restraint.addPerBondParameter('k')
    dist_restraint.addPerBondParameter('r0')

    r0 = static_init_dist * unit.angstroms
    k = settings['dist_fc'] * unit.kilocalories_per_mole / unit.angstroms**2

    dist_restraint.addBond(D_i[0], H_i[0], [k, r0])
    static_restraints.append(dist_restraint)

    # Create Angle Restraint 1
    static_angle_rest_1 = [D[1], D[0], H[0]]
    static_init_angle_1 = pt.angle(traj, D[1] + ' ' + D[0] + ' ' + H[0])[0]

    angle_restraint_1 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2')
    angle_restraint_1.addPerAngleParameter('k')
    angle_restraint_1.addPerAngleParameter('theta0')

    theta0 = static_init_angle_1 * unit.degrees
    k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2

    angle_restraint_1.addAngle(D_i[1], D_i[0], H_i[0], [k, theta0])
    static_restraints.append(angle_restraint_1)

    # Create Dihedral Restraint 1
    static_dihedral_rest_1 = [D[2], D[1], D[0], H[0]]
    static_init_dihedral_1 = pt.dihedral(
        traj, D[2] + ' ' + D[1] + ' ' + D[0] + ' ' + H[0])[0]

    dihedral_restraint_1 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2')
    dihedral_restraint_1.addPerTorsionParameter('k')
    dihedral_restraint_1.addPerTorsionParameter('theta0')

    theta0 = static_init_dihedral_1 * unit.degrees
    k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2

    dihedral_restraint_1.addTorsion(D_i[2], D_i[1], D_i[0], H_i[0],
                                    [k, theta0])
    static_restraints.append(dihedral_restraint_1)

    # Create Angle Restraint 2
    static_angle_rest_2 = [D[0], H[0], H[1]]
    static_init_angle_2 = pt.angle(traj, D[0] + ' ' + H[0] + ' ' + H[1])[0]

    angle_restraint_2 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2')
    angle_restraint_2.addPerAngleParameter('k')
    angle_restraint_2.addPerAngleParameter('theta0')

    theta0 = static_init_angle_2 * unit.degrees
    k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2

    angle_restraint_2.addAngle(D_i[0], H_i[0], H_i[1], [k, theta0])
    static_restraints.append(angle_restraint_2)

    # Create Dihedral Restraint 2
    static_dihedral_rest_2 = [D[1], D[0], H[0], H[1]]
    static_init_dihedral_2 = pt.dihedral(
        traj, D[1] + ' ' + D[0] + ' ' + H[0] + ' ' + H[1])[0]

    dihedral_restraint_2 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2')
    dihedral_restraint_2.addPerTorsionParameter('k')
    dihedral_restraint_2.addPerTorsionParameter('theta0')

    theta0 = static_init_dihedral_2 * unit.degrees
    k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2

    dihedral_restraint_2.addTorsion(D_i[1], D_i[0], H_i[0], H_i[1],
                                    [k, theta0])
    static_restraints.append(dihedral_restraint_2)

    # Create Dihedral Restraint 3
    static_dihedral_rest_3 = [D[0], H[0], H[1], H[2]]
    static_init_dihedral_3 = pt.dihedral(
        traj, D[0] + ' ' + H[0] + ' ' + H[1] + ' ' + H[2])[0]

    dihedral_restraint_3 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2')
    dihedral_restraint_3.addPerTorsionParameter('k')
    dihedral_restraint_3.addPerTorsionParameter('theta0')

    theta0 = static_init_dihedral_3 * unit.degrees
    k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2

    dihedral_restraint_3.addTorsion(D_i[0], H_i[0], H_i[1], H_i[2],
                                    [k, theta0])
    static_restraints.append(dihedral_restraint_3)

    #system.addForce(pos_restraint)

    if num_rests > 0:
        for rest in static_restraints[0:num_rests]:
            system.addForce(rest)

    simulation = app.Simulation(prmtop.topology, system, integrator,
                                mm.Platform.getPlatformByName('CPU'))
    simulation.context.setPositions(inpcrd.positions)

    simulation.reporters.append(NetCDFReporter(path + traj_out, 250))
    simulation.reporters.append(
        app.StateDataReporter(path + md_out,
                              250,
                              step=True,
                              time=True,
                              potentialEnergy=True,
                              kineticEnergy=True,
                              totalEnergy=True,
                              temperature=True,
                              volume=True,
                              density=True))

    simulation.step(settings['numsteps'])
Exemplo n.º 4
0
        constraints=settings["constraints"],
        implicitSolvent=settings["implicit_solvent"],
    )
    static_restraints = []

    dist_restraint = mm.CustomBondForce("k*(r-r0)^2")
    dist_restraint.addPerBondParameter("k")
    dist_restraint.addPerBondParameter("r0")

    rest = rests[0]  # first static restraint
    static_init_dist = rest.phase[phase]["targets"][window_num]
    bond_fc = rest.phase[phase]["force_constants"][window_num]
    r0 = static_init_dist * unit.angstroms
    k = bond_fc * unit.kilocalories_per_mole / unit.angstroms**2

    a1 = utils.index_from_mask(structure, mask=rest.mask1, amber_index=False)
    a2 = utils.index_from_mask(structure, mask=rest.mask2, amber_index=False)
    dist_restraint.addBond(a1[0], a2[0], [k, r0])
    static_restraints.append(dist_restraint)

    angle_restraint_1 = mm.CustomAngleForce("0.5*k*(theta-theta0)^2")
    angle_restraint_1.addPerAngleParameter("k")
    angle_restraint_1.addPerAngleParameter("theta0")

    rest = rests[1]  # second static restraint
    static_init_angle_1 = rest.phase[phase]["targets"][window_num]
    angle_fc = rest.phase[phase]["force_constants"][window_num]
    theta0 = static_init_angle_1 * unit.degrees
    k = angle_fc * unit.kilocalories_per_mole / unit.radians**2

    a1 = utils.index_from_mask(structure, mask=rest.mask1, amber_index=False)