Esempio n. 1
0
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)
Esempio n. 2
0
    def write(self, object, configuration = None, tag = None):
        """
        Write  an object to the file

        :param object: the object to be written
        :type object: :class:~MMTK.Collections.GroupOfAtoms
        :param configuration: the configuration from which the coordinates 
                              are taken (default: current configuration)
        :type configuration: :class:~MMTK.ParticleProperties.Configuration
        """
        if not ChemicalObjects.isChemicalObject(object):
            for o in object:
                self.write(o, configuration)
        else:
            toplevel = tag is None
            if toplevel:
                tag = Utility.uniqueAttribute()
            if hasattr(object, 'pdbmap'):
                for residue in object.pdbmap:
                    self.file.nextResidue(residue[0], )
                    sorted_atoms = residue[1].items()
                    sorted_atoms.sort(lambda x, y:
                                      cmp(x[1].number, y[1].number))
                    for atom_name, atom in sorted_atoms:
                        atom = object.getAtom(atom)
                        p = atom.position(configuration)
                        if Utility.isDefinedPosition(p):
                            try: occ = atom.occupancy
                            except AttributeError: occ = 0.
                            try: temp = atom.temperature_factor
                            except AttributeError: temp = 0.
                            self.file.writeAtom(atom_name, p/Units.Ang,
                                                occ, temp, atom.type.symbol)
                            self.atom_sequence.append(atom)
                        else:
                            self.warning = True
                        setattr(atom, tag, None)
            else:
                if hasattr(object, 'is_protein'):
                    for chain in object:                    
                        self.write(chain, configuration, tag)
                elif hasattr(object, 'is_chain'):
                        self.file.nextChain(None, object.name)
                        for residue in object:
                            self.write(residue, configuration, tag)
                        self.file.terminateChain()
                elif hasattr(object, 'molecules'):
                    for m in object.molecules:
                        self.write(m, configuration, tag)
                elif hasattr(object, 'groups'):
                    for g in object.groups:
                        self.write(g, configuration, tag)
            if toplevel:
                for a in object.atomList():
                    if not hasattr(a, tag):
                        self.write(a, configuration, tag)
                    delattr(a, tag)
Esempio n. 3
0
    def write(self, object, configuration = None, tag = None):
        """
        Write  an object to the file

        :param object: the object to be written
        :type object: :class:`~MMTK.Collections.GroupOfAtoms`
        :param configuration: the configuration from which the coordinates 
                              are taken (default: current configuration)
        :type configuration: :class:`~MMTK.ParticleProperties.Configuration`
        """
        if not ChemicalObjects.isChemicalObject(object):
            for o in object:
                self.write(o, configuration)
        else:
            toplevel = tag is None
            if toplevel:
                tag = Utility.uniqueAttribute()
            if hasattr(object, 'pdbmap'):
                for residue in object.pdbmap:
                    self.file.nextResidue(residue[0], )
                    sorted_atoms = residue[1].items()
                    sorted_atoms.sort(lambda x, y:
                                      cmp(x[1].number, y[1].number))
                    for atom_name, atom in sorted_atoms:
                        atom = object.getAtom(atom)
                        p = atom.position(configuration)
                        if Utility.isDefinedPosition(p):
                            try: occ = atom.occupancy
                            except AttributeError: occ = 0.
                            try: temp = atom.temperature_factor
                            except AttributeError: temp = 0.
                            self.file.writeAtom(atom_name, p/Units.Ang,
                                                occ, temp, atom.type.symbol)
                            self.atom_sequence.append(atom)
                        else:
                            self.warning = True
                        setattr(atom, tag, None)
            else:
                if hasattr(object, 'is_protein'):
                    for chain in object:                    
                        self.write(chain, configuration, tag)
                elif hasattr(object, 'is_chain'):
                        self.file.nextChain(None, object.name)
                        for residue in object:
                            self.write(residue, configuration, tag)
                        self.file.terminateChain()
                elif hasattr(object, 'molecules'):
                    for m in object.molecules:
                        self.write(m, configuration, tag)
                elif hasattr(object, 'groups'):
                    for g in object.groups:
                        self.write(g, configuration, tag)
            if toplevel:
                for a in object.atomList():
                    if not hasattr(a, tag):
                        self.write(a, configuration, tag)
                    delattr(a, tag)
