예제 #1
0
def AddBond():
    """Template written as an example for OTHER people to write their own"""
    from Pmv.picker import AtomPicker
    p = AtomPicker(self, numberOfObjects=2, gui=0)
    p.go(modal=1)
    atoms = p.getObjects()
    assert atoms[0].top == atoms[1].top
    from MolKit.molecule import Bond
    Bond(atoms[0], atoms[1])
    self.lines(atoms[0].top)
    self.GUI.VIEWER.Redraw()
예제 #2
0
    def buildBondscif(self, ):
        mmCIF_dict = self.mmCIF_dict
        nbonds = len(mmCIF_dict["_geom_bond_atom_site_label_1"])
        labels1 = mmCIF_dict["_geom_bond_atom_site_label_1"]
        labels2 = mmCIF_dict["_geom_bond_atom_site_label_2"]
        if nbonds == 0:
            return
        ignoreSym = False
        if "_geom_bond_site_symmetry_1" in mmCIF_dict:
            ignoreSym = True
        for i in range(nbonds):
            # 1- Get the atoms corresponding of the indices of the pair
            atm1 = self.mol.allAtoms.get(labels1[i])[0]
            if len(atm1.bonds) > atm1.maxBonds:
                continue
            atm2 = self.mol.allAtoms.get(labels2[i])[0]
            # 2- Need to make sure that the two atoms are not already
            # bonded.
            if atm1.isBonded(atm2): continue

            if len(atm2.bonds) > atm2.maxBonds:
                continue

            if ignoreSym and (mmCIF_dict["_geom_bond_site_symmetry_1"][i] != "." or \
                    mmCIF_dict["_geom_bond_site_symmetry_2"][i] != "."):
                continue

            # 3- Need to make sure that the two atoms of this pairs are not
            # alternate location.
            if not atm1.altname is None and not atm2.altname is None:
                # atm1 and atm2 are alternate locations
                if atm1.altname == atm2.altname:
                    # Can only be bound if they have the same altname
                    bond = Bond(atm1, atm2, origin='BuiltByCif', check=0)
            # 4- Create a bonds between the two atoms:
            else:
                #bond = Bond(atm1, atm2, origin='Bhtree', check=0)
                bond = Bond(atm1, atm2, origin='BuiltByCif', check=0)
예제 #3
0
    def parse_MOL2_Bonds(self, bondlines):
        """ Function to build the bonds object using the bond record of
        the mol2 file."""
        bondlines = map(string.split, bondlines)
        for bd in bondlines:
            at1 = self.mol.atmNum[int(bd[1])]
            at2 = self.mol.atmNum[int(bd[2])]

            if at1.isBonded(at2): continue
            bond = Bond(at1, at2, check=0)
            bond.type = bd[3]
            try:
                bond.bondOrder = int(bd[3])
            except:
                if bd[3] == 'ar':
                    bond.bondOrder = 'aromatic'
                elif bd[3] == 'am':
                    bond.bondOrder = 'amide'
                else:
                    bond.bondOrder = bd[3]
        self.mol.bondsflag = 1
        self.mol.hasBonds = 1
예제 #4
0
    def parse_MOL2_Bonds(self, bondlines):
        """ Function to build the bonds object using the bond record of
        the mol2 file."""
        bondlines = map(string.split, bondlines)
        for bd in bondlines:
            at1 = self.mol.atmNum[int(bd[1])]
            at2 = self.mol.atmNum[int(bd[2])]

            if at1.isBonded(at2): continue
            bond = Bond(at1, at2, check=0)
            bond.type = bd[3]
            try:
                bond.bondOrder = int(bd[3])
            except:
                if bd[3]=='ar':
                    bond.bondOrder = 'aromatic'
                elif bd[3]=='am':
                    bond.bondOrder = 'amide'
                else:
                    bond.bondOrder = bd[3]
        self.mol.bondsflag = 1
        self.mol.hasBonds = 1
