Exemplo n.º 1
0
def main():
  print("Reading the PSF file");

  # Read the PSF file
  psf = app.CharmmPsfFile('g1_25mm.psf');

  boxsize = 5 # Boxsize in nm
  psf.setBox(boxsize*nanometer, boxsize*nanometer, boxsize*nanometer);

  print("Reading the pdb file")
  pdb = app.PDBFile('g1_25mm.pdb');

  # Load the parameter set
  lib = 'toppar/'
  #params = app.CharmmParameterSet('toppar/top_all36_cgenff.rtf','toppar/par_all36_cgenff.prm','toppar/cgenff3.0.1/top_all36_cgenff.rtf','toppar/cgenff3.0.1/par_all36_cgenff.prm','g1_new.str','toppar_water_ions.str')
  params = app.CharmmParameterSet('toppar/cgenff3.0.1/top_all36_cgenff.rtf','toppar/cgenff3.0.1/par_all36_cgenff.prm','g1_new.str','toppar_water_ions.str')


  #platform = openmm.Platform.getPlatformByName('CUDA');
  platform = openmm.Platform.getPlatformByName('Reference');

  # Creating the system
  system = psf.createSystem(params, 
                            nonbondedMethod=app.PME, 
                            nonbondedCutoff=1.2*nanometer, 
                            switchDistance=1.0*nanometer, 
                            ewaldErrorTolerance= 0.0001, 
                            constraints=app.HBonds);

  # Thermostat @ 298 K
  system.addForce(openmm.AndersenThermostat(298*kelvin, 1/picosecond)) 
  # adding the barostat for now
  system.addForce(openmm.MonteCarloBarostat(1*bar, 298*kelvin));

  integrator = openmm.VerletIntegrator(0.001*picoseconds)

  simulation = app.Simulation(psf.topology, system, integrator, platform)
  simulation.context.setPositions(pdb.getPositions())
  simulation.minimizeEnergy(maxIterations = 500)

  #nsavcrd = 10000 # save coordinates every 10 ps
  #nstep  = 2000000 # write dcd files every 2 ps
  #nprint = 2000 # report every 2 ps
  nsavcrd = 10 # save coordinates every 10 ps
  nstep  = 200 # write dcd files every 2 ps
  nprint = 20 # report every 2 ps
  firstDcdStep = nsavcrd ;


  # Reporters
  dcd = app.DCDReporter('g1_new.dcd', nsavcrd)
  dcd._dcd = app.DCDFile(dcd._out, simulation.topology, simulation.integrator.getStepSize(), firstDcdStep, nsavcrd)
  simulation.reporters.append(dcd)

  simulation.reporters.append(app.StateDataReporter('g1_new.out', nprint, step=True, kineticEnergy=True, potentialEnergy=True, totalEnergy=True, temperature=True, volume=True, speed=True))
  simulation.step(nstep)
  simulation.reporters.pop()
  simulation.reporters.pop()
  dcd._out.close()
Exemplo n.º 2
0
def readCharmmParameters(folder, listfile=None):
    from glob import glob
    import os
    if listfile is None:
        files = glob(os.path.join(folder, '*'))
    elif isinstance(listfile, list):
        files = [os.path.join(folder, f) for f in listfile]
    return app.CharmmParameterSet(*files)
Exemplo n.º 3
0
def main():
  print("Reading the PSF file");

  # Read the PSF file
  psf = app.CharmmPsfFile('holo_neutr.psf');

  boxsize = 4.895883 # Boxsize in nm
  psf.setBox(boxsize*nanometer, boxsize*nanometer, boxsize*nanometer);

  print("Reading the pdb file")
  pdb  = app.PDBFile('holo_neutr.pdb')

  # Load the parameter set
  lib = 'toppar/'
  params = app.CharmmParameterSet(
                            'toppar/cgenff3.0.1/top_all36_cgenff.rtf',
                            'toppar/cgenff3.0.1/par_all36_cgenff.prm',
                            'g1_new.str','oah_groups.str',
                            'toppar_water_ions.str'
  )


  platform = openmm.Platform.getPlatformByName('CUDA');

  #isPeriodic = False
  #isShortSim = False
  isShortSim = True
  isPeriodic = False
  #if not isPeriodic :
  #  isShortSim = True;

  # Creating the system
  if (isPeriodic) :
    system = psf.createSystem(params, 
                              nonbondedMethod=app.PME, 
                              nonbondedCutoff=1.2*nanometer, 
                              switchDistance=1.0*nanometer, 
                              ewaldErrorTolerance= 0.0001, 
                              constraints=app.HBonds
    );
  else :
    system = psf.createSystem(params, 
    #                          nonbondedMethod=app.PME, 
                              nonbondedCutoff=1.2*nanometer, 
                              switchDistance=1.0*nanometer, 
                              ewaldErrorTolerance= 0.0001, 
                              constraints=app.HBonds
    );

  #Retrieve the nonbonded force 
  forces = { force.__class__.__name__  : for force in system.getForces()}:
  nbforce = forces['NonbondedForce']
def _read_charmm_params(filename):
    charmmExt = ['rtf', 'prm', 'str']
    paramFiles = ()

    for line in open(filename, 'r'):
        if line.find("#") >= 0:
            line = line.split("#")[0]
        parfile = line.strip()
        if len(parfile) > 0:
            ext = parfile.lower().split('.')[-1]
            if ext in charmmExt:
                paramFiles += (parfile,)

    return app.CharmmParameterSet(*paramFiles)
Exemplo n.º 5
0
        b = float(tokens[3]) * u.angstroms
    if tokens[1] == 'C':
        c = float(tokens[3]) * u.angstroms
    if tokens[1] == 'FFTX':
        fftx = int(tokens[3])
    if tokens[1] == 'FFTY':
        ffty = int(tokens[3])
    if tokens[1] == 'FFTZ':
        fftz = int(tokens[3])

psf = app.CharmmPsfFile(os.path.join(prefix, 'step3_pbcsetup.psf'))
# Taken from output of CHARMM run
psf.setBox(a, b, c)
crd = app.CharmmCrdFile(os.path.join(prefix, 'step3_pbcsetup.crd'))
params = app.CharmmParameterSet(
    os.path.join(prefix, 'toppar/par_all36_prot.prm'),
    os.path.join(prefix, 'toppar/par_all36_na.prm'),
    os.path.join(prefix, 'toppar/toppar_water_ions.str'))

system = psf.createSystem(params,
                          nonbondedMethod=app.PME,
                          nonbondedCutoff=12 * u.angstroms,
                          switchDistance=10 * u.angstroms)

for force in system.getForces():
    if isinstance(force, mm.CustomNonbondedForce):
        #print('CustomNonbondedForce: %s' % force.getUseSwitchingFunction())
        #print('LRC? %s' % force.getUseLongRangeCorrection())
        force.setUseLongRangeCorrection(False)
    elif isinstance(force, mm.NonbondedForce):
        #print('NonbondedForce: %s' % force.getUseSwitchingFunction())
        #print('LRC? %s' % force.getUseDispersionCorrection())
Exemplo n.º 6
0
    # load the charmm file for the topology
    psf = omma.CharmmPsfFile(charmm_psf_path)

    # load the coordinates
    pdb = mdj.load_pdb(pdb_path)

    # convert the mdtraj topology to a json one
    top_str = mdtraj_to_json_topology(pdb.topology)

    # write the JSON topology out
    with open(json_top_path, mode='w') as json_wf:
        json_wf.write(top_str)


    # to use charmm forcefields get your parameters
    params = omma.CharmmParameterSet(*charmm_param_paths)

    # set the box size lengths and angles
    lengths = [8.2435*unit.nanometer for i in range(3)]
    angles = [90*unit.degree for i in range(3)]
    psf.setBox(*lengths, *angles)

    # create a system using the topology method giving it a topology and
    # the method for calculation
    system = psf.createSystem(params,
                              nonbondedMethod=omma.CutoffPeriodic,
                              nonbondedCutoff=1.0 * unit.nanometer,
                              constraints=omma.HBonds)

    # we want to have constant pressure
    barostat = omm.MonteCarloBarostat(1.0*unit.atmosphere, 300.0*unit.kelvin, 50)