Esempio n. 4
0
 def createGroups(self, mapping):
     groups = []
     for name in self.molecules.keys():
         full_name = mapping.get(name, None)
         if full_name is not None:
             for molecule in self.molecules[name]:
                 g = ChemicalObjects.Group(full_name)
                 setConfiguration(g, [molecule], toplevel=0)
                 groups.append(g)
     return groups
Esempio n. 5
0
 def makeChemicalObjects(self, template, top_level):
     self.groups[template.name].locked = True
     if top_level:
         if template.attributes.has_key('sequence'):
             object = ChemicalObjects.ChainMolecule(None)
         else:
             object = ChemicalObjects.Molecule(None)
     else:
         object = ChemicalObjects.Group(None)
     object.atoms = []
     object.bonds = Bonds.BondList([])
     object.groups = []
     object.type = self.groups[template.name]
     object.parent = None
     child_objects = []
     for child in template.children:
         if isinstance(child, GroupTemplate):
             group = self.makeChemicalObjects(child, False)
             object.groups.append(group)
             object.atoms.extend(group.atoms)
             object.bonds.extend(group.bonds)
             group.parent = object
             child_objects.append(group)
         else:
             atom = ChemicalObjects.Atom(child.element)
             object.atoms.append(atom)
             atom.parent = object
             child_objects.append(atom)
     for name, index in template.names.items():
         setattr(object, name, child_objects[index])
         child_objects[index].name = name
     for name, value in template.attributes.items():
         path = name.split('.')
         setattr(self.namePath(object, path[:-1]), path[-1], value)
     for atom1, atom2 in template.bonds:
         atom1 = self.namePath(object, atom1)
         atom2 = self.namePath(object, atom2)
         object.bonds.append(Bonds.Bond((atom1, atom2)))
     for name, vector in template.positions.items():
         path = name.split('.')
         self.namePath(object, path).setPosition(vector)
     return object
Esempio n. 6
0
 def createMolecule(self, name=None):
     """
     :returns: a :class:~MMTK.ChemicalObjects.Molecule object corresponding 
               to the molecule in the PDB file. The parameter name 
               specifies the molecule name as defined in the chemical database.
               It can be left out for known molecules (currently
               only water).
     :rtype: :class:~MMTK.ChemicalObjects.Molecule
     """
     if name is None:
         name = molecule_names[self.name]
     m = ChemicalObjects.Molecule(name)
     setConfiguration(m, [self])
     return m
