def to_openmm_Modeller(item, atom_indices='all', coordinates=None, box=None, check=True): if check: digest_item(item, 'openmm.Topology') atom_indices = digest_atom_indices(atom_indices) coordinates = digest_coordinates(coordinates) box = digest_box(box) from . import extract from molsysmt import puw from openmm.app import Modeller tmp_item = extract(item, atom_indices=atom_indices, copy_if_all=False, check=False) positions = puw.convert(coordinates[0], 'nm', to_form='openmm.unit') tmp_item = Modeller(tmp_item, positions) return tmp_item
def to_mdtraj_Trajectory(item, atom_indices='all', check=True): if check: try: is_pdbfixer_PDBFixer(item) except: raise WrongFormError('pdbfixer.PDBFixer') try: atom_indices = digest_atom_indices(atom_indices) except: raise WrongAtomIndicesError() try: from mdtraj.core.trajectory import Trajectory as mdtraj_Trajectory except: raise LibraryNotFoundError('MDTraj') from molsysmt import puw from . import to_mdtraj_Topology from . import get_coordinates_from_atom tmp_item = to_mdtraj_Topology(item, atom_indices=atom_indices, check=False) coordinates = get_coordinates_from_atom(tmp_item, indices=atom_indices, check=False) coordinates = puw.convert(coordinates, to_units='nanometer', to_form='openmm.unit') tmp_item = mdtraj_Trajectory(coordinates, tmp_item) return tmp_item
def to_openmm_Modeller(item, atom_indices='all', check=True): if check: try: is_pdbfixer_PDBFixer(item) except: raise WrongFormError('pdbfixer.PDBFixer') try: atom_indices = digest_atom_indices(atom_indices) except: raise WrongAtomIndicesError() try: structure_indices = digest_structure_indices(structure_indices) except: raise WrongStructureIndicesError() from molsysmt import puw from . import to_openmm_Topology tmp_item = to_openmm_Topology(item, atom_indices=atom_indices, check=False) coordinates = get_coordinates_from_atom(tmp_item, indices=atom_indices, check=False) coordinates = puw.convert(coordinates, to_units='nanometer', to_form='openmm.unit') tmp_item = openmm_Modeller(tmp_item, coordinates) return tmp_item
def to_openmm_Simulation(item, molecular_system=None, atom_indices='all', structure_indices='all'): from molsysmt.basic import convert, get from openmm.app import Simulation topology = convert(molecular_system, to_form='openmm.Topology', selection=atom_indices) positions = get(molecular_system, target='atom', selection=atom_indices, structure_indices=structure_indices, coordinates=True) positions = puw.convert(positions[0], to_unit='nm', to_form='openmm.unit') simulation = convert(molecular_system, to_form='molsysmt.Simulation') integrator = simulation.to_openmm_Integrator() platform = simulation.to_openmm_Platform() properties = simulation.get_openmm_Simulation_parameters() tmp_item = Simulation(topology, item, integrator, platform, properties) tmp_item.context.setPositions(positions) if simulation.initial_velocities_to_temperature: temperature = puw.convert(simulation.temperature, to_unit='K', to_form='openmm.unit') tmp_item.context.setVelocitiesToTemperature(temperature) if molecular_system is not None: tmp_molecular_system = molecular_system.combine_with_items( tmp_item, atom_indices=atom_indices, structure_indices=structure_indices) else: tmp_molecular_system = None return tmp_item, tmp_molecular_system
def to_openmm_Integrator(self): from openmm import LangevinIntegrator temperature = puw.convert(self.temperature, to_unit='K', to_form='openmm.unit') collisions_rate = puw.convert(self.collisions_rate, to_unit='1/ps', to_form='openmm.unit') integration_timestep = puw.convert(self.integration_timestep, to_unit='fs', to_form='openmm.unit') if self.integrator == 'Langevin': integrator = LangevinIntegrator(temperature, collisions_rate, integration_timestep) if self.constraint_tolerance is not None: integrator.setConstraintTolerance(self.constraint_tolerance) else: raise NotImplementedError() return integrator
def unwrap(molecular_system, selection='all', structure_indices='all', syntaxis='MolSysMT', engine='MolSysMT', in_place=False): engine = digest_engine(engine) structure_indices = digest_structure_indices(structure_indices) if engine=='MolSysMT': from molsysmt.basic import select, get, set, extract coordinates= get(molecular_system, target='atom', selection=selection, coordinates=True) n_structures = coordinates.shape[0] n_atoms = coordinates.shape[1] box, box_shape = get(molecular_system, target='system', structure_indices=structure_indices, box=True, box_shape=True) orthogonal = 0 if box_shape is None: raise ValueError("The system has no PBC box. The input argument 'pbc' can not be True.") elif box_shape == 'cubic': orthogonal =1 length_units = puw.get_unit(coordinates) box = puw.convert(box, to_unit=length_units) box = np.asfortranarray(puw.get_value(box), dtype='float64') coordinates = np.asfortranarray(puw.get_value(coordinates), dtype='float64') libbox.unwrap(coordinates, box, orthogonal, n_atoms, n_structures) coordinates=np.ascontiguousarray(coordinates)*length_units else: raise NotImpementedEngineError() if in_place: set(molecular_system, target='atom', selection=selection, structure_indices=structure_indices, syntaxis=syntaxis, coordinates=coordinates) pass else: tmp_molecular_system = extract(molecular_system, selection=selection, structure_indices=structure_indices, syntaxis=syntaxis) set(tmp_molecular_system, target='atom', selection='all', structure_indices='all', syntaxis='MolSysMT', coordinates=coordinates) return tmp_molecular_system
def set_coordinates_to_atom(item, indices='all', structure_indices='all', value=None): length_unit = puw.get_unit(item['coordinates']) value = puw.convert(value, to_unit=length_unit) if indices is 'all': if structure_indices is 'all': item['coordinates'] = value else: item['coordinates'][structure_indices, :, :] = value else: if structure_indices is 'all': item['coordinates'][:, indices, :] = value else: item['coordinates'][np.ix_(indices, structure_indices)] = value pass
def to_string_pdb_text(item, atom_indices='all', coordinates=None, box=None, check=True): if check: digest_item(item, 'openmm.Topology') atom_indices = digest_atom_indices(atom_indices) coordinates = digest_coordinates(coordinates) box = digest_box(box) from io import StringIO from openmm.app import PDBFile from molsysmt import __version__ as msm_version from openmm import Platform # the openmm version is taken from this module (see: openmm/app/pdbfile.py) from molsysmt import puw n_structures = coordinates.shape[0] if n_structures > 1: import warnings warnings.warn( "Openmm.Topology/to_string_pdb_text got more than a single structure. Only the 0-th is taken." ) tmp_io = StringIO() coordinates = puw.convert(coordinates[0], 'nm', to_form='openmm.unit') PDBFile.writeFile(item, coordinates, tmp_io, keepIds=True) filedata = tmp_io.getvalue() openmm_version = Platform.getOpenMMVersion() filedata = filedata.replace( 'WITH OPENMM ' + openmm_version, 'WITH OPENMM ' + openmm_version + ' BY MOLSYSMT ' + msm_version) tmp_io.close() del (tmp_io) tmp_item = filedata return tmp_item
def set_box_to_system(item, structure_indices='all', value=None, check=True): if check: _digest_item(item, 'openmm.Topology') structure_indices = _digest_structure_indices(structure_indices) box = _digest_box(value) box = _puw.convert(value, to_unit='nanometers', to_form='openmm.unit') n_structures = box.shape[0] if n_structures == 1: item.setPeriodicBoxVectors(box[0]) else: raise ValueError( "The box to set in to a openmm.Topology has more than a frame") pass
def to_openmm_Modeller(item, atom_indices='all', structure_indices='all', check=True): if check: digest_item(item, 'molsysmt.MolSys') atom_indices = digest_atom_indices(atom_indices) structure_indices = digest_structure_indices(structure_indices) try: from openmm.app import Modeller except: raise LibraryNotFound(openmm) from . import to_openmm_Topology from . import get_coordinates_from_atom from molsysmt import puw tmp_topology = to_openmm_Topology(item, atom_indices=atom_indices, structure_indices=structure_indices, check=False) tmp_positions = get_coordinates_from_atom(item, indices=atom_indices, structure_indices=structure_indices, check=False) tmp_positions = puw.convert(tmp_positions, to_form='openmm.unit') tmp_item = Modeller(tmp_topology, tmp_positions[0]) return tmp_item
def wrap_to_pbc(molecular_system, selection='all', structure_indices='all', center='[0,0,0] nanometers', center_of_selection=None, weights_for_center=None, recenter=True, keep_covalent_bonds=False, syntaxis='MolSysMT', engine='MolSysMT', in_place=False): engine = digest_engine(engine) structure_indices = digest_structure_indices(structure_indices) if engine == 'MolSysMT': from molsysmt.basic import select, get, set, extract, copy atom_indices = select(molecular_system, selection=selection, syntaxis=syntaxis) coordinates = get(molecular_system, target='atom', indices=atom_indices, coordinates=True) length_units = puw.get_unit(coordinates) n_structures = coordinates.shape[0] n_atoms = coordinates.shape[1] box, box_shape = get(molecular_system, target='system', structure_indices=structure_indices, box=True, box_shape=True) box = puw.convert(box, to_unit=length_units) orthogonal = 0 if box_shape is None: raise ValueError( "The system has no PBC box. The input argument 'pbc' can not be True." ) elif box_shape == 'cubic': orthogonal = 1 if center_of_selection is not None: from molsysmt.structure import get_center center = get_center(molecular_system, selection=center_of_selection, weights=weights_for_center, structure_indices=structure_indices, syntaxis=syntaxis, engine='MolSysMT') center = puw.convert(center, to_unit=length_units) center = puw.get_value(center) else: center = puw.quantity(center) center = puw.convert(center, to_unit=length_units) center = puw.get_value(center) center_shape = np.shape(center) if len(center_shape) == 1 and center_shape[-1] == 3: center = np.tile(center, [n_structures, 1, 1]) elif len(center_shape) == 2 and center_shape[ -1] == 3 and center_shape[0] == n_structures: center = np.expand_dims(center, axis=1) elif len(center_shape ) == 2 and center_shape[-1] == 3 and center_shape[0] == 1: center = np.tile(center[0], [n_structures, 1, 1]) elif len(center_shape ) == 3 and center_shape[-1] == 3 and center_shape[ 0] == n_structures and center_shape[1] == 1: center = np.array(center) else: raise ValueError('center needs the right shape') box = np.asfortranarray(puw.get_value(box), dtype='float64') coordinates = np.asfortranarray(puw.get_value(coordinates), dtype='float64') center = np.asfortranarray(center, dtype='float64') libbox.wrap_pbc(coordinates, center, box, orthogonal, n_atoms, n_structures) if recenter: translation = np.tile(-center, (n_atoms, 1)) coordinates += translation coordinates = np.ascontiguousarray(coordinates) * length_units else: raise NotImpementedEngineError() if in_place: set(molecular_system, target='atom', indices=atom_indices, structure_indices=structure_indices, syntaxis=syntaxis, coordinates=coordinates) pass else: tmp_molecular_system = copy(molecular_system) set(tmp_molecular_system, target='atom', indices=atom_indices, structure_indices=structure_indices, syntaxis=syntaxis, coordinates=coordinates) return tmp_molecular_system
def solvate(molecular_system, box_geometry="truncated octahedral", clearance='14.0 angstroms', anion='Cl-', num_anions="neutralize", cation='Na+', num_cations="neutralize", ionic_strength='0.0 molar', engine="LEaP", to_form=None, logfile=False, verbose=False): """solvate(item, geometry=None, water=None, engine=None) Methods and wrappers to create and solvate boxes Parameters ---------- anion: 'Cl-', 'Br-', 'F-', and 'I-' num_anions: number of cations to add. integer or "neutralize" cation: "NA" 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+' num_cations: number of cations to add. integer or "neutralize" box_geometry: "cubic", "truncated_octahedral" or "rhombic_dodecahedron" (Default: "truncated_octahedral") Returns ------- item : bla bla bla bla Examples -------- See Also -------- Notes ----- """ from molsysmt.basic import get_form, convert engine = digest_engine(engine) to_form = digest_to_form(to_form) if to_form is None: to_form = get_form(molecular_system) if engine == "OpenMM": from openmm import Vec3 clearance = puw.convert(clearance, to_form='openmm.unit') ionic_strength = puw.convert(ionic_strength, to_form='openmm.unit') modeller = convert(molecular_system, to_form='openmm.Modeller') molecular_mechanics = convert(molecular_system, to_form='molsysmt.MolecularMechanics') parameters = molecular_mechanics.get_openmm_System_parameters() forcefield = molecular_mechanics.to_openmm_ForceField() solvent_model = None if molecular_mechanics.water_model == 'SPC': solvent_model = 'tip3p' elif molecular_mechanics.water_model in [ 'TIP3P', 'TIP3PFB', 'SPCE', 'TIP4PEW', 'TIP4PFB', 'TIP5P' ]: solvent_model = molecular_mechanics.water_model.lower() else: raise NotImplementedError() if box_geometry == "truncated octahedral": max_size = max( max((pos[i] for pos in modeller.positions)) - min((pos[i] for pos in modeller.positions)) for i in range(3)) vectors = Vec3(1.0, 0, 0), Vec3(1.0 / 3.0, 2.0 * np.sqrt(2.0) / 3.0, 0.0), Vec3(-1.0 / 3.0, np.sqrt(2.0) / 3.0, np.sqrt(6.0) / 3.0) box_vectors = [(max_size + clearance) * v for v in vectors] modeller.addSolvent(forcefield, model=solvent_model, boxVectors=box_vectors, ionicStrength=ionic_strength, positiveIon=cation, negativeIon=anion) elif box_geometry == "rhombic dodecahedral": max_size = max( max((pos[i] for pos in modeller.positions)) - min((pos[i] for pos in modeller.positions)) for i in range(3)) vectors = Vec3(1.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0), Vec3(0.5, 0.5, np.sqrt(2) / 2) box_vectors = [(max_size + clearance) * v for v in vectors] modeller.addSolvent(forcefield, model=solvent_model, boxVectors=box_vectors, ionicStrength=ionic_strength, positiveIon=cation, negativeIon=anion) else: modeller.addSolvent(forcefield, model=solvent_model, padding=clearance, ionicStrength=ionic_strength, positiveIon=cation, negativeIon=anion) tmp_item = convert(modeller, to_form=to_form) del (modeller) return tmp_item elif engine == "PDBFixer": from openmm import Vec3 clearance = puw.convert(clearance, to_form='openmm.unit') ionic_strength = puw.convert(ionic_strength, to_form='openmm.unit') pdbfixer = convert(molecular_system, to_form='pdbfixer.PDBFixer') max_size = max( max((pos[i] for pos in pdbfixer.positions)) - min((pos[i] for pos in pdbfixer.positions)) for i in range(3)) box_size = None box_vectors = None if box_geometry == "truncated octahedral": vectors = Vec3(1.0, 0, 0), Vec3(1.0 / 3.0, 2.0 * np.sqrt(2.0) / 3.0, 0.0), Vec3(-1.0 / 3.0, np.sqrt(2.0) / 3.0, np.sqrt(6.0) / 3.0) elif box_geometry == "rhombic dodecahedral": vectors = Vec3(1.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0), Vec3(0.5, 0.5, np.sqrt(2) / 2) elif box_geometry == "cubic": vectors = Vec3(1.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0), Vec3(0.0, 0.0, 1.0) box_vectors = [(max_size + clearance) * v for v in vectors] pdbfixer.addSolvent(boxVectors=box_vectors, ionicStrength=ionic_strength, positiveIon=cation, negativeIon=anion) tmp_item = convert(pdbfixer, to_form=to_form) del (pdbfixer) return tmp_item elif engine == "LEaP": from molsysmt.thirds.tleap import TLeap from molsysmt._private.files_and_directories import temp_directory, temp_filename from molsysmt.tools.file_pdb import replace_HETATM_by_ATOM_in_terminal_cappings from shutil import rmtree, copyfile from os import getcwd, chdir from molsysmt.basic import set as _set, select from molsysmt.build import has_hydrogens, remove_hydrogens if has_hydrogens(molecular_system): raise ValueError( "A molecular system without hydrogen atoms is needed.") #molecular_system = remove_hydrogens(molecular_system) #if verbose: # print("All Hydrogen atoms were removed to be added by LEaP\n\n") indices_NME_C = select( molecular_system, target='atom', selection='group_name=="NME" and atom_name=="C"') with_NME_C = (len(indices_NME_C) > 0) if with_NME_C: _set(molecular_system, target='atom', selection='group_name=="NME" and atom_name=="C"', atom_name='CH3') current_directory = getcwd() working_directory = temp_directory() pdbfile_in = temp_filename(dir=working_directory, extension='pdb') _ = convert(molecular_system, to_form=pdbfile_in) #replace_HETATM_from_capping_atoms(pdbfile_in) tmp_prmtop = temp_filename(dir=working_directory, extension='prmtop') tmp_inpcrd = tmp_prmtop.replace('prmtop', 'inpcrd') tmp_logfile = tmp_prmtop.replace('prmtop', 'leap.log') molecular_mechanics = convert(molecular_system, to_form='molsysmt.MolecularMechanics') parameters = molecular_mechanics.get_leap_parameters() forcefield = parameters['forcefield'] water = parameters['water_model'] solvent_model = None if water == 'SPC': solvent_model = 'SPCBOX' elif water == 'TIP3P': solvent_model = 'TIP3PBOX' elif water == 'TIP4P': solvent_model = 'TIP4PBOX' if verbose: print('Working directory:', working_directory) tleap = TLeap() tleap.load_parameters(*forcefield) tleap.load_unit('MolecularSystem', pdbfile_in) tleap.check_unit('MolecularSystem') tleap.get_total_charge('MolecularSystem') tleap.solvate('MolecularSystem', solvent_model, clearance, box_geometry=box_geometry) if num_anions != 0: if num_anions == 'neutralize': num_anions = 0 tleap.add_ions('MolecularSystem', anion, num_ions=num_anions, replace_solvent=True) if num_cations != 0: if num_cations == 'neutralize': num_cations = 0 tleap.add_ions('MolecularSystem', cation, num_ions=num_cations, replace_solvent=True) tleap.save_unit('MolecularSystem', tmp_prmtop) errors = tleap.run(working_directory=working_directory, verbose=verbose) del (tleap) if logfile: copyfile(tmp_logfile, current_directory + '/build_peptide.log') tmp_item = convert([tmp_prmtop, tmp_inpcrd], to_form=to_form) if with_NME_C: _set(tmp_item, target='atom', selection='group_name=="NME" and atom_name=="CH3"', atom_name='C') rmtree(working_directory) return tmp_item else: raise NotImplementedError
def get_openmm_System_parameters(self): from openmm import app parameters = {} if self.non_bonded_method == 'no_cutoff': parameters['nonbondedMethod'] = app.NoCutoff elif self.non_bonded_method == 'cutoff_non_periodic': parameters['nonbondedMethod'] = app.CutoffNonPeriodic elif self.non_bonded_method == 'cutoff_periodic': parameters['nonbondedMethod'] = app.CutoffPeriodic elif self.non_bonded_method == 'Ewald': parameters['nonbondedMethod'] = app.Ewald elif self.non_bonded_method == 'PME': parameters['nonbondedMethod'] = app.PME elif self.non_bonded_method == 'LJPME': parameters['nonbondedMethod'] = app.LJPME else: raise NotImplementedError() if self.non_bonded_cutoff is not None: parameters['nonbondedCutoff'] = puw.convert(self.non_bonded_cutoff, to_form='openmm.unit', to_unit='nm') if self.switch_distance is not None: parameters['switchDistance'] = puw.convert(self.switch_distance, to_form='openmm.unit', to_unit='nm') if self.constraints is not None: if self.constraints == 'h_bonds': parameters['constraints'] = app.HBonds elif self.constraints == 'all_bonds': parameters['constraints'] = app.HBonds elif self.constraints == 'h_angles': parameters['constraints'] = app.HAngles else: raise NotImplementedError() else: parameters['constraints'] = None parameters['hydrogenMass'] = self.hydrogen_mass parameters['rigidWater'] = self.rigid_water #parameters['removeCMMotion']=self.remove_cm_motion parameters['residueTemplates'] = self.residue_templates parameters['ignoreExternalBonds'] = self.ignore_external_bonds parameters['flexibleConstraints'] = self.flexible_constraints if self.implicit_solvent is not None: if self.implicit_solvent == 'HCT': parameters['implicitSolvent'] = app.HCT elif self.implicit_solvent == 'OBC1': parameters['implicitSolvent'] = app.OBC1 elif self.implicit_solvent == 'OBC2': parameters['implicitSolvent'] = app.OBC2 elif self.implicit_solvent == 'GBn': parameters['implicitSolvent'] = app.GBn elif self.implicit_solvent == 'GBn2': parameters['implicitSolvent'] = app.GBn2 else: raise NotImplementedError parameters['implicitSolventSaltConc'] = puw.convert( self.implicit_solvent_salt_cont, to_unit='mole/liter', to_form='openmm.unit') parameters['implicitSolventKappa'] = puw.convert( self.implicit_solvent_salt_kappa, to_unit='1/nm', to_form='openmm.unit') parameters['soluteDielectric'] = self.solute_dielectric parameters['solventDielectric'] = self.solvent_dielectric else: parameters['implicitSolvent'] = None #parameters['useDispersionCorrection']=self.use_dispersion_correction #parameters['ewaldErrorTolerance']=self.ewald_error_tolerance return parameters