Exemplo n.º 7
0
def main(n_runs,
         n_cycles,
         steps,
         n_walkers,
         n_workers=1,
         debug_prints=False,
         seed=None):
    ## Load objects needed for various purposes

    # load a json string of the topology
    with open(json_top_path, mode='r') as rf:
        sEH_TPPU_system_top_json = rf.read()

    # an openmm.State object for setting the initial walkers up
    with open(omm_state_path, mode='rb') as rf:
        omm_state = pickle.load(rf)

    ## set up the OpenMM Runner

    # load the psf which is needed for making a system in OpenMM with
    # CHARMM force fields
    psf = omma.CharmmPsfFile(charmm_psf_path)

    # set the box size lengths and angles
    lengths = [CUBE_LENGTH for i in range(3)]
    angles = [CUBE_ANGLE for i in range(3)]
    psf.setBox(*lengths, *angles)

    # charmm forcefields parameters
    params = omma.CharmmParameterSet(*charmm_param_paths)

    # create a system using the topology method giving it a topology and
    # the method for calculation
    system = psf.createSystem(params,
                              nonbondedMethod=omma.CutoffPeriodic,
                              nonbondedCutoff=NONBONDED_CUTOFF,
                              constraints=omma.HBonds)

    # make this a constant temperature and pressure simulation at 1.0
    # atm, 300 K, with volume move attempts every 50 steps
    barostat = omm.MonteCarloBarostat(PRESSURE, TEMPERATURE, VOLUME_MOVE_FREQ)

    # add it as a "Force" to the system
    system.addForce(barostat)

    # make an integrator object that is constant temperature
    integrator = omm.LangevinIntegrator(TEMPERATURE, FRICTION_COEFFICIENT,
                                        STEP_SIZE)

    # set up the OpenMMRunner with the system
    runner = OpenMMRunner(system, psf.topology, integrator, platform=PLATFORM)

    # the initial state, which is used as reference for many things
    init_state = OpenMMState(omm_state)

    ## Make the distance Metric

    # load the crystal structure coordinates
    crystal_traj = mdj.load_pdb(pdb_path)

    # get the atoms in the binding site according to the crystal structure
    bs_idxs = binding_site_atoms(crystal_traj.top, LIG_RESID,
                                 crystal_traj.xyz[0])
    lig_idxs = ligand_idxs(crystal_traj.top, LIG_RESID)
    prot_idxs = protein_idxs(crystal_traj.top)

    # make the distance metric with the ligand and binding site
    # indices for selecting atoms for the image and for doing the
    # alignments to only the binding site. All images will be aligned
    # to the reference initial state
    unb_distance = UnbindingDistance(lig_idxs, bs_idxs, init_state)

    ## Make the resampler

    # make a Wexplore resampler with default parameters and our
    # distance metric
    resampler = WExploreResampler(distance=unb_distance,
                                  init_state=init_state,
                                  max_n_regions=MAX_N_REGIONS,
                                  max_region_sizes=MAX_REGION_SIZES,
                                  pmin=PMIN,
                                  pmax=PMAX)

    ## Make the Boundary Conditions

    # makes ref_traj and selects lingand_atom and protein atom  indices
    # instantiate a revo unbindingboudaryconditiobs
    ubc = UnbindingBC(cutoff_distance=CUTOFF_DISTANCE,
                      initial_state=init_state,
                      topology=crystal_traj.topology,
                      ligand_idxs=lig_idxs,
                      receptor_idxs=prot_idxs)

    ## make the reporters

    # WepyHDF5

    # make a dictionary of units for adding to the HDF5
    # open it in truncate mode first, then switch after first run
    hdf5_reporter = WepyHDF5Reporter(
        hdf5_path,
        mode='w',
        # the fields of the State that will be saved in the HDF5 file
        save_fields=SAVE_FIELDS,
        # the topology in a JSON format
        topology=sEH_TPPU_system_top_json,
        # the resampler and boundary
        # conditions for getting data
        # types and shapes for saving
        resampler=resampler,
        boundary_conditions=ubc,
        # the units to save the fields in
        units=dict(UNITS),
        # sparse (in time) fields
        sparse_fields=dict(SPARSE_FIELDS),
        # sparse atoms fields
        main_rep_idxs=np.concatenate((lig_idxs, prot_idxs)),
        all_atoms_rep_freq=ALL_ATOMS_SAVE_FREQ)

    dashboard_reporter = WExploreDashboardReporter(
        dashboard_path,
        mode='w',
        step_time=STEP_SIZE.value_in_unit(unit.second),
        max_n_regions=resampler.max_n_regions,
        max_region_sizes=resampler.max_region_sizes,
        bc_cutoff_distance=ubc.cutoff_distance)

    setup_reporter = SetupReporter(setup_state_path, mode='w')

    restart_reporter = RestartReporter(restart_state_path, mode='w')

    reporters = [
        hdf5_reporter, dashboard_reporter, setup_reporter, restart_reporter
    ]

    ## The work mapper

    # we use a mapper that uses GPUs
    work_mapper = WorkerMapper(worker_type=OpenMMGPUWorker,
                               num_workers=n_workers)

    ## Combine all these parts and setup the simulation manager

    # set up parameters for running the simulation
    # initial weights
    init_weight = 1.0 / n_walkers

    # a list of the initial walkers
    init_walkers = [
        Walker(OpenMMState(omm_state), init_weight) for i in range(n_walkers)
    ]

    # Instantiate a simulation manager
    sim_manager = Manager(init_walkers,
                          runner=runner,
                          resampler=resampler,
                          boundary_conditions=ubc,
                          work_mapper=work_mapper,
                          reporters=reporters)

    ### RUN the simulation
    for run_idx in range(n_runs):
        print("Starting run: {}".format(run_idx))
        sim_manager.run_simulation(n_cycles, steps, debug_prints=True)
        print("Finished run: {}".format(run_idx))
Exemplo n.º 8
0
def run_simulation(gro_file='conf.gro',
                   psf_file='topol.psf',
                   prm_file='ff.prm',
                   dt=0.001,
                   T=300,
                   P=1,
                   tcoupl='langevin',
                   pcoupl='iso',
                   cos=0,
                   restart=None):
    print('Building system...')
    gro = oh.GroFile(gro_file)
    psf = oh.OplsPsfFile(psf_file,
                         periodicBoxVectors=gro.getPeriodicBoxVectors())
    prm = app.CharmmParameterSet(prm_file)
    system = psf.createSystem(prm,
                              nonbondedMethod=app.PME,
                              nonbondedCutoff=1.2 * nm,
                              constraints=app.HBonds,
                              rigidWater=True,
                              verbose=True)
    is_drude = any(type(f) == mm.DrudeForce for f in system.getForces())

    ### apply TT damping for CLPol force field
    donors = [atom.idx for atom in psf.atom_list if atom.attype == 'HO']
    if is_drude and len(donors) > 0:
        print('Add TT damping between HO and Drude dipoles')
        ttforce = oh.CLPolCoulTT(system, donors)
        print(ttforce.getEnergyFunction())

    print('Initializing simulation...')
    if tcoupl == 'langevin':
        if is_drude:
            print('Drude Langevin thermostat: 5.0 /ps, 20 /ps')
            integrator = mm.DrudeLangevinIntegrator(T * kelvin, 5.0 / ps,
                                                    1 * kelvin, 20 / ps,
                                                    dt * ps)
            integrator.setMaxDrudeDistance(0.02 * nm)
        else:
            print('Langevin thermostat: 1.0 /ps')
            integrator = mm.LangevinIntegrator(T * kelvin, 1.0 / ps, dt * ps)
    elif tcoupl == 'nose-hoover':
        if is_drude:
            print(
                'Drude temperature-grouped Nose-Hoover thermostat: 10 /ps, 40 /ps'
            )
        else:
            print('Nose-Hoover thermostat: 10 /ps')
        from velocityverletplugin import VVIntegrator
        integrator = VVIntegrator(T * kelvin, 10 / ps, 1 * kelvin, 40 / ps,
                                  dt * ps)
        integrator.setUseMiddleScheme(True)
        integrator.setMaxDrudeDistance(0.02 * nm)
    else:
        raise Exception('Available thermostat: langevin, nose-hoover')

    if pcoupl != 'no':
        oh.apply_mc_barostat(system, pcoupl, P, T)

    if cos != 0:
        try:
            integrator.setCosAcceleration(cos)
        except:
            raise Exception(
                'Cosine acceleration not compatible with this integrator')

    _platform = mm.Platform.getPlatformByName('CUDA')
    _properties = {'CudaPrecision': 'mixed'}
    sim = app.Simulation(psf.topology, system, integrator, _platform,
                         _properties)
    if restart:
        sim.loadCheckpoint(restart)
        sim.currentStep = round(
            sim.context.getState().getTime().value_in_unit(ps) / dt / 10) * 10
        sim.context.setTime(sim.currentStep * dt)
        append = True
    else:
        sim.context.setPositions(gro.positions)
        sim.context.setVelocitiesToTemperature(T * kelvin)
        append = False

    sim.reporters.append(
        app.DCDReporter('dump.dcd',
                        10000,
                        enforcePeriodicBox=False,
                        append=append))
    sim.reporters.append(oh.CheckpointReporter('cpt.cpt', 10000))
    sim.reporters.append(
        oh.GroReporter('dump.gro', 1000, logarithm=True, append=append))
    sim.reporters.append(
        oh.StateDataReporter(sys.stdout,
                             1000,
                             box=False,
                             volume=True,
                             append=append))
    if is_drude:
        sim.reporters.append(
            oh.DrudeTemperatureReporter('T_drude.txt', 10000, append=append))
    if cos != 0:
        sim.reporters.append(
            oh.ViscosityReporter('viscosity.txt', 1000, append=append))

    return sim
