Exemplo n.º 1
0
    def test_modeller(self):
        """Test addition of hydrogens to a PDB file using modeller."""
        pdb = app.PDBFile(
            get_test_data("glu_ala_his_noH.pdb", "testsystems/tripeptides/"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")
        modeller = app.Modeller(pdb.topology, pdb.positions)
        modeller.addHydrogens(forcefield)
        # Should have 59 hydrogens after adding them
        assert modeller.topology.getNumAtoms() == 59

        system = forcefield.createSystem(modeller.topology)
Exemplo n.º 2
0
 def test_create_system(self):
     """Create a system using the amber10 constph force field."""
     cif = app.PDBxFile(
         get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                       "testsystems/tripeptides/"))
     forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                 "tip3p.xml")
     system = forcefield.createSystem(
         cif.topology,
         nonbondedMethod=app.PME,
         nonbondedCutoff=1.0 * unit.nanometers,
         constraints=app.HBonds,
         rigidWater=True,
         ewaldErrorTolerance=0.0005,
     )
Exemplo n.º 3
0
def run_prep_ffxml_main(jsonfile):
    """Main simulation loop."""

    log.info(f"Preparing a run from '{jsonfile}'")

    # TODO Validate json input with json schema?
    settings = yaml.load(open(jsonfile, "r"))

    log.debug(f"Loaded these settings. {settings}")

    try:
        format_vars: Dict[str, str] = settings["format_vars"]
    except KeyError:
        format_vars = dict()

    # Input files
    inp = settings["input"]
    idir = inp["dir"].format(**format_vars)

    # Make a ForceField object from user directed files

    # Look for block in input
    try:
        ff: Dict[str, List[str]] = settings["forcefield"]
    except KeyError:
        raise KeyError("No forcefield block specified")

    # Any files included with openmm/protons by default are retrieved here
    try:
        default_ff: List[str] = ff["default"]
    except KeyError:
        # In typical use case I wouldn't expect purely user files to be used.
        warn("'default' list missing from 'forcefield' block.", UserWarning)
        default_ff = []

    # all user provided files here
    try:
        user_ff: List[str] = ff["user"]
        user_ff_paths: List[str] = []
        for user_file in user_ff:
            rel_path = os.path.join(idir, user_file.format(**format_vars))
            user_ff_paths.append(os.path.abspath(rel_path))
    except KeyError:
        user_ff_paths = []

    if len(default_ff) + len(user_ff_paths) == 0:
        raise ValueError("No forcefield files provided.")
    forcefield = app.ForceField(*(user_ff_paths + default_ff))

    # Load structure
    # The input should be an mmcif/pdbx file'
    ifilename = inp["structure"].format(**format_vars)
    joined_path = os.path.join(idir, ifilename)
    input_pdbx_file = os.path.abspath(joined_path)
    pdb_object = app.PDBxFile(input_pdbx_file)

    # Atoms , connectivity, residues
    topology = pdb_object.topology
    # Store topology for serialization
    topology_file_content = open(input_pdbx_file, "r").read()

    # XYZ positions for every atom
    positions = pdb_object.positions

    # Quick fix for histidines in topology
    # Openmm relabels them HIS, which leads to them not being detected as
    # titratable. Renaming them fixes this.

    for residue in topology.residues():
        if residue.name == "HIS":
            residue.name = "HIP"
        # TODO doublecheck if ASH GLH need to be renamed
        elif residue.name == "ASP":
            residue.name = "ASH"
        elif residue.name == "GLU":
            residue.name = "GLH"

    # Naming the output files
    out = settings["output"]
    odir = out["dir"].format(**format_vars)
    obasename = out["basename"].format(**format_vars)
    if not os.path.isdir(odir):
        os.makedirs(odir)
    lastdir = os.getcwd()
    os.chdir(odir)

    # File for resuming simulation
    output_checkpoint_file = f"{obasename}-checkpoint-0.xml"

    # Structure preprocessing settings
    if "preprocessing" in settings:
        preproc: Dict[str, Any] = settings["preprocessing"]

        # Steps of MD before starting the main loop
        num_thermalization_steps = int(preproc["num_thermalization_steps"])
        pre_run_minimization_tolerance: unit.Quantity = float(
            preproc["minimization_tolerance_kjmol"]
        ) * unit.kilojoule / unit.mole
        minimization_max_iterations = int(preproc["minimization_max_iterations"])

    # System Configuration
    sysprops = settings["system"]
    temperature = float(sysprops["temperature_k"]) * unit.kelvin
    if "salt_concentration_molar" in sysprops:
        salt_concentration: unit.Quantity = float(
            sysprops["salt_concentration_molar"]
        ) * unit.molar
    elif "PME" in sysprops:
        salt_concentration = 0.0 * unit.molar
    else:
        salt_concentration = None

    rigidWater = True
    constraints = app.HBonds

    if "PME" in sysprops:
        pmeprops = sysprops["PME"]
        nonbondedMethod = app.PME
        ewaldErrorTolerance = float(pmeprops["ewald_error_tolerance"])
        barostatInterval = int(pmeprops["barostat_interval"])
        switching_distance = float(pmeprops["switching_distance_nm"]) * unit.nanometers
        nonbondedCutoff = float(pmeprops["nonbonded_cutoff_nm"]) * unit.nanometers
        pressure = float(pmeprops["pressure_atm"]) * unit.atmosphere
        disp_corr = bool(pmeprops["dispersion_correction"])

        system = forcefield.createSystem(
            topology,
            nonbondedMethod=nonbondedMethod,
            constraints=constraints,
            rigidWater=rigidWater,
            ewaldErrorTolerance=ewaldErrorTolerance,
            nonbondedCutoff=nonbondedCutoff,
        )
        for force in system.getForces():
            if isinstance(force, mm.NonbondedForce):
                force.setUseSwitchingFunction(True)
                force.setSwitchingDistance(switching_distance)
                force.setUseDispersionCorrection(disp_corr)

        # NPT simulation
        system.addForce(mm.MonteCarloBarostat(pressure, temperature, barostatInterval))
    else:
        pressure = None
        system = forcefield.createSystem(
            topology,
            nonbondedMethod=app.NoCutoff,
            constraints=app.HBonds,
            rigidWater=True,
        )

    # Integrator options
    integrator_opts = settings["integrator"]
    timestep = integrator_opts["timestep_fs"] * unit.femtosecond
    constraint_tolerance = integrator_opts["constraint_tolerance"]
    collision_rate = integrator_opts["collision_rate_per_ps"] / unit.picosecond
    number_R_steps = 1

    integrator = ExternalGBAOABIntegrator(
        number_R_steps=number_R_steps,
        temperature=temperature,
        collision_rate=collision_rate,
        timestep=timestep,
        constraint_tolerance=constraint_tolerance,
    )
    ncmc_propagation_integrator = ExternalGBAOABIntegrator(
        number_R_steps=number_R_steps,
        temperature=temperature,
        collision_rate=collision_rate,
        timestep=timestep,
        constraint_tolerance=constraint_tolerance,
    )

    # Define a compound integrator
    compound_integrator = mm.CompoundIntegrator()
    compound_integrator.addIntegrator(integrator)
    compound_integrator.addIntegrator(ncmc_propagation_integrator)
    compound_integrator.setCurrentIntegrator(0)

    # Script specific settings

    if "importance" in settings:
        sampling_method = SamplingMethod.IMPORTANCE
    else:
        sampling_method = SamplingMethod.MCMC

    driver = ForceFieldProtonDrive(
        temperature,
        topology,
        system,
        forcefield,
        user_ff_paths + ["amber10-constph.xml"],
        pressure=pressure,
        perturbations_per_trial=100_000,
        propagations_per_step=1,
    )

    if "reference_free_energies" in settings:
        # calibrated free energy values can be provided here
        gk_dict = settings["reference_free_energies"]

        # Clean comments inside dictionary
        to_delete = list()
        for key in gk_dict.keys():
            if key.startswith("_"):
                to_delete.append(key)

        for key in to_delete:
            del (gk_dict[key])

        # Make arrays
        for key, value in gk_dict.items():
            # Convert to array of float
            val_array = np.asarray(value).astype(np.float64)
            if not val_array.ndim == 1:
                raise ValueError("Reference free energies should be simple lists.")
            gk_dict[key] = val_array

        driver.import_gk_values(gk_dict)

    # TODO allow platform specification for setup

    platform = mm.Platform.getPlatformByName("OpenCL")
    properties = {"OpenCLPrecision": "double"}

    # Set up calibration mode
    # SAMS settings

    if "SAMS" in settings and "importance" in settings:
        raise NotImplementedError("Cannot combine SAMS and importance sampling.")

    elif "SAMS" in settings:
        sams = settings["SAMS"]

        beta_burnin = float(sams["beta"])
        min_burnin = int(sams["min_burn"])
        min_slow = int(sams["min_slow"])
        min_fast = int(sams["min_fast"])

        flatness_criterion = float(sams["flatness_criterion"])
        if sams["update_rule"] == "binary":
            update_rule = UpdateRule.BINARY
        elif sams["update_rule"] == "global":
            update_rule = UpdateRule.GLOBAL
        else:
            update_rule = UpdateRule.BINARY

        # Assumes calibration residue is always the last titration group if onesite

        if sams["sites"] == "multi":
            driver.enable_calibration(
                approach=SAMSApproach.MULTISITE,
                update_rule=update_rule,
                flatness_criterion=flatness_criterion,
                min_burn=min_burnin,
                min_slow=min_slow,
                min_fast=min_fast,
                beta_sams=beta_burnin,
            )
        elif sams["sites"] == "one":
            if "group_index" in sams:
                calibration_titration_group_index = int(sams["group_index"])
            else:
                calibration_titration_group_index = len(driver.titrationGroups) - 1

            driver.enable_calibration(
                approach=SAMSApproach.ONESITE,
                group_index=calibration_titration_group_index,
                update_rule=update_rule,
                flatness_criterion=flatness_criterion,
                min_burn=min_burnin,
                min_slow=min_slow,
                min_fast=min_fast,
            )
            # Define residue pools
            pools = {"calibration": [calibration_titration_group_index]}
            # TODO the pooling feature could eventually be exposed in the json
            driver.define_pools(pools)

    # Create simulation object
    # If calibration is required, this class will automatically deal with it.
    simulation = app.ConstantPHSimulation(
        topology,
        system,
        compound_integrator,
        driver,
        platform=platform,
        platformProperties=properties,
    )
    simulation.context.setPositions(positions)

    # After the simulation system has been defined, we can add salt to the system using saltswap.
    if salt_concentration is not None:
        salinator = Salinator(
            context=simulation.context,
            system=system,
            topology=topology,
            ncmc_integrator=compound_integrator.getIntegrator(1),
            salt_concentration=salt_concentration,
            pressure=pressure,
            temperature=temperature,
        )
        salinator.neutralize()
        salinator.initialize_concentration()
        if "neutral_charge_rule" not in sysprops:
            raise KeyError(
                "Specification of neutral_charge_rule for explicit solvent required in system."
            )

        charge_rule = NeutralChargeRule(sysprops["neutral_charge_rule"])
        driver.enable_neutralizing_ions(
            salinator.swapper, neutral_charge_rule=charge_rule
        )
    else:
        # Implicit solvent
        salinator = None

    # Set the fixed titration state in case of importance sampling
    if sampling_method is SamplingMethod.IMPORTANCE:
        if "titration_states" in settings["importance"]:
            fixed_states = settings["importance"]["titration_states"]

            if len(fixed_states) != len(driver.titrationStates):
                raise IndexError(
                    "The number of residues specified for importance sampling does not match the number of titratable residues."
                )

            else:
                for group_id, state_id in enumerate(fixed_states):
                    driver.set_titration_state(
                        group_id,
                        state_id,
                        updateContextParameters=True,
                        updateIons=True,
                    )

                # Minimize the initial configuration to remove bad contacts
                if "preprocessing" in settings:
                    simulation.minimizeEnergy(
                        tolerance=pre_run_minimization_tolerance,
                        maxIterations=minimization_max_iterations,
                    )
                    # Slightly equilibrate the system, detect early issues.
                    simulation.step(num_thermalization_steps)

                # export the context
                create_protons_checkpoint_file(
                    output_checkpoint_file,
                    driver,
                    simulation.context,
                    simulation.system,
                    simulation.integrator,
                    topology_file_content,
                    salinator=salinator,
                )

        elif "systematic" in settings["importance"]:
            if settings["importance"]["systematic"]:

                # Make checkpoint files for the combinatorial space of residue states.
                for importance_index, state_combination in enumerate(
                    product(*[np.arange(len(res)) for res in driver.titrationGroups])
                ):
                    for res_id, state_id in enumerate(state_combination):
                        driver.set_titration_state(
                            res_id,
                            state_id,
                            updateContextParameters=True,
                            updateIons=True,
                        )

                    # Minimize the initial configuration to remove bad contacts
                    if "preprocessing" in settings:
                        simulation.minimizeEnergy(
                            tolerance=pre_run_minimization_tolerance,
                            maxIterations=minimization_max_iterations,
                        )
                        # Slightly equilibrate the system, detect early issues.
                        simulation.step(num_thermalization_steps)

                    # export the context
                    create_protons_checkpoint_file(
                        f"{obasename}-importance-state-{importance_index}-checkpoint-0.xml",
                        driver,
                        simulation.context,
                        simulation.system,
                        simulation.integrator,
                        topology_file_content,
                        salinator=salinator,
                    )
            os.chdir(lastdir)

    else:

        # Minimize the initial configuration to remove bad contacts
        if "preprocessing" in settings:
            simulation.minimizeEnergy(
                tolerance=pre_run_minimization_tolerance,
                maxIterations=minimization_max_iterations,
            )
            # Slightly equilibrate the system, detect early issues.
            simulation.step(num_thermalization_steps)

        # export the context
        create_protons_checkpoint_file(
            output_checkpoint_file,
            driver,
            simulation.context,
            simulation.system,
            simulation.integrator,
            topology_file_content,
            salinator=salinator,
        )

    os.chdir(lastdir)
