Beispiel #1
0
	def __init__(self, netcdfPath, startFrame, endFrame):
		from MMTK.Trajectory import Trajectory
		replyobj.status("Reading NetCDF file\n", blankAfter=0)
		try:
			self.trajectory = Trajectory(None, netcdfPath)
		finally:
			replyobj.status("Done reading NetCDF file\n")

		replyobj.status("Processing trajectory\n", blankAfter=0)

		self.atomNames = []
		self.elements = []
		self.resNames = []
		self.atomIndices = {}
		self.bonds = []
		self.ipres = [1]

		from chimera import Element
		univ = self.trajectory.universe
		for i, a in enumerate(univ.atomList()):
			self.atomIndices[a] = i
			self.atomNames.append(a.name)
			self.elements.append(Element(a.getAtomProperty(a,
								"symbol")))
		for obj in univ:
			self._processObj(obj)
		delattr(self, "atomIndices")
		self.ipres.pop()
		
		self.startFrame = startFrame
		self.endFrame = endFrame

		self.name = os.path.basename(netcdfPath)

		replyobj.status("Done processing trajectory\n")
 def __init__(self, fileName, ncInfo):
     from chimera import UserError, Molecule, Element, openModels, replyobj
     from chimera import Coord, connectMolecule
     self.name = "Particle trajectory from %s" % fileName
     self.molecule = m = Molecule()
     self.isRealMolecule = False
     try:
         m.name = ncInfo.title
     except AttributeError:
         m.name = fileName
     tc = Element("Tc")
     coords = ncInfo.variables['coordinates']
     try:
         pnames = ncInfo.variables['particle_names']
     except KeyError:
         pnames = ["prt"] * len(coords)
     try:
         radii = ncInfo.variables['radii']
     except KeyError:
         radii = [1.0] * len(coords)
     try:
         mnames = ncInfo.variables['molecule_names']
         mnumbers = ncInfo.variables['molecule_numbers']
     except KeyError:
         mnames = ["PRT"]
         mnumbers = [1] * len(coords)
     serial = 1
     atoms = []
     residues = {}
     for name, radius, crd, mnumber in zip(pnames[:], radii[:],
                                           coords[0][:], mnumbers[:]):
         try:
             r = residues[mnumber]
         except KeyError:
             r = m.newResidue(string(mnames[mnumber - 1]), " ", mnumber,
                              " ")
         name = string(name)
         a = m.newAtom(name, tc)
         atoms.append(a)
         a.radius = radius
         r.addAtom(a)
         a.setCoord(Coord(*tuple(crd)))
         a.serialNumber = serial
         serial += 1
     try:
         connections = ncInfo.variables['connections']
     except KeyError:
         connections = []
     for i1, i2 in connections[:]:
         m.newBond(atoms[i1 - 1], atoms[i2 - 1])
     csNum = 1
     for crds in coords[1:]:
         cs = m.newCoordSet(csNum)
         for a, crd in zip(atoms, crds):
             a.setCoord(Coord(*tuple(crd)), cs)
         csNum += 1
Beispiel #3
0
def createCN(): 						
		cn= Molecule() 					# create an instance of a molecule

		# r = cn.newResidue(residue type, chain identifier, sequence number, insertion code)
		r = cn.newResidue("cn", " ", 1, " ")

		atomC = cn.newAtom("CE", Element("C")) 				# now create the atoms of the residue. 
		atomN = cn.newAtom("NF", Element("N"))

		bondLength_cn = 1.156
		
		atomC.setCoord(Coord(0, 0, 0))
		atomN.setCoord(Coord(bondLength_cn, 0, 0))
		
		r.addAtom(atomC)
		r.addAtom(atomN)

		cn.newBond(atomC, atomN)
		openModels.add([cn])
def bondWithHLength(heavy, geom):
    element = heavy.element.name
    if element == "C":
        if geom == 4:
            return 1.09
        if geom == 3:
            return 1.08
        if geom == 2:
            return 1.056
    elif element == "N":
        return N_H
    elif element == "O":
        # can't rely on water being in chain "water" anymore...
        if len(heavy.bonds) == 0 or (len(heavy.bonds) == 2 and len(
            [nb for nb in heavy.neighbors if nb.element.number > 1]) == 0):
            return 0.9572
        return 0.96
    elif element == "S":
        return 1.336
    return Element.bondLength(heavy.element, Element(1))
Beispiel #5
0
def determineElementFromMass(mass, considerHydrogens=True):
    from chimera import Element
    H = Element('H')
    nearest = None
    for high in range(1, 93):
        if Element(high).mass > mass:
            break
    else:
        high = 93

    if considerHydrogens:
        maxHyds = 6
    else:
        maxHyds = 0
    for numHyds in range(maxHyds + 1):
        adjMass = mass - numHyds * H.mass
        lowMass = Element(high - 1).mass
        while lowMass > adjMass and high > 1:
            high -= 1
            lowMass = Element(high - 1).mass
        highMass = Element(high).mass
        lowDiff = abs(adjMass - lowMass)
        highDiff = abs(adjMass - highMass)
        if lowDiff < highDiff:
            diff = lowDiff
            element = high - 1
        else:
            diff = highDiff
            element = high
        if nearest is None or diff < nearest[1]:
            nearest = (element, diff)
    return Element(nearest[0])
Beispiel #6
0
def placeFragment(fragment, resName, model="scratch", position=None):
    """place a Fragment (see Fragment.py)

	   'resName' is the name of the new residue that will contain the
	   fragment.  (It will be in the 'het' chain.)

	   'model' can either be a chimera.Molecule instance or a string.
	   If the latter, then a new model is created with the string as
	   its .name attribute.

	   'position' can either be a chimera.Point or None.  If None, then
	   the fragment is positioned at the center of the view.
	"""

    if isinstance(model, basestring):
        model = _newModel(model)
    r = _newResidue(model, resName)
    needFocus = False
    if position is None:
        if len(chimera.openModels.list()) == 1:
            needFocus = True
        xf = model.openState.xform
        position = xf.inverse().apply(Point(*chimera.viewer.camera.center))
    # find fragment center
    x = y = z = 0.0
    for element, xyz in fragment.atoms:
        x += xyz[0]
        y += xyz[1]
        z += xyz[2]
    numAtoms = len(fragment.atoms)
    fragCenter = Point(x / numAtoms, y / numAtoms, z / numAtoms)
    correction = position - fragCenter

    from chimera.molEdit import addAtom, genAtomName
    atoms = []
    for element, xyz in fragment.atoms:
        atoms.append(
            addAtom(genAtomName(element, r), Element(element), r,
                    Point(*xyz) + correction))
    for indices, depict in fragment.bonds:
        r.molecule.newBond(atoms[indices[0]], atoms[indices[1]])
    if needFocus:
        chimera.runCommand("focus")
    return r