Exemplo n.º 9
0
    def init_openmm(self, integrator_params=None, create_system_params=None):
        """
        Method that initiates OpenMM by creating

        Parameters
        ----------
        integrator_params : dict
            Keyword arguments passed to the simtk.openmm.openmm.LangevinIntegrator
        create_system_params : dict
            Keyword arguments passed to simtk.openmm.app.amberprmtopfile.createSystem

        Returns
        -------
        system : simtk.openmm.openmm.System
            OpenMM system created.
        """
        from simtk.openmm import XmlSerializer

        assert self.topology_format is not None, "No topology format was provided."
        assert self.crd_format is not None, "No coordinate format was provided."

        if self.topology_format.upper() in ["AMBER", "GROMACS", "CHARMM"]:
            assert self.top_file is not None, "Topology format is {} but no topology file was provided.".format(
                self.topology_format)
        else:
            raise NotImplementedError(
                "Topology format {} is not known.".format(
                    self.topology_format))

        assert self.crd_file is not None, "create_system flag is True but no crd_file was provided."
        if self.platform_name is None:
            logging.info("No platform set. Will use reference.")
            self.platform_name = "Reference"
        else:
            assert self.platform_name in [
                "Reference", "CPU", "OpenCL", "CUDA"
            ], """create_system flag is True but no
               correct platform was provided."""

        # Read topology
        if self.topology_format.upper() == "AMBER":
            if self.topology is None:
                top = app.AmberPrmtopFile(self.top_file)
                self.topology = top.topology
        elif self.topology_format.upper() == "GROMACS":
            if self.topology is None:
                top = app.GromacsTopFile(self.top_file)
                self.topology = top.topology
        elif self.topology_format.upper() == "CHARMM":
            if self.topology is None:
                top = app.CharmmPsfFile(self.top_file)
                self.topology = top.topology
                charmm_params = app.CharmmParameterSet('charmm.rtf',
                                                       self.charmm_param_file)
        else:
            raise NotImplementedError(
                "Topology format {} is not currently supported.".format(
                    self.topology_format))

        # Read coordinate file
        if self.crd_format.upper() == "AMBER":
            crd = app.AmberInpcrdFile(self.crd_file)
        elif self.crd_format.upper() == "GROMACS":
            crd = app.GromacsGroFile(self.crd_file)
        elif self.crd_format.upper() == "CHARMM":
            crd = app.CharmmCrdFile(self.crd_file)
        elif self.crd_format.upper() == "PDB":
            crd = app.PDBFile(self.crd_file)
        else:
            raise NotImplementedError(
                "Coordinate format {} is not currently supported.".format(
                    self.crd_format))

        if self.system is None:
            if self.xml_file is None:
                assert create_system_params is not None, "No settings to create the system were provided."

                logging.info("Creating OpenMM System from {} file.".format(
                    self.topology_format))
                if self.topology_format.upper() == "CHARMM":
                    self.system = top.createSystem(charmm_params,
                                                   **create_system_params)
                else:
                    self.system = top.createSystem(**create_system_params)
            else:
                logging.info("Creating OpenMM System from XML file.")
                xml_file = open(self.xml_file)
                self.system = XmlSerializer.deserializeSystem(xml_file.read())
                xml_file.close()

        if self.integrator is None:
            assert integrator_params is not None, "No settings to create the integrator were provided."

            self.integrator = openmm.LangevinIntegrator(
                integrator_params['temperature'],
                integrator_params["frictionCoeff"],
                integrator_params["stepSize"])
            logging.info("Creating OpenMM integrator.")
        if self.platform is None:
            self.platform = openmm.Platform.getPlatformByName(
                self.platform_name)
            logging.info("Creating OpenMM platform.")
        if self.context is None:
            self.context = openmm.Context(self.system, self.integrator,
                                          self.platform)
            logging.info("Creating OpenMM Context.")

        # Set positions in context
        self.context.setPositions(crd.positions)

        return self.system
Exemplo n.º 10
0
    paralib = '/pubhome/qyfu02/lck_drude/run1/drude_toppar_2018_10/'

if ftype == 'c36':
    timestep = 0.002
    paralib = '/home/qiuzy/paralib/charmm/toppar_c36_jul17/'

# Read PSF File

psf = app.CharmmPsfFile(chfpre + '.psf')
psf.setBox(latta, lattb, lattc, 90.00 * degree, 90.00 * degree, 90.00 * degree)
# crd = app.CharmmCrdFile(chfpre+'.crd')
crd = PDBFile(chfpre + '.pdb')

# Load the parameter set.
if ftype == 'drude':
    params = app.CharmmParameterSet(paralib +
                                    'toppar_drude_master_protein_2013f.str')
if ftype == 'c36':
    params = app.CharmmParameterSet(paralib + 'top_all36_prot.rtf',
                                    paralib + 'par_all36_prot.prm',
                                    paralib + 'toppar_water_ions.str')

# Instantiate the system
platform = mm.Platform.getPlatformByName('CUDA')

if ftype == 'drude':
    system = psf.createSystem(params,
                              nonbondedMethod=ff.PME,
                              nonbondedCutoff=1.20,
                              switchDistance=1.00,
                              ewaldErrorTolerance=0.0001,
                              constraints=ff.HBonds)
Exemplo n.º 11
0
def compare_energies(system_name,
                     pdb_filename,
                     psf_filename,
                     ffxml_filenames,
                     toppar_filenames,
                     box_vectors_filename=None,
                     system_kwargs=None,
                     tolerance=1e-5,
                     units=u.kilojoules_per_mole,
                     write_serialized_xml=False):
    """
    Compare energies between (pdb, psf, toppar) loaded via ParmEd and (pdb, ffxml) loaded by OpenMM ForceField

    Parameters
    ----------
    system_name : str
        Name of the test system
    pdb_filename : str
        Name of PDB file that should contain CRYST entry and PDB format compliant CONECT records for HETATM residues.
    psf_filename : str
        CHARMM PSF file
    ffxml_filenames : list of str
        List of OpenMM ffxml files
    toppar_filenames : list of CHARMM toppar filenames to load into CharmmParameterSet
        List of CHARMM toppar files
    box_vectors_filename : str, optional, default=None
        If specified, read box vectors from a file like step2.1_waterbox.prm
    system_kwargs : dict, optional, default=None
        Keyword arguments to pass to CharmmPsfFile.createSystem() and ForceField.CreateSystem() when constructing System objects for energy comparison
    tolerance : float, optional, default=1e-5
        Relative energy discrepancy tolerance
    units : simtk.unit.Unit
        Unit to use for energy comparison
    write_serialized_xml : bool, optional, default=False
        If True, will write out serialized System XML files for OpenMM systems to aid debugging.

    """

    is_periodic = False
    if (system_kwargs is not None) and ('nonbondedMethod'
                                        in system_kwargs) and (
                                            system_kwargs['nonbondedMethod']
                                            in [app.CutoffPeriodic, app.PME]):
        is_periodic = True

    # Load PDB file
    pdbfile = app.PDBFile(pdb_filename)

    # Read box vectors
    if box_vectors_filename:
        box_vectors = read_box_vectors(box_vectors_filename)
        pdbfile.topology.setPeriodicBoxVectors(box_vectors)
    else:
        box_vectors = pdbfile.topology.getPeriodicBoxVectors()

    # Load CHARMM system through OpenMM
    openmm_toppar = app.CharmmParameterSet(*toppar_filenames)
    openmm_psf = app.CharmmPsfFile(psf_filename)
    # Set box vectors
    if is_periodic:
        openmm_psf.setBox(box_vectors[0][0], box_vectors[1][1],
                          box_vectors[2][2])
    openmm_system = openmm_psf.createSystem(openmm_toppar, **system_kwargs)
    openmm_structure = openmm.load_topology(openmm_psf.topology,
                                            openmm_system,
                                            xyz=pdbfile.positions)
    #openmm_energies = openmm.energy_decomposition_system(openmm_structure, openmm_system, nrg=units)
    #print('OpenMM CHARMM loader energy components : %s' % str(openmm_energies))
    openmm_total_energy = compute_potential(openmm_system,
                                            pdbfile.positions) / units

    # Load CHARMM system through ParmEd
    parmed_toppar = CharmmParameterSet(*toppar_filenames)
    parmed_structure = CharmmPsfFile(psf_filename)
    #structure.load_parameters(toppar)
    parmed_structure.positions = pdbfile.positions
    # Set box vectors
    if is_periodic:
        parmed_structure.box = (box_vectors[0][0] / u.angstroms,
                                box_vectors[1][1] / u.angstroms,
                                box_vectors[2][2] / u.angstroms, 90, 90, 90)
    parmed_system = parmed_structure.createSystem(parmed_toppar,
                                                  **system_kwargs)
    #parmed_energies = openmm.energy_decomposition_system(parmed_structure, parmed_system, nrg=units)
    #print('ParmEd CHARMM loader energy components : %s' % str(parmed_energies))
    parmed_total_energy = compute_potential(parmed_system,
                                            pdbfile.positions) / units

    # Delete H-H bonds from waters and retreive updated topology and positions
    modeller = app.Modeller(openmm_psf.topology, pdbfile.positions)
    hhbonds = [
        b for b in modeller.topology.bonds()
        if b[0].element == app.element.hydrogen
        and b[1].element == app.element.hydrogen
    ]
    modeller.delete(hhbonds)
    ffxml_topology = modeller.topology

    # OpenMM system with ffxml
    ff = app.ForceField(*ffxml_filenames)
    ffxml_system = ff.createSystem(ffxml_topology, **system_kwargs)
    ffxml_structure = openmm.load_topology(ffxml_topology,
                                           ffxml_system,
                                           xyz=pdbfile.positions)
    #ffxml_energies = openmm.energy_decomposition_system(ffxml_structure, ffxml_system, nrg=units)
    #print('ffxml energy components : %s' % str(ffxml_energies))
    ffxml_total_energy = compute_potential(ffxml_system,
                                           pdbfile.positions) / units

    write_serialized_xml = True  # DEBUG
    if write_serialized_xml:
        print('Writing serialized XML files...')
        write_serialized_system(system_name + '.charmm.system.xml',
                                openmm_system)
        write_serialized_system(system_name + '.parmed.system.xml',
                                parmed_system)
        write_serialized_system(system_name + '.openmm.system.xml',
                                ffxml_system)

    print('-' * 100)
    print('')
    print('OpenMM CHARMM reader total energy: %14.3f' % openmm_total_energy)
    print('ParmEd CHARMM reader total energy: %14.3f' % parmed_total_energy)
    print('OPENMM ffxml total energy:         %14.3f' % ffxml_total_energy)
    print('TOTAL ERROR:                       %14.3f' %
          (ffxml_total_energy - openmm_total_energy))
    print('')

    print('-' * 100)

    # TODO : Automate comparison
    return

    # calc rel energies and assert
    rel_energies = []
    for i, j in zip(ffxml_energies, parmed_energies):
        if i[0] != j[0]:
            raise Exception('Mismatch in energy tuples naming.')
        if abs(i[1]) > NEARLYZERO:
            rel_energies.append((i[0], abs((i[1] - j[1]) / i[1])))
        else:
            if abs(j[1]) > NEARLYZERO:
                raise AssertionError(
                    'One of the CHARMM %s energies (%s) for %s is zero, '
                    'while the corresponding OpenMM energy is non-zero' %
                    (system_name, i[0], ffxml))
            rel_energies.append((i[0], 0))

    dihedrals_done = False
    for i in rel_energies:
        if i[0] != 'PeriodicTorsionForce':
            if i[1] > tolerance:
                raise AssertionError(
                    '%s energies (%s, %f) outside of allowed tolerance (%f) for %s'
                    % (system_name, i[0], i[1], tolerance, ffxml))
        else:
            if not dihedrals_done:
                if i[1] > tolerance:
                    raise AssertionError(
                        '%s energies (%s, %f) outside of allowed tolerance (%f) for %s'
                        % (system_name, i[0], i[1], tolerance, ffxml))
                dihedrals_done = True
            else:  #impropers
                if i[1] > improper_tolerance:
                    raise AssertionError(
                        '%s energies (%s-impropers, %f) outside of allowed tolerance (%f) for %s'
                        % (system_name, i[0], i[1], improper_tolerance, ffxml))

    # logging
    if not no_log:
        charmm_energies_log = dict()
        omm_energies_log = dict()
        rel_energies_log = dict()
        charmm_energies_log['ffxml_name'] = ffxml
        charmm_energies_log['test_system'] = system_name
        charmm_energies_log['data_type'] = 'CHARMM'
        charmm_energies_log['units'] = units
        omm_energies_log['ffxml_name'] = ffxml
        omm_energies_log['test_system'] = system_name
        omm_energies_log['data_type'] = 'OpenMM'
        omm_energies_log['units'] = units
        rel_energies_log['ffxml_name'] = ffxml
        rel_energies_log['test_system'] = system_name
        rel_energies_log['data_type'] = 'abs((CHARMM-OpenMM)/CHARMM)'
        dihedrals_done = False
        for item in amber_energies:
            if item[0] == 'PeriodicTorsionForce' and not dihedrals_done:
                charmm_energies_log['PeriodicTorsionForce_dihedrals'] = item[1]
                dihedrals_done = True
            elif item[0] == 'PeriodicTorsionForce' and dihedrals_done:
                charmm_energies_log['PeriodicTorsionForce_impropers'] = item[1]
            elif item[0] == 'CMMotionRemover':
                continue
            else:
                charmm_energies_log[item[0]] = item[1]
        dihedrals_done = False
        for item in omm_energies:
            if item[0] == 'PeriodicTorsionForce' and not dihedrals_done:
                omm_energies_log['PeriodicTorsionForce_dihedrals'] = item[1]
                dihedrals_done = True
            elif item[0] == 'PeriodicTorsionForce' and dihedrals_done:
                omm_energies_log['PeriodicTorsionForce_impropers'] = item[1]
            elif item[0] == 'CMMotionRemover':
                continue
            else:
                omm_energies_log[item[0]] = item[1]
        dihedrals_done = False
        for item in rel_energies:
            if item[0] == 'PeriodicTorsionForce' and not dihedrals_done:
                rel_energies_log['PeriodicTorsionForce_dihedrals'] = item[1]
                dihedrals_done = True
            elif item[0] == 'PeriodicTorsionForce' and dihedrals_done:
                rel_energies_log['PeriodicTorsionForce_impropers'] = item[1]
            elif item[0] == 'CMMotionRemover':
                continue
            else:
                rel_energies_log[item[0]] = item[1]

        logger.log(charmm_energies_log)
        logger.log(omm_energies_log)
        logger.log(rel_energies_log)
