def get_minimum_energy_ensemble(topology,replica_energies,replica_positions,ensemble_size=5,file_name=None): """ Get an ensemble of low (potential) energy poses, and write the lowest energy structure to a PDB file if a file_name is provided. :param topology: OpenMM Topology() :type topology: `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ :param replica_energies: List of dimension num_replicas X simulation_steps, which gives the energies for all replicas at all simulation steps :type replica_energies: List( List( float * simtk.unit.energy for simulation_steps ) for num_replicas ) :param replica_positions: List of positions for all output frames for all replicas :type replica_positions: np.array( ( float * simtk.unit.positions for num_beads ) for simulation_steps ) :param file_name: Output destination for PDB coordinates of minimum energy pose, Default = None :returns: - ensemble ( List() ) - A list of poses that are in the minimum energy ensemble. :Example: >>> from foldamers.cg_model.cgmodel import CGModel >>> from cg_openmm.simulation.rep_exch import * >>> cgmodel = CGModel() >>> replica_energies,replica_positions,replica_state_indices = run_replica_exchange(cgmodel.topology,cgmodel.system,cgmodel.positions) >>> ensemble_size = 5 >>> file_name = "minimum.pdb" >>> minimum_energy_ensemble = get_minimum_energy_ensemble(cgmodel.topology,replica_energies,replica_positions,ensemble_size=ensemble_size,file_name=file_name) """ # Get the minimum energy structure sampled during the simulation ensemble = [] ensemble_energies = [] for replica in range(len(replica_energies)): energies = np.array([energy for energy in replica_energies[replica][replica]]) for energy in range(len(energies)): if len(ensemble) < ensemble_size: ensemble.append(replica_positions[replica][energy]) ensemble_energies.append(energies[energy]) else: for comparison in range(len(ensemble_energies)): if energies[energy] < ensemble_energies[comparison]: ensemble_energies[comparison] = energies[energy] ensemble[comparison] = replica_positions[replica][energy] if file_name == None: index = 1 for pose in ensemble: file = open(str("re_min_"+str(index)+".pdb"),"w") PDBFile.writeFile(topology,pose,file=file) else: file = open(file_name,"w") for pose in ensemble: PDBFile.writeFile(topology,pose,file=file) return(ensemble)
def write_single_pdb(xp, top, target): """Dump coordinates to a pdb file `target`.""" try: target = Path(target) except TypeError: if hasattr(target, 'write'): PDBFile.writeFile(top, xp, target) else: raise else: with open(target, 'w') as fp: PDBFile.writeFile(top, xp, fp)
def get_topology_from_pdbfile(filename): """ Reads the positions from a PDB file. :param filename: Path to the file where we will read PDB coordinates. :type filename: str :returns: - topology ( `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ ) - OpenMM Topology() object, which stores bonds, angles, and other structural attributes of the coarse grained model """ pdb_mm_obj = PDBFile(filename) topology = pdb_mm_obj.getTopology() return topology
def get_positions_from_pdbfile(filename): """ Reads the positions from a PDB file. :param filename: Path to the file where we will read PDB coordinates. :type filename: str :returns: - positions ( `Quantity() <https://docs.openmm.org/development/api-python/generated/simtk.unit.quantity.Quantity.html>`_ ( np.array( [cgmodel.num_beads,3] ), simtk.unit ) ) - Positions for the particles in the PDB file. """ pdb_mm_obj = PDBFile(filename) positions = pdb_mm_obj.getPositions() return positions
def __init__(self, system=None, filename=None): from simtk.openmm.app.pdbfile import PDBFile from simtk.openmm import app from BigDFT.IO import read_pdb, write_pdb from tempfile import NamedTemporaryFile as tmp if filename is not None: pdb = PDBFile(open(filename)) sys = read_pdb(open(filename)) elif system is not None: sys = system ofile = tmp('w+') write_pdb(system=system, ofile=ofile) ofilename = ofile.name pdb = PDBFile(open(ofilename)) ofile.close() System.__init__(self, **sys.dict()) self.pdb = pdb self.modeller = app.Modeller(pdb.topology, pdb.positions)
def read_pdbfile(cgmodel, filename): """ Reads the positions and topology from a PDB file. :param cgmodel: CGModel() class object :type cgmodel: class :param filename: Path to the file where we will read PDB coordinates. :type filename: str :returns: - cgmodel - A CGModel() class object with the positions and topology from the PDB file that was read. """ pdb_mm_obj = PDBFile(filename) cgmodel.positions = pdb_mm_obj.getPositions() cgmodel.topology = pdb_mm_obj.getTopology() return cgmodel
def fix_pdb(pdb_id): path = os.getcwd() if len(pdb_id) != 4: print("Creating PDBFixer...") fixer = PDBFixer(pdb_id) print("Finding missing residues...") fixer.findMissingResidues() chains = list(fixer.topology.chains()) keys = fixer.missingResidues.keys() for key in list(keys): chain = chains[key[0]] if key[1] == 0 or key[1] == len(list(chain.residues())): print("ok") del fixer.missingResidues[key] print("Finding nonstandard residues...") fixer.findNonstandardResidues() print("Replacing nonstandard residues...") fixer.replaceNonstandardResidues() print("Removing heterogens...") fixer.removeHeterogens(keepWater=True) print("Finding missing atoms...") fixer.findMissingAtoms() print("Adding missing atoms...") fixer.addMissingAtoms() print("Adding missing hydrogens...") fixer.addMissingHydrogens(7) print("Writing PDB file...") PDBFile.writeFile( fixer.topology, fixer.positions, open( os.path.join(path, "%s_fixed_pH_%s.pdb" % (pdb_id.split('.')[0], 7)), "w"), keepIds=True) return "%s_fixed_pH_%s.pdb" % (pdb_id.split('.')[0], 7)
def make_replica_pdb_files(topology,replica_positions): """ Make PDB files from replica exchange simulation trajectory data :param topology: OpenMM Topology :type topology: `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ :param replica_positions: Positions array for the replica exchange data for which we will write PDB files :type replica_positions: `Quantity() <http://docs.openmm.org/development/api-python/generated/simtk.unit.quantity.Quantity.html>`_ ( np.array( [n_replicas,cgmodel.num_beads,3] ), simtk.unit ) :returns: - file_list ( List( str ) ) - A list of names for the files that were written :Example: >>> from foldamers.cg_model.cgmodel import CGModel >>> from cg_openmm.simulation.rep_exch import * >>> cgmodel = CGModel() >>> replica_energies,replica_positions,replica_state_indices = run_replica_exchange(cgmodel.topology,cgmodel.system,cgmodel.positions) >>> pdb_file_list = make_replica_pdb_files(cgmodel.topology,replica_positions) """ replica_index = 1 file_list = [] for replica_index in range(len(replica_positions)): replica_trajectory = replica_positions[replica_index] file_name = str("replica_"+str(replica_index+1)+".pdb") file = open(file_name,"w") PDBFile.writeHeader(topology,file=file) modelIndex=1 for positions in replica_trajectory: PDBFile.writeModel(topology,positions,file=file,modelIndex=modelIndex) PDBFile.writeFooter(topology,file=file) file.close() file_list.append(file_name) return(file_list)
'bb_bb_sc_angle_0': bb_bb_sc_equil_bond_angle } # Torsion angle definitions torsion_force_constant = 0.5 * unit.kilocalorie_per_mole / unit.radian / unit.radian torsion_force_constants = {'bb_bb_bb_bb_torsion_k': torsion_force_constant} bb_bb_bb_bb_equil_torsion_angle = 78.0 * ( 3.14 / 180.0) # OpenMM requires angle definitions in units of radians bb_bb_bb_sc_equil_torsion_angle = 78.0 * (3.14 / 180.0) equil_torsion_angles = { 'bb_bb_bb_bb_torsion_0': bb_bb_bb_bb_equil_torsion_angle } torsion_periodicities = {'bb_bb_bb_bb_period': 1} # Get initial positions from local file positions = PDBFile("helix.pdb").getPositions() # Build a coarse grained model cgmodel = CGModel(polymer_length=polymer_length, backbone_lengths=backbone_lengths, sidechain_lengths=sidechain_lengths, sidechain_positions=sidechain_positions, masses=masses, sigmas=sigmas, epsilons=epsilons, bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, equil_torsion_angles=equil_torsion_angles,
def build_topology(cgmodel, use_pdbfile=False, pdbfile=None): """ Construct an OpenMM `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ class object for our coarse grained model, :param cgmodel: CGModel() class object :type cgmodel: class :param use_pdbfile: Determines whether or not to use a PDB file in order to generate the Topology(). :type use_pdbfile: Logical :param pdbfile: Name of a PDB file to use when building the topology. :type pdbfile: str :returns: - topology (`Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ ) - OpenMM Topology() object :Example: >>> from foldamers.cg_model.cgmodel import CGModel >>> from foldamers.util.iotools import write_pdbfile_without_topology >>> input_pdb = "top.pdb" >>> cgmodel = CGModel() >>> write_pdbfile_without_topology(cgmodel,input_pdb) >>> topology = build_topology(cgmodel,use_pdbfile=True,pdbfile=input_pdb) >>> cgmodel.topology = topology .. warning:: When 'use_pdbfile'=True, this function will use the `PDBFile() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1pdbfile_1_1PDBFile.html>`_ class object from OpenMM to build the Topology(). In order for this approach to function correctly, the particle names in the PDB file must match the particle names in the coarse grained model. """ if cgmodel.constrain_bonds: use_pdbfile = True if use_pdbfile: if pdbfile is None: tf = tempfile.NamedTemporaryFile() write_pdbfile_without_topology(cgmodel, tf.name) pdb = PDBFile(tf.name) topology = pdb.getTopology() tf.close() return topology else: pdb = PDBFile(pdbfile) topology = pdb.getTopology() return topology topology = Topology() chain = topology.addChain() residue_index = -1 openmm_particle_list = list() for particle in cgmodel.particle_list: if particle["monomer"] > residue_index: residue_index = particle["monomer"] residue = topology.addResidue(str(residue_index), chain) particle_symbol = particle["name"] element = elem.Element.getBySymbol(particle_symbol) openmm_particle = topology.addAtom(particle_symbol, element, residue) openmm_particle_list.append(particle) if cgmodel.include_bond_forces or cgmodel.constrain_bonds: for bond in cgmodel.bond_list: topology.addBond(openmm_particle_list[bond[0]], openmm_particle_list[bond[1]]) cgmodel.topology = topology verify_topology(cgmodel) return topology
def test_random_builder(tmpdir): """See if the random builder can build a simple 1b1s model""" # Coarse grained model settings include_bond_forces = True include_bond_angle_forces = True include_nonbonded_forces = True include_torsion_forces = False constrain_bonds = False random_positions = True # Bond definitions bond_length = 1.5 * unit.angstrom bond_lengths = { "bb_bb_bond_length": bond_length, "bb_sc_bond_length": bond_length, "sc_sc_bond_length": bond_length, } bond_force_constant = 1000 * unit.kilojoule_per_mole / unit.nanometer / unit.nanometer bond_force_constants = { "bb_bb_bond_force_constant": bond_force_constant, "bb_sc_bond_force_constant": bond_force_constant, "sc_sc_bond_force_constant": bond_force_constant, } # Particle definitions mass = 100.0 * unit.amu r_min = 1.5 * bond_length # Lennard-Jones potential r_min # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigma = r_min / (2.0 ** (1.0 / 6.0)) epsilon = 0.5 * unit.kilojoule_per_mole bb = {"particle_type_name": "bb", "sigma": sigma, "epsilon": epsilon, "mass": mass} sc = {"particle_type_name": "sc", "sigma": sigma, "epsilon": epsilon, "mass": mass} # Bond angle definitions bond_angle_force_constant = 100 * unit.kilojoule_per_mole / unit.radian / unit.radian bond_angle_force_constants = { "bb_bb_bb_bond_angle_force_constant": bond_angle_force_constant, "bb_bb_sc_bond_angle_force_constant": bond_angle_force_constant, } # OpenMM requires angle definitions in units of radians bb_bb_bb_equil_bond_angle = 120.0 * unit.degrees bb_bb_sc_equil_bond_angle = 120.0 * unit.degrees equil_bond_angles = { "bb_bb_bb_equil_bond_angle": bb_bb_bb_equil_bond_angle, "bb_bb_sc_equil_bond_angle": bb_bb_sc_equil_bond_angle, } # Torsion angle definitions torsion_force_constant = 20.0 * unit.kilojoule_per_mole torsion_force_constants = { "bb_bb_bb_bb_torsion_force_constant": torsion_force_constant, "bb_bb_bb_sc_torsion_force_constant": torsion_force_constant } bb_bb_bb_bb_torsion_phase_angle = 75.0 * unit.degrees bb_bb_bb_sc_torsion_phase_angle = 75.0 * unit.degrees torsion_phase_angles = { "bb_bb_bb_bb_torsion_phase_angle": bb_bb_bb_bb_torsion_phase_angle, "bb_bb_bb_sc_torsion_phase_angle": bb_bb_bb_sc_torsion_phase_angle } torsion_periodicities = { "bb_bb_bb_bb_torsion_periodicity": 3, "bb_bb_bb_sc_torsion_periodicity": 3} # Monomer definitions A = { "monomer_name": "A", "particle_sequence": [bb, sc], "bond_list": [[0, 1]], "start": 0, "end": 0, } sequence = 5 * [A] # Build a coarse grained model cgmodel = CGModel( particle_type_list=[bb,sc], bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, torsion_phase_angles=torsion_phase_angles, torsion_periodicities=torsion_periodicities, include_nonbonded_forces=include_nonbonded_forces, include_bond_forces=include_bond_forces, include_bond_angle_forces=include_bond_angle_forces, include_torsion_forces=include_torsion_forces, sequence=sequence, constrain_bonds=constrain_bonds, random_positions=random_positions, monomer_types=[A], ) output_directory = tmpdir.mkdir("output") filename = f"{output_directory}/5mer_1b1s_builder_test.pdb" write_pdbfile_without_topology(cgmodel, filename) positions = PDBFile(filename).getPositions() assert len(positions)==10
def build_topology(cgmodel, use_pdbfile=False, pdbfile=None): """ Construct an OpenMM `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ class object for our coarse grained model, :param cgmodel: CGModel() class object :type cgmodel: class :param use_pdbfile: Determines whether or not to use a PDB file in order to generate the Topology(). :type use_pdbfile: Logical :param pdbfile: Name of a PDB file to use when building the topology. :type pdbfile: str :returns: - topology (`Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ ) - OpenMM Topology() object :Example: >>> from foldamers.cg_model.cgmodel import CGModel >>> from foldamers.util.iotools import write_pdbfile_without_topology >>> input_pdb = "top.pdb" >>> cgmodel = CGModel() >>> write_pdbfile_without_topology(cgmodel,input_pdb) >>> topology = build_topology(cgmodel,use_pdbfile=True,pdbfile=input_pdb) >>> cgmodel.topology = topology .. warning:: When 'use_pdbfile'=True, this function will use the `PDBFile() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1pdbfile_1_1PDBFile.html>`_ class object from OpenMM to build the Topology(). In order for this approach to function correctly, the particle names in the PDB file must match the particle names in the coarse grained model. """ if use_pdbfile == True: if pdbfile == None: write_pdbfile_without_topology(cgmodel, "topology_source.pdb") pdb = PDBFile("topology_source.pdb") topology = pdb.getTopology() os.remove("topology_source.pdb") return (topology) else: pdb = PDBFile(pdbfile) topology = pdb.getTopology() return (topology) topology = Topology() chain = topology.addChain() residue_index = 1 cg_particle_index = 0 for monomer_type in cgmodel.sequence: residue = topology.addResidue(str(residue_index), chain) for backbone_bead in range(monomer_type['backbone_length']): particle_symbol = cgmodel.get_particle_name(cg_particle_index) element = elem.Element.getBySymbol(particle_symbol) particle = topology.addAtom(particle_symbol, element, residue) if backbone_bead == 0 and residue_index != 1: topology.addBond(particle, last_backbone_particle) last_backbone_particle = particle cg_particle_index = cg_particle_index + 1 if backbone_bead in [monomer_type['sidechain_positions']]: for sidechain_bead in range(monomer_type['sidechain_length']): particle_symbol = cgmodel.get_particle_name( cg_particle_index) element = elem.Element.getBySymbol(particle_symbol) particle = topology.addAtom(particle_symbol, element, residue) if sidechain_bead == 0: topology.addBond(particle, last_backbone_particle) if sidechain_bead != 0: topology.addBond(particle, last_sidechain_particle) last_sidechain_particle = particle cg_particle_index = cg_particle_index + 1 residue_index = residue_index + 1 cgmodel.topology = topology verify_topology(cgmodel) return (topology)
def test_run_replica_exchange(tmpdir): """ Run a short replica exchange MD simulation of a 24mer 1b1s model Test replica exchange processing (write pdb files) Test heat capacity analysis code Test physical validation code """ global_context_cache.platform = openmm.Platform.getPlatformByName("CPU") # Set output directory # In pytest we need to use a temp directory # tmpdir is a fixture - hence we need to pass it into test function, not import it output_directory = tmpdir.mkdir("output") # Replica exchange simulation settings total_simulation_time = 1.0 * unit.picosecond simulation_time_step = 5.0 * unit.femtosecond total_steps = int(np.floor(total_simulation_time / simulation_time_step)) output_data = os.path.join(output_directory, "output.nc") number_replicas = 4 min_temp = 200.0 * unit.kelvin max_temp = 300.0 * unit.kelvin temperature_list = get_temperature_list(min_temp, max_temp, number_replicas) exchange_frequency = 10 # Number of steps between exchange attempts # Coarse grained model settings include_bond_forces = True include_bond_angle_forces = True include_nonbonded_forces = True include_torsion_forces = True constrain_bonds = False # Bond definitions bond_length = 1.5 * unit.angstrom bond_lengths = { "bb_bb_bond_length": bond_length, "bb_sc_bond_length": bond_length, "sc_sc_bond_length": bond_length, } bond_force_constant = 1000 * unit.kilojoule_per_mole / unit.nanometer / unit.nanometer bond_force_constants = { "bb_bb_bond_force_constant": bond_force_constant, "bb_sc_bond_force_constant": bond_force_constant, "sc_sc_bond_force_constant": bond_force_constant, } # Particle definitions mass = 100.0 * unit.amu r_min = 1.5 * bond_length # Lennard-Jones potential r_min # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigma = r_min / (2.0**(1.0 / 6.0)) epsilon = 0.5 * unit.kilojoule_per_mole bb = { "particle_type_name": "bb", "sigma": sigma, "epsilon": epsilon, "mass": mass } sc = { "particle_type_name": "sc", "sigma": sigma, "epsilon": epsilon, "mass": mass } # Bond angle definitions bond_angle_force_constant = 100 * unit.kilojoule_per_mole / unit.radian / unit.radian bond_angle_force_constants = { "bb_bb_bb_bond_angle_force_constant": bond_angle_force_constant, "bb_bb_sc_bond_angle_force_constant": bond_angle_force_constant, } # OpenMM requires angle definitions in units of radians bb_bb_bb_equil_bond_angle = 120.0 * unit.degrees bb_bb_sc_equil_bond_angle = 120.0 * unit.degrees equil_bond_angles = { "bb_bb_bb_equil_bond_angle": bb_bb_bb_equil_bond_angle, "bb_bb_sc_equil_bond_angle": bb_bb_sc_equil_bond_angle, } # Torsion angle definitions torsion_force_constant = 20.0 * unit.kilojoule_per_mole torsion_force_constants = { "bb_bb_bb_bb_torsion_force_constant": torsion_force_constant, "bb_bb_bb_sc_torsion_force_constant": torsion_force_constant } bb_bb_bb_bb_torsion_phase_angle = 75.0 * unit.degrees bb_bb_bb_sc_torsion_phase_angle = 75.0 * unit.degrees torsion_phase_angles = { "bb_bb_bb_bb_torsion_phase_angle": bb_bb_bb_bb_torsion_phase_angle, "bb_bb_bb_sc_torsion_phase_angle": bb_bb_bb_sc_torsion_phase_angle } torsion_periodicities = { "bb_bb_bb_bb_torsion_periodicity": 3, "bb_bb_bb_sc_torsion_periodicity": 3 } # Monomer definitions A = { "monomer_name": "A", "particle_sequence": [bb, sc], "bond_list": [[0, 1]], "start": 0, "end": 0, } sequence = 24 * [A] pdb_path = os.path.join(structures_path, "24mer_1b1s_initial_structure.pdb") positions = PDBFile(pdb_path).getPositions() # Build a coarse grained model cgmodel = CGModel( particle_type_list=[bb, sc], bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, torsion_phase_angles=torsion_phase_angles, torsion_periodicities=torsion_periodicities, include_nonbonded_forces=include_nonbonded_forces, include_bond_forces=include_bond_forces, include_bond_angle_forces=include_bond_angle_forces, include_torsion_forces=include_torsion_forces, constrain_bonds=constrain_bonds, positions=positions, sequence=sequence, monomer_types=[A], ) run_replica_exchange( cgmodel.topology, cgmodel.system, cgmodel.positions, temperature_list=temperature_list, simulation_time_step=simulation_time_step, total_simulation_time=total_simulation_time, exchange_frequency=exchange_frequency, output_data=output_data, ) assert os.path.isfile(f"{output_directory}/output.nc") # Process replica exchange output # 1) With plot production only and print_timing: replica_energies, replica_states, production_start, sample_spacing, n_transit, mixing_stats = process_replica_exchange_data( output_data=output_data, output_directory=output_directory, plot_production_only=True, print_timing=True, ) # 2) With non-default equil_nskip replica_energies, replica_states, production_start, sample_spacing, n_transit, mixing_stats = process_replica_exchange_data( output_data=output_data, output_directory=output_directory, plot_production_only=True, equil_nskip=2, ) # 3) With frame_begin used to circumvent detectEquilibration replica_energies, replica_states, production_start, sample_spacing, n_transit, mixing_stats = process_replica_exchange_data( output_data=output_data, output_directory=output_directory, frame_begin=5, ) # 4) With frame end specified to analyze only the beginning of a trajectory replica_energies, replica_states, production_start, sample_spacing, n_transit, mixing_stats = process_replica_exchange_data( output_data=output_data, output_directory=output_directory, frame_end=25, ) # 5) Without writing .dat file: replica_energies, replica_states, production_start, sample_spacing, n_transit, mixing_stats = process_replica_exchange_data( output_data=output_data, output_directory=output_directory, write_data_file=False, ) # Test pdb writer: make_replica_pdb_files( cgmodel.topology, output_dir=output_directory, ) make_state_pdb_files(cgmodel.topology, output_dir=output_directory) assert os.path.isfile(f"{output_directory}/replica_4.pdb") assert os.path.isfile(f"{output_directory}/state_4.pdb") # With non-default frame_begin, stride, no centering: make_replica_pdb_files(cgmodel.topology, frame_begin=10, frame_stride=2, output_dir=output_directory) make_state_pdb_files(cgmodel.topology, frame_begin=10, frame_stride=2, output_dir=output_directory, center=False) # Test dcd writer: make_replica_dcd_files(cgmodel.topology, timestep=simulation_time_step, time_interval=exchange_frequency, output_dir=output_directory) make_state_dcd_files(cgmodel.topology, timestep=simulation_time_step, time_interval=exchange_frequency, output_dir=output_directory) assert os.path.isfile(f"{output_directory}/replica_4.dcd") assert os.path.isfile(f"{output_directory}/state_4.dcd") # With non-default frame_begin, stride, no centering: make_replica_dcd_files(cgmodel.topology, timestep=simulation_time_step, time_interval=exchange_frequency, frame_begin=10, frame_stride=2, output_dir=output_directory) make_state_dcd_files(cgmodel.topology, timestep=simulation_time_step, time_interval=exchange_frequency, frame_begin=10, frame_stride=2, output_dir=output_directory, center=False)
mass = 100.0 * unit.amu masses = {'backbone_bead_masses': mass, 'sidechain_bead_masses': mass} r_min = 3.0 * bond_length # Lennard-Jones potential r_min sigma = r_min / (2.0**(1/6)) # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigmas = {'bb_sigma': sigma,'sc_sigma': sigma} # Torsion angle definitions torsion_force_constant = 0.0001 * unit.kilocalorie_per_mole / unit.radian / unit.radian torsion_force_constants = {'bb_bb_bb_bb_torsion_k': torsion_force_constant}#,'sc_bb_bb_sc_torsion_k': torsion_force_constant} bb_bb_bb_bb_equil_torsion_angle = 78.0 * (3.14/180.0) # OpenMM defaults to units of radians for angle definitions #sc_bb_bb_sc_equil_torsion_angle = 110.0 * (3.14/180.0) equil_torsion_angles = {'bb_bb_bb_bb_torsion_0': bb_bb_bb_bb_equil_torsion_angle}#,'sc_bb_bb_sc_torsion_0': sc_bb_bb_sc_equil_torsion_angle} torsion_periodicities = {'bb_bb_bb_bb_period': 1}#,'sc_bb_bb_sc_period': 2} # Initiate cgmodel using positions from local file positions = PDBFile("init.pdb").getPositions() epsilon_list = [i*0.001*unit.kilocalorie_per_mole for i in [1,10,20,50,100]] A_list = [] Pf_list = [] E_list = [] S_list = [] C_list = [] for epsilon in epsilon_list: epsilons = {'bb_eps': epsilon,'sc_eps': epsilon} output_directory = str(str(output)+"/"+str(round(epsilon._value,2))) if not os.path.exists(output_directory): os.mkdir(output_directory)
def make_state_pdb_files(topology, output_dir="output", output_data="output.nc", checkpoint_data="output_checkpoint.nc", frame_begin=0, frame_stride=1, center=True): """ Make pdb files by state from replica exchange simulation trajectory data. Note: these are discontinuous trajectories with constant temperature state. :param topology: OpenMM Topology :type topology: `Topology() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1app_1_1topology_1_1Topology.html>`_ :param output_directory: path to which we will write the output (default='output') :type output_directory: str :param output_data: name of output .nc data file (default='output.nc') :type output_data: str :param checkpoint_data: name of checkpoint .nc data file (default='output_checkpoint.nc') :type checkpoint_data: str :param frame_begin: Frame at which to start writing the pdb trajectory (default=0) :type frame_begin: int :param frame_stride: advance by this many frames when writing pdb trajectories (default=1) :type frame_stride: int :param center: align the center of mass of each structure in the discontinuous state trajectory (default=True) :type center: Boolean :returns: - file_list ( List( str ) ) - A list of names for the files that were written """ file_list = [] output_data_path = os.path.join(output_dir, output_data) # Get number of states: reporter = MultiStateReporter(output_data_path, open_mode="r") states = reporter.read_thermodynamic_states()[0] sampler_states = reporter.read_sampler_states(iteration=0) xunit = sampler_states[0].positions[0].unit for state_index in range(len(states)): state_trajectory = extract_trajectory(topology, state_index=state_index, output_data=output_data_path, checkpoint_data=checkpoint_data, frame_begin=frame_begin, frame_stride=frame_stride) file_name = f"{output_dir}/state_{state_index+1}.pdb" file = open(file_name, "w") PDBFile.writeHeader(topology, file=file) modelIndex = 1 # TODO: replace this with MDTraj alignment tool if center == True: center_x = np.mean(state_trajectory[0, :, 0]) center_y = np.mean(state_trajectory[0, :, 1]) center_z = np.mean(state_trajectory[0, :, 2]) for positions in state_trajectory: if center == True: positions[:, 0] += (center_x - np.mean(positions[:, 0])) positions[:, 1] += (center_y - np.mean(positions[:, 1])) positions[:, 2] += (center_z - np.mean(positions[:, 2])) # Add the units consistent with replica_energies positions *= xunit PDBFile.writeModel(topology, positions, file=file, modelIndex=modelIndex) PDBFile.writeFooter(topology, file=file) file.close() file_list.append(file_name) return file_list
import os, timeit import numpy as np import matplotlib.pyplot as pyplot from simtk import unit from simtk.openmm.app.pdbfile import PDBFile from foldamers.cg_model.cgmodel import CGModel from foldamers.parameters.secondary_structure import * positions = PDBFile(str(str(os.getcwd().split('examples')[0])+"ensembles/12_1_1_0/helix.pdb")).getPositions() cgmodel = CGModel(positions=positions) pitch,radius,monomers_per_turn,residual = get_helical_parameters(cgmodel) print(pitch,radius,monomers_per_turn,residual) cgmodel = orient_along_z_axis(cgmodel) show_helical_fit(cgmodel) p2 = calculate_p2(cgmodel) print(p2) exit()
def test_sums_periodic_torsions_5(): # Test cg_model with sums of periodic torsions - test 5 # Two periodic torsion terms, parameters input as quantities with list values # Parameters are applied to all torsion types using the default input method # Coarse grained model settings include_bond_forces = True include_bond_angle_forces = True include_nonbonded_forces = True include_torsion_forces = True constrain_bonds = False # Bond definitions bond_length = 1.5 * unit.angstrom bond_lengths = { "bb_bb_bond_length": bond_length, "bb_sc_bond_length": bond_length, "sc_sc_bond_length": bond_length, } bond_force_constant = 1000 * unit.kilojoule_per_mole / unit.nanometer / unit.nanometer bond_force_constants = { "bb_bb_bond_force_constant": bond_force_constant, "bb_sc_bond_force_constant": bond_force_constant, "sc_sc_bond_force_constant": bond_force_constant, } # Particle definitions mass = 100.0 * unit.amu r_min = 1.5 * bond_length # Lennard-Jones potential r_min # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigma = r_min / (2.0**(1.0 / 6.0)) epsilon = 0.5 * unit.kilojoule_per_mole bb = { "particle_type_name": "bb", "sigma": sigma, "epsilon": epsilon, "mass": mass } sc = { "particle_type_name": "sc", "sigma": sigma, "epsilon": epsilon, "mass": mass } # Bond angle definitions bond_angle_force_constant = 100 * unit.kilojoule_per_mole / unit.radian / unit.radian bond_angle_force_constants = { "bb_bb_bb_bond_angle_force_constant": bond_angle_force_constant, "bb_bb_sc_bond_angle_force_constant": bond_angle_force_constant, } # OpenMM requires angle definitions in units of radians bb_bb_bb_equil_bond_angle = 120.0 * unit.degrees bb_bb_sc_equil_bond_angle = 120.0 * unit.degrees equil_bond_angles = { "bb_bb_bb_equil_bond_angle": bb_bb_bb_equil_bond_angle, "bb_bb_sc_equil_bond_angle": bb_bb_sc_equil_bond_angle, } # Torsion angle definitions torsion_force_constants = { "default_torsion_force_constant": [5, 10] * unit.kilojoule_per_mole, } torsion_phase_angles = { "default_torsion_phase_angle": [0, 180] * unit.degrees, } torsion_periodicities = { "default_torsion_periodicity": [1, 3], } # Monomer definitions A = { "monomer_name": "A", "particle_sequence": [bb, sc], "bond_list": [[0, 1]], "start": 0, "end": 0, } sequence = 24 * [A] pdb_path = os.path.join(data_path, "24mer_1b1s_initial_structure.pdb") positions = PDBFile(pdb_path).getPositions() # Build a coarse grained model cgmodel = CGModel( particle_type_list=[bb, sc], bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, torsion_phase_angles=torsion_phase_angles, torsion_periodicities=torsion_periodicities, include_nonbonded_forces=include_nonbonded_forces, include_bond_forces=include_bond_forces, include_bond_angle_forces=include_bond_angle_forces, include_torsion_forces=include_torsion_forces, constrain_bonds=constrain_bonds, positions=positions, sequence=sequence, monomer_types=[A], ) # Check the number of periodic torsions terms: n_torsion_forces = cgmodel.system.getForces()[3].getNumTorsions() assert n_torsion_forces == 176
def create_cgmodel(): # Coarse grained model settings include_bond_forces = True include_bond_angle_forces = True include_nonbonded_forces = True include_torsion_forces = True constrain_bonds = False # Bond definitions bond_length = 1.5 * unit.angstrom bond_lengths = { "bb_bb_bond_length": bond_length, "bb_sc_bond_length": bond_length, "sc_sc_bond_length": bond_length, } bond_force_constant = 1000 * unit.kilojoule_per_mole / unit.nanometer / unit.nanometer bond_force_constants = { "bb_bb_bond_force_constant": bond_force_constant, "bb_sc_bond_force_constant": bond_force_constant, "sc_sc_bond_force_constant": bond_force_constant, } # Particle definitions mass = 100.0 * unit.amu r_min = 1.5 * bond_length # Lennard-Jones potential r_min # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigma = r_min / (2.0**(1.0 / 6.0)) epsilon = 0.5 * unit.kilojoule_per_mole bb = { "particle_type_name": "bb", "sigma": sigma, "epsilon": epsilon, "mass": mass } sc = { "particle_type_name": "sc", "sigma": sigma, "epsilon": epsilon, "mass": mass } # Bond angle definitions bond_angle_force_constant = 100 * unit.kilojoule_per_mole / unit.radian / unit.radian bond_angle_force_constants = { "bb_bb_bb_bond_angle_force_constant": bond_angle_force_constant, "bb_bb_sc_bond_angle_force_constant": bond_angle_force_constant, } # OpenMM requires angle definitions in units of radians bb_bb_bb_equil_bond_angle = 120.0 * unit.degrees bb_bb_sc_equil_bond_angle = 120.0 * unit.degrees equil_bond_angles = { "bb_bb_bb_equil_bond_angle": bb_bb_bb_equil_bond_angle, "bb_bb_sc_equil_bond_angle": bb_bb_sc_equil_bond_angle, } # Torsion angle definitions torsion_force_constant = 20.0 * unit.kilojoule_per_mole torsion_force_constants = { "bb_bb_bb_bb_torsion_force_constant": torsion_force_constant, "bb_bb_bb_sc_torsion_force_constant": torsion_force_constant } bb_bb_bb_bb_torsion_phase_angle = 75.0 * unit.degrees bb_bb_bb_sc_torsion_phase_angle = 75.0 * unit.degrees torsion_phase_angles = { "bb_bb_bb_bb_torsion_phase_angle": bb_bb_bb_bb_torsion_phase_angle, "bb_bb_bb_sc_torsion_phase_angle": bb_bb_bb_sc_torsion_phase_angle } torsion_periodicities = { "bb_bb_bb_bb_torsion_periodicity": 3, "bb_bb_bb_sc_torsion_periodicity": 3 } # Monomer definitions A = { "monomer_name": "A", "particle_sequence": [bb, sc], "bond_list": [[0, 1]], "start": 0, "end": 0, } sequence = 24 * [A] pdb_path = os.path.join(data_path, "24mer_1b1s_initial_structure.pdb") positions = PDBFile(pdb_path).getPositions() # Build a coarse grained model cgmodel = CGModel( particle_type_list=[bb, sc], bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, torsion_phase_angles=torsion_phase_angles, torsion_periodicities=torsion_periodicities, include_nonbonded_forces=include_nonbonded_forces, include_bond_forces=include_bond_forces, include_bond_angle_forces=include_bond_angle_forces, include_torsion_forces=include_torsion_forces, constrain_bonds=constrain_bonds, positions=positions, sequence=sequence, monomer_types=[A], ) return cgmodel
from foldamers.thermo.calc import * from foldamers.utilities.plot import plot_distribution from foldamers.utilities.util import random_positions from cg_openmm.build.cg_build import build_topology from cg_openmm.simulation.rep_exch import * grid_size = 6 native_structure_file = str( str(os.getcwd().split('examples/')[0]) + "ensembles/12_1_1_0/helix.pdb") if not os.path.exists(native_structure_file): print("Error: file " + str(native_structure_file) + " not found.") exit() native_structure = PDBFile(native_structure_file).getPositions() # Job settings top_directory = 'output' if not os.path.exists(top_directory): os.mkdir(top_directory) # OpenMM simulation settings print_frequency = 20 # Number of steps to skip when printing output total_simulation_time = 0.5 * unit.nanosecond # Units = picoseconds simulation_time_step = 5.0 * unit.femtosecond total_steps = round(total_simulation_time.__div__(simulation_time_step)) # Yank (replica exchange) simulation settings output_data = str(str(top_directory) + "/output.nc") number_replicas = 30
def test_run_simulation(tmpdir): """Run a short MD simulation of a 24mer 1b1s model""" # Set output directory # In pytest we need to use a temp directory # tmpdir is a fixture - hence we need to pass it into test function, not import it output_directory = tmpdir.mkdir("output") # OpenMM simulation settings print_frequency = 10 # Number of steps to skip when printing output total_simulation_time = 1.0 * unit.picosecond simulation_time_step = 5.0 * unit.femtosecond total_steps = int(np.floor(total_simulation_time / simulation_time_step)) temperature = 200 * unit.kelvin friction = 1.0 / unit.picosecond # Coarse grained model settings include_bond_forces = True include_bond_angle_forces = True include_nonbonded_forces = True include_torsion_forces = True constrain_bonds = False # Bond definitions bond_length = 1.5 * unit.angstrom bond_lengths = { "bb_bb_bond_length": bond_length, "bb_sc_bond_length": bond_length, "sc_sc_bond_length": bond_length, } bond_force_constant = 1000 * unit.kilojoule_per_mole / unit.nanometer / unit.nanometer bond_force_constants = { "bb_bb_bond_force_constant": bond_force_constant, "bb_sc_bond_force_constant": bond_force_constant, "sc_sc_bond_force_constant": bond_force_constant, } # Particle definitions mass = 100.0 * unit.amu r_min = 1.5 * bond_length # Lennard-Jones potential r_min # Factor of /(2.0**(1/6)) is applied to convert r_min to sigma sigma = r_min / (2.0**(1.0 / 6.0)) epsilon = 0.5 * unit.kilojoule_per_mole bb = { "particle_type_name": "bb", "sigma": sigma, "epsilon": epsilon, "mass": mass } sc = { "particle_type_name": "sc", "sigma": sigma, "epsilon": epsilon, "mass": mass } # Bond angle definitions bond_angle_force_constant = 100 * unit.kilojoule_per_mole / unit.radian / unit.radian bond_angle_force_constants = { "bb_bb_bb_bond_angle_force_constant": bond_angle_force_constant, "bb_bb_sc_bond_angle_force_constant": bond_angle_force_constant, } # OpenMM requires angle definitions in units of radians bb_bb_bb_equil_bond_angle = 120.0 * unit.degrees bb_bb_sc_equil_bond_angle = 120.0 * unit.degrees equil_bond_angles = { "bb_bb_bb_equil_bond_angle": bb_bb_bb_equil_bond_angle, "bb_bb_sc_equil_bond_angle": bb_bb_sc_equil_bond_angle, } # Torsion angle definitions torsion_force_constant = 20.0 * unit.kilojoule_per_mole torsion_force_constants = { "bb_bb_bb_bb_torsion_force_constant": torsion_force_constant, "bb_bb_bb_sc_torsion_force_constant": torsion_force_constant } bb_bb_bb_bb_torsion_phase_angle = 75.0 * unit.degrees bb_bb_bb_sc_torsion_phase_angle = 75.0 * unit.degrees torsion_phase_angles = { "bb_bb_bb_bb_torsion_phase_angle": bb_bb_bb_bb_torsion_phase_angle, "bb_bb_bb_sc_torsion_phase_angle": bb_bb_bb_sc_torsion_phase_angle } torsion_periodicities = { "bb_bb_bb_bb_torsion_periodicity": 3, "bb_bb_bb_sc_torsion_periodicity": 3 } # Monomer definitions A = { "monomer_name": "A", "particle_sequence": [bb, sc], "bond_list": [[0, 1]], "start": 0, "end": 0, } sequence = 24 * [A] pdb_path = os.path.join(structures_path, "24mer_1b1s_initial_structure.pdb") positions = PDBFile(pdb_path).getPositions() # Build a coarse grained model cgmodel = CGModel( particle_type_list=[bb, sc], bond_lengths=bond_lengths, bond_force_constants=bond_force_constants, bond_angle_force_constants=bond_angle_force_constants, torsion_force_constants=torsion_force_constants, equil_bond_angles=equil_bond_angles, torsion_phase_angles=torsion_phase_angles, torsion_periodicities=torsion_periodicities, include_nonbonded_forces=include_nonbonded_forces, include_bond_forces=include_bond_forces, include_bond_angle_forces=include_bond_angle_forces, include_torsion_forces=include_torsion_forces, constrain_bonds=constrain_bonds, positions=positions, sequence=sequence, monomer_types=[A], ) run_simulation( cgmodel, total_simulation_time, simulation_time_step, temperature, friction=friction, print_frequency=print_frequency, output_directory=output_directory, ) assert os.path.isfile(f"{output_directory}/simulation.dat") assert os.path.isfile(f"{output_directory}/simulation.pdb")