示例#1
0
def align_molecule():

    # TODO: Not ported.
    from chimera import selection
    atoms = selection.currentAtoms(ordered=True)
    mols = set([a.molecule for a in atoms])
    if len(mols) != 1:
        return
    mol = mols.pop()
    molxf = mol.openState.xform
    from Molecule import atom_positions
    axyz = atom_positions(atoms, molxf)
    from numpy import roll, float32, float64
    from Matrix import xform_matrix, xform_points
    from chimera.match import matchPositions
    xflist = []
    for mset in cage_marker_sets():
        for p in polygons(mset):
            if p.n == len(atoms):
                c = p.center()
                vxyz = [p.vertex_xyz(m) for m in p.vertices]
                exyz = (0.5 * (vxyz + roll(vxyz, 1, axis=0))).astype(float32)
                xform_points(exyz, mset.transform(), molxf)
                xf, rms = matchPositions(exyz.astype(float64),
                                         axyz.astype(float64))
                xflist.append(xf)

    molxf.multiply(xflist[0])
    mol.openState.xform = molxf

    import MultiScale
    mm = MultiScale.multiscale_manager()
    tflist = [xform_matrix(xf) for xf in xflist]
    mm.molecule_multimer(mol, tflist)
示例#2
0
    def update(self, trigName, myData, changes):
        # print >> __stdout__, "update", trigName, myData, dir(changes), changes.modified
        # coordSet = list(changes.modified)[0]
        # print >> __stdout__, len(coordSet.coords())
        # print >> __stdout__, dir(coordSet)
        # print >> __stdout__, "update"

        # atoms = []
        # for selection in xla.get_gui().Subunits.getMovableAtomSpecs():
        #     atoms.extend(evalSpec(selection).atoms())

        for serie in self.series:

            serie['new'] = []
            for chainId in serie['chainIds']:
                atoms = evalSpec(':.{0}'.format(chainId)).atoms()
                serie['new'].append(numpyArrayFromAtoms(atoms))
            # if self.was_changed():
            i = 0
            changed_c = None
            for old_c, new_c in zip(serie['old'], serie['new']):
                if not (old_c == new_c).all():
                    changed_c = i
                i = i + 1

            if changed_c is not None:
                other = set(range(len(serie['chainIds'])))
                other.remove(changed_c)

                t3d, rmsd = matchPositions(serie['new'][changed_c],
                                           serie['old'][changed_c])
                for o in other:
                    newT = Xform.identity()
                    newT.premultiply(serie['t3ds'][o][changed_c])

                    newT.premultiply(t3d)

                    newT.premultiply(serie['t3ds'][changed_c][o])

                    atoms = evalSpec(':.{0}'.format(
                        serie['chainIds'][o])).atoms()
                    for a in atoms:
                        a.setCoord(newT.apply(a.coord()))

                serie['old'] = []
                for chainId in serie['chainIds']:
                    atoms = evalSpec(':.{0}'.format(chainId)).atoms()
                    serie['old'].append(numpyArrayFromAtoms(atoms))
示例#3
0
    def update(self, trigName, myData, changes):
        # print >> __stdout__, "update", trigName, myData, dir(changes), changes.modified
        # coordSet = list(changes.modified)[0]
        # print >> __stdout__, len(coordSet.coords())
        # print >> __stdout__, dir(coordSet)
        # print >> __stdout__, "update"

        # atoms = []
        # for selection in xla.get_gui().Subunits.getMovableAtomSpecs():
        #     atoms.extend(evalSpec(selection).atoms())

        for serie in self.series:

            serie['new'] = []
            for chainId in serie['chainIds']:
                atoms = evalSpec(':.{0}'.format(chainId)).atoms()
                serie['new'].append(numpyArrayFromAtoms(atoms))
            # if self.was_changed():
            i = 0
            changed_c = None
            for old_c, new_c in zip(serie['old'], serie['new']):
                if not (old_c == new_c).all():
                    changed_c = i
                i = i + 1

            if changed_c is not None:
                other = set(range(len(serie['chainIds'])))
                other.remove(changed_c)

                t3d, rmsd = matchPositions(serie['new'][changed_c], serie['old'][changed_c])
                for o in other:
                    newT = Xform.identity()
                    newT.premultiply(serie['t3ds'][o][changed_c])

                    newT.premultiply(t3d)

                    newT.premultiply(serie['t3ds'][changed_c][o])

                    atoms = evalSpec(':.{0}'.format(serie['chainIds'][o])).atoms()
                    for a in atoms:
                        a.setCoord(newT.apply(a.coord()))

                serie['old'] = []
                for chainId in serie['chainIds']:
                    atoms = evalSpec(':.{0}'.format(chainId)).atoms()
                    serie['old'].append(numpyArrayFromAtoms(atoms))