Esempio n. 7
0
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()))
Esempio n. 8
0
    def __init__(self, *items, **properties):
        """
        :param items: either a sequence of peptide chain objects, or
                      a string, which is interpreted as the name of a
                      database definition for a protein.
                      If that definition does not exist, the string
                      is taken to be the name of a PDB file, from which
                      all peptide chains are constructed and
                      assembled into a protein.
        :keyword model: one of "all" (all-atom), "no_hydrogens" or "none"
                        (no hydrogens),"polar_hydrogens" or "polar"
                        (united-atom with only polar hydrogens),
                        "polar_charmm" (like "polar", but defining
                        polar hydrogens like in the CHARMM force field),
                        "polar_opls" (like "polar", but defining
                        polar hydrogens like in the latest OPLS force field),
                        "calpha" (only the |C_alpha| atom of each residue).
                        Default is "all".
        :type model: str
        :keyword position: the center-of-mass position of the protein
        :type position: Scientific.Geometry.Vector
        :keyword name: a name for the protein
        :type name: str
        """
        if items == (None,):
            return
        self.name = ''
        if len(items) == 1 and type(items[0]) == type(''):
            try:
                filename = Database.databasePath(items[0], 'Proteins')
                found = 1
            except IOError:
                found = 0
            if found:
                blueprint = Database.BlueprintProtein(items[0])
                items = blueprint.chains
                for attr, value in vars(blueprint).items():
                    if attr not in ['type', 'chains']:
                        setattr(self, attr, value)
            else:
                import PDB
                conf = PDB.PDBConfiguration(items[0])
                model = properties.get('model', 'all')
                items = conf.createPeptideChains(model)
        molecules = []
        for i in items:
            if ChemicalObjects.isChemicalObject(i):
                molecules.append(i)
            else:
                molecules = molecules + list(i)
        for m, i in zip(molecules, range(len(molecules))):
            m._numbers = [i]
            if not m.name:
                m.name = 'chain'+`i`
        ss = self._findSSBridges(molecules)
        new_mol = {}
        for m in molecules:
            new_mol[m] = ([m],[])
        for bond in ss:
            m1 = new_mol[bond[0].topLevelChemicalObject()]
            m2 = new_mol[bond[1].topLevelChemicalObject()]
            if m1 == m2:
                m1[1].append(bond)
            else:
                combined = (m1[0] + m2[0], m1[1] + m2[1] + [bond])
                for m in combined[0]:
                    new_mol[m] = combined
        self.molecules = []
        while new_mol:
            m = new_mol.values()[0]
            for i in m[0]:
                del new_mol[i]
            bonds = m[1]
            if len(m[0]) == 1:
                m = m[0][0]
                m._addSSBridges(bonds)
            else:
                numbers = sum((i._numbers for i in m[0]), [])
                m = ConnectedChains(m[0])
                m._numbers = numbers
                m._addSSBridges(bonds)
                m._finalize()
                for c in m:
                    c.parent = self
            m.parent = self
            self.molecules.append(m)

        self.atoms = []
        self.chains = []
        for m in self.molecules:
            self.atoms.extend(m.atoms)
            if hasattr(m, 'is_connected_chains'):
                for c, name, i in zip(range(len(m)),
                                   m.chain_names, m._numbers):
                    self.chains.append((m, c, name, i))
            else:
                try: name = m.name
                except AttributeError: name = ''
                self.chains.append((m, None, name, m._numbers[0]))
        self.chains.sort(lambda c1, c2: cmp(c1[3], c2[3]))
        self.chains = map(lambda c: c[:3], self.chains)

        self.parent = None
        self.type = None
        self.configurations = {}
        try:
            self.name = properties['name']
            del properties['name']
        except KeyError: pass
        if properties.has_key('position'):
            self.translateTo(properties['position'])
            del properties['position']
        self.addProperties(properties)

        undefined = 0
        for a in self.atoms:
            if a.position() is None:
                undefined += 1
        if undefined > 0 and undefined != len(self.atoms):
            Utility.warning('Some atoms in a protein ' +
                            'have undefined positions.')
Esempio n. 9
0
 def createMolecules(self, names = None, permit_undefined=True):
     """
     :param names: If a list of molecule names (as defined in the
                   chemical database) and/or PDB residue names,
                   only molecules mentioned in this list will be
                   constructed. If a dictionary, it is used to map
                   PDB residue names to molecule names. With the
                   default (None), only water molecules are
                   built.
     :type names: list
     :param permit_undefined: If False, an exception is raised
                              when a PDB residue is encountered for
                              which no molecule name is supplied
                              in names. If True, an AtomCluster
                              object is constructed for each unknown
                              molecule.
     :returns: a collection of :class:~MMTK.ChemicalObjects.Molecule objects,
               one for each molecule in the PDB file. Each PDB residue not 
               describing an amino acid or nucleotide residue is considered a
               molecule.
     :rtype: :class:~MMTK.Collections.Collection
     """
     collection = Collections.Collection()
     mol_dicts = [molecule_names]
     if type(names) == type({}):
         mol_dicts.append(names)
         names = None
     for name in self.molecules.keys():
         full_name = None
         for dict in mol_dicts:
             full_name = dict.get(name, None)
         if names is None or name in names or full_name in names:
             if full_name is None and not permit_undefined:
                 raise ValueError("no definition for molecule " + name)
             for molecule in self.molecules[name]:
                 if full_name:
                     m = ChemicalObjects.Molecule(full_name)
                     setConfiguration(m, [molecule])
                 else:
                     pdbdict = {}
                     atoms = []
                     i = 0
                     for atom in molecule:
                         aname = atom.name
                         while aname[0] in string.digits:
                             aname = aname[1:] + aname[0]
                         try:
                             element = atom['element'].strip()
                             a = ChemicalObjects.Atom(element, name = aname)
                         except KeyError:
                             try:
                                 a = ChemicalObjects.Atom(aname[:2].strip(),
                                                          name = aname)
                             except IOError:
                                 a = ChemicalObjects.Atom(aname[:1],
                                                          name = aname)
                         a.setPosition(atom.position)
                         atoms.append(a)
                         pdbdict[atom.name] = Database.AtomReference(i)
                         i += 1
                     m = ChemicalObjects.AtomCluster(atoms, name = name)
                     if len(pdbdict) == len(molecule):
                         # pdbmap is correct only if the AtomCluster has
                         # unique atom names
                         m.pdbmap = [(name, pdbdict)]
                     setConfiguration(m, [molecule])
                 collection.addObject(m)
     return collection