Exemplo n.º 12
0
prefix = '/tmp/'  # temporary directory to write dcd

# Read the CHARMM PSF file
psf = app.CharmmPsfFile('csptm.psf')

boxsize = 6.9  # boxsize in nanometer
psf.setBox(boxsize * nanometer, boxsize * nanometer, boxsize * nanometer)

# Get the coordinates from the CHARMM crd file
crd = app.CharmmCrdFile('csptm.crd')
# pdb = app.PDBFile('csptm.pdb')  # in case a pdb file instead of crd is used

# Load the parameter set.
lib = 'toppar/'  # path of force field topology and parameter files
params = app.CharmmParameterSet(lib + 'top_all36_prot.rtf',
                                lib + 'par_all36m_prot.prm',
                                lib + 'toppar_water_ions.str')
# params = app.CharmmParameterSet(lib+'top_all36_prot.rtf', lib+'par_all36m_prot.prm', lib+'toppar_n010water_ions.str') # in case alternative water model is used to sample more extended states of IDPs

platform = mm.Platform.getPlatformByName('CUDA')  # make sure the GPU is used

system = psf.createSystem(params,
                          nonbondedMethod=app.PME,
                          nonbondedCutoff=1.2 * nanometer,
                          switchDistance=1.0 * nanometer,
                          ewaldErrorTolerance=0.0001,
                          constraints=app.HBonds)

system.addForce(mm.AndersenThermostat(300 * kelvin,
                                      1 / picosecond))  # thermostat