示例#4
0
def interpolate(mol, molXform, segments, equivAtoms, method, rMethod,
			frames, cartesian, cb):
	# mol		molecule where new coordinate sets are added
	#		should already have first frame in place
	# molXform	transform to convert atoms from their own
	#		local coordinate system into "mol" local coordinates
	#		(usually [inverse transform of trajectory model] x
	#		[transform of target model])
	# segments	list of 2-tuples of matching residue lists
	# equivAtoms	dictionary of equivalent atoms
	#		key is atom from first frame
	#		value is 2-tuple of atoms from last frame and "mol"
	# method	interpolation method name
	# rMethod	rate profile, e.g., "linear"
	# frames	number of frames to generate in trajectory
	# cartesian	use cartesian coordinate interpolation?
	# cb		function called for every frame generated 

	import InterpResidue
	from util import getAtomList, findBestMatch
	import chimera
	from chimera import match

	method = findBestMatch(method, InterpolationMap.iterkeys())
	interpolateFunction = InterpolationMap[method]
	rMethod = findBestMatch(rMethod, RateMap.iterkeys())
	rateFunction = RateMap[rMethod]
	if cartesian:
		planFunction = InterpResidue.planCartesian
	else:
		planFunction = InterpResidue.planInternal

	rate = rateFunction(frames)
	numFrames = len(rate) + 1
	activeCS = mol.activeCoordSet
	csSize = len(mol.activeCoordSet.coords())
	baseCS = max(mol.coordSets.keys()) + 1
	segMap = {}
	plan = {}
	for seg in segments:
		rList0, rList1 = seg
		aList0 = getAtomList(rList0)
		aList1 = [ equivAtoms[a0] for a0 in aList0 ]
		c1 = chimera.Point([ a.coord() for a in aList1 ])
		segMap[seg] = (aList0, aList1, molXform.apply(c1))
		for r in rList0:
			plan[r] = planFunction(r)

	import numpy
	def coordsToPosition(atoms):
		return numpy.array([a.coord().data() for a in atoms])
	def xformCoordsToPosition(atoms):
		return numpy.array([molXform.apply(a.coord()).data()
							for a in atoms])
	lo = 0.0
	interval = 1.0
	for i in range(len(rate)):
		f = (rate[i] - lo) / interval
		lo = rate[i]
		interval = 1.0 - lo
		cs = mol.newCoordSet(baseCS + i, csSize)
		for seg in segments:
			aList0, aList1, c1 = segMap[seg]
			c = chimera.Point([ a.coord() for a in aList0 ])
			cList0 = coordsToPosition(aList0)
			cList1 = xformCoordsToPosition(aList1)
			xform, rmsd = match.matchPositions(cList1, cList0)
			xf, xf1 = interpolateFunction(xform, c, c1, f)
			xf1.multiply(molXform)
			rList0, rList1 = seg
			for r in rList0:
				InterpResidue.applyPlan(plan[r], r, cs, f,
						equivAtoms, xf, xf1)
		mol.activeCoordSet = cs
		if cb:
			cb(mol)
	cs = mol.newCoordSet(baseCS + len(rate), csSize)
	for a0, a1 in equivAtoms.iteritems():
		a0.setCoord(molXform.apply(a1.coord()), cs)
	mol.activeCoordSet = cs