Exemplo n.º 4
0
    def test_system_charge_reporting(self):
        """Test if the system_charge is correctly reported."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        initial_charge = (
            0
        )  # Ion totals are 0, and the system starts in state 0 for both, GLU deprotonated, HIS protonated
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
        )

        # pools defined by their residue index for convenience later on
        driver.define_pools({"0": [0], "1": [1]})
        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        filename = uuid.uuid4().hex + ".nc"
        ncfile = netCDF4.Dataset(filename, "w")
        print("Temporary file: ", filename)
        newreporter = tr.TitrationReporter(ncfile, 2)
        simulation.update_reporters.append(newreporter)

        # Regular MD step
        simulation.step(1)
        # Update the titration states forcibly from a pregenerated series

        glu_states = np.asarray([
            1, 4, 4, 1, 0, 2, 0, 2, 4, 3, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 1, 2,
            1, 3, 1
        ])
        his_states = np.asarray([
            2, 1, 0, 1, 2, 2, 1, 2, 2, 1, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 2,
            2, 2, 1
        ])

        for i in range(len(glu_states)):

            simulation.drive.set_titration_state(0,
                                                 glu_states[i],
                                                 updateContextParameters=False)
            simulation.drive.set_titration_state(1,
                                                 his_states[i],
                                                 updateContextParameters=False)
            simulation.update_reporters[0].report(simulation)
            tot_charge = 0
            for resi, residue in enumerate(simulation.drive.titrationGroups):
                icharge = int(floor(0.5 + residue.total_charge))
                tot_charge += icharge
                assert (
                    ncfile["Protons/Titration/{}_charge".format(resi)][i] ==
                    icharge), "Residue charge is not recorded correctly."
            assert (
                ncfile["Protons/Titration/complex_charge"][i] == tot_charge
            ), "The recorded complex total charge does not match the actual charge."

        # close files to avoid segfaults, possibly
        ncfile.close()
Exemplo n.º 5
0
    def test_atom_status_reporting(self):
        """Test if the atom_status is correctly reported."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
        )

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        filename = uuid.uuid4().hex + ".nc"
        ncfile = netCDF4.Dataset(filename, "w")
        print("Temporary file: ", filename)
        newreporter = tr.TitrationReporter(ncfile, 2)
        simulation.update_reporters.append(newreporter)

        # Regular MD step
        simulation.step(1)
        # Update the titration states forcibly from a pregenerated series
        glu_states = np.asarray([
            1, 4, 4, 1, 0, 2, 0, 2, 4, 3, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 1, 2,
            1, 3, 1
        ])
        his_states = np.asarray([
            2, 1, 0, 1, 2, 2, 1, 2, 2, 1, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 2,
            2, 2, 1
        ])

        for i in range(len(glu_states)):
            simulation.drive.set_titration_state(0,
                                                 glu_states[i],
                                                 updateContextParameters=False)
            simulation.drive.set_titration_state(1,
                                                 his_states[i],
                                                 updateContextParameters=False)
            simulation.update_reporters[0].report(simulation)
            # check glu
            self._verify_atom_status(i, 0, ncfile, simulation)
            # check his
            self._verify_atom_status(i, 1, ncfile, simulation)

        ncfile.close()
