def createPlane(self, name, atoms, number=None, radius=None, radiusOffset=0.0, color=None, sourceModel=None, thickness=defaults[PLANE_THICKNESS]): if len(atoms) < 3: raise ValueError("Need at least 3 atoms to define plane") numbers = dict([(pl.number, pl) for pl in self.planes]) if number == None: if numbers: number = max(numbers.keys()) + 1 else: number = 1 elif number in numbers: self.removePlanes([numbers[number]]) if color == None: from StructMeasure import matchStructureColor color = matchStructureColor(atoms) if sourceModel == None: sourceModel = self._getSourceModel(atoms) import StructMeasure if radius == None: plane, proj, radius = StructMeasure.plane( chimera.numpyArrayFromAtoms(atoms), findBounds=True) radius += radiusOffset else: plane = StructMeasure.plane( chimera.numpyArrayFromAtoms(atoms), findBounds=False) replyobj.info("%s has radius %g\n" % (name, radius)) self.planeOrdinal += 1 return self._instantiatePlane(number, name, self.planeOrdinal, color, radius, thickness, sourceModel, atoms, plane)
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))
def createAxis(self, name, atoms, number=None, radius=None, color=None, sourceModel=None, helicalCorrection=True, massWeighting=False): if len(atoms) < 3: raise ValueError("Need at least 3 atoms to define axis") numbers = dict([(a.number, a) for a in self.axes]) if number == None: if numbers: number = max(numbers.keys()) + 1 else: number = 1 elif number in numbers: self.removeAxes([numbers[number]]) if color == None: from StructMeasure import matchStructureColor color = matchStructureColor(atoms) if sourceModel == None: sourceModel = self._getSourceModel(atoms) axisKw = {} if massWeighting: from numpy import array axisKw['weights'] = array([a.element.mass for a in atoms]) import StructMeasure if radius == None: pt, vec, b1, b2, radius = StructMeasure.axis( chimera.numpyArrayFromAtoms(atoms), findBounds=True, findRadius=True, iterate=helicalCorrection, **axisKw) else: pt, vec, b1, b2 = StructMeasure.axis( chimera.numpyArrayFromAtoms(atoms), findBounds=True, findRadius=False, iterate=helicalCorrection, **axisKw) replyobj.info("%s has radius %g\n" % (name, radius)) return self._instantiateAxis(number, name, color, radius, sourceModel, atoms, pt, vec, (b1, b2))
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))
[writer.writerow(r) for r in table] # gather the names of .pdb files in the folder file_names = [fn for fn in os.listdir(".") if fn.endswith(".pdb")] # loop through the files, opening, processing, and closing each in turn for fn in file_names: replyobj.status("Processing " + fn) # show what file we're working on rc("open " + fn) rc("delete markers") #make receptor plane #select the top of each transmembrane# measure the center of the pocket (#1)#make a plane that mimics the mebrane (p1) rc("select #0:32,87,100,166,188,260,277") rc("measure center sel mark true radius .3") rc("define plane sel") atoms = selection.currentAtoms() numpyCorrds = numpyArrayFromAtoms(atoms) plane = StructMeasure.plane(numpyCorrds) # #select chemokine #measure axis of mass for the chemokine (a1)#measure center of mass for the chemokine (#2)#centriod for chemokine (c1) rc("select :.b") rc("define axis color red radius 2 sel") rc("measure center sel mark true radius .3") rc("define centroid mass true color blue radius 10 sel") # # z_distance = Midas.distance( '#1:1' '#2:1' ) #distance center of mass of chemokine to center of pocket at membrane z_short = Midas.distance( '#1',
def __init__(self): self.m = chimera.openModels.list()[0] # Matchmaker yRvb12.hexamer.pdb, chain C (#1) with yRvb12.hexamer.pdb, chain A (#0), sequence alignment score = 1986.2 # with these parameters: # chain pairing: bb # Needleman-Wunsch using BLOSUM-62 # ss fraction: 0.3 # gap open (HH/SS/other) 18/18/6, extend 1 # ss matrix: # (H, O): -6 # (S, S): 6 # (H, H): 6 # (O, S): -6 # (O, O): 4 # (H, S): -9 # iteration cutoff: 2 # RMSD between 393 atom pairs is 0.001 angstroms # Position of yRvb12.hexamer.pdb (#0) relative to yRvb12.hexamer.pdb (#1) coordinates: # Matrix rotation and translation # -0.50000042 0.86602516 0.00000116 -103.53997515 # -0.86602516 -0.50000042 0.00000058 179.33655802 # 0.00000108 -0.00000072 1.00000000 0.00005125 # Axis -0.00000075 0.00000005 -1.00000000 # Axis point -0.00001174 119.55767842 0.00000000 # Rotation angle (degrees) 120.00002798 # Shift along axis 0.00003425 self.series = [ { 'tr3d': Xform.xform(-0.50000042, 0.86602516, 0.00000116, -103.53997515, -0.86602516, -0.50000042, 0.00000058, 179.33655802, 0.00000108, -0.00000072, 1.00000000, 0.00005125, orthogonalize=True), 'chainIds': ['A', 'C', 'E'], 'old': [], 'new': [] } ] # for a in evalSpec(':.A').atoms(): # a.setCoord(self.symTr3d.apply(a.coord())) for serie in self.series: serie['t3ds'] = [[None for i in range(len(serie['chainIds']))] for j in range(len(serie['chainIds']))] for i in range(len(serie['chainIds'])): # self.t3ds.append([]) for j in range(len(serie['chainIds'])): count = abs(j-i) symTr3d = Xform.identity() for c in range(count): symTr3d.multiply(serie['tr3d']) newT = Xform.identity() if i < j: newT = symTr3d elif i > j: newT = symTr3d.inverse() serie['t3ds'][i][j] = newT for chainId in serie['chainIds']: atoms = evalSpec(':.{0}'.format(chainId)).atoms() serie['old'].append(numpyArrayFromAtoms(atoms))
def __init__(self): self.m = chimera.openModels.list()[0] # Matchmaker yRvb12.hexamer.pdb, chain C (#1) with yRvb12.hexamer.pdb, chain A (#0), sequence alignment score = 1986.2 # with these parameters: # chain pairing: bb # Needleman-Wunsch using BLOSUM-62 # ss fraction: 0.3 # gap open (HH/SS/other) 18/18/6, extend 1 # ss matrix: # (H, O): -6 # (S, S): 6 # (H, H): 6 # (O, S): -6 # (O, O): 4 # (H, S): -9 # iteration cutoff: 2 # RMSD between 393 atom pairs is 0.001 angstroms # Position of yRvb12.hexamer.pdb (#0) relative to yRvb12.hexamer.pdb (#1) coordinates: # Matrix rotation and translation # -0.50000042 0.86602516 0.00000116 -103.53997515 # -0.86602516 -0.50000042 0.00000058 179.33655802 # 0.00000108 -0.00000072 1.00000000 0.00005125 # Axis -0.00000075 0.00000005 -1.00000000 # Axis point -0.00001174 119.55767842 0.00000000 # Rotation angle (degrees) 120.00002798 # Shift along axis 0.00003425 self.series = [{ 'tr3d': Xform.xform(-0.50000042, 0.86602516, 0.00000116, -103.53997515, -0.86602516, -0.50000042, 0.00000058, 179.33655802, 0.00000108, -0.00000072, 1.00000000, 0.00005125, orthogonalize=True), 'chainIds': ['A', 'C', 'E'], 'old': [], 'new': [] }] # for a in evalSpec(':.A').atoms(): # a.setCoord(self.symTr3d.apply(a.coord())) for serie in self.series: serie['t3ds'] = [[None for i in range(len(serie['chainIds']))] for j in range(len(serie['chainIds']))] for i in range(len(serie['chainIds'])): # self.t3ds.append([]) for j in range(len(serie['chainIds'])): count = abs(j - i) symTr3d = Xform.identity() for c in range(count): symTr3d.multiply(serie['tr3d']) newT = Xform.identity() if i < j: newT = symTr3d elif i > j: newT = symTr3d.inverse() serie['t3ds'][i][j] = newT for chainId in serie['chainIds']: atoms = evalSpec(':.{0}'.format(chainId)).atoms() serie['old'].append(numpyArrayFromAtoms(atoms))
def matchAtoms(fixedAtoms, movableAtoms, fCoordSet=None, mCoordSet=None): mArray = chimera.numpyArrayFromAtoms(movableAtoms, mCoordSet) fArray = chimera.numpyArrayFromAtoms(fixedAtoms, fCoordSet) return matchPositions(fArray, mArray)
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)
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()