示例#5
0
	def fillInUI(self, parent):
		from chimera.match import matchPositions
		from chimera import numpyArrayFromAtoms
		from chimera import selection, UserError

		self._computing = False

		# load needed coord sets...
		frameNums = range(self.startFrame, self.endFrame+1, self.stride)
		for frameNum in frameNums:
			if not self.movie.findCoordSet(frameNum):
				self.status("loading frame %d" % frameNum)
				self.movie._LoadFrame(frameNum,
							makeCurrent=False)

		# compute RMSDs
		from analysis import analysisAtoms
		try:
			atoms = analysisAtoms(self.movie, self.useSel,
					self.ignoreBulk, self.ignoreHyds)
		except UserError:
			self.Close()
			raise

		self.buttonWidgets['Close'].configure(text="Abort")
		numFrames = len(frameNums)
		self.status("Fetching %d coordinate arrays" % numFrames)
		numpyArrays = {}
		from time import time
		t0 = time()
		for i, fn in enumerate(frameNums):
			numpyArrays[fn] = numpyArrayFromAtoms(atoms,
						self.movie.findCoordSet(fn))
			self._computing = True
			self._abort = False
			parent.update() # allow Abort button to function
			self._computing = False
			if self._abort:
				parent.after_idle(self.Close)
				return
			if i == numFrames - 1:
				self.status("Fetched %d coordinate arrays"
									% (i+1))
			else:
				elapsed = time() - t0
				perSec = elapsed / (i+1)
				remaining = perSec * (numFrames - (i+1))
				self.status("Fetched %d of %d coordinate arrays"
					"\nAbout %.1f minutes remaining" %
					(i+1, numFrames, remaining / 60.0))
		t0 = time()
		totalRMSDs = numFrames * (numFrames - 1) / 2
		self.status("Computing %d RMSDs" % totalRMSDs)
		from EnsembleMatch.distmat import DistanceMatrix
		fullDM = DistanceMatrix(numFrames)
		sameAs = {}
		for i, frame1 in enumerate(frameNums):
			na1 = numpyArrays[frame1]
			for j, frame2 in enumerate(frameNums[i+1:]):
				na2 = numpyArrays[frame2]
				rmsd = matchPositions(na1, na2)[1]
				fullDM.set(i, i+j+1, rmsd)
				if rmsd == 0.0:
					sameAs[frame2] = frame1
			self._computing = True
			self._abort = False
			parent.update() # allow Abort button to function
			self._computing = False
			if self._abort:
				parent.after_idle(self.Close)
				return
			numComputed = totalRMSDs - ((numFrames - (i+1)) *
							(numFrames - (i+2))) / 2
			if numComputed == totalRMSDs:
				self.status("Computed %d RMSDs" % totalRMSDs)
			else:
				elapsed = time() - t0
				perSec = elapsed / numComputed
				remaining = perSec * (totalRMSDs - numComputed)
				if remaining < 50:
					timeEst = "%d seconds" % int(
							remaining + 0.5)
				else:
					timeEst = "%.1f minutes" % (
							remaining / 60.0)
				self.status("Computed %d of %d RMSDs\n"
					"About %s remaining" % (numComputed,
					totalRMSDs, timeEst))
		self.status("Generating clusters")
		self.buttonWidgets['Close'].configure(text="Close")
		if not sameAs:
			dm = fullDM
			reducedFrameNums = frameNums
			indexMap = range(len(frameNums))
		elif len(sameAs) == numFrames - 1:
			raise UserError("All frames to cluster are identical!")
			self.Close()
		else:
			dm = DistanceMatrix(numFrames - len(sameAs))
			reducedFrameNums = []
			indexMap = []
			for i, fn in enumerate(frameNums):
				if fn in sameAs:
					continue
				reducedFrameNums.append(fn)
				indexMap.append(i)
			for i in range(len(reducedFrameNums)):
				mapi = indexMap[i]
				for j in range(i+1, len(reducedFrameNums)):
					mapj = indexMap[j]
					dm.set(i, j, fulldm.get(mapi, mapj))
		from EnsembleMatch.nmrclust import NMRClust
		clustering = NMRClust(dm)
		self.clusterMap = {}
		self.representatives = []
		self.clusters = []
		unsortedClusters = [(c, clustering.representative(c))
						for c in clustering.clusters]
		# sort the clusters so that the coloring is reproducible
		# while trying to avoid using adjacent colors for
		# adjacent clusters
		clusters = [unsortedClusters.pop()]
		while unsortedClusters:
			bestCluster = bestVal = None
			for uc in unsortedClusters:
				val = abs(uc[-1] - clusters[-1][-1])
				if len(clusters) > 1:
					val += 0.5 * abs(uc[-1]
							- clusters[-2][-1])
				if len(clusters) > 2:
					val += 0.25 * abs(uc[-1]
							- clusters[-3][-1])
				if bestVal == None or val > bestVal:
					bestCluster = uc
					bestVal = val
			unsortedClusters.remove(bestCluster)
			clusters.append(bestCluster)
		colors = colorRange(len(clusters))
		for c, rep in clusters:
			cluster = Cluster()
			cluster.color = colors.pop()
			self.clusters.append(cluster)
			cluster.representative = reducedFrameNums[rep]
			cluster.members = []
			for m in c.members():
				f = reducedFrameNums[m]
				self.clusterMap[f] = cluster
				cluster.members.append(f)
		for dup, base in sameAs.items():
			c = self.clusterMap[base]
			self.clusterMap[dup] = c
			c.members.append(dup)
		self.status("%d clusters" % len(self.clusters))

		from CGLtk.Table import SortableTable
		self.table = SortableTable(parent)
		self.table.addColumn("Color", "color", format=(False, False),
							titleDisplay=False)
		membersCol = self.table.addColumn("Members",
				"lambda c: len(c.members)", format="%d")
		self.table.addColumn("Representative Frame", "representative",
								format="%d")
		self.table.setData(self.clusters)
		self.table.launch(browseCmd=self.showRep)
		self.table.sortBy(membersCol)
		self.table.sortBy(membersCol) # to get descending order
		self.table.grid(sticky="nsew")
		self.timeLine = Pmw.ScrolledCanvas(parent, canvas_height="0.5i")
		self.timeLine.grid(row=1, column=0, sticky="nsew")
		parent.rowconfigure(0, weight=1)
		parent.columnconfigure(0, weight=1)
		self.zoom = 2.0
		self.drawTimeLine()
    def fillInUI(self, parent):
        from chimera.match import matchPositions
        from chimera import numpyArrayFromAtoms
        from chimera import selection, UserError

        self._computing = False
        top = parent.winfo_toplevel()
        menuBar = Tkinter.Menu(top)
        top.config(menu=menuBar)

        self.dependentDialogs = []
        rmsdMenu = Tkinter.Menu(menuBar)
        menuBar.add_cascade(label="RMSD", menu=rmsdMenu)
        rmsdMenu.add_command(label="Change thresholds...",
                             command=self.launchRmsdBoundsDialog)

        numFrames = self.endFrame - self.startFrame + 1
        scale1size = numFrames / self.stride
        if scale1size < 200:
            scale = int(1 + 200 / scale1size)
        else:
            scale = 1
        # load needed coord sets...
        for frameNum in range(self.startFrame, self.endFrame + 1, self.stride):
            if not self.movie.findCoordSet(frameNum):
                self.status("loading frame %d" % frameNum)
                self.movie._LoadFrame(frameNum, makeCurrent=False)

        self.widgets = []
        width = max(len(str(self.endFrame)), 6)
        for i in range(2):
            entryFrame = Tkinter.Frame(parent)
            entryFrame.grid(row=1, column=i)
            entry = Pmw.EntryField(entryFrame,
                                   labelpos='w',
                                   entry_width=width,
                                   label_text="Frame",
                                   validate='numeric')
            entry.configure(command=lambda ent=entry: self.entryCB(ent))
            entry.grid(row=0, column=0)
            self.widgets.append(entry)
            goBut = Tkinter.Button(entryFrame,
                                   text="Go",
                                   padx=0,
                                   pady=0,
                                   command=lambda ent=entry: self.entryCB(ent))
            goBut.grid(row=0, column=1)
            self.widgets.append(goBut)
        self.widgets[0].insert(0, "Click")
        self.widgets[2].insert(0, "on map")
        for widget in self.widgets:
            if isinstance(widget, Pmw.EntryField):
                widget = widget.component('entry')
            widget.config(state='disabled')

        size = scale1size * scale
        self.scrCanvas = Pmw.ScrolledCanvas(parent,
                                            canvas_bg="blue",
                                            canvas_width=size,
                                            canvas_height=size,
                                            borderframe=True)
        self.scrCanvas.grid(row=0, column=0, columnspan=2, sticky="nsew")
        parent.rowconfigure(0, weight=1)
        parent.columnconfigure(0, weight=1)
        parent.columnconfigure(1, weight=1)

        # compute RMSD/image canvas
        from analysis import analysisAtoms
        try:
            atoms = analysisAtoms(self.movie, self.useSel, self.ignoreBulk,
                                  self.ignoreHyds)
        except UserError:
            self.Close()
            raise

        self.buttonWidgets['Close'].configure(text="Abort")
        self.rects = {}
        numpyArrays = {}
        if self.recolor:
            rmsds = []
        minRmsd = maxRmsd = None
        for step1, frame1 in enumerate(
                range(self.startFrame, self.endFrame + 1, self.stride)):
            self.status("compute/show RMSDs for frame %d" % frame1)
            try:
                na1 = numpyArrays[frame1]
            except KeyError:
                na1 = numpyArrayFromAtoms(atoms,
                                          self.movie.findCoordSet(frame1))
                numpyArrays[frame1] = na1
            canvas = self.scrCanvas.component('canvas')
            for step2, frame2 in enumerate(
                    range(frame1, self.endFrame + 1, self.stride)):
                try:
                    na2 = numpyArrays[frame2]
                except KeyError:
                    na2 = numpyArrayFromAtoms(atoms,
                                              self.movie.findCoordSet(frame2))
                    numpyArrays[frame2] = na2
                rmsd = matchPositions(na1, na2)[1]
                if self.recolor:
                    rmsds.append(rmsd)
                color = self.tkRmsdColor(rmsd)
                rect1 = canvas.create_rectangle(step1 * scale,
                                                (step1 + step2) * scale,
                                                (step1 + 1) * scale,
                                                (step1 + step2 + 1) * scale,
                                                fill=color,
                                                outline="")
                self.rects[rect1] = (frame1, frame2, rmsd)
                rect2 = canvas.create_rectangle((step1 + step2) * scale,
                                                step1 * scale,
                                                (step1 + step2 + 1) * scale,
                                                (step1 + 1) * scale,
                                                fill=color,
                                                outline="")
                self.rects[rect2] = (frame2, frame1, rmsd)
                if frame1 != frame2:
                    if minRmsd is None:
                        minRmsd = maxRmsd = rmsd
                    elif rmsd < minRmsd:
                        minRmsd = rmsd
                    elif rmsd > maxRmsd:
                        maxRmsd = rmsd

            if step1 == 0:
                self.scrCanvas.resizescrollregion()
            self._computing = True
            self._abort = False
            canvas.update()  # show each line and allow quit
            self._computing = False
            if self._abort:
                canvas.after_idle(self.Close)
                return
        self.buttonWidgets['Close'].configure(text="Close")
        if self.recolor:
            self.status("Calculating recoloring thresholds\n")
            rmsds.sort()
            newMin = float("%.1f" % rmsds[int(len(rmsds) / 3)])
            newMax = float("%.1f" % rmsds[int(2 * len(rmsds) / 3)])
            if newMin == newMax:
                if newMin > 0:
                    newMin -= 0.1
                else:
                    newMax += 0.1
            self.newMinMax(newMin, newMax)
        canvas.bind("<Motion>", self.mouseOverCB)
        canvas.bind("<Button-1>", self.mouseClickCB)
        self.status("Calculated RMSD varies from %.3f to %.3f\n" %
                    (minRmsd, maxRmsd),
                    log=True)