예제 #5
0
    def addHydrogens(self, mol):
        #check for bonds
        if len(mol.allAtoms.bonds[0]) == 0:
            mol.buildBondsByDistance()
        bonds = mol.allAtoms.bonds[0]
        #could have preset babel_types
        #so check if allAtoms are already typed
        try:
            t = mol.allAtoms.babel_type
        except:
            #if all are not pretyped, type them
            babel = AtomHybridization()
            babel.assignHybridization(mol.allAtoms)

        if self.method == 'withBondOrder':
            mol.rings = RingFinder()
            mol.rings.findRings2(mol.allAtoms, mol.allAtoms.bonds[0])
            mol.rings.bondRings = {}
            for ind in xrange(len(mol.rings.rings)):
                r = mol.rings.rings[ind]
                for b in r['bonds']:
                    if not mol.rings.bondRings.has_key(b):
                        mol.rings.bondRings[b] = [
                            ind,
                        ]
                    else:
                        mol.rings.bondRings[b].append(ind)
            bo = BondOrder()
            bo.assignBondOrder(mol.allAtoms, bonds, mol.rings)
            mol.allAtoms._bndtyped = 1
            # do aromatic here
            arom = Aromatic(mol.rings)
            arom.find_aromatic_atoms(mol.allAtoms)

        hat = AddHydrogens().addHydrogens(mol.allAtoms, method=self.method)
        bondedAtomDict = {}  # key is heavy atom
        for a in hat:
            if bondedAtomDict.has_key(a[1]):
                bondedAtomDict[a[1]].append(a)
            else:
                bondedAtomDict[a[1]] = [a]

        # now create Atom object for hydrogens
        # and add the to the residues's atom list
        molNewHs = AtomSet([])  # list of created H atoms for this molecule
        heavyAtoms = AtomSet([])  # list of atoms that need new radii

        for heavyAtom, HatmsDscr in bondedAtomDict.items():
            #don't add hydrogens to carbons: polar Only!!!
            if self.htype != 'all' and heavyAtom.element == 'C':
                continue
            res = heavyAtom.parent
            # find where to insert H atom
            childIndex = res.children.index(heavyAtom) + 1

            # loop over H atoms description to be added
            # start at the end to number correctly
            l = len(HatmsDscr)
            for i in range(l - 1, -1, -1):
                a = HatmsDscr[i]
                # build H atom's name
                if len(heavyAtom.name) == 1:
                    name = 'H' + heavyAtom.name
                else:
                    name = 'H' + heavyAtom.name[1:]

                # if more than 1 H atom, add H atom index
                # for instance HD11, HD12, Hd13 (index is 1,2,3)
                if l > 1:
                    name = name + str(i + 1)

                # create the H atom object
                atom = Atom(name,
                            res,
                            top=heavyAtom.top,
                            chemicalElement='H',
                            childIndex=childIndex,
                            assignUniqIndex=0)

                # set atoms attributes
                atom._coords = [a[0]]
                if hasattr(a[1], 'segID'): atom.segID = a[1].segID
                atom.hetatm = 0
                atom.alternate = []
                #atom.element = 'H'
                atom.occupancy = 1.0
                atom.conformation = 0
                atom.temperatureFactor = 0.0
                atom.babel_atomic_number = a[2]
                atom.babel_type = a[3]
                atom.babel_organic = 1
                atom.radius = 1.2

                # create the Bond object bonding Hatom to heavyAtom
                bond = Bond(a[1], atom, bondOrder=1)

                # add the created atom the the list
                molNewHs.append(atom)
                # in case this new hydrogen atom ever ends up in pmv
                # HAVE TO CREATE THESE ENTRIES
                # create the color entries for all geoemtries
                # available for the heavyAtom
                for key, value in heavyAtom.colors.items():
                    atom.colors[key] = (0.0, 1.0, 1.0)
                    atom.opacities[key] = 1.0

        mol.allAtoms = mol.chains.residues.atoms
        if self.renumber:
            mol.allAtoms.number = range(1, len(mol.allAtoms) + 1)
        return len(molNewHs)