Beispiel #7
0
def placeHelium(resName, model="scratch", position=None):
    """place a new helium atom

	   'resName' is the name of the new residue that will contain the
	   helium.  (It will be in the 'het' chain.)

	   'model' can either be a chimera.Molecule instance or a string.
	   If the latter, then a new model is created with the string as
	   its .name attribute.

	   'position' can either be a chimera.Point or None.  If None, then
	   the helium is positioned at the center of the view.
	"""

    if isinstance(model, basestring):
        model = _newModel(model)

    r = _newResidue(model, resName)
    if position is None:
        xf = model.openState.xform
        position = xf.inverse().apply(Point(*chimera.viewer.camera.center))
    from chimera.molEdit import addAtom
    return addAtom('He1', Element('He'), r, position)
def newHydrogen(parentAtom, Hnum, totalHydrogens, namingSchema, pos):
    global _serial, _metals
    nearbyMetals = _metals.searchTree(pos.data(), _metalDist)
    for metal in nearbyMetals:
        if metal.molecule != parentAtom.molecule:
            continue
        metalPos = metal.coord()
        parentPos = parentAtom.coord()
        if metalClash(metalPos, pos, parentPos):
            return
    newH = addAtom(_Hname(parentAtom, Hnum, totalHydrogens, namingSchema),
                   Element(1),
                   parentAtom.residue,
                   pos,
                   serialNumber=_serial,
                   bondedTo=parentAtom)
    _serial = newH.serialNumber + 1
    from Midas import elementColor
    parentColor = parentAtom.color
    if parentColor == elementColor(parentAtom.element.name):
        newH.color = elementColor("H")
    else:
        newH.color = parentColor
Beispiel #9
0
    def include_dummies(self, metal_class):
        """
        Include oriented Dummy Atoms
        inside the molecular system.

        Parameters
        ----------

        metal_class: str
                Build - in Metal class pointer
        """
        metal = metal_class.metal
        residue = metal.residue

        # Remove existing pseudobonds
        if hasattr(metal, 'pseudoBonds') and metal.pseudoBonds:
            metal.pseudoBonds[0].pseudoBondGroup.deleteAll()

        # Adding Dummies
        for i, dummy in enumerate(metal_class.dummies):
            dummy.atom = addAtom("D{}".format(i + 1), Element(dummy.Type),
                                 residue, chimera.Coord(dummy.xyz))
            dummy.atom.drawMode = 3
            dummy.atom.radius = 0.2
Beispiel #10
0
	center = Point(coords)
	correction = position - center
	for r in residues:
		for a in r.atoms:
			a.setCoord(a.coord() + correction)
	from Midas import ksdssp
	ksdssp([model])
	if needFocus:
		chimera.runCommand("focus")
	return residues

from chimera import elements
elementRadius = {}
for i in range(len(chimera.elements.name)):
	element = Element(i)
	elementRadius[element] = 0.985 * Element.bondRadius(element)
elementRadius[elements.C] = 0.7622
elementRadius[elements.H] = 0.1869
elementRadius[elements.N] = 0.6854
elementRadius[elements.O] = 0.6454
elementRadius[elements.P] = 0.9527
elementRadius[elements.S] = 1.0428

class ParamError(ValueError):
	pass

def bondLength(a1, geom, e2, a2info=None):
	if e2.number == 1:
		from AddH import bondWithHLength
		return bondWithHLength(a1, geom)
	e1 = a1.element
def postAdd(fakeN, fakeC):
    # fix up non-"true" terminal residues (terminal simply because
    # next residue is missing)
    for fn in fakeN:
        try:
            n = fn.atomsMap["N"][0]
            ca = fn.atomsMap["CA"][0]
            c = fn.atomsMap["C"][0]
        except KeyError:
            continue
        dihed = None
        for cnb in c.primaryNeighbors():
            if cnb.name == "N":
                pn = cnb
                break
        else:
            dihed = 0.0
        if dihed is None:
            try:
                pr = pn.residue
                pc = pr.atomsMap["C"][0]
                pca = pr.atomsMap["CA"][0]
                if pr.type == "PRO":
                    ph = pr.atomsMap["CD"][0]
                else:
                    ph = pr.atomsMap["H"][0]
            except KeyError:
                dihed = 0.0
        for nb in n.primaryNeighbors():
            if nb.element.number == 1:
                nb.molecule.deleteAtom(nb)
        if fn.type == "PRO":
            continue
        if dihed is None:
            dihed = chimera.dihedral(pc.coord(), pca.coord(), pn.coord(),
                                     ph.coord())
        replyobj.info("Adding 'H' to %s\n" % str(fn))
        from chimera.molEdit import addDihedralAtom, addBond
        h = addDihedralAtom("H",
                            Element(1),
                            n,
                            ca,
                            c,
                            1.01,
                            120.0,
                            dihed,
                            bonded=True)
        # also need to set N's IDATM type, because if we leave it as
        # N3+ then the residue will be identified by AddCharge as
        # terminal and there will be no charge for the H atom
        n.idatmType = "Npl"

    for fc in fakeC:
        try:
            c = fc.atomsMap["C"][0]
        except KeyError:
            continue
        for nb in c.primaryNeighbors():
            if nb.element.number == 1:
                replyobj.info("Removing spurious proton from"
                              " 'C' of %s\n" % str(fc))
                nb.molecule.deleteAtom(nb)
        # the N proton may have been named 'HN'; fix that
        try:
            hn = fc.atomsMap["HN"][0]
        except KeyError:
            continue
        addAtom("H",
                Element(1),
                fc,
                hn.coord(),
                serialNumber=hn.serialNumber,
                bondedTo=hn.neighbors[0])
        fc.molecule.deleteAtom(hn)