示例#7
0
def getRotamers(res,
                phi=None,
                psi=None,
                cisTrans="trans",
                resType=None,
                lib="Dunbrack",
                log=False):
    """Takes a Residue instance and optionally phi/psi angles  
	   (if different from the Residue), residue type (e.g. "TYR"), and/or  
	   rotamer library name.  Returns a boolean and a list of Molecule  
	   instances.  The boolean indicates whether the rotamers are backbone  
	   dependent.  The Molecules are each a single residue (a rotamer) and  
	   are in descending probability order.  Each has an attribute  
	   "rotamerProb" for the probability and "chis" for the chi angles.
	"""
    # find n/c/ca early to identify swapping non-amino acid before
    # the NoResidueRotamersError gets raised, which will attempt
    # a swap for ALA/GLY (and result in a traceback)
    resAtomsMap = res.atomsMap
    try:
        n = resAtomsMap["N"][0]
        ca = resAtomsMap["CA"][0]
        c = resAtomsMap["C"][0]
    except KeyError:
        raise LimitationError("N, CA, or C missing from %s:"
                              " needed to position CB" % res)
    resType = resType or res.type
    if not phi and not psi:
        ignore, phi, psi, cisTrans = extractResInfo(res)
        if log:

            def _info(ang):
                if ang is None:
                    return "none"
                return "%.1f" % ang

            replyobj.info("%s: phi %s, psi %s" % (res, _info(phi), _info(psi)))
            if cisTrans:
                replyobj.info(" " + cisTrans)
            replyobj.info("\n")
    replyobj.status("Retrieving rotamers from %s library\n" %
                    getattr(lib, "displayName", lib))
    bbdep, params = getRotamerParams(resType,
                                     phi=phi,
                                     psi=psi,
                                     cisTrans=cisTrans,
                                     lib=lib)
    replyobj.status("Rotamers retrieved from %s library\n" %
                    getattr(lib, "displayName", lib))

    template = chimera.restmplFindResidue(resType, False, False)
    tmplMap = template.atomsMap
    tmplN = tmplMap["N"]
    tmplCA = tmplMap["CA"]
    tmplC = tmplMap["C"]
    tmplCB = tmplMap["CB"]
    from chimera.molEdit import addAtom, addDihedralAtom, addBond
    from chimera.match import matchPositions, _coordArray
    xform, rmsd = matchPositions(_coordArray([n, ca, c]),
                                 _coordArray([tmplN, tmplCA, tmplC]))
    ncoord = xform.apply(tmplN.coord())
    cacoord = xform.apply(tmplCA.coord())
    cbcoord = xform.apply(tmplCB.coord())
    from data import chiInfo
    info = chiInfo[resType]
    bondCache = {}
    angleCache = {}
    torsionCache = {}
    from chimera.bondGeom import bondPositions
    mols = []
    middles = {}
    ends = {}
    for i, rp in enumerate(params):
        m = chimera.Molecule()
        mols.append(m)
        m.name = "rotamer %d of %s" % (i + 1, res)
        r = m.newResidue(resType, ' ', 1, ' ')
        # can't use a local variable for r.atomsMap since we receive
        # only an unchanging copy of the map
        m.rotamerProb = rp.p
        m.chis = rp.chis
        rotN = addAtom("N", tmplN.element, r, ncoord)
        rotCA = addAtom("CA", tmplCA.element, r, cacoord, bondedTo=rotN)
        rotCB = addAtom("CB", tmplCB.element, r, cbcoord, bondedTo=rotCA)
        todo = []
        for i, chi in enumerate(rp.chis):
            n3, n2, n1, new = info[i]
            blen, angle = _lenAngle(new, n1, n2, tmplMap, bondCache,
                                    angleCache)
            n3 = r.atomsMap[n3][0]
            n2 = r.atomsMap[n2][0]
            n1 = r.atomsMap[n1][0]
            new = tmplMap[new]
            a = addDihedralAtom(new.name,
                                new.element,
                                n1,
                                n2,
                                n3,
                                blen,
                                angle,
                                chi,
                                bonded=True)
            todo.append(a)
            middles[n1] = [a, n1, n2]
            ends[a] = [a, n1, n2]

        # if there are any heavy non-backbone atoms bonded to template
        # N and they haven't been added by the above (which is the
        # case for Richardson proline parameters) place them now
        for tnnb in tmplN.bondsMap.keys():
            if tnnb.name in r.atomsMap or tnnb.element.number == 1:
                continue
            tnnbcoord = xform.apply(tnnb.coord())
            addAtom(tnnb.name, tnnb.element, r, tnnbcoord, bondedTo=rotN)

        # fill out bonds and remaining heavy atoms
        from chimera.idatm import typeInfo
        from chimera import distance
        done = set([rotN, rotCA])
        while todo:
            a = todo.pop(0)
            if a in done:
                continue
            tmplA = tmplMap[a.name]
            for bonded, bond in tmplA.bondsMap.items():
                if bonded.element.number == 1:
                    continue
                try:
                    rbonded = r.atomsMap[bonded.name][0]
                except KeyError:
                    # use middles if possible...
                    try:
                        p1, p2, p3 = middles[a]
                        conn = p3
                    except KeyError:
                        p1, p2, p3 = ends[a]
                        conn = p2
                    t1 = tmplMap[p1.name]
                    t2 = tmplMap[p2.name]
                    t3 = tmplMap[p3.name]
                    xform, rmsd = matchPositions(_coordArray([p1, p2, p3]),
                                                 _coordArray([t1, t2, t3]))
                    pos = xform.apply(tmplMap[bonded.name].coord())
                    rbonded = addAtom(bonded.name,
                                      bonded.element,
                                      r,
                                      pos,
                                      bondedTo=a)
                    middles[a] = [rbonded, a, conn]
                    ends[rbonded] = [rbonded, a, conn]
                if a not in rbonded.bondsMap:
                    addBond(a, rbonded)
                if rbonded not in done:
                    todo.append(rbonded)
            done.add(a)
    return bbdep, mols