Esempio n. 10
0
    def __init__(self, *items, **properties):
        """
        :param items: either a sequence of peptide chain objects, or
                      a string, which is interpreted as the name of a
                      database definition for a protein.
                      If that definition does not exist, the string
                      is taken to be the name of a PDB file, from which
                      all peptide chains are constructed and
                      assembled into a protein.
        :keyword model: one of "all" (all-atom), "no_hydrogens" or "none"
                        (no hydrogens),"polar_hydrogens" or "polar"
                        (united-atom with only polar hydrogens),
                        "polar_charmm" (like "polar", but defining
                        polar hydrogens like in the CHARMM force field),
                        "polar_opls" (like "polar", but defining
                        polar hydrogens like in the latest OPLS force field),
                        "calpha" (only the |C_alpha| atom of each residue).
                        Default is "all".
        :type model: str
        :keyword position: the center-of-mass position of the protein
        :type position: Scientific.Geometry.Vector
        :keyword name: a name for the protein
        :type name: str
        """
        if items == (None,):
            return
        self.name = ''
        if len(items) == 1 and type(items[0]) == type(''):
            try:
                filename = Database.databasePath(items[0], 'Proteins')
                found = 1
            except IOError:
                found = 0
            if found:
                blueprint = Database.BlueprintProtein(items[0])
                items = blueprint.chains
                for attr, value in vars(blueprint).items():
                    if attr not in ['type', 'chains']:
                        setattr(self, attr, value)
            else:
                import PDB
                conf = PDB.PDBConfiguration(items[0])
                model = properties.get('model', 'all')
                items = conf.createPeptideChains(model)
        molecules = []
        for i in items:
            if ChemicalObjects.isChemicalObject(i):
                molecules.append(i)
            else:
                molecules = molecules + list(i)
        for m, i in zip(molecules, range(len(molecules))):
            m._numbers = [i]
            if not m.name:
                m.name = 'chain'+`i`
        ss = self._findSSBridges(molecules)
        new_mol = {}
        for m in molecules:
            new_mol[m] = ([m],[])
        for bond in ss:
            m1 = new_mol[bond[0].topLevelChemicalObject()]
            m2 = new_mol[bond[1].topLevelChemicalObject()]
            if m1 == m2:
                m1[1].append(bond)
            else:
                combined = (m1[0] + m2[0], m1[1] + m2[1] + [bond])
                for m in combined[0]:
                    new_mol[m] = combined
        self.molecules = []
        while new_mol:
            m = new_mol.values()[0]
            for i in m[0]:
                del new_mol[i]
            bonds = m[1]
            if len(m[0]) == 1:
                m = m[0][0]
                m._addSSBridges(bonds)
            else:
                numbers = sum((i._numbers for i in m[0]), [])
                m = ConnectedChains(m[0])
                m._numbers = numbers
                m._addSSBridges(bonds)
                m._finalize()
                for c in m:
                    c.parent = self
            m.parent = self
            self.molecules.append(m)

        self.atoms = []
        self.chains = []
        for m in self.molecules:
            self.atoms.extend(m.atoms)
            if hasattr(m, 'is_connected_chains'):
                for c, name, i in zip(range(len(m)),
                                   m.chain_names, m._numbers):
                    self.chains.append((m, c, name, i))
            else:
                try: name = m.name
                except AttributeError: name = ''
                self.chains.append((m, None, name, m._numbers[0]))
        self.chains.sort(lambda c1, c2: cmp(c1[3], c2[3]))
        self.chains = map(lambda c: c[:3], self.chains)

        self.parent = None
        self.type = None
        self.configurations = {}
        try:
            self.name = properties['name']
            del properties['name']
        except KeyError: pass
        if properties.has_key('position'):
            self.translateTo(properties['position'])
            del properties['position']
        self.addProperties(properties)

        undefined = 0
        for a in self.atoms:
            if a.position() is None:
                undefined += 1
        if undefined > 0 and undefined != len(self.atoms):
            Utility.warning('Some atoms in a protein ' +
                            'have undefined positions.')