Beispiel #12
0
def hydPositions(heavy, includeLonePairs=False):
    """Return list of positions for hydrogens attached to this atom.
	   If a hydrogen could be in one of several positions, don't
	   return any of those.
	"""

    # first, find known attached atoms
    bondedHeavys = []
    hyds = []
    for atom in heavy.primaryNeighbors():
        if atom.element.number > 1:
            bondedHeavys.append(atom)
        else:
            hyds.append(atom)

    # convert to Points
    hydLocs = []
    for hyd in hyds:
        hydLocs.append(hyd.xformCoord())

    if hydLocs and not includeLonePairs:
        # explicit hydrogens "win" over atom types
        return hydLocs

    if typeInfo.has_key(heavy.idatmType):
        info = typeInfo[heavy.idatmType]
        geom = info.geometry
        if includeLonePairs:
            subs = geom
        else:
            subs = info.substituents
        bondedLocs = hydLocs[:]
        for bHeavy in bondedHeavys:
            bondedLocs.append(bHeavy.xformCoord())
    else:
        return hydLocs

    knownSubs = len(bondedLocs)
    if knownSubs >= subs or knownSubs == 0:
        return hydLocs
    # above eliminates 'single' geometry

    if knownSubs == 1 and geom == tetrahedral:
        # rotamer
        return hydLocs

    maxSubs = geom
    if maxSubs - subs > 0:
        # the "empty" bond could be anywhere
        return hydLocs

    heavyLoc = heavy.xformCoord()
    bondLen = Element.bondLength(heavy.element, Element(1))

    if geom == planar:
        coPlanar = []
        for bHeavy in bondedHeavys:
            try:
                bhGeom = typeInfo[bHeavy.idatmType].geometry
            except KeyError:
                bhGeom = None
            if bhGeom != planar:
                continue
            for atom in bHeavy.primaryNeighbors():
                if atom != heavy:
                    coPlanar.append(atom.xformCoord())
    else:
        coPlanar = None

    hydLocs = hydLocs + bondPositions(
        heavyLoc, geom, bondLen, bondedLocs, coPlanar=coPlanar)
    return hydLocs