system.addForce(mm.MonteCarloBarostat(1 * bar, 300 * kelvin))  # barostat
Exemplo n.º 13
0
Because we are using OpenMM as our MD engine, we need to setup the 
MD molecular system in the format required by OpenMM. The format/object 
used by OpenMM for a molecular system happens to be a class called System. 
Therefore, we will prepare our MD molecular system as an OpenMM System.
When we prepare the OpenMM system, we will add two CustomTorsionForces so
that we can add biasing potentials to the system in the following umbrella
sampling.
'''

import simtk.openmm.app as omm_app
import simtk.openmm as omm
import simtk.unit as unit
import math

## read CHARMM force field for proteins
charmm_toppar = omm_app.CharmmParameterSet("./data/top_all36_prot.rtf",
                                           "./data/par_all36_prot.prm")

## read psf and pdb file of dialanine
psf = omm_app.CharmmPsfFile("./output/dialanine.psf")
pdb = omm_app.PDBFile('./data/dialanine.pdb')

## create a OpenMM system based on psf of dialanine and CHARMM force field
system = psf.createSystem(charmm_toppar, nonbondedMethod=omm_app.NoCutoff)

## add harmonic biasing potentials on two dihedrals of dialanine (psi, phi) in the OpenMM system
## for dihedral psi
bias_torsion_psi = omm.CustomTorsionForce(
    "0.5*k_psi*dtheta^2; dtheta = min(tmp, 2*pi-tmp); tmp = abs(theta - psi)")
bias_torsion_psi.addGlobalParameter("pi", math.pi)
bias_torsion_psi.addGlobalParameter("k_psi", 1.0)
bias_torsion_psi.addGlobalParameter("psi", 0.0)
Exemplo n.º 14
0
def gen_simulation(gro_file, psf_file, prm_file, T, P, pcoupl='iso'):
    print('Building system...')
    gro = app.GromacsGroFile(gro_file)
    psf = OplsPsfFile(psf_file, periodicBoxVectors=gro.getPeriodicBoxVectors())
    prm = app.CharmmParameterSet(prm_file)
    system = psf.createSystem(prm,
                              nonbondedMethod=app.PME,
                              ewaldErrorTolerance=1E-5,
                              nonbondedCutoff=1.2 * nm,
                              constraints=app.HBonds,
                              rigidWater=True,
                              verbose=True)

    if not psf.is_drude:
        print('\tLangevin thermostat: 1.0/ps')
        integrator = mm.LangevinIntegrator(T * kelvin, 1.0 / ps, 0.001 * ps)
    else:
        print('\tDual Langevin thermostat: 10/ps, 50/ps')
        integrator = mm.DrudeLangevinIntegrator(T * kelvin, 10 / ps,
                                                1 * kelvin, 50 / ps,
                                                0.001 * ps)
        integrator.setMaxDrudeDistance(0.02 * nm)

    if pcoupl == 'iso':
        print('\tIsotropic barostat')
        system.addForce(mm.MonteCarloBarostat(P * bar, T * kelvin, 25))
    elif pcoupl == 'xyz':
        print('\tAnisotropic barostat')
        system.addForce(
            mm.MonteCarloAnisotropicBarostat([P * bar] * 3, T * kelvin, True,
                                             True, True, 25))
    elif pcoupl == 'xy':
        print('\tAnisotropic Barostat only for X and Y')
        system.addForce(
            mm.MonteCarloAnisotropicBarostat([P * bar] * 3, T * kelvin, True,
                                             True, False, 25))
    else:
        print('\tNo barostat')

    print('Initializing simulation...')
    platform = mm.Platform.getPlatformByName('CUDA')
    properties = {'CudaPrecision': 'mixed'}
    sim = app.Simulation(psf.topology, system, integrator, platform,
                         properties)
    sim.context.setPositions(gro.positions)
    sim.context.setVelocitiesToTemperature(T * kelvin)
    sim.reporters.append(GroReporter('dump.gro', 10000))
    sim.reporters.append(app.DCDReporter('dump.dcd', 1000))
    sim.reporters.append(
        app.StateDataReporter(sys.stdout,
                              500,
                              step=True,
                              temperature=True,
                              potentialEnergy=True,
                              kineticEnergy=True,
                              volume=True,
                              density=True,
                              elapsedTime=True,
                              speed=True,
                              separator='\t'))
    state = sim.context.getState(getEnergy=True)
    print('Energy: ' + str(state.getPotentialEnergy()))
    return sim
Exemplo n.º 15
0
def run_omm(options):

    inp = Config(options.input)

    dt = float(inp.getWithDefault("timestep", 4)) * u.femtosecond
    temperature = float(inp.getWithDefault("temperature", 300)) * u.kelvin
    thermostattemperature = float(
        inp.getWithDefault("thermostattemperature", 300)) * u.kelvin
    logPeriod = 1 * u.picosecond
    trajectoryPeriod = int(inp.getWithDefault("trajectoryperiod", 25000)) * dt
    run_steps = int(inp.run)
    basename = "output"
    trajectory_file = basename + ".dcd"

    if 'PME' in inp and not inp.getboolean('PME'):
        nonbondedMethod = app.NoCutoff
    else:
        nonbondedMethod = app.PME
    nonbondedCutoff = float(inp.getWithDefault("cutoff", 9.0)) * u.angstrom
    switchDistance = float(inp.getWithDefault("switchdistance",
                                              7.5)) * u.angstrom
    frictionCoefficient = float(inp.getWithDefault("thermostatdamping",
                                                   0.1)) / u.picosecond

    endTime = run_steps * dt

    util.check_openmm()

    if options.platform is None:
        print("Selecting best platform:")
        req_platform_name = util.get_best_platform()
    else:
        print(f"Requesting platform {options.platform}")
        req_platform_name = options.platform
    req_platform = mm.Platform.getPlatformByName(req_platform_name)

    req_properties = {}  # {'UseBlockingSync':'true'}
    if options.device is not None and 'DeviceIndex' in req_platform.getPropertyNames(
    ):
        print("    Setting DeviceIndex = " + options.device)
        req_properties['DeviceIndex'] = options.device
    if options.precision is not None and 'Precision' in req_platform.getPropertyNames(
    ):
        print("    Setting Precision = " + options.precision)
        req_properties['Precision'] = options.precision

    # Same logic as https://software.acellera.com/docs/latest/acemd3/reference.html
    if dt > 2 * u.femtosecond:
        hydrogenMass = 4 * u.amu
        constraints = app.AllBonds
        rigidWater = True
    elif dt > 0.5 * u.femtosecond:
        hydrogenMass = None
        constraints = app.HBonds
        rigidWater = True
    else:
        hydrogenMass = None
        constraints = None
        rigidWater = False

    print(f"""
                            Host: {socket.gethostname()}
                            Date: {datetime.datetime.now().ctime()}
                        Timestep: {dt}
                     Constraints: {constraints}
                     Rigid water: {rigidWater}
                       Nonbonded: {nonbondedMethod}
    Hydrogen mass repartitioning: {hydrogenMass}
    """)
    _printPluginInfo()

    if 'parmfile' in inp:
        print(f"Creating an AMBER system...")
        if 'structure' in inp:
            print("Warning: 'structure' given but ignored for AMBER")
        prmtop = app.AmberPrmtopFile(inp.parmfile)
        system = prmtop.createSystem(nonbondedMethod=nonbondedMethod,
                                     nonbondedCutoff=nonbondedCutoff,
                                     switchDistance=switchDistance,
                                     constraints=constraints,
                                     hydrogenMass=hydrogenMass,
                                     rigidWater=rigidWater)
        topology = prmtop.topology
    else:
        print(f"Creating a CHARMM system...")
        psf = app.CharmmPsfFile(inp.structure)
        params = app.CharmmParameterSet(inp.parameters, permissive=True)
        psf.setBox(50. * u.angstrom, 50. * u.angstrom,
                   50. * u.angstrom)  # otherwise
        # refuses
        # PME
        system = psf.createSystem(params,
                                  nonbondedMethod=nonbondedMethod,
                                  nonbondedCutoff=nonbondedCutoff,
                                  switchDistance=switchDistance,
                                  constraints=constraints,
                                  hydrogenMass=hydrogenMass,
                                  rigidWater=rigidWater)
        topology = psf.topology

    if 'barostat' in inp and inp.getboolean('barostat'):
        pressure = float(inp.barostatpressure) * u.bar
        print(f"Enabling barostat at {pressure}...")
        system.addForce(mm.MonteCarloBarostat(pressure, thermostattemperature))

    if 'plumedfile' in inp:
        print("Attempting to load PLUMED plugin...")
        from openmmplumed import PlumedForce
        plines = util.plumed_parser(inp.plumedfile)
        system.addForce(PlumedForce(plines))

    integrator = mm.LangevinIntegrator(thermostattemperature,
                                       frictionCoefficient, dt)
    integrator.setConstraintTolerance(1e-5)

    simulation = app.Simulation(topology, system, integrator, req_platform,
                                req_properties)
    ctx = simulation.context
    platform = ctx.getPlatform()
    print(f"Got platform {platform.getName()} with properties:")
    for prop in platform.getPropertyNames():
        print(f"    {prop}\t\t{platform.getPropertyValue(ctx,prop)}")
    print("")

    resuming = False
    if os.path.exists(checkpoint_file):
        with open(checkpoint_file, 'rb') as cf:
            ctx.loadCheckpoint(cf.read())
        # ctx.loadCheckpoint(str(checkpoint_file))
        util.round_state_time(ctx, 10 * dt)
        print(f"Successfully loaded {checkpoint_file}, resuming simulation...")
        resuming = True

    else:
        print(
            f"File {checkpoint_file} absent, starting simulation from the beginning..."
        )
        coords = util.get_coords(inp)
        ctx.setPositions(coords)

    if not resuming:
        (boxa, boxb, boxc) = util.get_box_size(inp)
        ctx.setPeriodicBoxVectors(boxa, boxb, boxc)

        if 'minimize' in inp:
            print(f'Minimizing for max {inp.minimize} iterations...')
            simulation.minimizeEnergy(maxIterations=int(inp.minimize))
            simulation.saveState(f"miniomm_minimized.xml")
        else:
            if 'binvelocities' in inp:
                print(f"Reading velocities from NAMDBin: " + inp.binvelocities)
                vels = NAMDBin(inp.binvelocities).getVelocities()
                ctx.setVelocities(vels)
            else:
                print(f"Resetting thermal velocities at {temperature}")
                ctx.setVelocitiesToTemperature(temperature)

    # -------------------------------------------------------
    print("")
    inp.printWarnings()

    # -------------------------------------------------------
    print("")

    startTime = ctx.getState().getTime()
    startTime_f = startTime.in_units_of(u.nanoseconds).format("%.3f")
    endTime_f = endTime.in_units_of(u.nanoseconds).format("%.3f")
    remaining_steps = round((endTime - startTime) / dt)
    remaining_ns = remaining_steps * dt.value_in_unit(u.nanosecond)
    print(
        f"Current simulation time is {startTime_f}, running up to {endTime_f}."
    )
    print(
        f"Will run for {remaining_steps} timesteps = {remaining_ns:.3f} ns...")
    print("")

    log_every = util.every(logPeriod, dt)
    save_every = util.every(trajectoryPeriod, dt)
    if remaining_steps % save_every != 0:
        raise ValueError(
            "Remaining steps is not a multiple of trajectoryperiod")

    util.add_reporters(simulation, trajectory_file, log_every, save_every,
                       remaining_steps, resuming, checkpoint_file)

    # ----------------------------------------
    simulation.saveState(f"miniomm_pre.xml")

    # ----------------------------------------
    simulation.step(remaining_steps)

    # ----------------------------------------
    simulation.saveState(f"miniomm_post.xml")
    final_state = simulation.context.getState(getPositions=True,
                                              getVelocities=True)
    final_coor = final_state.getPositions(asNumpy=True)
    NAMDBin(final_coor).write_file(f"{basename}.coor")

    final_box = final_state.getPeriodicBoxVectors(asNumpy=True)
    write_xsc(f"{basename}.xsc", remaining_steps, final_state.getTime(),
              final_box)
    # ----------------------------------------
    print('Done!')
    return
import simtk.openmm as mm
import simtk.openmm.app as app
from simtk import unit

# input topology, psf, and force field files generated from CHARMM-GUI Solution Builder
print('Parsing system topology')
topology = app.CharmmPsfFile('step3_charmm2omm.psf')
parameters = app.CharmmParameterSet('top_all36_prot.rtf',\
            'par_all36_prot.prm' ,'toppar_water_ions.str')

print('Parsing system coordinates')
# for using PBC in OpenMM, we need to make sure that
# the origin of the sytem is at (0,0,0)
# and that the extremum of the system is at (Lx, Ly, Lz)
coord = app.PDBFile('step3_pbcsetup.pdb')
# translate the coordinates, we'll use numpy here.
import numpy as np
xyz = np.array(coord.positions/unit.nanometer)
xyz[:,0] -= np.amin(xyz[:,0])
xyz[:,1] -= np.amin(xyz[:,1])
xyz[:,2] -= np.amin(xyz[:,2])
coord.positions = xyz*unit.nanometer

print('Constructing sytem')
# set periodic box vectors
topology.setBox(7.5*unit.nanometer, 7.5*unit.nanometer, 7.5*unit.nanometer)
# use PME for long-range electrostatics, cutoff for short-range interactions
# constrain H-bonds with RATTLE, constrain water with SETTLE
system = topology.createSystem(parameters, nonbondedMethod=app.PME, 
    nonbondedCutoff=1.2*unit.nanometers, constraints=app.HBonds, rigidWater=True, 
    ewaldErrorTolerance=0.0005)
Exemplo n.º 17
0
def main():
    print("Reading the PSF file")

    # Read the PSF file
    #psf = app.CharmmPsfFile('g1_25mm.psf');
    psf = app.CharmmPsfFile('holo_neutr.psf')

    boxsize = 4.895883  # Boxsize in nm
    psf.setBox(boxsize * nanometer, boxsize * nanometer, boxsize * nanometer)

    print("Reading the pdb file")
    #pdb = app.PDBFile('g1_25mm.pdb');
    #pdb  = app.PDBFile('md_298k_100ns.pdb')
    pdb = app.PDBFile('holo_neutr.pdb')

    # Load the parameter set
    lib = 'toppar/'
    #params = app.CharmmParameterSet('toppar/top_all36_cgenff.rtf','toppar/par_all36_cgenff.prm','toppar/cgenff3.0.1/top_all36_cgenff.rtf','toppar/cgenff3.0.1/par_all36_cgenff.prm','g1_new.str','toppar_water_ions.str')
    #params = app.CharmmParameterSet('toppar/cgenff3.0.1/top_all36_cgenff.rtf','toppar/cgenff3.0.1/par_all36_cgenff.prm','g1_new.str','toppar_water_ions.str')
    params = app.CharmmParameterSet('toppar/cgenff3.0.1/top_all36_cgenff.rtf',
                                    'toppar/cgenff3.0.1/par_all36_cgenff.prm',
                                    'g1_new.str', 'oah_groups.str',
                                    'toppar_water_ions.str')

    platform = openmm.Platform.getPlatformByName('CUDA')

    isShortSim = False
    #isShortSim = True
    isPeriodic = True
    #isPeriodic = False
    #if not isPeriodic :
    #  isShortSim = True;

    # Creating the system
    if (isPeriodic):
        print("PME is being used")
        system = psf.createSystem(params,
                                  nonbondedMethod=app.PME,
                                  nonbondedCutoff=1.2 * nanometer,
                                  switchDistance=1.0 * nanometer,
                                  ewaldErrorTolerance=0.0001,
                                  constraints=app.HBonds)
    else:
        print("PME is not being used")
        system = psf.createSystem(
            params,
            #                          nonbondedMethod=app.PME,
            nonbondedCutoff=1.2 * nanometer,
            switchDistance=1.0 * nanometer,
            ewaldErrorTolerance=0.0001,
            constraints=app.HBonds)

    #for force in system.getForces():
    #  print(force, force.usesPeriodicBoundaryConditions())
    # Thermostat @ 298 K
    #system.addForce(openmm.AndersenThermostat(298*kelvin, 1/picosecond))
    # adding the barostat for now
    #system.addForce(openmm.MonteCarloBarostat(1*bar, 298*kelvin));

    # adding positional restriants
    if isPeriodic:
        force = openmm.CustomExternalForce(
            "k*periodicdistance(x, y, z, x0, y0, z0)^2")
    else:
        force = openmm.CustomExternalForce("k*((x-x0)^2+(y-y0)^2+(z-z0)^2)")
        #force = openmm.CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2");

    force.addGlobalParameter("k", 0.1 * kilocalories_per_mole / angstroms**2)
    force.addPerParticleParameter("x0")
    force.addPerParticleParameter("y0")
    force.addPerParticleParameter("z0")

    topology = pdb.getTopology()
    positions = pdb.getPositions()
    #for atom in  topology.atoms():
    #  print(atom)

    host = []
    guest = []
    for res in topology.residues():
        if res.name == 'OAH':
            for atom in res.atoms():
                host.append(atom.index)
                force.addParticle(atom.index, positions[atom.index])
                #force.addParticle(atom.index, (0, 0, 0)*nanometers)
        if res.name == 'GOA':
            for atom in res.atoms():
                guest.append(atom.index)
    system.addForce(force)

    print("Does customExternalForce use periodic boundary condition : ",
          force.usesPeriodicBoundaryConditions())
    # adding restraint between the host and guest
    # this will be inside the umbrella sampling loop
    host_guest_centroid_force = openmm.CustomCentroidBondForce(
        2, "0.5*k*(distance(g1,g2)-d0)^2")
    host_guest_centroid_force.addGlobalParameter(
        "k", 10.0 * kilocalories_per_mole / angstroms**2)
    #d0_global_parameter_index = force.addGlobalParameter("d0", 2.0*angstroms);
    #d0_perBond_parameter_index = force.addPerBondParameter("d0", 2.0*angstroms);
    d0_perBond_parameter_index = host_guest_centroid_force.addPerBondParameter(
        "d0")
    group1 = host_guest_centroid_force.addGroup(host)
    group2 = host_guest_centroid_force.addGroup(guest)
    host_guest_bond = host_guest_centroid_force.addBond([group1, group2])
    host_guest_centroid_force.setBondParameters(host_guest_bond,
                                                [group1, group2],
                                                [20 * angstroms])
    system.addForce(host_guest_centroid_force)
    #sys.exit(0)
    """
  # Restrain along z axis
  # adding positional restriants
  if isPeriodic :
    z_force = openmm.CustomExternalForce("k*periodicdistance(x, x0)^2");
  else :
    z_force = openmm.CustomExternalForce("k*((x-x0)^2+(y-y0)^2)");
    #force = openmm.CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2");

  z_force.addGlobalParameter("k", 0.1*kilocalories_per_mole/angstroms**2);
  z_force.addPerParticleParameter("x0");
  z_force.addPerParticleParameter("y0");

  for res in topology.residues():
    if res.name == 'GOA' :
      for atom in res.atoms():
        pos = list(positions[atom.index])
        print(pos[2])
        z_force.addParticle(atom.index, [pos[0], pos[1]])
  system.addForce(z_force)
  """

    # langevin integrator
    integrator = openmm.LangevinIntegrator(
        298 * kelvin,  # Temperature 
        1.0 / picoseconds,  # Friction coefficient
        0.001 * picoseconds  # Time step
    )
    #integrator = openmm.VerletIntegrator(0.001*picoseconds);
    simulation = app.Simulation(psf.topology, system, integrator, platform)
    simulation.context.setPositions(pdb.getPositions())

    #currentState = simulation.context.getState(getPositions=True)
    #pdbr = app.PDBReporter("pdbreport.pdb",1);
    #pdbr.report(simulation, currentState)

    print("Minimizing...")
    simulation.minimizeEnergy(maxIterations=2000)
    print("Equilibrating...")
    simulation.context.setVelocitiesToTemperature(298 * kelvin)
    #currentState = simulation.context.getState(getPositions=True)
    #pdbr = app.PDBReporter("pdbreport_after_min.pdb",1);
    #pdbr.report(simulation, currentState)
    #pdbr = app.PDBReporter("pdbreport_after_step1.pdb",1);

    nsavcrd = 10000  # save coordinates every 10 ps
    nprint = 2000  # report every 2 ps
    if isShortSim:
        nstep = 20000  # run the simulation for 0.2ns
    else:
        nstep = 2000000  # run the simulation for 2ns
    firstDcdStep = nsavcrd

    # Reporters
    dcdReportInterval = 10000  # save coordinates every 10 ps
    dcd = app.DCDReporter('umb_3.dcd', dcdReportInterval)
    dcd._dcd = app.DCDFile(dcd._out, simulation.topology,
                           simulation.integrator.getStepSize(), firstDcdStep,
                           nsavcrd)

    stateReporter = app.StateDataReporter('umb_3.out',
                                          nprint,
                                          step=True,
                                          kineticEnergy=True,
                                          potentialEnergy=True,
                                          totalEnergy=True,
                                          temperature=True,
                                          volume=True,
                                          speed=True)

    simulation.reporters.append(dcd)
    simulation.reporters.append(stateReporter)
    #simulation.reporters.append(pdbr);
    #simulation.reporters.append(app.StateDataReporter('umb.out', nprint, step=True, kineticEnergy=True, potentialEnergy=True, totalEnergy=True, temperature=True, volume=True, speed=True))

    # Run the simulation
    print("Simulation begins ...")
    #simulation.step(1)
    #sys.exit(0)
    for i in range(15):
        print("Simulation for umbrella : ", i)
        host_guest_centroid_force.setBondParameters(host_guest_bond,
                                                    [group1, group2],
                                                    [(5 + 3 * i) * angstroms])
        #force.setGlobalParameterDefaultValue(d0_global_parameter_index, (2+i)*angstroms)
        host_guest_centroid_force.updateParametersInContext(simulation.context)
        print("host guest bond parameters",
              host_guest_centroid_force.getBondParameters(host_guest_bond))
        #serialized = openmm.XmlSerializer.serialize(simulation.system)
        #of = open("serial_sim_"+str(i)+".xml",'w');
        #of.write(serialized);
        #of.close();
        #simulation.saveState("state_"+str(i)+".xml");
        simulation.step(nstep)

    simulation.reporters.pop()
    simulation.reporters.pop()
    dcd._out.close()
Exemplo n.º 18
0
def run_simulation(nstep,
                   gro_file='conf.gro',
                   psf_file='topol.psf',
                   prm_file='ff.prm',
                   dt=0.001,
                   T=333,
                   voltage=0,
                   screen=0,
                   restart=None):
    print('Building system...')
    gro = oh.GroFile(gro_file)
    lz = gro.getUnitCellDimensions()[2].value_in_unit(nm)
    psf = oh.OplsPsfFile(psf_file,
                         periodicBoxVectors=gro.getPeriodicBoxVectors())
    prm = app.CharmmParameterSet(prm_file)
    system = psf.createSystem(prm,
                              nonbondedMethod=app.PME,
                              nonbondedCutoff=1.2 * nm,
                              constraints=app.HBonds,
                              rigidWater=True,
                              verbose=True)
    nbforce = next(f for f in system.getForces()
                   if type(f) == mm.NonbondedForce)
    ljforce = next(f for f in system.getForces()
                   if type(f) == mm.CustomNonbondedForce)
    bforce = next(f for f in system.getForces()
                  if type(f) == mm.HarmonicBondForce)
    is_drude = any(type(f) == mm.DrudeForce for f in system.getForces())

    ### assign groups
    atoms = list(psf.topology.atoms())
    group_mos = [atom.index for atom in atoms if atom.residue.name == 'MoS2']
    group_mos_core = [
        i for i in group_mos if not atoms[i].name.startswith('D')
    ]
    group_img = [atom.index for atom in atoms if atom.residue.name == 'IMG']
    group_ils = [
        atom.index for atom in atoms
        if atom.residue.name not in ['MoS2', 'IMG']
    ]
    group_ils_drude = [i for i in group_ils if atoms[i].name.startswith('D')]
    image_pairs = list(zip(group_ils, group_img))
    print('Assigning groups...')
    print('    Number of atoms in group %10s: %i' % ('mos', len(group_mos)))
    print('    Number of atoms in group %10s: %i' % ('ils', len(group_ils)))
    print('    Number of atoms in group %10s: %i' % ('img', len(group_img)))
    print('    Number of atoms in group %10s: %i' %
          ('mos_core', len(group_mos_core)))

    ### apply TT damping for CLPol force field
    donors = [atom.idx for atom in psf.atom_list if atom.attype == 'HO']
    if is_drude and len(donors) > 0:
        print('Add TT damping between HO and Drude dipoles')
        ttforce = oh.CLPolCoulTT(system, donors)
        print(ttforce.getEnergyFunction())

    ### assign image charges
    for parent, image in image_pairs:
        q, _, _ = nbforce.getParticleParameters(parent)
        nbforce.setParticleParameters(image, -q, 1, 0)

    ### eliminate the interactions between images and MoS2
    ljforce.addInteractionGroup(set(group_img), set(group_ils))
    ljforce.addInteractionGroup(set(group_mos + group_ils),
                                set(group_mos + group_ils))

    ### apply screening between ils and images
    if screen != 0:
        print('Add screening between ILs and images...')
        tforce = mm.CustomNonbondedForce(
            '-%.6f*q1*q2/r*(1+0.5*screen*r)*exp(-screen*r);'
            'screen=%.4f' % (oh.CONST.ONE_4PI_EPS0, screen))
        print(tforce.getEnergyFunction())
        tforce.addPerParticleParameter('q')
        for i in range(system.getNumParticles()):
            q, _, _ = nbforce.getParticleParameters(i)
            tforce.addParticle([q])
        tforce.setNonbondedMethod(mm.CustomNonbondedForce.CutoffPeriodic)
        tforce.setCutoffDistance(1.2 * nm)
        tforce.addInteractionGroup(set(group_ils), set(group_img))
        tforce.setForceGroup(9)
        system.addForce(tforce)

    ### restrain the movement of MoS2 cores (Drude particles are free if exist)
    print('Add restraint for MoS2...')
    oh.spring_self(system, gro.positions.value_in_unit(nm), group_mos_core,
                   [0.01, 0.01, 5.0] * kcal_mol / angstrom**2)

    ### in case Drude particles kiss their images
    print('Add wall for Drude particles of ILs...')
    wall = oh.wall_lj126(system,
                         group_ils_drude,
                         'z', [0, lz / 2],
                         epsilon=0.5 * kcal_mol,
                         sigma=0.15 * nm)
    print(wall.getEnergyFunction())

    ### randomlize particle positions to get ride of overlap
    random.seed(0)
    for i in range(system.getNumParticles()):
        gro.positions[i] += (random.random(), random.random(),
                             random.random()) * nm / 1000

    ### velocity-Verlet-middle integrator
    from velocityverletplugin import VVIntegrator
    integrator = VVIntegrator(T * kelvin, 10 / ps, 1 * kelvin, 40 / ps,
                              dt * ps)
    integrator.setUseMiddleScheme(True)
    integrator.setMaxDrudeDistance(0.02 * nm)
    ### thermostat MoS2 by Langevin dynamics
    for i in group_mos:
        integrator.addParticleLangevin(i)
    ### assign image pairs
    integrator.setMirrorLocation(lz / 2 * nm)
    for parent, image in image_pairs:
        integrator.addImagePair(image, parent)
        # add fake bond between image and parent so that they are always in the same periodic cell
        bforce.addBond(image, parent, 0, 0)
    ### apply electric field on ils
    if voltage != 0:
        integrator.setElectricField(voltage / lz * 2 * volt / nm)
        for i in group_ils:
            integrator.addParticleElectrolyte(i)

    print('Initializing simulation...')
    _platform = mm.Platform.getPlatformByName('CUDA')
    _properties = {'CudaPrecision': 'mixed'}
    sim = app.Simulation(psf.topology, system, integrator, _platform,
                         _properties)
    if restart:
        sim.loadCheckpoint(restart)
        sim.currentStep = round(
            sim.context.getState().getTime().value_in_unit(ps) / dt / 10) * 10
        sim.context.setTime(sim.currentStep * dt)
        append = True
    else:
        sim.context.setPositions(gro.positions)
        sim.context.setVelocitiesToTemperature(T * kelvin)
        append = False

    sim.reporters.append(
        app.DCDReporter('dump.dcd',
                        10000,
                        enforcePeriodicBox=False,
                        append=append))
    sim.reporters.append(oh.CheckpointReporter('cpt.cpt', 10000))
    sim.reporters.append(
        oh.GroReporter('dump.gro',
                       1000,
                       logarithm=True,
                       subset=group_mos + group_ils,
                       append=append))
    sim.reporters.append(
        oh.StateDataReporter(sys.stdout, 10000, box=False, append=append))
    sim.reporters.append(
        oh.DrudeTemperatureReporter('T_drude.txt', 100000, append=append))

    print('Running...')
    oh.energy_decomposition(sim)
    sim.runForClockTime(99.9, 'rst.cpt', 'rst.xml', 1)
    print(
        '# clock time limit: step= %i time= %f' %
        (sim.currentStep, sim.context.getState().getTime().value_in_unit(ps)))
Exemplo n.º 19
0
def gen_simulation(
    gro_file="conf.gro",
    psf_file="topol.psf",
    prm_file="ff.prm",
    dt=0.001,
    T=300,
    P=1,
    tcoupl="langevin",
    pcoupl="iso",
    cos=0,
    field=0,
    restart=None,
):
    print("Building system...")
    gro = oh.GroFile(gro_file)
    psf = oh.OplsPsfFile(psf_file,
                         periodicBoxVectors=gro.getPeriodicBoxVectors())
    prm = app.CharmmParameterSet(prm_file)
    system = psf.createSystem(
        prm,
        nonbondedMethod=app.PME,
        nonbondedCutoff=1.2 * nm,
        constraints=app.HBonds,
        rigidWater=True,
        verbose=True,
    )
    is_drude = any(type(f) == mm.DrudeForce for f in system.getForces())

    ### apply TT damping for CLPol force field
    # donors = [atom.idx for atom in psf.atom_list if atom.attype == "HO"]
    # all HO atoms, even those with numbers after.
    # i.e. HO for choline, but also HO3 / HO5 for DHP
    donors = [
        atom.idx for atom in psf.atom_list
        if atom.attype.startswith("HO") or atom.attype.startswith("HW")
    ]
    if is_drude and len(donors) > 0:
        print("Add TT damping between HO/HW and Drude dipoles")
        ttforce = oh.CLPolCoulTT(system, donors)
        print(ttforce.getEnergyFunction())

    print("Initializing simulation...")
    if tcoupl == "langevin":
        if is_drude:
            print("Drude Langevin thermostat: 5.0 /ps, 20 /ps")
            integrator = mm.DrudeLangevinIntegrator(T * kelvin, 5.0 / ps,
                                                    1 * kelvin, 20 / ps,
                                                    dt * ps)
            integrator.setMaxDrudeDistance(0.02 * nm)
        else:
            print("Langevin thermostat: 1.0 /ps")
            integrator = mm.LangevinIntegrator(T * kelvin, 1.0 / ps, dt * ps)
    elif tcoupl == "nose-hoover":
        if is_drude:
            print(
                "Drude temperature-grouped Nose-Hoover thermostat: 10 /ps, 40 /ps"
            )
        else:
            print("Nose-Hoover thermostat: 10 /ps")
        from velocityverletplugin import VVIntegrator

        print("using nose-hoover")
        integrator = VVIntegrator(T * kelvin, 10 / ps, 1 * kelvin, 40 / ps,
                                  dt * ps)
        integrator.setUseMiddleScheme(True)
        integrator.setMaxDrudeDistance(0.02 * nm)
    else:
        raise Exception("Available thermostat: langevin, nose-hoover")

    if pcoupl != "no":
        oh.apply_mc_barostat(system, pcoupl, P, T)

    if cos != 0:
        try:
            integrator.setCosAcceleration(cos)
        except:
            raise Exception(
                "Cosine acceleration not compatible with this integrator")

    if field != 0:
        try:
            print(
                f"Electric field strength of {field} applied in the y-direction, acting on all atoms"
            )
            # apply field to all atoms
            atoms = [a.index for a in psf.topology.atoms()]
            # field applied in y-direction
            elecfield = oh.electric_field(system, atoms, [0, field, 0])
        except:
            raise Exception("Electric field cannot be used with this setup")

    _platform = mm.Platform.getPlatformByName("CUDA")
    _properties = {"CudaPrecision": "mixed"}
    sim = app.Simulation(psf.topology, system, integrator, _platform,
                         _properties)
    if restart:
        sim.loadCheckpoint(restart)
        sim.currentStep = (round(
            sim.context.getState().getTime().value_in_unit(ps) / dt / 10) * 10)
        sim.context.setTime(sim.currentStep * dt)
    else:
        sim.context.setPositions(gro.positions)
        sim.context.setVelocitiesToTemperature(T * kelvin)

    # For each reporter, check if we should append to the file - allows for restart files to
    # be used in another directory
    append_dcd = "dump.dcd" in os.listdir(".")
    sim.reporters.append(
        app.DCDReporter("dump.dcd",
                        10000,
                        enforcePeriodicBox=True,
                        append=append_dcd))
    sim.reporters.append(oh.CheckpointReporter("cpt.cpt", 10000))

    append_gro = "dump.gro" in os.listdir(".")
    sim.reporters.append(
        oh.GroReporter("dump.gro", 1000, logarithm=True, append=append_gro))
    # if appending to dumps, also append here
    sim.reporters.append(
        oh.StateDataReporter(sys.stdout,
                             1000,
                             box=False,
                             volume=True,
                             append=append_dcd))
    if is_drude:
        append_drude = "T_drude.txt" in os.listdir(".")
        sim.reporters.append(
            oh.DrudeTemperatureReporter("T_drude.txt",
                                        10000,
                                        append=append_drude))
    if cos != 0:
        append_cos = "viscosity.txt" in os.listdir(".")
        sim.reporters.append(
            oh.ViscosityReporter("viscosity.txt", 1000, append=append_cos))

    return sim
Exemplo n.º 20
0
'''