Exemplo n.º 6
0
    def test_reports(self):
        """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        num_atoms = pdb.topology.getNumAtoms()
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
        )

        num_titratable = len(driver.titrationGroups)
        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        filename = uuid.uuid4().hex + ".nc"
        print("Temporary file: ", filename)
        newreporter = tr.TitrationReporter(filename, 2)
        simulation.update_reporters.append(newreporter)

        # Regular MD step
        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(6)
        # Basic checks for dimension
        assert (newreporter.ncfile["Protons/Titration"].dimensions["update"].
                size == 3), "There should be 3 updates recorded."
        assert (
            newreporter.ncfile["Protons/Titration"].dimensions["residue"].size
            == num_titratable
        ), "There should be {} residues recorded.".format(num_titratable)
        assert (
            newreporter.ncfile["Protons/Titration"].dimensions["atom"].size ==
            num_atoms), "There should be {} atoms recorded.".format(num_atoms)
        newreporter.ncfile.close()
Exemplo n.º 7
0
def main(jsonfile):
    """Main simulation loop."""

    settings = json.load(open(jsonfile))
    # Parameters include format strings that are used to format the names of input and output files
    prms = settings["parameters"]

    # Input files
    inp = settings["input"]
    idir = inp["dir"].format(**prms)
    input_pdbx_file = os.path.join(idir,
                                   inp["calibration_system"].format(**prms))

    # If supplied, tell the code to find and load supplied ffxml file
    custom_xml_provided = False
    if "ffxml" in inp:
        custom_xml_provided = True

    # Load the PDBxfile and the forcefield files
    if custom_xml_provided:
        custom_xml = os.path.join(idir, inp["ffxml"].format(**prms))
        custom_xml = os.path.abspath(custom_xml)
        forcefield = app.ForceField('amber10-constph.xml', 'gaff.xml',
                                    custom_xml, 'tip3p.xml', 'ions_tip3p.xml')
    else:
        forcefield = app.ForceField('amber10-constph.xml', 'gaff.xml',
                                    'tip3p.xml', 'ions_tip3p.xml')

    pdb_object = app.PDBxFile(input_pdbx_file)

    # Prepare the Simulation
    topology = pdb_object.topology
    positions = pdb_object.positions

    # Quick fix for histidines in topology
    # Openmm relabels them HIS, which leads to them not being detected as
    # titratable. Renaming them fixes this.
    for residue in topology.residues():
        if residue.name == 'HIS':
            residue.name = 'HIP'

    # Naming the output files
    out = settings["output"]
    odir = out["dir"].format(**prms)

    if not os.path.isdir(odir):
        os.makedirs(odir)
    lastdir = os.getcwd()
    os.chdir(odir)

    name_netcdf = out["netcdf"].format(**prms)
    dcd_output_name = out["dcd"].format(**prms)

    # Files for resuming simulation
    resumes = out["resume_files"]

    output_context_xml = resumes["state"].format(**prms)
    output_drive_xml = resumes["drive"].format(**prms)
    output_calibration_json = resumes["calibration"].format(**prms)

    # Integrator options
    integrator_opts = prms["integrator"]
    timestep = integrator_opts["timestep_fs"] * unit.femtosecond
    constraint_tolerance = integrator_opts["constraint_tolerance"]
    collision_rate = integrator_opts["collision_rate_per_ps"] / unit.picosecond
    number_R_steps = 1

    # Steps of MD before starting the main loop
    num_thermalization_steps = int(prms["num_thermalization_steps"])
    # Steps of MD in between MC moves
    steps_between_updates = int(prms["steps_between_updates"])

    ncmc = prms["ncmc"]
    counterion_method = ncmc["counterion_method"].lower()
    if counterion_method not in ["chen-roux", "chenroux", "background"]:
        raise ValueError(
            "Invalid ncmc counterion method, {}. Please pick Chen-Roux or background."
            .format(counterion_method))
    ncmc_steps_per_trial = int(ncmc["steps_per_trial"])
    prop_steps_per_trial = int(ncmc["propagations_per_step"])
    total_iterations = int(prms["total_attempts"])

    # settings for minimization
    minimization = prms["minimization"]
    pre_run_minimization_tolerance = float(
        minimization["tolerance_kjmol"]) * unit.kilojoule / unit.mole
    minimization_max_iterations = int(minimization["max_iterations"])

    # SAMS settings
    sams = prms["SAMS"]
    beta_burnin = sams["beta_sams"]
    flatness_criterion = sams["flatness_criterion"]

    # Script specific settings

    # Register the timeout handling
    signal.signal(signal.SIGALRM, timeout_handler)

    script_timeout = 428400  # 119 hours

    # Platform Options

    platform = mm.Platform.getPlatformByName('CUDA')
    properties = {
        'CudaPrecision': 'mixed',
        'DeterministicForces': 'true',
        'CudaDeviceIndex': os.environ['CUDA_VISIBLE_DEVICES']
    }
    # System Configuration
    sysprops = prms["system"]
    nonbondedMethod = app.PME
    constraints = app.HBonds
    rigidWater = True
    ewaldErrorTolerance = float(sysprops["ewald_error_tolerance"])
    barostatInterval = int(sysprops["barostat_interval"])
    switching_distance = float(
        sysprops["switching_distance_nm"]) * unit.nanometers
    nonbondedCutoff = float(sysprops["nonbonded_cutoff_nm"]) * unit.nanometers
    pressure = float(sysprops["pressure_atm"]) * unit.atmosphere
    temperature = float(sysprops["temperature_k"]) * unit.kelvin

    system = forcefield.createSystem(topology,
                                     nonbondedMethod=nonbondedMethod,
                                     constraints=constraints,
                                     rigidWater=rigidWater,
                                     ewaldErrorTolerance=ewaldErrorTolerance,
                                     nonbondedCutoff=nonbondedCutoff)

    #
    for force in system.getForces():
        if isinstance(force, mm.NonbondedForce):
            force.setUseSwitchingFunction(True)

            force.setSwitchingDistance(switching_distance)

    # NPT simulation
    system.addForce(
        mm.MonteCarloBarostat(pressure, temperature, barostatInterval))

    integrator = ExternalGBAOABIntegrator(
        number_R_steps=number_R_steps,
        temperature=temperature,
        collision_rate=collision_rate,
        timestep=timestep,
        constraint_tolerance=constraint_tolerance)
    ncmc_propagation_integrator = ExternalGBAOABIntegrator(
        number_R_steps=number_R_steps,
        temperature=temperature,
        collision_rate=collision_rate,
        timestep=timestep,
        constraint_tolerance=constraint_tolerance)

    # Define a compound integrator
    compound_integrator = mm.CompoundIntegrator()
    compound_integrator.addIntegrator(integrator)
    compound_integrator.addIntegrator(ncmc_propagation_integrator)
    compound_integrator.setCurrentIntegrator(0)

    if custom_xml_provided:
        driver = ForceFieldProtonDrive(
            temperature,
            topology,
            system,
            forcefield, ['amber10-constph.xml', custom_xml],
            pressure=pressure,
            perturbations_per_trial=ncmc_steps_per_trial,
            propagations_per_step=prop_steps_per_trial)
    else:
        driver = ForceFieldProtonDrive(
            temperature,
            topology,
            system,
            forcefield, ['amber10-constph.xml'],
            pressure=pressure,
            perturbations_per_trial=ncmc_steps_per_trial,
            propagations_per_step=prop_steps_per_trial)

    # Assumes calibration residue is always the last titration group
    calibration_titration_group_index = len(driver.titrationGroups) - 1

    # Define residue pools
    pools = {'calibration': [calibration_titration_group_index]}
    driver.define_pools(pools)
    # Create SAMS sampler
    simulation = app.ConstantPHCalibration(
        topology,
        system,
        compound_integrator,
        driver,
        group_index=calibration_titration_group_index,
        platform=platform,
        platformProperties=properties,
        samsProperties=sams)
    simulation.context.setPositions(positions)

    # After the simulation system has been defined, we can add salt to the system using saltswap.
    salinator = Salinator(context=simulation.context,
                          system=system,
                          topology=topology,
                          ncmc_integrator=compound_integrator.getIntegrator(1),
                          salt_concentration=0.150 * unit.molar,
                          pressure=pressure,
                          temperature=temperature)
    salinator.neutralize()
    salinator.initialize_concentration()
    swapper = salinator.swapper

    # Protons can use the scheme from [Chen2015]_ to maintain charge neutrality.
    # If the Chen-Roux scheme is requested, attach swapper. Else, use neutralizing background charge (happens under the hood of openmm).
    if counterion_method in ["chenroux", "chen-roux"]:
        simulation.drive.attach_swapper(swapper)

    # Minimize the initial configuration to remove bad contacts
    simulation.minimizeEnergy(tolerance=pre_run_minimization_tolerance,
                              maxIterations=minimization_max_iterations)
    # Slightly equilibrate the system, detect early issues.
    simulation.step(num_thermalization_steps)

    # Add reporters, these write out simulation data at regular intervals
    dcdreporter = app.DCDReporter(dcd_output_name,
                                  int(steps_between_updates / 10))
    ncfile = netCDF4.Dataset(name_netcdf, "w")
    metdatarep = MetadataReporter(ncfile)
    ncmcrep = NCMCReporter(ncfile, 1)
    titrep = TitrationReporter(ncfile, 1)
    simulation.reporters.append(dcdreporter)
    simulation.update_reporters.append(metdatarep)
    simulation.update_reporters.append(ncmcrep)
    simulation.update_reporters.append(titrep)
    samsrep = SAMSReporter(ncfile, 1)
    simulation.calibration_reporters.append(samsrep)

    # MAIN SIMULATION LOOP STARTS HERE

    # Raises an exception if the simulation runs out of time, so that the script can be killed cleanly from within python
    signal.alarm(script_timeout)

    try:
        for i in range(total_iterations):
            log.info("Iteration %i", i)
            if i == 5:
                log.info(
                    "Simulation seems to be working. Suppressing debugging info."
                )
                log.setLevel(logging.INFO)
            # Regular MD
            simulation.step(steps_between_updates)
            # Update protonation state
            simulation.update(1, pool='calibration')
            # Adapt SAMS weight
            simulation.adapt()
        # Reset timer
        signal.alarm(0)

    except TimeOutError:
        log.warn("Simulation ran out of time, saving current results.")

    finally:
        # export the context
        serialize_state(simulation.context, output_context_xml)
        # export the driver
        serialize_drive(simulation.drive, output_drive_xml)
        # export the calibration status
        serialize_sams_status(simulation, output_calibration_json)

        ncfile.close()
        os.chdir(lastdir)
Exemplo n.º 8
0
# coding=utf-8
"""
Adds hydrogens to 2HYY-noH.pdb
"""

from protons import app
from simtk.openmm import openmm
from simtk.unit import *
from protons.app.integrators import GBAOABIntegrator

# Load relevant template definitions for modeller, forcefield and topology

app.Modeller.loadHydrogenDefinitions('imatinib-hydrogens.xml')
forcefield = app.ForceField('amber10-constph.xml', 'gaff.xml', 'imatinib.xml', 'tip3p.xml', 'ions_tip3p.xml')

pdb = app.PDBFile('2HYY-noH.pdb')

modeller = app.Modeller(pdb.topology, pdb.positions)

# The pdb contains solvent but not the right ions.
# This would mean we need to equilibrate again even if we just add new ions.
# In this case its easiest to just delete and re-add the solvent with the right amount of ions

modeller.deleteWater()
ions = [ atom for atom in modeller.topology.atoms() if atom.element.symbol in ['Cl', 'Na'] ]
modeller.delete(ions)


modeller.addHydrogens(forcefield=forcefield)
modeller.addSolvent(forcefield, model='tip3p', padding=1.0*nanometers, positiveIon='Na+', negativeIon='Cl-', ionicStrength=120*millimolar, neutralize=True)
Exemplo n.º 9
0
    def test_reports(self):
        """Instantiate a simulation at 300K/1 atm for a small peptide with reporter."""

        pdb = app.PDBxFile(
            get_test_data(
                "glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides"
            )
        )
        forcefield = app.ForceField(
            "amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml"
        )

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=3,
        )

        # prep the driver for calibration
        driver.enable_calibration(
            SAMSApproach.ONESITE, group_index=1, update_rule=UpdateRule.BINARY
        )

        calibration = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        calibration.context.setPositions(pdb.positions)
        calibration.context.setVelocitiesToTemperature(temperature)
        filename = uuid.uuid4().hex + ".nc"
        print("Temporary file: ", filename)
        newreporter = sr.SAMSReporter(filename, 2)
        calibration.calibration_reporters.append(newreporter)

        # Regular MD step
        for iteration in range(4):
            calibration.step(1)
            # Update the titration states using the uniform proposal
            calibration.update(1)
            # adapt sams weights
            calibration.adapt()

        # Basic checks for dimension
        assert (
            newreporter.ncfile["Protons/SAMS"].dimensions["adaptation"].size == 2
        ), "There should be 2 updates recorded."
        assert (
            newreporter.ncfile["Protons/SAMS"].dimensions["state"].size == 3
        ), "There should be 3 states reported."

        newreporter.ncfile.close()
Exemplo n.º 10
0
    def test_reports_every_perturbation_saltswap(self):
        """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide, save every perturbation step, with saltswap."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=3,
        )

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        filename = uuid.uuid4().hex + ".nc"
        print("Temporary file: ", filename)
        # The salinator initializes the system salts
        salinator = Salinator(
            context=simulation.context,
            system=simulation.system,
            topology=simulation.topology,
            ncmc_integrator=simulation.integrator.getIntegrator(1),
            salt_concentration=0.2 * unit.molar,
            pressure=pressure,
            temperature=temperature,
        )
        salinator.neutralize()
        salinator.initialize_concentration()
        swapper = salinator.swapper
        driver.enable_neutralizing_ions(swapper)

        newreporter = ncr.NCMCReporter(filename, 1, cumulativeworkInterval=1)
        simulation.update_reporters.append(newreporter)

        # Regular MD step
        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(4)
        # Basic checks for dimension
        assert (newreporter.ncfile["Protons/NCMC"].dimensions["update"].size ==
                4), "There should be 4 updates recorded."
        assert (newreporter.ncfile["Protons/NCMC"].dimensions["residue"].size
                == 2), "There should be 2 residues recorded."
        assert (newreporter.ncfile["Protons/NCMC"].dimensions["perturbation"].
                size == 3), "There should be max 3 perturbations recorded."
        assert (newreporter.ncfile["Protons/NCMC"].dimensions["ion_site"].size
                == 1269), "The system should have 1269 potential ion sites."

        # Ensure clean exit
        newreporter.ncfile.sync()
        newreporter.ncfile.close()
