def restorePseudoBondGroups(pbInfo): for category, groupInfo in pbInfo.items(): modelID, attrs, bonds, grpColor = groupInfo grp = getPseudoBondGroup(category, modelID) for attr, val in attrs.items(): if attr == "wireStipple": if val[0]: grp.lineType = chimera.Dash continue setattr(grp, attr, val) grp.color = getColor(grpColor) for bondInfo in bonds: osl1, osl2, bondColor, labelColor, attrs = bondInfo try: a1 = oslLookup(osl1) a2 = oslLookup(osl2) except ValueError: continue pb = grp.newPseudoBond(a1, a2) v1._oslItemMap[getOSL(pb)] = pb if bondColor: pb.color = getColor(bondColor) if labelColor: pb.labelColor = getColor(labelColor) for attr, val in attrs.items(): setattr(pb, attr, val)
def _addGroup(category, color): g = getPseudoBondGroup(category, modelID=-2, hidden=1) if not hasattr(g, 'fixedLabels'): def _setColor(color=color, g=g): from chimera.colorTable import getColorByName g.color = getColorByName(color) g.lineType = chimera.Dash # delay setting the color until colors are set up chimera.registerPostGraphicsFunc(_setColor) g.fixedLabels = 0 g.updateCallbacks = [] return g
def processClashes(residue, rotamers, overlap, hbondAllow, scoreMethod, makePBs, pbColor, pbWidth, ignoreOthers): testAtoms = [] for rot in rotamers: testAtoms.extend(rot.atoms) from DetectClash import detectClash clashInfo = detectClash(testAtoms, clashThreshold=overlap, interSubmodel=True, hbondAllowance=hbondAllow) if makePBs: from chimera.misc import getPseudoBondGroup from DetectClash import groupName pbg = getPseudoBondGroup(groupName) pbg.deleteAll() pbg.lineWidth = pbWidth pbg.color = pbColor else: import DetectClash DetectClash.nukeGroup() resAtoms = set(residue.atoms) for rot in rotamers: score = 0 for ra in rot.atoms: if ra.name in ("CA", "N", "CB"): # any clashes of CA/N/CB are already clashes of # base residue (and may mistakenly be thought # to clash with "bonded" atoms in nearby # residues continue if ra not in clashInfo: continue for ca, clash in clashInfo[ra].items(): if ca in resAtoms: continue if ignoreOthers \ and ca.molecule.id != residue.molecule.id: continue if scoreMethod == "num": score += 1 else: score += clash if makePBs: pbg.newPseudoBond(ra, ca) rot.clashScore = score if scoreMethod == "num": return "%2d" return "%4.2f"
def restorePseudoBondGroups(pbInfo): from chimera.misc import getPseudoBondGroup mgr = chimera.PseudoBondMgr.mgr() sm = globals.sessionMap groups = [] for category, id, color, showStubBonds, lineWidth, stickScale, \ lineType, bondInfo in zip( pbInfo['category'], pbInfo['id'], expandSummary(pbInfo['color']), expandSummary(pbInfo['showStubBonds']), expandSummary(pbInfo['lineWidth']), expandSummary(pbInfo['stickScale']), expandSummary(pbInfo['lineType']), pbInfo['bondInfo'] ): g = getPseudoBondGroup(category, id) groups.append(g) g.color = getColor(color) g.showStubBonds = showStubBonds g.lineWidth = lineWidth g.stickScale = stickScale g.lineType = lineType for atoms, drawMode, display, halfbond, label, color, \ labelColor in zip( bondInfo['atoms'], expandSummary(bondInfo['drawMode']), expandSummary(bondInfo['display']), expandSummary(bondInfo['halfbond']), expandSummary(bondInfo['label']), expandSummary(bondInfo['color']), expandSummary(bondInfo['labelColor']) ): a1, a2 = [idLookup(a) for a in atoms] pb = g.newPseudoBond(a1, a2) pb.drawMode = drawMode pb.display = display pb.halfbond = halfbond pb.label = label pb.color = getColor(color) pb.labelColor = getColor(labelColor) sm[len(sm)] = pb for g in groups: sm[len(sm)] = g
def restorePseudoBondGroups(pbInfo): from chimera.misc import getPseudoBondGroup mgr = chimera.PseudoBondMgr.mgr() for category, id, color, showStubBonds, lineWidth, stickScale, \ wireStipple, bondInfo in zip( pbInfo['category'], pbInfo['id'], expandSummary(pbInfo['color']), expandSummary(pbInfo['showStubBonds']), expandSummary(pbInfo['lineWidth']), expandSummary(pbInfo['stickScale']), expandSummary(pbInfo['wireStipple']), pbInfo['bondInfo'] ): g = getPseudoBondGroup(category, id) g.color = getColor(color) g.showStubBonds = showStubBonds g.lineWidth = lineWidth g.stickScale = stickScale if wireStipple[0]: g.lineType = chimera.Dash for atoms, drawMode, display, halfbond, label, color, \ labelColor in zip( bondInfo['atoms'], expandSummary(bondInfo['drawMode']), expandSummary(bondInfo['display']), expandSummary(bondInfo['halfbond']), expandSummary(bondInfo['label']), expandSummary(bondInfo['color']), expandSummary(bondInfo['labelColor']) ): a1, a2 = [idLookup(a) for a in atoms] pb = g.newPseudoBond(a1, a2) pb.drawMode = drawMode pb.display = display pb.halfbond = halfbond pb.label = label pb.color = getColor(color) pb.labelColor = getColor(labelColor)
def draw_bond_orders(molecule, error_spring=True): pbg = getPseudoBondGroup('Bond order errors', associateWith=[molecule]) pbg.lineWidth, pbg.lineType, pbg.color = 2, 1, getColorByName('red') def draw_spring(bond): pbg = getPseudoBondGroup('Bond order errors') pb = pbg.newPseudoBond(*bond.atoms) pb.drawMode = 2 pb.radius = bond.radius + 0.1 for bond in molecule.bonds: order = getattr(bond, 'order', None) if not order: print('! Invalid order for bond', bond) if error_spring: draw_spring(bond) continue if not hasattr(bond, '_oldradius'): bond._oldradius = bond.radius bond.radius = bond._oldradius * order * 0.5 return pbg
def cmdDetectClash(testAtoms, overlapCutoff=defaults[CLASH_THRESHOLD], hbondAllowance=defaults[HBOND_ALLOWANCE], test="others", setAttrs=defaults[ACTION_ATTR], selectClashes=defaults[ACTION_SELECT], colorClashes=defaults[ACTION_COLOR], clashColor=defColors[CLASH_COLOR], nonclashColor=defColors[NONCLASH_COLOR], makePseudobonds=defaults[ACTION_PSEUDOBONDS], pbColor=defColors[PB_COLOR], lineWidth=defaults[PB_WIDTH], bondSeparation=defaults[BOND_SEPARATION], saveFile=None, namingStyle=None, ignoreIntraRes=defaults[IGNORE_INTRA_RES], interSubmodel=False, log=defaults[ACTION_REPLYLOG], summary=True, continuous=False): global _continuousID from Midas import MidasError if continuous: if setAttrs or saveFile != None or log: raise MidasError("log/setAttrs/saveFile not allowed" " with continuous detection") if _continuousID == None: from inspect import getargvalues, currentframe argNames, fArgs, fKw, frameDict = getargvalues(currentframe()) callData = [frameDict[an] for an in argNames] def preCB(trigName, myData, changes): if 'transformation change' in changes.reasons: return _motionCB(myData) _continuousID = chimera.triggers.addHandler( 'OpenState', preCB, callData) elif _continuousID != None: chimera.triggers.deleteHandler('OpenState', _continuousID) _continuousID = None if isinstance(test, basestring): if test.startswith("other"): test = "others" elif test not in ('self', 'model'): # atom spec from chimera.specifier import evalSpec try: test = evalSpec(test).atoms() except: raise MidasError("Could not parse atom spec '%s'" % test) clashes = detectClash(testAtoms, test=test, hbondAllowance=hbondAllowance, clashThreshold=overlapCutoff, bondSeparation=bondSeparation, intraRes=not ignoreIntraRes, interSubmodel=interSubmodel) if selectClashes: chimera.selection.setCurrent(clashes.keys()) if test == "self": outputGrouping = set() else: outputGrouping = testAtoms info = (overlapCutoff, hbondAllowance, bondSeparation, ignoreIntraRes, clashes, outputGrouping) if log: import sys # put a separator in the Reply Log print >> sys.stdout, "" _fileOutput(sys.stdout, info, namingStyle=namingStyle) if saveFile == '-': from FindHBond.MolInfoDialog import SaveMolInfoDialog SaveMolInfoDialog(info, _fileOutput, initialfile="overlaps", title="Choose Overlap Info Save File", historyID="Overlap info") elif saveFile is not None: _fileOutput(saveFile, info, namingStyle=namingStyle) if summary == True: def _summary(msg): from chimera import replyobj replyobj.status(msg + '\n') replyobj.info(msg + '\n') summary = _summary if summary: if clashes: total = 0 for clashList in clashes.values(): total += len(clashList) summary("%d contacts" % (total / 2)) else: summary("No contacts") if not (setAttrs or colorClashes or makePseudobonds): nukeGroup() return clashes if test in ("others", "model"): atoms = [ a for m in chimera.openModels.list(modelTypes=[chimera.Molecule]) for a in m.atoms ] else: atoms = testAtoms if setAttrs: # delete the attribute in _all_ atoms... for m in chimera.openModels.list(modelTypes=[chimera.Molecule]): for a in m.atoms: if hasattr(a, attrName): delattr(a, attrName) for a in atoms: if a in clashes: clashVals = clashes[a].values() clashVals.sort() setattr(a, attrName, clashVals[-1]) if colorClashes: for a in atoms: a.surfaceColor = None if a in clashes: a.color = clashColor else: a.color = nonclashColor if makePseudobonds: from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup(groupName) pbg.deleteAll() pbg.lineWidth = lineWidth pbg.color = pbColor seen = set() for a in atoms: if a not in clashes: continue seen.add(a) for clasher in clashes[a].keys(): if clasher in seen: continue pbg.newPseudoBond(a, clasher) else: nukeGroup() return clashes
def combine(mols, refMol, newChainIDs=True, log=False, returnMapping=False): from chimera import replyobj # figure out residue chain/number remapping origChainIDs = {} numChains = 0 minNums = {} maxNums = {} for m in mols: seenIDs = set() for r in m.residues: chainID = r.id.chainId num = r.id.position key = (m, chainID) if key in minNums: if num > maxNums[key]: maxNums[key] = num elif num < minNums[key]: minNums[key] = num else: minNums[key] = maxNums[key] = num if chainID in seenIDs: continue numChains += 1 seenIDs.add(chainID) origChainIDs.setdefault(chainID, []).append(m) resMap = {} if newChainIDs: if numChains > 62: raise CombineError("More than 62 chains; cannot" " uniquely identify with single characters") from string import uppercase, lowercase, digits possibleIDs = uppercase + lowercase + digits usedChainIDs = set(origChainIDs.keys()) chainIDmap = {} for chainID, idMols in origChainIDs.items(): if len(chainID) > 1: continue chainIDmap[(idMols[0], chainID)] = chainID usedChainIDs.add(chainID) for m in idMols[1:]: for c in possibleIDs: if c not in usedChainIDs: break if log: replyobj.info("Remapping %s chain %s" " to %s\n" % (m, chainID, c)) usedChainIDs.add(c) chainIDmap[(m, chainID)] = c for m in mols: for r in m.residues: chainID = r.id.chainId if len(chainID) > 1: continue resMap[r] = (chainIDmap[(m, chainID)], r.id.position) # handle renumbering for all chains if newChainIDs False, # otherwise just water/het chains offsets = {} for chainID, idMols in origChainIDs.items(): if newChainIDs and len(chainID) < 2: continue minMaxs = [] for m in idMols: mmin = minNums[(m, chainID)] mmax = maxNums[(m, chainID)] for omin, omax in minMaxs: if omin < mmin < omax or omin < mmax < omax: gmax = max([mm[1] for mm in minMaxs]) offset = gmax - mmin + 1 break else: offset = 0 offsets[(m, chainID)] = offset minMaxs.append((mmin+offset, mmax+offset)) if log and offset: replyobj.info("Adding %d to %s chain %s" " numbering\n" % (offset, m, chainID)) for m in mols: for r in m.residues: chainID = r.id.chainId try: offset = offsets[(m, chainID)] except KeyError: continue resMap[r] = (chainID, r.id.position + offset) # combine... from chimera import Atom, Bond, Residue, Molecule combined = Molecule() combined.name = "combination" from SimpleSession.save import optionalAttributes from chimera.molEdit import addAtom atomAttrs = optionalAttributes[Atom].keys() + ['color', 'vdwColor', 'labelColor', 'surfaceColor', 'drawMode', 'display', 'label', 'radius', 'surfaceDisplay', 'surfaceCategory', 'surfaceOpacity', 'vdw'] bondAttrs = optionalAttributes[Bond].keys() + ['drawMode', 'display', 'radius'] resAttrs = optionalAttributes[Residue].keys() + ['ribbonColor', 'labelColor', 'isHelix', 'isSheet', 'isTurn', 'ribbonDrawMode', 'ribbonDisplay', 'label', 'isHet'] serial = 1 atomMap = {} for m in mols: if m.openState == refMol.openState: xform = None else: xform = refMol.openState.xform xform.invert() for r in m.residues: chainID, pos = resMap[r] nr = combined.newResidue(r.type, chainID, pos, r.id.insertionCode) for attrName in resAttrs: try: setattr(nr, attrName, getattr(r, attrName)) except AttributeError: continue ratoms = r.atoms ratoms.sort(lambda a1, a2: cmp(a1.coordIndex, a2.coordIndex)) for a in ratoms: if xform is None: crd = a.coord() else: crd = xform.apply(a.xformCoord()) na = addAtom(a.name, a.element, nr, crd, serialNumber=serial) na.altLoc = a.altLoc atomMap[a] = na serial += 1 for attrName in atomAttrs: try: setattr(na, attrName, getattr(a, attrName)) except AttributeError: continue for b in m.bonds: a1, a2 = b.atoms nb = combined.newBond(atomMap[a1], atomMap[a2]) for attrName in bondAttrs: try: setattr(nb, attrName, getattr(b, attrName)) except AttributeError: continue consensusAttrs = ['color', 'display', 'lineWidth', 'pointSize', 'stickScale', 'surfaceOpacity', 'ballScale', 'vdwDensity', 'autochain', 'ribbonHidesMainchain'] for attrName in consensusAttrs: consensusVal = None for m in mols: val = getattr(m, attrName) if consensusVal == None: consensusVal = val elif val != consensusVal: break else: setattr(combined, attrName, consensusVal) associatedModels = set() for m in mols: associatedModels.update(m.associatedModels()) from chimera import PseudoBondMgr for opbg in PseudoBondMgr.mgr().pseudoBondGroups: if opbg in associatedModels: if opbg.category.startswith("internal-chain-"): continue assert(opbg.category.startswith("coordination complex")) from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup("coordination complexes of %s" % combined.name, associateWith=[combined]) for attrName in ['color', 'showStubBonds', 'lineWidth', 'stickScale', 'lineType']: setattr(pbg, attrName, getattr(opbg, attrName)) else: pbg = opbg for opb in opbg.pseudoBonds: oa1, oa2 = opb.atoms na1 = atomMap.get(oa1, oa1) na2 = atomMap.get(oa2, oa2) if oa1 == na1 and oa2 == na2: continue pb = pbg.newPseudoBond(na1, na2) for attrName in ['drawMode', 'display', 'halfbond', 'label', 'color', 'labelColor']: setattr(pb, attrName, getattr(opb, attrName)) if returnMapping: return atomMap, combined return combined
def draw_spring(bond): pbg = getPseudoBondGroup('Bond order errors') pb = pbg.newPseudoBond(*bond.atoms) pb.drawMode = 2 pb.radius = bond.radius + 0.1
def combine(mols, refMol, newChainIDs=True, log=False, returnMapping=False): from chimera import replyobj # figure out residue chain/number remapping origChainIDs = {} numChains = 0 minNums = {} maxNums = {} for m in mols: seenIDs = set() for r in m.residues: chainID = r.id.chainId num = r.id.position key = (m, chainID) if key in minNums: if num > maxNums[key]: maxNums[key] = num elif num < minNums[key]: minNums[key] = num else: minNums[key] = maxNums[key] = num if chainID in seenIDs: continue numChains += 1 seenIDs.add(chainID) origChainIDs.setdefault(chainID, []).append(m) resMap = {} if newChainIDs: if numChains > 62: raise CombineError("More than 62 chains; cannot" " uniquely identify with single characters") from string import uppercase, lowercase, digits possibleIDs = uppercase + lowercase + digits usedChainIDs = set(origChainIDs.keys()) chainIDmap = {} for chainID, idMols in origChainIDs.items(): if len(chainID) > 1: continue chainIDmap[(idMols[0], chainID)] = chainID usedChainIDs.add(chainID) for m in idMols[1:]: for c in possibleIDs: if c not in usedChainIDs: break if log: replyobj.info("Remapping %s chain %s" " to %s\n" % (m, chainID, c)) usedChainIDs.add(c) chainIDmap[(m, chainID)] = c for m in mols: for r in m.residues: chainID = r.id.chainId if len(chainID) > 1: continue resMap[r] = (chainIDmap[(m, chainID)], r.id.position) # handle renumbering for all chains if newChainIDs False, # otherwise just water/het chains offsets = {} for chainID, idMols in origChainIDs.items(): if newChainIDs and len(chainID) < 2: continue minMaxs = [] for m in idMols: mmin = minNums[(m, chainID)] mmax = maxNums[(m, chainID)] for omin, omax in minMaxs: if omin < mmin < omax or omin < mmax < omax: gmax = max([mm[1] for mm in minMaxs]) offset = gmax - mmin + 1 break else: offset = 0 offsets[(m, chainID)] = offset minMaxs.append((mmin + offset, mmax + offset)) if log and offset: replyobj.info("Adding %d to %s chain %s" " numbering\n" % (offset, m, chainID)) for m in mols: for r in m.residues: chainID = r.id.chainId try: offset = offsets[(m, chainID)] except KeyError: continue resMap[r] = (chainID, r.id.position + offset) # combine... from chimera import Atom, Bond, Residue, Molecule combined = Molecule() combined.name = "combination" from SimpleSession.save import optionalAttributes from chimera.molEdit import addAtom atomAttrs = optionalAttributes[Atom].keys() + [ 'color', 'vdwColor', 'labelColor', 'surfaceColor', 'drawMode', 'display', 'label', 'radius', 'surfaceDisplay', 'surfaceCategory', 'surfaceOpacity', 'vdw' ] bondAttrs = optionalAttributes[Bond].keys() + [ 'drawMode', 'display', 'radius' ] resAttrs = optionalAttributes[Residue].keys() + [ 'ribbonColor', 'labelColor', 'isHelix', 'isSheet', 'isTurn', 'ribbonDrawMode', 'ribbonDisplay', 'label', 'isHet' ] serial = 1 atomMap = {} for m in mols: if m.openState == refMol.openState: xform = None else: xform = refMol.openState.xform xform.invert() for r in m.residues: chainID, pos = resMap[r] nr = combined.newResidue(r.type, chainID, pos, r.id.insertionCode) for attrName in resAttrs: try: setattr(nr, attrName, getattr(r, attrName)) except AttributeError: continue ratoms = r.atoms ratoms.sort(lambda a1, a2: cmp(a1.coordIndex, a2.coordIndex)) for a in ratoms: if xform is None: crd = a.coord() else: crd = xform.apply(a.xformCoord()) na = addAtom(a.name, a.element, nr, crd, serialNumber=serial) na.altLoc = a.altLoc atomMap[a] = na serial += 1 for attrName in atomAttrs: try: setattr(na, attrName, getattr(a, attrName)) except AttributeError: continue for b in m.bonds: a1, a2 = b.atoms nb = combined.newBond(atomMap[a1], atomMap[a2]) for attrName in bondAttrs: try: setattr(nb, attrName, getattr(b, attrName)) except AttributeError: continue consensusAttrs = [ 'color', 'display', 'lineWidth', 'pointSize', 'stickScale', 'surfaceOpacity', 'ballScale', 'vdwDensity', 'autochain', 'ribbonHidesMainchain' ] for attrName in consensusAttrs: consensusVal = None for m in mols: val = getattr(m, attrName) if consensusVal == None: consensusVal = val elif val != consensusVal: break else: setattr(combined, attrName, consensusVal) associatedModels = set() for m in mols: associatedModels.update(m.associatedModels()) from chimera import PseudoBondMgr for opbg in PseudoBondMgr.mgr().pseudoBondGroups: if opbg in associatedModels: if opbg.category.startswith("internal-chain-"): continue assert (opbg.category.startswith("coordination complex")) from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup("coordination complexes of %s" % combined.name, associateWith=[combined]) for attrName in [ 'color', 'showStubBonds', 'lineWidth', 'stickScale', 'lineType' ]: setattr(pbg, attrName, getattr(opbg, attrName)) else: pbg = opbg for opb in opbg.pseudoBonds: oa1, oa2 = opb.atoms na1 = atomMap.get(oa1, oa1) na2 = atomMap.get(oa2, oa2) if oa1 == na1 and oa2 == na2: continue pb = pbg.newPseudoBond(na1, na2) for attrName in [ 'drawMode', 'display', 'halfbond', 'label', 'color', 'labelColor' ]: setattr(pb, attrName, getattr(opb, attrName)) if returnMapping: return atomMap, combined return combined
def processHbonds(residue, rotamers, drawHbonds, bondColor, lineWidth, relax, distSlop, angleSlop, twoColors, relaxColor, groupName, ignoreOtherModels, cacheDA=False): from FindHBond import findHBonds if ignoreOtherModels: targetModels = [residue.molecule] + rotamers else: targetModels = chimera.openModels.list( modelTypes=[chimera.Molecule]) + rotamers if relax and twoColors: color = relaxColor else: color = bondColor hbonds = dict.fromkeys( findHBonds(targetModels, intramodel=False, distSlop=distSlop, angleSlop=angleSlop, cacheDA=True), color) if relax and twoColors: hbonds.update( dict.fromkeys(findHBonds(targetModels, intramodel=False), bondColor)) backboneNames = set(['CA', 'C', 'N', 'O']) # invalid H-bonds: involving residue side chain or rotamer backbone invalidAtoms = set( [ra for ra in residue.atoms if ra.name not in backboneNames]) invalidAtoms.update([ ra for rot in rotamers for ra in rot.atoms if ra.name in backboneNames ]) rotAtoms = set( [ra for rot in rotamers for ra in rot.atoms if ra not in invalidAtoms]) for rot in rotamers: rot.numHbonds = 0 if drawHbonds: from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup(groupName) pbg.deleteAll() pbg.lineWidth = lineWidth elif groupName: nukeGroup(groupName) for hb, color in hbonds.items(): d, a = hb if (d in rotAtoms) == (a in rotAtoms): # only want rotamer to non-rotamer continue if d in invalidAtoms or a in invalidAtoms: continue if d in rotAtoms: rot = d.molecule else: rot = a.molecule rot.numHbonds += 1 if drawHbonds: pb = pbg.newPseudoBond(d, a) pb.color = color
def createHBonds(models=None, intramodel=True, intermodel=True, relax=True, distSlop=recDistSlop, angleSlop=recAngleSlop, twoColors=False, selRestrict=None, lineWidth=1.0, saveFile=None, batch=False, interSubmodel=False, makePseudobonds=True, retainCurrent=False, reveal=False, namingStyle=None, log=False, cacheDA=None, color=(0.0, 0.8, 0.9, 1.0), slopColor=(0.95, 0.5, 0.0, 1.0)): """Wrapper to be called by gui and command line. Use findHBonds for other programming applications. """ inColors = (color, slopColor) outColors = [] for c in inColors: if isinstance(c, basestring): from chimera.colorTable import getColorByName try: outColors.append(getColorByName(c)) except KeyError: raise "No known color named '%s'" % c elif isinstance(c, tuple): oc = chimera.MaterialColor() oc.ambientDiffuse = c[:3] if len(c) > 3: oc.opacity = c[-1] outColors.append(oc) else: outColors.append(c) bondColor, slopColor = outColors donors = acceptors = None if selRestrict is not None: selAtoms = currentAtoms(asDict=True) if not selAtoms: if batch: return raise UserError("No atoms in selection.") if (not intermodel or selRestrict == "both") and models is None: # intramodel only or both ends in selection models = currentMolecules() if selRestrict == "both": # both ends in selection donors = acceptors = selAtoms if models is None: models = chimera.openModels.list(modelTypes=[chimera.Molecule]) if not relax: distSlop = angleSlop = 0.0 if cacheDA == None: # cache trajectories by default cacheDA = len(models) == 1 and len(models[0].coordSets) > 1 hbonds = findHBonds(models, intermodel=intermodel, intramodel=intramodel, distSlop=distSlop, angleSlop=angleSlop, donors=donors, acceptors=acceptors, interSubmodel=interSubmodel, cacheDA=cacheDA) if selRestrict and donors == None: hbonds = _filterBySel(hbonds, selAtoms, selRestrict) outputInfo = (intermodel, intramodel, relax, distSlop, angleSlop, models, hbonds) if log: import sys # provide a separator from other output print>>sys.stdout, "" _fileOutput(sys.stdout, outputInfo, namingStyle) if saveFile == '-': from MolInfoDialog import SaveMolInfoDialog SaveMolInfoDialog(outputInfo, _fileOutput, initialfile="hbond.info", title="Choose H-Bond Save File", historyID="H-bond info") elif saveFile is not None: _fileOutput(saveFile, outputInfo, namingStyle) replyobj.status("%d hydrogen bonds found\n" % len(hbonds), log=1, blankAfter=120) if not makePseudobonds: return if twoColors: # color relaxed constraints differently precise = findHBonds(models, intermodel=intermodel, intramodel=intramodel, donors=donors, acceptors=acceptors, interSubmodel=interSubmodel, cacheDA=cacheDA) if selRestrict and donors == None: precise = _filterBySel(precise, selAtoms, selRestrict) # give another opportunity to read the result... replyobj.status("%d hydrogen bonds found\n" % len(hbonds), blankAfter=120) from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup("hydrogen bonds", issueHint=True) if not retainCurrent: pbg.deleteAll() pbg.lineWidth = lineWidth for don, acc in hbonds: if don.associated(acc, "hydrogen bonds"): continue pb = pbg.newPseudoBond(don, acc) if twoColors: if (don, acc) in precise: color = bondColor else: color = slopColor else: color = bondColor pb.color = color if reveal: for end in [don, acc]: if end.display: continue for ea in end.residue.oslChildren(): ea.display = True
from chimera import runCommand runCommand("findhbond linewidth 2 color yellow") from chimera.misc import getPseudoBondGroup hbonds = len(getPseudoBondGroup("hydrogen bonds").pseudoBonds) runCommand("2dlabels change mylabel text '%d H-bonds'" % hbonds)
def cmdDetectClash(testAtoms, overlapCutoff=defaults[CLASH_THRESHOLD], hbondAllowance=defaults[HBOND_ALLOWANCE], test="others", setAttrs=defaults[ACTION_ATTR], selectClashes= defaults[ACTION_SELECT], colorClashes=defaults[ACTION_COLOR], clashColor=defColors[CLASH_COLOR], nonclashColor= defColors[NONCLASH_COLOR], makePseudobonds= defaults[ACTION_PSEUDOBONDS], pbColor=defColors[PB_COLOR], lineWidth=defaults[PB_WIDTH], bondSeparation= defaults[BOND_SEPARATION], saveFile=None, namingStyle=None, ignoreIntraRes=defaults[IGNORE_INTRA_RES], interSubmodel=False, log=defaults[ACTION_REPLYLOG], summary=True, continuous=False): global _continuousID from Midas import MidasError if continuous: if setAttrs or saveFile != None or log: raise MidasError("log/setAttrs/saveFile not allowed" " with continuous detection") if _continuousID == None: from inspect import getargvalues, currentframe argNames, fArgs, fKw, frameDict = getargvalues( currentframe()) callData = [frameDict[an] for an in argNames] def preCB(trigName, myData, changes): if 'transformation change' in changes.reasons: return _motionCB(myData) _continuousID = chimera.triggers.addHandler( 'OpenState', preCB, callData) elif _continuousID != None: chimera.triggers.deleteHandler('OpenState', _continuousID) _continuousID = None if isinstance(test, basestring): if test.startswith("other"): test = "others" elif test not in ('self', 'model'): # atom spec from chimera.specifier import evalSpec try: test = evalSpec(test).atoms() except: raise MidasError("Could not parse atom spec '%s'" % test) clashes = detectClash(testAtoms, test=test, hbondAllowance=hbondAllowance, clashThreshold=overlapCutoff, bondSeparation=bondSeparation, intraRes=not ignoreIntraRes, interSubmodel=interSubmodel) if selectClashes: chimera.selection.setCurrent(clashes.keys()) if test == "self": outputGrouping = set() else: outputGrouping = testAtoms info = (overlapCutoff, hbondAllowance, bondSeparation, ignoreIntraRes, clashes, outputGrouping) if log: import sys # put a separator in the Reply Log print>>sys.stdout, "" _fileOutput(sys.stdout, info, namingStyle=namingStyle) if saveFile == '-': from FindHBond.MolInfoDialog import SaveMolInfoDialog SaveMolInfoDialog(info, _fileOutput, initialfile="overlaps", title="Choose Overlap Info Save File", historyID="Overlap info") elif saveFile is not None: _fileOutput(saveFile, info, namingStyle=namingStyle) if summary == True: def _summary(msg): from chimera import replyobj replyobj.status(msg + '\n') replyobj.info(msg + '\n') summary = _summary if summary: if clashes: total = 0 for clashList in clashes.values(): total += len(clashList) summary("%d contacts" % (total/2)) else: summary("No contacts") if not (setAttrs or colorClashes or makePseudobonds): nukeGroup() return clashes if test in ("others", "model"): atoms = [a for m in chimera.openModels.list( modelTypes=[chimera.Molecule]) for a in m.atoms] else: atoms = testAtoms if setAttrs: # delete the attribute in _all_ atoms... for m in chimera.openModels.list(modelTypes=[chimera.Molecule]): for a in m.atoms: if hasattr(a, attrName): delattr(a, attrName) for a in atoms: if a in clashes: clashVals = clashes[a].values() clashVals.sort() setattr(a, attrName, clashVals[-1]) if colorClashes: for a in atoms: a.surfaceColor = None if a in clashes: a.color = clashColor else: a.color = nonclashColor if makePseudobonds: from chimera.misc import getPseudoBondGroup pbg = getPseudoBondGroup(groupName) pbg.deleteAll() pbg.lineWidth = lineWidth pbg.color = pbColor seen = set() for a in atoms: if a not in clashes: continue seen.add(a) for clasher in clashes[a].keys(): if clasher in seen: continue pbg.newPseudoBond(a, clasher) else: nukeGroup() return clashes