import simtk.openmm.app as omm_app
import simtk.openmm as omm
import simtk.unit as unit
import math
import os
import numpy as np
from sys import exit

## read psf and pdb file of butane
psf = omm_app.CharmmPsfFile('./data/butane.psf')
pdb = omm_app.PDBFile('./data/butane.pdb')

## read CHARMM force field for butane
params = omm_app.CharmmParameterSet('./data/top_all35_ethers.rtf',
                                    './data/par_all35_ethers.prm')

## create a OpenMM system based on psf of butane and CHARMM force field
system = psf.createSystem(params, nonbondedMethod=omm_app.NoCutoff)

## add a harmonic biasing potential on butane dihedral to the OpenMM system
bias_torsion = omm.CustomTorsionForce(
    "0.5*K*dtheta^2; dtheta = min(diff, 2*Pi-diff); diff = abs(theta - theta0)"
)
bias_torsion.addGlobalParameter("Pi", math.pi)
bias_torsion.addGlobalParameter("K", 1.0)
bias_torsion.addGlobalParameter("theta0", 0.0)
## 3, 6, 9, 13 are indices of the four carton atoms in butane, between which
## the dihedral angle is biased.
bias_torsion.addTorsion(3, 6, 9, 13)
system.addForce(bias_torsion)
Exemplo n.º 21
0
# vector of all lengths
LENGTHS = [CUBE_LENGTH for i in range(3)]
ANGLES = [CUBE_ANGLE for i in range(3)]