示例#8
0
	def fillInUI(self, parent):
		from chimera.match import matchPositions
		from chimera import numpyArrayFromAtoms
		from chimera import selection, UserError

		self._computing = False
		top = parent.winfo_toplevel()
		menuBar = Tkinter.Menu(top)
		top.config(menu=menuBar)

		self.dependentDialogs = []
		rmsdMenu = Tkinter.Menu(menuBar)
		menuBar.add_cascade(label="RMSD", menu=rmsdMenu)
		rmsdMenu.add_command(label="Change thresholds...",
					command=self.launchRmsdBoundsDialog)

		numFrames = self.endFrame - self.startFrame + 1
		scale1size = numFrames / self.stride
		if scale1size < 200:
			scale = int(1 + 200 / scale1size)
		else:
			scale = 1
		# load needed coord sets...
		for frameNum in range(self.startFrame, self.endFrame+1,
								self.stride):
			if not self.movie.findCoordSet(frameNum):
				self.status("loading frame %d" % frameNum)
				self.movie._LoadFrame(frameNum,
							makeCurrent=False)

		self.widgets = []
		width = max(len(str(self.endFrame)), 6)
		for i in range(2):
			entryFrame = Tkinter.Frame(parent)
			entryFrame.grid(row=1, column=i)
			entry = Pmw.EntryField(entryFrame, labelpos='w',
					entry_width=width, label_text="Frame",
					validate='numeric')
			entry.configure(command=lambda ent=entry:
							self.entryCB(ent))
			entry.grid(row=0, column=0)
			self.widgets.append(entry)
			goBut = Tkinter.Button(entryFrame, text="Go",
				padx=0, pady=0,
				command=lambda ent=entry: self.entryCB(ent))
			goBut.grid(row=0, column=1)
			self.widgets.append(goBut)
		self.widgets[0].insert(0, "Click")
		self.widgets[2].insert(0, "on map")
		for widget in self.widgets:
			if isinstance(widget, Pmw.EntryField):
				widget = widget.component('entry')
			widget.config(state='disabled')

		size = scale1size * scale
		self.scrCanvas = Pmw.ScrolledCanvas(parent, canvas_bg="blue",
			canvas_width=size, canvas_height=size, borderframe=True)
		self.scrCanvas.grid(row=0, column=0, columnspan=2,
								sticky="nsew")
		parent.rowconfigure(0, weight=1)
		parent.columnconfigure(0, weight=1)
		parent.columnconfigure(1, weight=1)

		# compute RMSD/image canvas
		from analysis import analysisAtoms
		try:
			atoms = analysisAtoms(self.movie, self.useSel,
					self.ignoreBulk, self.ignoreHyds)
		except UserError:
			self.Close()
			raise

		self.buttonWidgets['Close'].configure(text="Abort")
		self.rects = {}
		numpyArrays = {}
		if self.recolor:
			rmsds = []
		minRmsd = maxRmsd = None
		for step1, frame1 in enumerate(range(self.startFrame,
						self.endFrame+1, self.stride)):
			self.status("compute/show RMSDs for frame %d" % frame1)
			try:
				na1 = numpyArrays[frame1]
			except KeyError:
				na1 = numpyArrayFromAtoms(atoms,
					self.movie.findCoordSet(frame1))
				numpyArrays[frame1] = na1
			canvas = self.scrCanvas.component('canvas')
			for step2, frame2 in enumerate(range(frame1,
						self.endFrame+1, self.stride)):
				try:
					na2 = numpyArrays[frame2]
				except KeyError:
					na2 = numpyArrayFromAtoms(atoms,
						self.movie.findCoordSet(frame2))
					numpyArrays[frame2] = na2
				rmsd = matchPositions(na1, na2)[1]
				if self.recolor:
					rmsds.append(rmsd)
				color = self.tkRmsdColor(rmsd)
				rect1 = canvas.create_rectangle(step1*scale,
					(step1+step2)*scale, (step1+1)*scale,
					(step1+step2+1)*scale, fill=color,
					outline="")
				self.rects[rect1] = (frame1, frame2, rmsd)
				rect2 = canvas.create_rectangle(
					(step1+step2)*scale, step1*scale,
					(step1+step2+1)*scale, (step1+1)*scale,
					fill=color, outline="")
				self.rects[rect2] = (frame2, frame1, rmsd)
				if frame1 != frame2:
					if minRmsd is None:
						minRmsd = maxRmsd = rmsd
					elif rmsd < minRmsd:
						minRmsd = rmsd
					elif rmsd > maxRmsd:
						maxRmsd = rmsd

			if step1 == 0:
				self.scrCanvas.resizescrollregion()
			self._computing = True
			self._abort = False
			canvas.update() # show each line and allow quit
			self._computing = False
			if self._abort:
				canvas.after_idle(self.Close)
				return
		self.buttonWidgets['Close'].configure(text="Close")
		if self.recolor:
			self.status("Calculating recoloring thresholds\n")
			rmsds.sort()
			newMin = float("%.1f" % rmsds[int(len(rmsds)/3)])
			newMax = float("%.1f" % rmsds[int(2*len(rmsds)/3)])
			if newMin == newMax:
				if newMin > 0:
					newMin -= 0.1
				else:
					newMax += 0.1
			self.newMinMax(newMin, newMax)
		canvas.bind("<Motion>", self.mouseOverCB)
		canvas.bind("<Button-1>", self.mouseClickCB)
		self.status("Calculated RMSD varies from %.3f to %.3f\n"
						% (minRmsd, maxRmsd), log=True)
    def fillInUI(self, parent):
        from chimera.match import matchPositions
        from chimera import numpyArrayFromAtoms
        from chimera import selection, UserError

        self._computing = False

        # load needed coord sets...
        frameNums = range(self.startFrame, self.endFrame + 1, self.stride)
        for frameNum in frameNums:
            if not self.movie.findCoordSet(frameNum):
                self.status("loading frame %d" % frameNum)
                self.movie._LoadFrame(frameNum, makeCurrent=False)

        # compute RMSDs
        from analysis import analysisAtoms
        try:
            atoms = analysisAtoms(self.movie, self.useSel, self.ignoreBulk,
                                  self.ignoreHyds)
        except UserError:
            self.Close()
            raise

        self.buttonWidgets['Close'].configure(text="Abort")
        numFrames = len(frameNums)
        self.status("Fetching %d coordinate arrays" % numFrames)
        numpyArrays = {}
        from time import time
        t0 = time()
        for i, fn in enumerate(frameNums):
            numpyArrays[fn] = numpyArrayFromAtoms(atoms,
                                                  self.movie.findCoordSet(fn))
            self._computing = True
            self._abort = False
            parent.update()  # allow Abort button to function
            self._computing = False
            if self._abort:
                parent.after_idle(self.Close)
                return
            if i == numFrames - 1:
                self.status("Fetched %d coordinate arrays" % (i + 1))
            else:
                elapsed = time() - t0
                perSec = elapsed / (i + 1)
                remaining = perSec * (numFrames - (i + 1))
                self.status("Fetched %d of %d coordinate arrays"
                            "\nAbout %.1f minutes remaining" %
                            (i + 1, numFrames, remaining / 60.0))
        t0 = time()
        totalRMSDs = numFrames * (numFrames - 1) / 2
        self.status("Computing %d RMSDs" % totalRMSDs)
        from EnsembleMatch.distmat import DistanceMatrix
        fullDM = DistanceMatrix(numFrames)
        sameAs = {}
        for i, frame1 in enumerate(frameNums):
            na1 = numpyArrays[frame1]
            for j, frame2 in enumerate(frameNums[i + 1:]):
                na2 = numpyArrays[frame2]
                rmsd = matchPositions(na1, na2)[1]
                fullDM.set(i, i + j + 1, rmsd)
                if rmsd == 0.0:
                    sameAs[frame2] = frame1
            self._computing = True
            self._abort = False
            parent.update()  # allow Abort button to function
            self._computing = False
            if self._abort:
                parent.after_idle(self.Close)
                return
            numComputed = totalRMSDs - ((numFrames - (i + 1)) * (numFrames -
                                                                 (i + 2))) / 2
            if numComputed == totalRMSDs:
                self.status("Computed %d RMSDs" % totalRMSDs)
            else:
                elapsed = time() - t0
                perSec = elapsed / numComputed
                remaining = perSec * (totalRMSDs - numComputed)
                if remaining < 50:
                    timeEst = "%d seconds" % int(remaining + 0.5)
                else:
                    timeEst = "%.1f minutes" % (remaining / 60.0)
                self.status("Computed %d of %d RMSDs\n"
                            "About %s remaining" %
                            (numComputed, totalRMSDs, timeEst))
        self.status("Generating clusters")
        self.buttonWidgets['Close'].configure(text="Close")
        if not sameAs:
            dm = fullDM
            reducedFrameNums = frameNums
            indexMap = range(len(frameNums))
        elif len(sameAs) == numFrames - 1:
            raise UserError("All frames to cluster are identical!")
            self.Close()
        else:
            dm = DistanceMatrix(numFrames - len(sameAs))
            reducedFrameNums = []
            indexMap = []
            for i, fn in enumerate(frameNums):
                if fn in sameAs:
                    continue
                reducedFrameNums.append(fn)
                indexMap.append(i)
            for i in range(len(reducedFrameNums)):
                mapi = indexMap[i]
                for j in range(i + 1, len(reducedFrameNums)):
                    mapj = indexMap[j]
                    dm.set(i, j, fulldm.get(mapi, mapj))
        from EnsembleMatch.nmrclust import NMRClust
        clustering = NMRClust(dm)
        self.clusterMap = {}
        self.representatives = []
        self.clusters = []
        unsortedClusters = [(c, clustering.representative(c))
                            for c in clustering.clusters]
        # sort the clusters so that the coloring is reproducible
        # while trying to avoid using adjacent colors for
        # adjacent clusters
        clusters = [unsortedClusters.pop()]
        while unsortedClusters:
            bestCluster = bestVal = None
            for uc in unsortedClusters:
                val = abs(uc[-1] - clusters[-1][-1])
                if len(clusters) > 1:
                    val += 0.5 * abs(uc[-1] - clusters[-2][-1])
                if len(clusters) > 2:
                    val += 0.25 * abs(uc[-1] - clusters[-3][-1])
                if bestVal == None or val > bestVal:
                    bestCluster = uc
                    bestVal = val
            unsortedClusters.remove(bestCluster)
            clusters.append(bestCluster)
        colors = colorRange(len(clusters))
        for c, rep in clusters:
            cluster = Cluster()
            cluster.color = colors.pop()
            self.clusters.append(cluster)
            cluster.representative = reducedFrameNums[rep]
            cluster.members = []
            for m in c.members():
                f = reducedFrameNums[m]
                self.clusterMap[f] = cluster
                cluster.members.append(f)
        for dup, base in sameAs.items():
            c = self.clusterMap[base]
            self.clusterMap[dup] = c
            c.members.append(dup)
        self.status("%d clusters" % len(self.clusters))

        from CGLtk.Table import SortableTable
        self.table = SortableTable(parent)
        self.table.addColumn("Color",
                             "color",
                             format=(False, False),
                             titleDisplay=False)
        membersCol = self.table.addColumn("Members",
                                          "lambda c: len(c.members)",
                                          format="%d")
        self.table.addColumn("Representative Frame",
                             "representative",
                             format="%d")
        self.table.setData(self.clusters)
        self.table.launch(browseCmd=self.showRep)
        self.table.sortBy(membersCol)
        self.table.sortBy(membersCol)  # to get descending order
        self.table.grid(sticky="nsew")
        self.timeLine = Pmw.ScrolledCanvas(parent, canvas_height="0.5i")
        self.timeLine.grid(row=1, column=0, sticky="nsew")
        parent.rowconfigure(0, weight=1)
        parent.columnconfigure(0, weight=1)
        self.zoom = 2.0
        self.drawTimeLine()