예제 #6
0
    def getMolecule(self, molInd):

        molecules = []
        if molInd == len(self.molIndex) - 1:
            lastLine = -1
        else:
            lastLine = self.molIndex[molInd + 1]
        # lines fotr that molecule
        lines = self.allLines[self.molIndex[molInd]:lastLine]
        lineIndex = 0
        atomsSeen = {}  # dict of atom types and number of atoms seen

        # parser header
        molName = lines[lineIndex].strip()
        lineIndex += 3

        # create molecule
        mol = Protein(name=molName)
        mol.info = lines[lineIndex + 1]
        mol.comment = lines[lineIndex + 1]
        #self.mol.parser = self
        chain = Chain(id='1', parent=mol, top=mol)
        res = Residue(type='UNK', number='1', parent=chain, top=mol)
        mol.levels = [Protein, Chain, Residue, Atom]

        # parse count line
        line = lines[lineIndex]
        assert line[
            33:
            39] == " V2000", "Format error: only V2000 is suported, got %s" % line[
                33:39]
        nba = int(line[0:3])  # number of atoms
        nbb = int(line[3:6])  # number of bonds
        nbal = int(line[6:9])  # number of atom lists
        ccc = int(line[12:15])  # chiral flag: 0=not chiral, 1=chiral
        sss = int(line[15:18])  # number of stext entries
        lineIndex += 1

        # parse atoms
        for anum in range(nba):
            line = lines[lineIndex]
            element = line[31:34].strip()
            if element in atomsSeen:
                atomsSeen[element] += 1
            else:
                atomsSeen[element] = 1
            atom = Atom(name='%s_%s' % (element, atomsSeen[element]),
                        parent=res,
                        chemicalElement=element,
                        top=mol)

            atom._coords = [[
                float(line[0:10]),
                float(line[10:20]),
                float(line[20:30])
            ]]
            atom._charges['sdf'] = int(line[35:38])
            atom.chargeSet = 'sdf'
            mol.allAtoms.append(atom)

            atom.massDiff = int(line[34:36])
            atom.stereo = int(line[38:41])
            atom.hcount = line[41:44]
            atom.valence = int(line[47:50])
            atom.hetatm = 1
            atom.occupancy = 0.0
            atom.temperatureFactor = 0.0
            lineIndex += 1

        # parse bonds
        for bnum in range(nba):
            line = lines[lineIndex]
            at1 = mol.allAtoms[int(line[0:3]) - 1]
            at2 = mol.allAtoms[int(line[3:6]) - 1]
            if at1.isBonded(at2): continue
            bond = Bond(at1, at2, check=0)

            bond.bondOrder = int(line[6:9])
            #1 = Single, 2 = Double,
            #3 = Triple, 4 = Aromatic,
            #5 = Single or Double,
            #6 = Single or Aromatic,
            #7 = Double or Aromatic, 8 = Any

            bond.stereo = int(line[9:12])
            #Single bonds: 0 = not stereo,
            #1 = Up, 4 = Either,
            #6 = Down, Double bonds: 0 = Use x-, y-, z-coords
            #from atom block to determine cis or trans,
            #3 = Cis or trans (either) double bond

            bond.topo = int(line[15:18])
            # 0 = Either, 1 = Ring, 2 = Chain

            try:
                bond.ReactionCenter = int(line[18:21])
            except ValueError:
                bond.ReactionCenter = 0
            #0 = unmarked, 1 = a center, -1 = not a center,
            #Additional: 2 = no change,
            #4 = bond made/broken,
            #8 = bond order changes
            #12 = 4+8 (both made/broken and changes);
            #5 = (4 + 1), 9 = (8 + 1), and 13 = (12 + 1)

        # "M END" and properties are not parsed at this point
        self.mol = mol
        mname = mol.name
        strRpr = mname + ':::'
        mol.allAtoms.setStringRepr(strRpr)
        strRpr = mname + ':'
        mol.chains.setStringRepr(strRpr)
        for c in mol.chains:
            cname = c.id
            strRpr = mname + ':' + cname + ':'
            c.residues.setStringRepr(strRpr)
            for r in c.residues:
                rname = r.name
                strRpr = mname + ':' + cname + ':' + rname + ':'
                r.atoms.setStringRepr(strRpr)
        molList = mol.setClass()
        molList.append(mol)
        mol.parser = self
        for n in molList.name:
            name = n + ','
        name = name[:-1]
        molList.setStringRepr(name)
        strRpr = name + ':::'
        molList.allAtoms.setStringRepr(strRpr)

        return molList
    def add_oxt(self, catom):
        if catom.element != 'C':
            return
        mol = catom.top
        ##check for bonds
        #if len(mol.allAtoms.bonds[0])==0:
        #    mol.buildBondsByDistance()
        #check whether residue already has OXT
        res = catom.parent
        if 'OXT' in res.atoms.name:
            print('not adding OXT to ', res.full_name(), '\n',
                  'it already has an OXT atom')
            return
        #check whether catom has a hydrogen to delete
        hatoms = catom.parent.atoms.get(lambda x: x.name == 'HC')
        if len(hatoms):
            hatom = hatoms[0]
            #check for hbonds
            if hasattr(hatom, 'hbonds'):
                #remove hbonds
                for b in hatom.hbonds:
                    atList = [b.donAt, b.accAt]
                    if b.hAt is not None:
                        atList.append(b.hAt)
                    for at in atList:
                        #hbonds might already be gone
                        if not hasattr(at, 'hbonds'):
                            continue
                        okhbnds = []
                        for hb in at.hbonds:
                            if hb != b:
                                okhbnds.append(hb)
                        if len(okhbnds):
                            at.hbonds = okhbnds
                        else:
                            delattr(at, 'hbonds')
            #remove covalent bonds
            for b in hatom.bonds:
                at2 = b.atom1
                if at2 == hatom: at2 = b.atom2
                at2.bonds.remove(b)
            hatom.parent.remove(hatom, cleanup=1)

        #have to type atoms before call to add_sp2_hydrogen:
        if not hasattr(catom, 'babel_type'):
            print('catom has no babel_type: calling typeAtoms')
            #self.warningMsg(msg)
            #typeAtoms does whole molecule
            babel = AtomHybridization()
            babel.assignHybridization(mol.allAtoms)

        #NB: bond_length 1.28 measured from OXT-C bond in 1crn
        tup1 = self.addh.add_sp2_hydrogen(catom, 1.28)
        res = catom.parent

        # find where to insert H atom
        childIndex = res.children.index(catom) + 1
        name = 'OXT'

        # create the OXT atom object
        atom = Atom(name,
                    res,
                    top=mol,
                    childIndex=childIndex,
                    assignUniqIndex=0)

        # set atoms attributes
        atom._coords = [tup1[0][0]]
        if hasattr(catom, 'segID'): atom.segID = catom.segID
        atom.hetatm = 0
        atom.alternate = []
        atom.element = 'O'
        atom.occupancy = 1.0
        atom.conformation = 0
        atom.temperatureFactor = 0.0
        atom.babel_atomic_number = 8
        atom.babel_type = 'O-'
        atom.babel_organic = 1

        # create the Bond object bonding Hatom to heavyAtom
        bond = Bond(catom, atom, bondOrder=2)

        # create the color entries for all geometries
        # available for the other oxygen atom attached to 'C'
        oatom = res.atoms.get(lambda x: x.name == 'O')[0]
        if oatom is not None:
            for key, value in list(oatom.colors.items()):
                atom.colors[key] = value
                #atom.opacities[key] = oatom.opacities[key]

                # update the allAtoms set in the molecule
        mol.allAtoms = mol.chains.residues.atoms

        # update numbers of allAtoms
        fst = mol.allAtoms[0].number
        mol.allAtoms.number = list(range(fst, len(mol.allAtoms) + fst))

        # update _uniqIndex of this residues atoms
        res.assignUniqIndex()
        #return AtomSet([atom])
        return atom