Exemplo n.º 11
0
    def test_create_simulation(self):
        """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
        )

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)

        # Regular MD step
        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(1)
        print("Done!")
Exemplo n.º 12
0
    def test_create_constantphcalibration_with_reporters(self):
        """Test running a calibration using constant-pH with reporters."""
        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=2,
            propagations_per_step=1,
        )

        # prep the driver for calibration
        driver.enable_calibration(SAMSApproach.ONESITE, group_index=-1)
        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        # Outputfile for reporters
        newname = uuid4().hex + ".nc"
        ncfile = netCDF4.Dataset(newname, "w")
        tr = TitrationReporter(ncfile, 1)
        mr = MetadataReporter(ncfile)
        nr = NCMCReporter(ncfile, 1)
        sr = SAMSReporter(ncfile, 1)
        simulation.update_reporters.append(tr)
        simulation.update_reporters.append(mr)
        simulation.update_reporters.append(nr)
        simulation.calibration_reporters.append(sr)

        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(1)
        # Adapt the weights using binary update.
        simulation.adapt()
        # Attempt to prevent segfaults by closing files
        ncfile.close()
Exemplo n.º 13
0
    def test_create_constantphcalibration_resume(self):
        """Test running a calibration using constant-pH."""
        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
        )
        driver.enable_calibration(SAMSApproach.ONESITE, group_index=-1)

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)
        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(1)
        # Adapt the weights using binary update, a few times just to rack up the counters.
        for x in range(5):
            simulation.adapt()
        # retrieve the samsProperties
        # TODO use deserialize proton drive for this
        xml = simulation.drive.state_to_xml()

        driver2 = NCMCProtonDrive(
            temperature,
            pdb.topology,
            system,
            pressure=pressure,
            perturbations_per_trial=0,
        )
        driver2.state_from_xml_tree(etree.fromstring(xml))
        integrator2 = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator2 = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )
        compound_integrator2 = mm.CompoundIntegrator()
        compound_integrator2.addIntegrator(integrator2)
        compound_integrator2.addIntegrator(ncmcintegrator2)

        # Make a new calibration and do another step, ignore the state for this example
        simulation2 = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator2,
            driver2,
            platform=self._default_platform,
        )

        assert (simulation2.drive.calibration_state._stage is
                simulation.drive.calibration_state._stage)
        # get going then
        simulation2.context.setPositions(pdb.positions)
        simulation2.context.setVelocitiesToTemperature(temperature)
        simulation2.step(1)
        # Update the titration states using the uniform proposal
        simulation2.update(1)
        # Adapt the weights using binary update.
        simulation2.adapt()

        assert (
            simulation2.drive.calibration_state._current_adaptation ==
            -simulation.drive.calibration_state._min_burn + 6
        ), "The resumed calibration does not have the right adaptation_index"
Exemplo n.º 14
0
    def test_create_importance_sampling_reporters(self):
        """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide using importance sampling with reporters."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
            sampling_method=SamplingMethod.IMPORTANCE,
        )

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)

        newname = uuid4().hex + ".nc"
        ncfile = netCDF4.Dataset(newname, "w")
        tr = TitrationReporter(ncfile, 1)
        mr = MetadataReporter(ncfile)
        nr = NCMCReporter(ncfile, 1)
        simulation.update_reporters.append(tr)
        simulation.update_reporters.append(mr)
        simulation.update_reporters.append(nr)

        # Regular MD step
        simulation.step(1)
        # Update the titration states using the uniform proposal
        niters = 3
        for x in range(niters):
            simulation.update(1)

        n_total_states = np.product(
            [len(group) for group in driver.titrationGroups])
        assert (len(ncfile["Protons/Titration/update"][:]) == n_total_states *
                niters), "The wrong number of updates were recorded"

        work_values = np.split(ncfile["Protons/NCMC/total_work"][:], niters)
        init_states = ncfile["Protons/NCMC/initial_state"][:, :]
        assert np.all(
            init_states == 0), "States should all be zero at the start."
        first_run = work_values[0]
        assert np.all(np.unique(first_run) == np.sort(
            first_run)), "No work values should be duplicated."

        # Since instanteneous switching is used, this should be true
        for x in range(1, niters):
            assert np.all(
                np.isclose(work_values[x],
                           first_run)), "Work should be equal for all states."

        # Switch state
        driver.set_titration_state(0,
                                   3,
                                   updateContextParameters=True,
                                   updateIons=True)
        driver.set_titration_state(1,
                                   1,
                                   updateContextParameters=True,
                                   updateIons=True)
        simulation.update(1)

        assert (ncfile["Protons/NCMC/initial_state"][-n_total_states, 0] == 3
                ), "Initial state was not changed correctly."
        assert (ncfile["Protons/NCMC/initial_state"][-n_total_states, 1] == 1
                ), "Initial state was not changed correctly."
        work_values = np.split(ncfile["Protons/NCMC/total_work"][:],
                               niters + 1)
        assert not np.all(
            np.isclose(work_values[0], work_values[-1])
        ), "Work values starting from different state should differ."

        return
