def addSolvent(universe, solvent, density, scale_factor=4.): """ Scales up the universe and adds as many solvent molecules as are necessary to obtain the specified solvent density, taking account of the solute molecules that are already present in the universe. The molecules are placed at random positions in the scaled-up universe, but without overlaps between any two molecules. :param universe: a finite universe :type universe: :class:~MMTK.Universe.Universe :param solvent: a molecule, or the name of a molecule in the database :type solvent: :class:~MMTK.ChemicalObjects.Molecule or str :param density: the density of the solvent (amu/nm**3) :type density: float :param scale_factor: the factor by which the initial universe is expanded before adding the solvent molecules :type scale_factor: float """ # Calculate number of solvent molecules and universe size if isinstance(solvent, basestring): solvent = ChemicalObjects.Molecule(solvent) cell_volume = universe.cellVolume() if cell_volume is None: raise TypeError("universe volume is undefined") solute = copy.copy(universe._objects) solute_volume = 0. excluded_regions = [] for o in solute: solute_volume = solute_volume + surfaceAndVolume(o)[1] excluded_regions.append(o.boundingSphere()) n_solvent = int( round(density * (cell_volume - solute_volume) / solvent.mass())) solvent_volume = n_solvent * solvent.mass() / density cell_volume = solvent_volume + solute_volume universe.translateBy(-solute.position()) universe.scaleSize((cell_volume / universe.cellVolume())**(1. / 3.)) # Scale up the universe and add solvent molecules at random positions universe.scaleSize(scale_factor) universe.scale_factor = scale_factor for i in range(n_solvent): m = copy.copy(solvent) m.translateTo(universe.randomPoint()) while True: s = m.boundingSphere() collision = False for region in excluded_regions: if (s.center - region.center).length() < s.radius + region.radius: collision = True break if not collision: break m.translateTo(universe.randomPoint()) universe.addObject(m) excluded_regions.append(s)
def addSolvent(universe, solvent, density, scale_factor=4.): """ Scales up the universe and adds as many solvent molecules as are necessary to obtain the specified solvent density, taking account of the solute molecules that are already present in the universe. The molecules are placed at random positions in the scaled-up universe, but without overlaps between any two molecules. :param universe: a finite universe :type universe: :class:`~MMTK.Universe.Universe` :param solvent: a molecule, or the name of a molecule in the database :type solvent: :class:`~MMTK.ChemicalObjects.Molecule` or str :param density: the density of the solvent (amu/nm**3) :type density: float :param scale_factor: the factor by which the initial universe is expanded before adding the solvent molecules :type scale_factor: float """ # Calculate number of solvent molecules and universe size if isinstance(solvent, basestring): solvent = ChemicalObjects.Molecule(solvent) cell_volume = universe.cellVolume() if cell_volume is None: raise TypeError("universe volume is undefined") solute = copy.copy(universe._objects) solute_volume = 0. excluded_regions = [] for o in solute: solute_volume = solute_volume + surfaceAndVolume(o)[1] excluded_regions.append(o.boundingSphere()) n_solvent = int(round(density*(cell_volume-solute_volume)/solvent.mass())) solvent_volume = n_solvent*solvent.mass()/density cell_volume = solvent_volume + solute_volume universe.translateBy(-solute.position()) universe.scaleSize((cell_volume/universe.cellVolume())**(1./3.)) # Scale up the universe and add solvent molecules at random positions universe.scaleSize(scale_factor) universe.scale_factor = scale_factor for i in range(n_solvent): m = copy.copy(solvent) m.translateTo(universe.randomPoint()) while True: s = m.boundingSphere() collision = False for region in excluded_regions: if (s.center-region.center).length() < s.radius+region.radius: collision = True break if not collision: break m.translateTo(universe.randomPoint()) universe.addObject(m) excluded_regions.append(s)
def get_sasa_mmtk(selection, state=-1, hydrogens='auto', quiet=1): ''' DESCRIPTION Get solvent accesible surface area using MMTK.MolecularSurface http://dirac.cnrs-orleans.fr/MMTK/ This command is very picky with missing atoms and wrong atom naming. SEE ALSO stub2ala, get_sasa, get_sasa_ball ''' try: import MMTK except ImportError: print(' ImportError: please install MMTK') raise CmdException from MMTK.PDB import PDBConfiguration from MMTK.Proteins import Protein from MMTK.MolecularSurface import surfaceAndVolume try: from cStringIO import StringIO except ImportError: from io import StringIO selection = selector.process(selection) state, quiet = int(state), int(quiet) radius = cmd.get_setting_float('solvent_radius') if hydrogens == 'auto': if cmd.count_atoms('(%s) and hydro' % selection) > 0: hydrogens = 'all' else: hydrogens = 'no_hydrogens' elif hydrogens == 'none': hydrogens = 'no_hydrogens' conf = PDBConfiguration(StringIO(cmd.get_pdbstr(selection))) system = Protein(conf.createPeptideChains(hydrogens)) try: area, volume = surfaceAndVolume(system, radius * 0.1) except: print(' Error: MMTK.MolecularSurface.surfaceAndVolume failed') raise CmdException if not quiet: print(' get_sasa_mmtk: %.3f Angstroms^2 (volume: %.3f Angstroms^3).' % (area * 1e2, volume * 1e3)) return area * 1e2
def get_sasa_mmtk(selection, state=-1, hydrogens='auto', quiet=1): ''' DESCRIPTION Get solvent accesible surface area using MMTK.MolecularSurface http://dirac.cnrs-orleans.fr/MMTK/ This command is very picky with missing atoms and wrong atom naming. SEE ALSO stub2ala, get_sasa, get_sasa_ball ''' try: import MMTK except ImportError: print(' ImportError: please install MMTK') raise CmdException from MMTK.PDB import PDBConfiguration from MMTK.Proteins import Protein from MMTK.MolecularSurface import surfaceAndVolume try: from cStringIO import StringIO except ImportError: from io import StringIO selection = selector.process(selection) state, quiet = int(state), int(quiet) radius = cmd.get_setting_float('solvent_radius') if hydrogens == 'auto': if cmd.count_atoms('(%s) and hydro' % selection) > 0: hydrogens = 'all' else: hydrogens = 'no_hydrogens' elif hydrogens == 'none': hydrogens = 'no_hydrogens' conf = PDBConfiguration(StringIO(cmd.get_pdbstr(selection))) system = Protein(conf.createPeptideChains(hydrogens)) try: area, volume = surfaceAndVolume(system, radius * 0.1) except: print(' Error: MMTK.MolecularSurface.surfaceAndVolume failed') raise CmdException if not quiet: print(' get_sasa_mmtk: %.3f Angstroms^2 (volume: %.3f Angstroms^3).' % (area * 1e2, volume * 1e3)) return area * 1e2
def numberOfSolventMolecules(universe, solvent, density): """ :param universe: a finite universe :type universe: :class:`~MMTK.Universe.Universe` :param solvent: a molecule, or the name of a molecule in the database :type solvent: :class:`~MMTK.ChemicalObjects.Molecule` or str :param density: the density of the solvent (amu/nm**3) :type density: float :returns: the number of solvent molecules that must be added to the universe, in addition to whatever it already contains, to obtain the given solvent density. :rtype: int """ if isinstance(solvent, basestring): solvent = ChemicalObjects.Molecule(solvent) cell_volume = universe.cellVolume() if cell_volume is None: raise TypeError("universe volume is undefined") solute_volume = 0. for o in universe._objects: solute_volume = solute_volume + surfaceAndVolume(o)[1] return int(round(density*(cell_volume-solute_volume)/solvent.mass()))