def findHBonds(models, intermodel=True, intramodel=True, donors=None,
				acceptors=None, distSlop=0.0, angleSlop=0.0,
				interSubmodel=False, cacheDA=False):
	# to restrict to specific donor/acceptor atoms, 'donors' and/or
	# acceptors should be atom lists (or dictionaries with atom keys)
	# 
	# 'cacheDA' allows donors/acceptors in molecules to be cached if
	# it is anticipated that the same structures will be examined for
	# H-bonds repeatedly (e.g. a dynamics trajectory).

	if donors and not isinstance(donors, (dict, set)):
		limitedDonors = set(donors)
	else:
		limitedDonors = donors
	if acceptors and not isinstance(acceptors, (dict, set)):
		limitedAcceptors = set(acceptors)
	else:
		limitedAcceptors = acceptors
	global _Dcache, _Acache, _prevLimited
	if cacheDA:
		if limitedDonors:
			dIDs = [id(d) for d in limitedDonors]
			dIDs.sort()
		else:
			dIDs = None
		if limitedAcceptors:
			aIDs = [id(a) for a in limitedAcceptors]
			aIDs.sort()
		else:
			aIDs = None
		key = (dIDs, aIDs)
		if _prevLimited and _prevLimited != key:
			flushCache()
		_prevLimited = key
		from weakref import WeakKeyDictionary
		if _Dcache is None:
			_Dcache = WeakKeyDictionary()
			_Acache = WeakKeyDictionary()
	else:
		flushCache()
	global donorParams, acceptorParams
	global processedDonorParams, processedAcceptorParams
	global _computeCache
	global verbose
	global _problem
	_problem = None

	badConnectivities = 0

	# Used as necessary to cache expensive calculations (by other
	# functions also)
	_computeCache = {}

	processKey = (distSlop, angleSlop)
	if processKey not in processedAcceptorParams:
		# copy.deepcopy() refuses to copy functions (even as
		# references), so do this instead...
		aParams = []
		for p in acceptorParams:
			aParams.append(copy.copy(p))

		for i in range(len(aParams)):
			aParams[i][3] = _processArgTuple(aParams[i][3],
							distSlop, angleSlop)
		processedAcceptorParams[processKey] = aParams
	else:
		aParams = processedAcceptorParams[processKey]

	# compute some info for generic acceptors/donors
	genericAccInfo = {}
	# oxygens...
	genericOAccArgs = _processArgTuple([3.53, 90], distSlop,
							angleSlop)
	genericAccInfo['miscO'] = (accGeneric, genericOAccArgs)
	# dictionary based on bonded atom's geometry...
	genericAccInfo['O2-'] = {
		single: (accGeneric, genericOAccArgs),
		linear: (accGeneric, genericOAccArgs),
		planar: (accPhiPsi, _processArgTuple([3.53, 90, 130],
						distSlop, angleSlop)),
		tetrahedral: (accGeneric, genericOAccArgs)
	}
	genericAccInfo['O3-'] = genericAccInfo['O2-']
	genericAccInfo['O2'] = {
		single: (accGeneric, genericOAccArgs),
		linear: (accGeneric, genericOAccArgs),
		planar: (accPhiPsi, _processArgTuple([3.30, 110, 130],
						distSlop, angleSlop)),
		tetrahedral: (accThetaTau, _processArgTuple(
			[3.03, 100, -180, 145], distSlop, angleSlop))
	}
	# list based on number of known bonded atoms...
	genericAccInfo['O3'] = [
		(accGeneric, genericOAccArgs),
		(accThetaTau, _processArgTuple([3.17, 100, -161, 145],
						distSlop, angleSlop)),
		(accPhiPsi, _processArgTuple([3.42, 120, 135],
						distSlop, angleSlop))
	]
	# nitrogens...
	genericNAccArgs = _processArgTuple([3.42, 90], distSlop,
							angleSlop)
	genericAccInfo['miscN'] = (accGeneric, genericNAccArgs)
	genericAccInfo['N2'] = (accPhiPsi, _processArgTuple([3.42, 140, 135],
						distSlop, angleSlop))
	# tuple based on number of bonded heavy atoms...
	genericN3MultHeavyAccArgs = _processArgTuple([3.30, 153, -180, 145],
						distSlop, angleSlop)
	genericAccInfo['N3'] = (
		(accGeneric, genericNAccArgs),
		# only one example to draw from; weaken by .1A, 5 degrees
		(accThetaTau, _processArgTuple([3.13, 98, -180, 150],
						distSlop, angleSlop)),
		(accThetaTau, genericN3MultHeavyAccArgs),
		(accThetaTau, genericN3MultHeavyAccArgs)
	)
	# one example only; weaken by .1A, 5 degrees
	genericAccInfo['N1'] = (accThetaTau, _processArgTuple(
				[3.40, 136, -180, 145], distSlop, angleSlop))
	# sulfurs...
	# one example only; weaken by .1A, 5 degrees
	genericAccInfo['S2'] = (accPhiPsi, _processArgTuple([3.83, 85, 140],
						distSlop, angleSlop))
	genericAccInfo['Sar'] = genericAccInfo['S3-'] = (accGeneric,
			_processArgTuple([3.83, 85], distSlop, angleSlop))
	# now the donors...
	
	# planar nitrogens
	genDonNpl1HParams = (donThetaTau, _processArgTuple([2.23, 136,
		2.23, 141, 140, 2.46, 136, 140], distSlop, angleSlop))
	genDonNpl2HParams = (donUpsilonTau, _processArgTuple([3.30, 90, -153,
		135, -45, 3.30, 90, -146, 140, -37.5, 130, 3.40, 108, -166, 125,
		-35, 140], distSlop, angleSlop))
	genDonODists = [2.41, 2.28, 2.28, 3.27, 3.14, 3.14]
	genDonOParams = (donGeneric, _processArgTuple(
					genDonODists, distSlop, angleSlop))
	genDonNDists = [2.36, 2.48, 2.48, 3.30, 3.42, 3.42]
	genDonNParams = (donGeneric, _processArgTuple(
					genDonNDists, distSlop, angleSlop))
	genDonSDists = [2.42, 2.42, 2.42, 3.65, 3.65, 3.65]
	genDonSParams = (donGeneric, _processArgTuple(
					genDonSDists, distSlop, angleSlop))
	genericDonInfo = {
		'O': genDonOParams,
		'N': genDonNParams,
		'S': genDonSParams
	}

	accTrees = {}
	hbonds = []
	hasSulfur = {}
	for model in models:
		replyobj.status("Finding acceptors in model '%s'\n"
						% model.name, blankAfter=0)
		if cacheDA \
		and _Acache.has_key(model) \
		and _Acache[model].has_key((distSlop, angleSlop)):
			accAtoms = []
			accData = []
			for accAtom, data in _Acache[model][(distSlop,
							angleSlop)].items():
				if not accAtom.__destroyed__:
					accAtoms.append(accAtom)
					accData.append(data)
		else:
			accAtoms, accData = _findAcceptors(model, aParams,
					limitedAcceptors, genericAccInfo)
			if cacheDA:
				cache = WeakKeyDictionary()
				for i in range(len(accAtoms)):
					cache[accAtoms[i]] = accData[i]
				if not _Acache.has_key(model):
					_Acache[model] = {}
				_Acache[model][(distSlop, angleSlop)] = cache
		xyz = []
		hasSulfur[model] = False
		for accAtom in accAtoms:
			c = accAtom.xformCoord()
			xyz.append([c.x, c.y, c.z])
			if accAtom.element.number == Element.S:
				hasSulfur[model] = True
		replyobj.status("Building search tree of acceptor atoms\n",
								blankAfter=0)
		accTrees[model] = AdaptiveTree(xyz, accData, 3.0)
	
	if processKey not in processedDonorParams:
		# find max donor distances before they get squared..

		# copy.deepcopy() refuses to copy functions (even as
		# references), so do this instead...
		dParams = []
		for p in donorParams:
			dParams.append(copy.copy(p))

		for di in range(len(dParams)):
			geomType = dParams[di][2]
			argList = dParams[di][4]
			donRad = Element.bondRadius(Element(Element.N))
			if geomType == thetaTau:
				maxDist = max((argList[0], argList[2],
								argList[5]))
			elif geomType == upsilonTau:
				maxDist = max((argList[0], argList[5],
								argList[11]))
			elif geomType == water:
				maxDist = max((argList[1], argList[4],
								argList[8]))
			else:
				maxDist = max(genDonODists
						+ genDonNDists + genDonSDists)
				donRad = Element.bondRadius(Element(Element.S))
			dParams[di].append(maxDist + distSlop + donRad
				+ Element.bondRadius(Element(Element.H)))

		for i in range(len(dParams)):
			dParams[i][4] = _processArgTuple(dParams[i][4],
							distSlop, angleSlop)
		processedDonorParams[processKey] = dParams
	else:
		dParams = processedDonorParams[processKey]
		
	genericWaterParams = _processArgTuple([2.36, 2.36 + OHbondDist, 146],
							distSlop, angleSlop)
	genericThetaTauParams = _processArgTuple([2.48, 132],
							distSlop, angleSlop)
	genericUpsilonTauParams = _processArgTuple([3.42, 90, -161, 125],
							distSlop, angleSlop)
	genericGenericParams = _processArgTuple([2.48, 3.42, 130, 90],
							distSlop, angleSlop)
	for dmi in range(len(models)):
		model = models[dmi]
		replyobj.status("Finding donors in model '%s'\n" % model.name,
								blankAfter=0)
		if cacheDA \
		and _Dcache.has_key(model) \
		and _Dcache[model].has_key((distSlop, angleSlop)):
			donAtoms = []
			donData = []
			for donAtom, data in _Dcache[model][(distSlop,
							angleSlop)].items():
				if not donAtom.__destroyed__:
					donAtoms.append(donAtom)
					donData.append(data)
		else:
			donAtoms, donData = _findDonors(model, dParams,
					limitedDonors, genericDonInfo)
			if cacheDA:
				cache = WeakKeyDictionary()
				for i in range(len(donAtoms)):
					cache[donAtoms[i]] = donData[i]
				if not _Dcache.has_key(model):
					_Dcache[model] = {}
				_Dcache[model][(distSlop, angleSlop)] = cache

		replyobj.status("Matching donors in model '%s' to acceptors\n"
						% model.name, blankAfter=0)
		for i in range(len(donAtoms)):
			donorAtom = donAtoms[i]
			geomType, tauSym, argList, testDist = donData[i]
			donorHyds = hydPositions(donorAtom)
			coord = donorAtom.xformCoord()
			for accModel in models:
				if accModel == model and not intramodel\
				or accModel != model and not intermodel:
					continue
				if accModel.id == model.id \
				   and not interSubmodel \
				   and accModel.subid != model.subid:
					continue
				if hasSulfur[accModel]:
					from commonGeom import SULFUR_COMP
					td = testDist + SULFUR_COMP
				else:
					td = testDist
				accs = accTrees[accModel].searchTree(
					[coord.x, coord.y, coord.z], td)
				if verbose:
					replyobj.message("Found %d possible acceptors for donor %s:\n" % (len(accs), donorAtom.oslIdent()))
					for accData in accs:
						replyobj.message("\t%s\n" % accData[0].oslIdent())
				for accAtom, geomFunc, args in accs:
					if accAtom == donorAtom:
						# e.g. hydroxyl
						if verbose:
							print "skipping: donor == acceptor"
						continue
					# exclude hbonding between
					# differing alt locations of
					# same residue
					if accAtom.altLoc.isalnum() and donorAtom.altLoc.isalnum() and accAtom.residue == donorAtom.residue and accAtom.altLoc != donorAtom.altLoc:
						continue
					try:
						if not apply(geomFunc,
						(donorAtom, donorHyds) + args):
							continue
					except ConnectivityError, v:
						replyobj.message("Skipping possible acceptor with bad geometry: %s\n%s\n\n" % (accAtom.oslIdent(), v))
						badConnectivities += 1
						continue
					if verbose:
						replyobj.message("\t%s satisfies acceptor criteria\n" % accAtom.oslIdent())
					if geomType == upsilonTau:
						donorFunc = donUpsilonTau
						addArgs = genericUpsilonTauParams + [tauSym]
					elif geomType == thetaTau:
						donorFunc = donThetaTau
						addArgs = genericThetaTauParams
					elif geomType == water:
						donorFunc = donWater
						addArgs = genericWaterParams
					else:
						if donorAtom.idatmType in ["Npl", "N2+"]:
							heavys = 0
							for bonded in donorAtom.primaryNeighbors():
								if bonded.element.number > 1:
									heavys += 1
							if heavys > 1:
								info = genDonNpl1HParams
							else:
								info = genDonNpl2HParams
						else:
							info = genericDonInfo[donorAtom.element.name]
						donorFunc, argList = info
						addArgs = genericGenericParams
						if donorFunc == donUpsilonTau:
							# tack on generic
							# tau symmetry
							addArgs = genericUpsilonTauParams + [4]
						elif donorFunc == donThetaTau:
							addArgs = genericThetaTauParams
					try:
						if not apply(donorFunc,
						(donorAtom, donorHyds, accAtom)
						+ tuple(argList + addArgs)):
							continue
					except ConnectivityError, v:
						replyobj.message("Skipping possible donor with bad geometry: %s\n%s\n\n" % (donorAtom.oslIdent(), v))
						badConnectivities += 1
						continue
					except AtomTypeError, v:
						_problem = ("atom type",
							donorAtom, v, None)
						continue
					if verbose:
						replyobj.message("\t%s satisfies donor criteria\n" % donorAtom.oslIdent())
					hbonds.append((donorAtom, accAtom))
	type of donor geometry
	degree of tau symmetry
	argument tuple used when geometry-check function is called

	in argument tuple, conversions will occur before function gets called.
	namely:
		positive floats are assumed to be distances, and will be squared
		integers are assumed to be angles in degrees, and will be
			converted to radians