예제 #8
0
    print "done"
    ##      db = filter(lambda x:x.bondOrder==2, bonds)
    ##      for b in db:
    ##          print b

    addh = AddHydrogens()
    #pdb.run("hat = addh.addHydrogens(allAtoms)")
    hat = addh.addHydrogens(allAtoms)

    from MolKit.molecule import Atom, Bond
    for a in hat:
        atom = Atom('H', a[1].parent, top=a[1].top)
        atom._coords = [a[0]]
        atom.segID = a[1].segID
        atom.hetatm = 0
        atom.alternate = []
        atom.element = 'H'
        atom.number = -1
        atom.occupancy = 1.0
        atom.conformation = 0
        atom.temperatureFactor = 0.0
        atom.babel_atomic_number = a[2]
        atom.babel_type = a[3]
        atom.babel_organic = 1
        bond = Bond(a[1], atom)

    from Pmv.moleculeViewer import MoleculeViewer
    mv = MoleculeViewer()
    mv.addMolecule(mol)
    mv.lines(mol)
예제 #9
0
 def doit(self, atom1, atom2, **kw):
     origin = kw['origin']
     bondOrder = kw['bondOrder']
     bond = Bond(atom1, atom2, origin=origin, bondOrder=bondOrder)
     event = EditAtomsEvent('coords', AtomSet([atom1, atom2]))
     self.vf.dispatchEvent(event)