# method for nonbonded interactions
NONBONDED_METHOD = omma.CutoffPeriodic
# distance cutoff for non-bonded interactions
NONBONDED_CUTOFF = 1.0 * unit.nanometer

# constraints on MD calculations
MD_CONSTRAINTS = omma.HBonds

# force field parameters
FORCE_FIELD = omma.CharmmParameterSet(*charmm_param_paths)

# Monte Carlo Barostat
# pressure to be maintained
PRESSURE = 1.0*unit.atmosphere
# temperature to be maintained
TEMPERATURE = 300.0*unit.kelvin
# frequency at which volume moves are attempted
VOLUME_MOVE_FREQ = 50

# Platform used for OpenMM which uses different hardware computation
# kernels. Options are: Reference, CPU, OpenCL, CUDA.

# CUDA is the best for NVIDIA GPUs
PLATFORM = 'OpenCL'
Exemplo n.º 22
0
def run_simulation(nstep,
                   gro_file='conf.gro',
                   psf_file='topol.psf',
                   prm_file='ff.prm',
                   dt=0.001,
                   T=333,
                   thole=0,
                   restart=None):
    print('Building system...')
    gro = oh.GroFile(gro_file)
    lz = gro.getUnitCellDimensions()[2].value_in_unit(nm)
    psf = oh.OplsPsfFile(psf_file,
                         periodicBoxVectors=gro.getPeriodicBoxVectors())
    prm = app.CharmmParameterSet(prm_file)
    system = psf.createSystem(prm,
                              nonbondedMethod=app.PME,
                              nonbondedCutoff=1.2 * nm,
                              constraints=app.HBonds,
                              rigidWater=True,
                              verbose=True)
    nbforce = next(f for f in system.getForces()
                   if type(f) == mm.NonbondedForce)
    is_drude = any(type(f) == mm.DrudeForce for f in system.getForces())

    ### assign groups
    atoms = list(psf.topology.atoms())
    group_mos = [atom.index for atom in atoms if atom.residue.name == 'MoS2']
    group_mos_core = [
        i for i in group_mos if not atoms[i].name.startswith('D')
    ]
    group_img = [atom.index for atom in atoms if atom.residue.name == 'IMG']
    group_ils = [
        atom.index for atom in atoms
        if atom.residue.name not in ['MoS2', 'IMG']
    ]
    group_ils_not_H = [
        i for i in group_ils if not atoms[i].name.startswith('H')
    ]
    print('Assigning groups...')
    print('    Number of atoms in group %10s: %i' % ('mos', len(group_mos)))
    print('    Number of atoms in group %10s: %i' % ('ils', len(group_ils)))
    print('    Number of atoms in group %10s: %i' % ('img', len(group_img)))
    print('    Number of atoms in group %10s: %i' %
          ('mos_core', len(group_mos_core)))
    print('    Number of atoms in group %10s: %i' %
          ('ils_not_H', len(group_ils_not_H)))

    ### apply TT damping for CLPol force field
    donors = [atom.idx for atom in psf.atom_list if atom.attype == 'HO']
    if is_drude and len(donors) > 0:
        print('Add TT damping between HO and Drude dipoles')
        ttforce = oh.CLPolCoulTT(system, donors)
        print(ttforce.getEnergyFunction())

    ### apply Thole screening between ILs and MoS2
    if thole != 0:
        print('Add Thole screening between ILs and MoS2...')
        parent_drude_dict = dict(psf.drudepair_list)
        drude_parent_dict = {pair[1]: pair[0] for pair in psf.drudepair_list}
        tforce = mm.CustomNonbondedForce(
            '-%.6f*q1*q2/r*(1+0.5*screen*r)*exp(-screen*r);'
            'screen=%.4f*(alpha1*alpha2)^(-1/6)' %
            (oh.CONST.ONE_4PI_EPS0, thole))
        print(tforce.getEnergyFunction())
        tforce.addPerParticleParameter('q')
        tforce.addPerParticleParameter('alpha')
        for i in range(system.getNumParticles()):
            if i in parent_drude_dict:
                q, _, _ = nbforce.getParticleParameters(parent_drude_dict[i])
                q = -q
                alpha, _ = psf.drudeconsts_list[i]
            elif i in drude_parent_dict:
                q, _, _ = nbforce.getParticleParameters(i)
                alpha, _ = psf.drudeconsts_list[drude_parent_dict[i]]
            else:
                q = 0 * qe
                alpha = -1
            q = q.value_in_unit(qe)
            alpha = -alpha / 1000  # convert from A^3 to nm^3
            tforce.addParticle([q, alpha])
        tforce.setNonbondedMethod(mm.CustomNonbondedForce.CutoffPeriodic)
        tforce.setCutoffDistance(1.2 * nm)
        tforce.addInteractionGroup(set(group_mos), set(group_ils_not_H))
        tforce.setForceGroup(9)
        system.addForce(tforce)

    ### apply slab correction, need to move all atoms to primary cell
    print('Add dipole slab correction...')
    for i in range(system.getNumParticles()):
        gro.positions[i] += (0, 0, 1) * nm
    oh.slab_correction(system)

    ### restrain the movement of MoS2 cores (Drude particles are free if exist)
    print('Add restraint for MoS2 cores...')
    oh.spring_self(system, gro.positions.value_in_unit(nm), group_mos_core,
                   [0.01, 0.01, 5.0] * kcal_mol / angstrom**2)

    ### velocity-Verlet-middle integrator
    # from velocityverletplugin import VVIntegrator
    # integrator = VVIntegrator(T * kelvin, 10 / ps, 1 * kelvin, 40 / ps, dt * ps)
    # integrator.setUseMiddleScheme(True)
    # integrator.setMaxDrudeDistance(0.02 * nm)
    ### thermostat MoS2 by Langevin dynamics
    # for i in group_mos:
    #     integrator.addParticleLangevin(i)
    ### Langevin thermostat
    integrator = mm.DrudeLangevinIntegrator(T * kelvin, 5 / ps, 1 * kelvin,
                                            20 / ps, dt * ps)
    integrator.setMaxDrudeDistance(0.02 * nm)

    print('Initializing simulation...')
    _platform = mm.Platform.getPlatformByName('CUDA')
    _properties = {'CudaPrecision': 'mixed'}
    sim = app.Simulation(psf.topology, system, integrator, _platform,
                         _properties)
    if restart:
        sim.loadCheckpoint(restart)
        sim.currentStep = round(
            sim.context.getState().getTime().value_in_unit(ps) / dt / 10) * 10
        sim.context.setTime(sim.currentStep * dt)
        append = True
    else:
        sim.context.setPositions(gro.positions)
        sim.context.setVelocitiesToTemperature(T * kelvin)
        append = False

    sim.reporters.append(
        app.DCDReporter('dump.dcd',
                        10000,
                        enforcePeriodicBox=False,
                        append=append))
    sim.reporters.append(oh.CheckpointReporter('cpt.cpt', 10000))
    sim.reporters.append(
        oh.GroReporter('dump.gro',
                       1000,
                       logarithm=True,
                       subset=group_mos + group_ils,
                       append=append))
    sim.reporters.append(
        oh.StateDataReporter(sys.stdout, 10000, append=append, box=False))
    sim.reporters.append(
        oh.DrudeTemperatureReporter('T_drude.txt', 100000, append=append))

    print('Running...')
    oh.energy_decomposition(sim)
    sim.runForClockTime(31.9, 'rst.cpt', 'rst.xml', 1)
    print(
        '# clock time limit: step= %i time= %f' %
        (sim.currentStep, sim.context.getState().getTime().value_in_unit(ps)))