"""
_het5NH = lambda mols: hetNH(mols, 5)
_hetAro6NH = lambda mols: hetNH(mols, 6, aromaticOnly=1)
water = intern("water")
thetaTau = intern('thetaTau')
upsilonTau = intern('upsilonTau')
OHbondDist = Element.bondLength(Element(Element.O), Element(1))
donorParams = [
	# neutral carboxylic acid
	[[['O3', ['Cac', H]], [1,1,0]],
		0, upsilonTau, 2,
		(2.87, 103, -128, 140, -30,
		 2.87, 103, -128, 155, -30, 150,
		 2.87, 103, -128, 140, -30, 150)],
	# protonated nitrogen double-bonded to carbon
	[[['Npl', [['C2', [SingleBond, SingleBond]], H, H]], [1,1,0,0,0,0]],
		0, upsilonTau, 4,
		(3.17,  90, -146, 140, -30,
		 3.17,  90, -146, 140, -22.5, 150,
		 # next line extrapolated
		 3.17, 113, -161, 125, None, 140)],
	[[['Ng+', ['C2', H, H]], [1,1,0,0]],
Beispiel #15
0
def placePeptide(sequence,
                 phiPsis,
                 model="scratch",
                 position=None,
                 rotlib=None,
                 chainID='A'):
    """place a peptide sequence

	   'sequence' contains the (upper case) sequence

	   'phiPsis' is a list of phi/psi tuples, one per residue

	   'model' can either be a chimera.Molecule instance or a string.
	   If the latter, then a new model is created with the string as
	   its .name attribute.

	   'position' can either be a chimera.Point or None.  If None, then
	   the fragment is positioned at the center of the view.
	"""

    if not sequence:
        raise ValueError("No sequence supplied")
    sequence = sequence.upper()
    if not sequence.isupper():
        raise ValueError("Sequence contains non-alphabetic characters")
    from chimera.resCode import protein1to3
    for c in sequence:
        if c not in protein1to3:
            raise ValueError("Unrecognized protein 1-letter code:" " %s" % c)
    if len(sequence) != len(phiPsis):
        raise ValueError("Number of phi/psis not equal to" " sequence length")
    if isinstance(model, basestring):
        model = _newModel(model)
    needFocus = False
    if position is None:
        if len(chimera.openModels.list()) == 1:
            needFocus = True
        xf = model.openState.xform
        position = xf.inverse().apply(Point(*chimera.viewer.camera.center))
    prev = [None] * 3
    pos = 1
    from Midas.addAA import DIST_N_C, DIST_CA_N, DIST_C_CA, DIST_C_O
    from chimera.molEdit import findPt, addAtom, addDihedralAtom
    serialNumber = None
    residues = []
    for c, phiPsi in zip(sequence, phiPsis):
        phi, psi = phiPsi
        while model.findResidue(chimera.MolResId(chainID, pos)):
            pos += 1
        r = model.newResidue(protein1to3[c], chainID, pos, ' ')
        residues.append(r)
        for backbone, dist, angle, dihed in (('N', DIST_N_C, 116.6, psi),
                                             ('CA', DIST_CA_N, 121.9, 180.0),
                                             ('C', DIST_C_CA, 110.1, phi)):
            if prev[0] == None:
                pt = Point(0.0, 0.0, 0.0)
            elif prev[1] == None:
                pt = Point(dist, 0.0, 0.0)
            elif prev[2] == None:
                pt = findPt(prev[0].coord(), prev[1].coord(),
                            Point(0.0, 1.0, 0.0), dist, angle, 0.0)
            else:
                pt = findPt(prev[0].coord(), prev[1].coord(), prev[2].coord(),
                            dist, angle, dihed)
            a = addAtom(backbone,
                        Element(backbone[0]),
                        r,
                        pt,
                        serialNumber=serialNumber,
                        bondedTo=prev[0])
            serialNumber = a.serialNumber + 1
            prev = [a] + prev[:2]
        o = addDihedralAtom("O",
                            Element("O"),
                            prev[0],
                            prev[1],
                            prev[2],
                            DIST_C_O,
                            120.4,
                            180.0 + psi,
                            bonded=True)
    # C terminus O/OXT at different angle than mainchain O
    model.deleteAtom(o)
    addDihedralAtom("O",
                    Element("O"),
                    prev[0],
                    prev[1],
                    prev[2],
                    DIST_C_O,
                    117.0,
                    180.0 + psi,
                    bonded=True)
    addDihedralAtom("OXT",
                    Element("O"),
                    prev[0],
                    prev[1],
                    prev[2],
                    DIST_C_O,
                    117.0,
                    psi,
                    bonded=True)
    from Rotamers import useBestRotamers
    # have to process one by one, otherwise side-chain clashes will occur
    kw = {}
    if rotlib:
        kw['lib'] = rotlib
    for r in residues:
        useBestRotamers("same", [r], criteria="cp", log=False, **kw)

    # find peptide center
    coords = []
    for r in residues:
        coords.extend([a.coord() for a in r.atoms])
    center = Point(coords)
    correction = position - center
    for r in residues:
        for a in r.atoms:
            a.setCoord(a.coord() + correction)
    from Midas import ksdssp
    ksdssp([model])
    if needFocus:
        chimera.runCommand("focus")
    return residues
Beispiel #16
0
def changeAtom(atom, element, geometry, numBonds, autoClose=True, name=None):
    if len(atom.primaryBonds()) > numBonds:
        raise ParamError(
            "Atom already has more bonds than requested.\n"
            "Either delete some bonds or choose a different number"
            " of requested bonds.")
    from chimera.molEdit import addAtom, genAtomName
    changedAtoms = [atom]
    if not name:
        name = genAtomName(element, atom.residue)
    changeAtomName(atom, name)
    atom.element = element
    if hasattr(atom, 'mol2type'):
        delattr(atom, 'mol2type')

    # if we only have one bond, correct its length
    if len(atom.primaryBonds()) == 1:
        neighbor = atom.primaryNeighbors()[0]
        newLength = bondLength(atom,
                               geometry,
                               neighbor.element,
                               a2info=(neighbor, numBonds))
        setBondLength(atom.primaryBonds()[0],
                      newLength,
                      movingSide="smaller side")

    if numBonds == len(atom.primaryBonds()):
        return changedAtoms

    from chimera.bondGeom import bondPositions
    coPlanar = None
    if geometry == 3 and len(atom.primaryBonds()) == 1:
        n = atom.primaryNeighbors()[0]
        if len(n.primaryBonds()) == 3:
            coPlanar = [
                nn.coord() for nn in n.primaryNeighbors() if nn != atom
            ]
    away = None
    if geometry == 4 and len(atom.primaryBonds()) == 1:
        n = atom.primaryNeighbors()[0]
        if len(n.primaryBonds()) > 1:
            nn = n.primaryNeighbors()[0]
            if nn == atom:
                nn = n.primaryNeighbors()[1]
            away = nn.coord()
    hydrogen = Element("H")
    positions = bondPositions(atom.coord(),
                              geometry,
                              bondLength(atom, geometry, hydrogen),
                              [n.coord() for n in atom.primaryNeighbors()],
                              coPlanar=coPlanar,
                              away=away)[:numBonds - len(atom.primaryBonds())]
    if autoClose:
        if len(atom.molecule.atoms) < 100:
            testAtoms = atom.molecule.atoms
        else:
            from CGLutil.AdaptiveTree import AdaptiveTree
            tree = AdaptiveTree(
                [a.coord().data() for a in atom.molecule.atoms],
                a.molecule.atoms, 2.5)
            testAtoms = tree.searchTree(atom.coord().data(), 5.0)
    else:
        testAtoms = []
    for pos in positions:
        for ta in testAtoms:
            if ta == atom:
                continue
            testLen = bondLength(ta, 1, hydrogen)
            testLen2 = testLen * testLen
            if (ta.coord() - pos).sqlength() < testLen2:
                bonder = ta
                # possibly knock off a hydrogen to
                # accomodate the bond...
                for bn in bonder.primaryNeighbors():
                    if bn.element.number > 1:
                        continue
                    if chimera.angle(atom.coord() - ta.coord(),
                                     bn.coord() - ta.coord()) > 45.0:
                        continue
                    if bn in testAtoms:
                        testAtoms.remove(bn)
                    atom.molecule.deleteAtom(bn)
                    break
                break
        else:
            bonder = addAtom(genAtomName(hydrogen, atom.residue),
                             hydrogen,
                             atom.residue,
                             pos,
                             bondedTo=atom)
            changedAtoms.append(bonder)
    return changedAtoms
Beispiel #17
0
    center = Point(coords)
    correction = position - center
    for r in residues:
        for a in r.atoms:
            a.setCoord(a.coord() + correction)
    from Midas import ksdssp
    ksdssp([model])
    if needFocus:
        chimera.runCommand("focus")
    return residues


from chimera import elements
elementRadius = {}
for i in range(len(chimera.elements.name)):
    element = Element(i)
    elementRadius[element] = 0.985 * Element.bondRadius(element)
elementRadius[elements.C] = 0.7622
elementRadius[elements.H] = 0.1869
elementRadius[elements.N] = 0.6854
elementRadius[elements.O] = 0.6454
elementRadius[elements.P] = 0.9527
elementRadius[elements.S] = 1.0428


class ParamError(ValueError):
    pass


def bondLength(a1, geom, e2, a2info=None):
    if e2.number == 1:
Beispiel #18
0
def hydPositions(heavy, includeLonePairs=False):
	"""Return list of positions for hydrogens attached to this atom.
	   If a hydrogen could be in one of several positions, don't
	   return any of those.
	"""

	# first, find known attached atoms
	bondedHeavys = []
	hyds = []
	for atom in heavy.primaryNeighbors():
		if atom.element.number > 1:
			bondedHeavys.append(atom)
		else:
			hyds.append(atom)
	
	# convert to Points
	hydLocs = []
	for hyd in hyds:
		hydLocs.append(hyd.xformCoord())
	
	if hydLocs and not includeLonePairs:
		# explicit hydrogens "win" over atom types
		return hydLocs

	if typeInfo.has_key(heavy.idatmType):
		info = typeInfo[heavy.idatmType]
		geom = info.geometry
		if includeLonePairs:
			subs = geom
		else:
			subs = info.substituents
		bondedLocs = hydLocs[:]
		for bHeavy in bondedHeavys:
			bondedLocs.append(bHeavy.xformCoord())
	else:
		return hydLocs
	
	knownSubs = len(bondedLocs)
	if knownSubs >= subs or knownSubs == 0:
		return hydLocs
	# above eliminates 'single' geometry
	
	if knownSubs == 1 and geom == tetrahedral:
		# rotamer
		return hydLocs
	
	maxSubs = geom
	if maxSubs - subs > 0:
		# the "empty" bond could be anywhere
		return hydLocs

	heavyLoc = heavy.xformCoord()
	bondLen = Element.bondLength(heavy.element, Element(1))

	if geom == planar:
		coPlanar = []
		for bHeavy in bondedHeavys:
			try:
				bhGeom = typeInfo[bHeavy.idatmType].geometry
			except KeyError:
				bhGeom = None
			if bhGeom != planar:
				continue
			for atom in bHeavy.primaryNeighbors():
				if atom != heavy:
					coPlanar.append(atom.xformCoord())
	else:
		coPlanar = None

	hydLocs = hydLocs + bondPositions(heavyLoc, geom, bondLen, bondedLocs,
							coPlanar=coPlanar)
	return hydLocs
Beispiel #19
0
    "Pa",
    "U",
    "Np",
    "Pu",
    "Am",
    "Cm",
    "Bk",
    "Cf",
    "Es",
    "Fm",  # 91 - 100
    "Md",
    "No",
    "Lr",  # 101 - 103
]

LP = Element(Element.LonePair)
H = Element(Element.H)
He = Element(Element.He)
Li = Element(Element.Li)
Be = Element(Element.Be)
B = Element(Element.B)
C = Element(Element.C)
N = Element(Element.N)
O = Element(Element.O)
F = Element(Element.F)
Ne = Element(Element.Ne)
Na = Element(Element.Na)
Mg = Element(Element.Mg)
Al = Element(Element.Al)
Si = Element(Element.Si)
P = Element(Element.P)
def _findDonors(model, dParams, limitedDonors, genericDonInfo):
	donAtoms = []
	donData = []
	stdDonors = {}
	for dp in dParams:
		groupKey, donorIndex, geomType, tauSym, argList, testDist = dp

		if groupKey:
			groups = findGroup(groupKey, [model])
		else:
			# generic donors
			groups = []
			for atom in model.atoms:
				if atom in stdDonors:
					continue
				if atom.element.number not in [7,8,16]:
					continue
				if limitedDonors \
				and atom not in limitedDonors:
					continue
				# oxygen, nitrogen, or sulfur
				try:
					expectBonds = typeInfo[
					  atom.idatmType].substituents
				except KeyError:
					expectBonds = 0
				numBonds = len(atom.primaryBonds())
				# screen out the partial terminal N that
				# AddH can leave, since the geometry is
				# problematic and the H direction isn't
				# really determined
				if atom.idatmType == "Npl" \
				and numBonds == 2 and 1 in [n.element.number
				for n in atom.primaryNeighbors()]:
					continue
				if numBonds < expectBonds:
					groups.append([atom])
					continue
				for bonded in atom.primaryNeighbors():
					if bonded.element.number == 1:
						groups.append([atom])
						break
			if verbose:
				for g in groups:
					print "generic donor:", g[0].oslIdent()
				
		if groups and geomType == thetaTau:
			# extend probe distance by H-bond length
			# so that all relevant acceptors will be found
			testDist = testDist + Element.bondLength(
					groups[0][donorIndex].element,
					Element(1))
		for group in groups:
			donorAtom = group[donorIndex]
			if limitedDonors \
			and donorAtom not in limitedDonors:
				continue
			if donorAtom in stdDonors:
				if groupKey != stdDonors[donorAtom] and not (
				# conflicts of non-ring groups with ring
				# groups not considered a problem (non-ring
				# groups "win")
				groupKey[0] in _ringFuncs and
				stdDonors[donorAtom][0] not in _ringFuncs):
					global _problem
					_problem = ("donor", donorAtom,
						stdDonors[donorAtom], groupKey)
				continue
			stdDonors[donorAtom] = groupKey
			donAtoms.append(donorAtom)
			donData.append((geomType, tauSym, argList, testDist))
	return donAtoms, donData
from chimera import Coord, Point
from chimera.bondGeom import tetrahedral, planar, linear, single, bondPositions
from chimera.idatm import *
from AddH import newHydrogen, findNearest, roomiest, bondWithHLength, \
       findRotamerNearest
from math import sin, cos, pi, sqrt
from chimera import Element
Element_H = Element(1)

sin5475 = sin(pi * 54.75 / 180.0)
cos5475 = cos(pi * 54.75 / 180.0)


def addHydrogens(atom, bondingInfo, namingSchema, totalHydrogens, idatmType,
                 invert, coordinations):
    away = away2 = planar = None
    geom = bondingInfo.geometry
    substs = bondingInfo.substituents
    curBonds = len(atom.primaryBonds())
    needed = substs - curBonds
    if needed <= 0:
        return
    atPos = atom.xformCoord()
    exclude = coordinations + atom.primaryNeighbors()
    if geom == 3 and curBonds == 1:
        bonded = atom.primaryNeighbors()[0]
        grandBonded = bonded.primaryNeighbors()
        grandBonded.remove(atom)
        if len(grandBonded) < 3:
            planar = [a.xformCoord() for a in grandBonded]
    if geom == 4 and not exclude:
Beispiel #22
0
        line = gl()
        retList = []
        while line != marker:
            retList.append(line)
            line = gl()
            if not line:
                raise IOError, "EOF while reading to marker"\
                 " '%s'"% marker
        return retList

    def rewind(self):
        self.f.seek(0)


from chimera import Element
O = Element('O')
N = Element('N')
C = Element('C')
H = Element('H')
S = Element('S')
Cu = Element('Cu')
Fe = Element('Fe')
Zn = Element('Zn')
Mg = Element('Mg')
Ca = Element('Ca')
Ar = Element('Ar')
F = Element('F')
Cl = Element('Cl')
Br = Element('Br')
Na = Element('Na')
Si = Element('Si')
Beispiel #23
0
def readSDF(fileName, identifyAs=None):
    from OpenSave import osOpen
    from chimera import UserError, Molecule, Element, openModels, replyobj
    from chimera import Coord
    state = "init"
    f = osOpen(fileName)
    mols = []
    nonblank = False
    for l in f:
        line = l.strip()
        nonblank = nonblank or line
        if state == "init":
            state = "post header 1"
            molName = line
        elif state == "post header 1":
            state = "post header 2"
        elif state == "post header 2":
            state = "counts"
        elif state == "counts":
            if not line:
                break
            state = "atoms"
            serial = 1
            anums = {}
            atoms = []
            try:
                numAtoms = int(l[:3].strip())
                numBonds = int(l[3:6].strip())
            except ValueError:
                raise UserError("Atom/bond counts line of"
                                " MOL/SDF file '%s' is botched: '%s'" %
                                (fileName, l))
            m = Molecule()
            mols.append(m)
            if identifyAs:
                m.name = identifyAs
            else:
                from chimera.misc import isInformativeName
                mn = molName.strip()
                if isInformativeName(mn):
                    m.name = mn
                else:
                    import os.path
                    m.name = os.path.split(fileName)[-1]
            r = m.newResidue("UNK", " ", 1, " ")
        elif state == "atoms":
            numAtoms -= 1
            if numAtoms == 0:
                if numBonds:
                    state = "bonds"
                else:
                    state = "properties"
            try:
                x = float(l[:10].strip())
                y = float(l[10:20].strip())
                z = float(l[21:30].strip())
                elem = l[31:34].strip()
            except ValueError:
                raise UserError("Atom line of MOL/SDF file"
                                " '%s' is not x y z element...: '%s'" %
                                (fileName, l))
            element = Element(elem)
            if element.number == 0:
                # lone pair or somesuch
                atoms.append(None)
                continue
            anum = anums.get(element.name, 0) + 1
            anums[element.name] = anum
            a = m.newAtom("%s%d" % (element.name, anum), element)
            atoms.append(a)
            r.addAtom(a)
            a.setCoord(Coord(x, y, z))
            a.serialNumber = serial
            serial += 1
        elif state == "bonds":
            numBonds -= 1
            if numBonds == 0:
                state = "properties"
            try:
                a1index = int(l[:3].strip())
                a2index = int(l[3:6].strip())
                order = int(l[6:9].strip())
            except ValueError:
                raise UserError("Bond line of MOL/SDF file"
                                " '%s' is not a1 a2 order...: '%s'" %
                                (fileName, l))
            a1 = atoms[a1index - 1]
            a2 = atoms[a2index - 1]
            if not a1 or not a2:
                continue
            m.newBond(a1, a2).order = order
        elif state == "properties":
            if not m.atoms:
                raise UserError("No atoms found for compound"
                                " '%s' in MOL/SDF file '%s'" %
                                (m.name, fileName))
            if line.split() == ["M", "END"]:
                state = "data"
        elif state == "data":
            if line == "$$$$":
                nonblank = False
                state = "init"
    f.close()
    if nonblank and state not in ["data", "init"]:
        if mols:
            replyobj.warning("Extraneous text after final $$$$"
                             " in MOL/SDF file '%s'" % fileName)
        else:
            raise UserError("Unexpected end of file (parser state:"
                            " %s) in MOL/SDF file '%s'" % (state, fileName))
    return mols