Exemplo n.º 15
0
    def test_create_importance_sampling(self):
        """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide using importance sampling."""

        pdb = app.PDBxFile(
            get_test_data("glu_ala_his-solvated-minimized-renamed.cif",
                          "testsystems/tripeptides"))
        forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml",
                                    "tip3p.xml")

        system = forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=app.PME,
            nonbondedCutoff=1.0 * unit.nanometers,
            constraints=app.HBonds,
            rigidWater=True,
            ewaldErrorTolerance=0.0005,
        )

        temperature = 300 * unit.kelvin
        integrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=False,
        )
        ncmcintegrator = GBAOABIntegrator(
            temperature=temperature,
            collision_rate=1.0 / unit.picoseconds,
            timestep=2.0 * unit.femtoseconds,
            constraint_tolerance=1.0e-7,
            external_work=True,
        )

        compound_integrator = mm.CompoundIntegrator()
        compound_integrator.addIntegrator(integrator)
        compound_integrator.addIntegrator(ncmcintegrator)
        pressure = 1.0 * unit.atmosphere

        system.addForce(mm.MonteCarloBarostat(pressure, temperature))
        driver = ForceFieldProtonDrive(
            temperature,
            pdb.topology,
            system,
            forcefield,
            ["amber10-constph.xml"],
            pressure=pressure,
            perturbations_per_trial=0,
            sampling_method=SamplingMethod.IMPORTANCE,
        )

        simulation = app.ConstantPHSimulation(
            pdb.topology,
            system,
            compound_integrator,
            driver,
            platform=self._default_platform,
        )
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(temperature)

        # Regular MD step
        simulation.step(1)
        # Update the titration states using the uniform proposal
        simulation.update(1)

        # Total states is 15 but proposing the same state as current does not get added to statistics.
        assert simulation.drive.nattempted == 14, "Not enough switch were attempted."
        assert simulation.drive.naccepted == 0, "No acceptance should have occurred."
        assert (simulation.drive.nattempted == simulation.drive.nrejected
                ), "The rejection count should match the number of attempts"

        print("Done!")