def body(self, guiParent): self.geometry('320x120') analysisProject = self.analysisProject guiParent.expandGrid(5,3) guiParent.expandGrid(5,4) row = 0 div = LabelDivider(guiParent, text='Multi-dimensional Marks', grid=(row,0), gridSpan=(1,4)) buttons = UtilityButtonList(guiParent, doClone=False, helpUrl=self.help_url) buttons.grid(row=row, column=4, sticky='w') row += 1 label = Label(guiParent, text='Maximum marks: ', grid=(row,0)) values = range(1, self.maxAllowedMarks+1) entries = [ str(x) for x in values] value = analysisProject.maxMarks tipText = 'Sets the maximum number of multi-dimensional cross-marks that the user can add to spectrum window displays' self.marks_menu = PulldownList(guiParent, callback=self.setMaxMarks, grid=(row,1), texts=entries, objects=values, index=value-1, tipText=tipText) label = Label(guiParent, text=' Mark colour: ', grid=(row,2)) tipText = 'Sets the line colour of the multi-dimensional cross-marks, excepting those that go through peak centers' self.marksSchemePulldown = PulldownList(guiParent, callback=self.setMarksColor, grid=(row,3), tipText=tipText) row += 1 label = Label(guiParent, text='(Non-peak marks only)', grid=(row,2), gridSpan=(1,2)) row += 1 div = LabelDivider(guiParent, text='1-dimensional Rulers', grid=(row,0), gridSpan=(1,5)) row += 1 label = Label(guiParent, text='Maximum rulers: ', grid=(row,0)) values = range(1, self.maxAllowedRulers+1) entries = [ str(x) for x in values] value = analysisProject.maxRulers tipText = 'Sets the maximum number of 1-dimensional ruler lines that the user can add to spectrum window displays' self.rulers_menu = PulldownList(guiParent, callback=self.setMaxRulers, grid=(row,1), texts=entries, objects=values, index=value-1, tipText=tipText) label = Label(guiParent, text=' Ruler colour: ', grid=(row,2)) tipText = 'Sets the line colour of the 1-dimensional ruler lines' self.rulersSchemePulldown = PulldownList(guiParent, callback=self.setRulersColor, grid=(row,3), tipText=tipText) self.updateSchemePulldowns()
def body(self, guiParent): guiParent.grid_columnconfigure(1,weight=1) row = 0 file_types = [ FileType('Python', ['*.py']), FileType('All', ['*']) ] self.file_select = FileSelect(guiParent, file_types=file_types, single_callback=self.chooseFile, double_callback=self.chooseFile) self.file_select.grid(row=row, column=0, columnspan=2, sticky='nsew') row = row + 1 headingList=('Function',) self.scrolledMatrix = ScrolledMatrix(guiParent, initialRows=4, headingList=headingList, callback=self.selectFunction) self.scrolledMatrix.grid(row=row, column=0, columnspan=2, sticky='nsew') guiParent.grid_rowconfigure(row,weight=1) row = row + 1 self.moduleLabel1 = Label(guiParent, text='Module: ') self.moduleLabel1.grid(row=row, column=0, sticky='nw') self.moduleLabel2 = Label(guiParent, text=' ') self.moduleLabel2.grid(row=row, column=1, sticky='nw') row = row + 1 self.functionLabel1 = Label(guiParent, text='Function: ') self.functionLabel1.grid(row=row, column=0, sticky='nw') self.functionLabel2 = Label(guiParent, text=' ') self.functionLabel2.grid(row=row, column=1, sticky='nw') row = row + 1 self.nameLabel = Label(guiParent, text='Name: ') self.nameLabel.grid(row=row, column=0, sticky='nw') self.nameEntry = Entry(guiParent, text=' ', width=40) self.nameEntry.grid(row=row, column=1, sticky='nw') row = row + 1 texts = [ 'Load Macro' ] commands = [ self.loadMacro ] buttons = UtilityButtonList(guiParent, texts=texts, commands=commands, helpUrl=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky='ew') self.loadButton = buttons.buttons[0] self.loadButton.disable() self.path = None self.module = None self.function = None
def body(self, guiFrame): '''This method describes the outline of the body of the application. args: guiFrame: frame the body should live in. ''' self.geometry('900x700') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=1) tabbedFrame = TabbedFrame(guiFrame, options=['Spectra', 'Annealing', 'Results', 'Bulk Transfer Assignments To Project', 'Save and Load'], callback=self.toggleTab, grid=(0, 0)) self.tabbedFrame = tabbedFrame autoFrame, NAFrame, resultsFrame, assignFrame, saveFrame = tabbedFrame.frames self.spectrumSelectionTab = SpectrumSelectionTab(self, autoFrame) self.assignTab = AssignMentTransferTab(self, assignFrame) self.saveLoadTab = SaveLoadTab(self, saveFrame) self.annealingSettingsTab = AnnealingSettingsTab(self, NAFrame) self.resultsTab = ResultsTab(self, resultsFrame) bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl='www.google.com') bottomButtons.grid(row=0, column=0, sticky='e') self.infoLabel = Label(guiFrame, text=' ') self.infoLabel.grid(row=2, column=0, sticky='w') self.waiting = False self.updateAfter() self.administerNotifiers(self.registerNotify)
def body(self, guiFrame): guiFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = LabelFrame(guiFrame, text='Matched Peak Groups') frame.grid_rowconfigure(0, weight=1) frame.grid_columnconfigure(0, weight=1) frame.grid(row=row, sticky='nsew') headingList, tipTexts = self.getHeadingList() self.scrolledMatrix = ScrolledMatrix(frame, initialRows=15, multiSelect=True, headingList=headingList, tipTexts=tipTexts, grid=(0,0), gridSpan=(1,3)) tipTexts = ['Remove the selected peak groups from the table', 'Show 1D positional ruler lines for the selected groups', 'Remove any ruler lines previously added for peak group', 'Display selected peak groups within strips of selected window'] texts = ['Remove\nGroups','Show\nRulers', 'Delete\nRulers','Display Groups\nIn Strips'] commands = [self.removeGroups,self.addRulers, self.removeRulers,self.stripGroups] self.buttons = ButtonList(frame, texts=texts, commands=commands, tipTexts=tipTexts) self.buttons.grid(row=1, column=0, sticky='ew') tipText = 'Selects the spectrum window in which to display strips & ruler lines' label = Label(frame, text='Target window:', grid=(1,1)) self.windowPulldown = PulldownList(frame, callback=None, grid=(1,2), tipText=tipText) row+= 1 bottomButtons = UtilityButtonList(guiFrame, helpUrl=self.help_url, expands=True, doClone=False) bottomButtons.grid(row = row, sticky = 'ew') self.update() for func in ('__init__', 'delete', 'setName'): self.registerNotify(self.updateWindowsAfter, 'ccpnmr.Analysis.SpectrumWindow', func)
def body(self, guiFrame): self.geometry('450x500') guiFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_columnconfigure(0, weight=1) options = ['Peak Separator', 'Advanced Settings'] tabbedFrame = TabbedFrame(guiFrame, options=options) tabbedFrame.grid(row=0, column=0, sticky='nsew') buttons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url) buttons.grid(row=0, column=0, sticky='e') self.tabbedFrame = tabbedFrame frameA, frameB = tabbedFrame.frames # # FrameA : Main Settings # frameA.grid_columnconfigure(1, weight=1) row = 0 # Label row row += 1 div = LabelDivider(frameA, text='Peak Separator Parameters') div.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 label = Label(frameA, text='Min. number of peaks:') label.grid(row=row, column=0, sticky='w') self.minPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \ tipText='Minimum number of peaks to find (must be > 0)') self.minPeaksEntry.grid(row=row, column=1, sticky='n') self.minPeaksEntry.bind('<Leave>', self.applyChange, '+') row += 1 label = Label(frameA, text='Max. number of peaks:') label.grid(row=row, column=0, sticky='w') self.maxPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \ tipText='Maximum number of peaks to find (0 is unlimited - not recommended)') self.maxPeaksEntry.grid(row=row, column=1, sticky='n') self.maxPeaksEntry.bind('<Leave>', self.applyChange, '+') row += 1 label = Label(frameA, text='Only pick positive peaks:') label.grid(row=row, column=0, sticky='w') entries = ['False', 'True'] self.posPeaksButtons = RadioButtons( frameA, entries=entries, select_callback=self.applyChange, direction='horizontal', tipTexts=[ 'Search for both positive and negative intensity peaks', 'Limit search to only positive peaks' ]) self.posPeaksButtons.grid(row=row, column=1, sticky='n') row += 1 label = Label(frameA, text='Peak Model:') label.grid(row=row, column=0, sticky='w') ### G/L Mixture works, but volume calculation involves Gamma function # entries = ['Gaussian', 'Lorentzian', 'G/L Mixture'] entries = ['Gaussian', 'Lorentzian'] self.shapeButtons = RadioButtons( frameA, entries=entries, select_callback=self.applyChange, direction='horizontal', tipTexts=[ 'Choose a Gaussian model peak shape to fit to peaks', 'Choose a Lorentzian model peak shape to fit to peaks' ]) self.shapeButtons.grid(row=row, column=1, sticky='n') row += 1 div = LabelDivider(frameA, text='Region', tipText='Region that search will limit itself to') div.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 label = Label(frameA, text='Peak List:') label.grid(row=row, column=0, sticky='nw') self.peakListPulldown = PulldownList( frameA, callback=self.setManuallyPickPeakList, tipText='Select which peak list new peaks are to be added to') self.peakListPulldown.grid(row=row, column=1, sticky='nw') # tricky scrolled matrix row += 1 self.regionTable = None frameA.grid_rowconfigure(row, weight=1) headings = ('dim.', 'start (ppm)', 'end (ppm)', 'actual size') self.editDimEntry = IntEntry(self, returnCallback=self.applyChange, width=5, tipText='Dimension number') self.editStartEntry = FloatEntry(self, returnCallback=self.applyChange, width=5, tipText='Search area lower bound') self.editEndEntry = FloatEntry(self, returnCallback=self.applyChange, width=5, tipText='Search area upper bound') editWidgets = [ self.editDimEntry, self.editStartEntry, self.editEndEntry, None ] editGetCallbacks = [None, None, None, None] editSetCallbacks = [None, None, None, None] self.regionTable = ScrolledMatrix(frameA, headingList=headings, multiSelect=False, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, initialRows=5) self.regionTable.grid(row=row, column=0, columnspan=2, sticky='nsew') # Run Button row += 1 texts = ['Add Region'] commands = [self.updateFromRegion] self.addResetButtons = ButtonList( frameA, texts=texts, commands=commands, tipTexts=['Add selected specrtral region']) self.addResetButtons.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 texts = ['Separate Peaks'] commands = [self.runPeakSeparator] self.runButton = ButtonList(frameA, texts=texts, commands=commands, expands=True, tipTexts=['Run peak search now']) self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew') # # FrameB : Further Settings # frameB.grid_columnconfigure(0, weight=1) row = 0 div = LabelDivider(frameB, text='Rate:') div.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 label = Label(frameB, text='Rate of MCMC step size change') label.grid(row=row, column=0, columnspan=1, sticky='w') self.rateEntry = FloatEntry(frameB, returnCallback=self.applyChange, width=10, \ tipText='Rate effects speed of run, smaller values take longer but may produce better results') self.rateEntry.grid(row=row, column=1, sticky='n') self.rateEntry.bind('<Leave>', self.applyChange, '+') self.rateEntry.set(self.params.rate) # tricky scrolled matrix for line width row += 2 div = LabelDivider(frameB, text='Line Width (Hz):') div.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 label = Label(frameB, text="Descr.") label.grid(row=row, rowspan=2, column=0, sticky='w') row += 1 self.lineWidthTable = None frameB.grid_rowconfigure(row, weight=1) lineWidthHeadings = ('dim.', 'min. σ (Hz)', 'max. σ (Hz)') self.editMinSigmaEntry = FloatEntry(self, returnCallback=self.applyChange, width=5, tipText='Minimum line width (Hz)') self.editMaxSigmaEntry = FloatEntry(self, returnCallback=self.applyChange, width=5, tipText='Maximum line width (Hz)') # self.editDimEntry is also from regionTable initialWidthRows = 4 editLineWidthWidgets = [ None, self.editMinSigmaEntry, self.editMaxSigmaEntry ] editLineWidthGetCallbacks = [None, self.getSigmaMin, self.getSigmaMax] editLineWidthSetCallbacks = [None, self.setSigmaMin, self.setSigmaMax] self.lineWidthTable = ScrolledMatrix( frameB, headingList=lineWidthHeadings, multiSelect=False, editWidgets=editLineWidthWidgets, editGetCallbacks=editLineWidthGetCallbacks, editSetCallbacks=editLineWidthSetCallbacks, initialRows=initialWidthRows) self.lineWidthTable.grid(row=row, column=0, columnspan=2, sticky='nsew') # option to 'repick' exisiting peak list row += initialWidthRows div = LabelDivider(frameB, text='(optional - repick entire peak list)') div.grid(row=row, column=0, columnspan=2, sticky='ew') row += 1 self.repickListPulldown = PulldownList( frameB, callback=self.setRePickPeakList, tipText= 'Select which peak list to repick (new peaks will be put into a new peak list)' ) self.repickListPulldown.grid(row=row, column=0, sticky='nw') texts = ['Repick Peak List'] commands = [self.runRepickPeaks] self.runButton = ButtonList( frameB, texts=texts, commands=commands, expands=True, tipTexts=['Repick selected peak list into a new peak list.']) self.runButton.grid(row=row, column=1, columnspan=1, sticky='nsew') row += 1 div = LabelDivider(frameB) row += 1 texts = ['Separate Peaks'] commands = [self.runPeakSeparator] self.runButton = ButtonList(frameB, texts=texts, commands=commands, expands=True, tipTexts=['Run peak search now']) self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew') self.setWidgetEntries() self.administerNotifiers(self.registerNotify)
def body(self, master): fileName = self.fileName directory = os.path.dirname(fileName) if not directory: directory = os.getcwd() fileName = os.path.basename(fileName) m = template_re.match(fileName) if m: n = len(m.groups(2)) ss = '%%0%dd' % n template = re.sub(template_re, r'\1%s\3' % ss, fileName) else: template = fileName master.rowconfigure(0, weight=1) master.rowconfigure(1, weight=1) master.columnconfigure(1, weight=1) tipTexts = [ 'The experiment is pseudo-N dimensional, with a sampled axis', 'The experiment is the regular kind with only NMR frequency axes' ] self.pseudoButton = RadioButtons( master, entries=self.pseudoEntries, select_callback=self.changedPseudoMode, grid=(0, 0), sticky='nw', tipTexts=tipTexts) frame = self.pseudoFrame = Frame(master) self.pseudoFrame.grid(row=1, column=0, sticky='nsew') row = 0 npts = self.params.npts[self.dim] tipText = 'Number of data points (planes) along sampled axis' label = Label(frame, text='Number of points: ') label.grid(row=row, column=0, sticky='e') self.nptsEntry = IntEntry(frame, text=npts, tipText=tipText, width=8, grid=(row, 1)) tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values' Button(frame, text='Load values from text file', command=self.loadValues, tipText=tipText, grid=(row, 2), sticky='ew') row = row + 1 tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis' label = Label(frame, text='Point values: ') label.grid(row=row, column=0, sticky='e') self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText) self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew') row = row + 1 tipText = 'Fetch the Point values from the files given by the NMRPipe template' button = Button( frame, text='Fetch values from file(s) specified by template below', command=self.fetchValues, tipText=tipText) button.grid(row=row, column=1, columnspan=2, sticky='w') row = row + 1 tipText = 'The directory where the data files reside' button = Button(frame, text='Data directory: ', command=self.chooseDirectory) button.grid(row=row, column=0, sticky='e') self.directoryEntry = Entry(frame, text=directory, width=40, tipText=tipText) self.directoryEntry.grid(row=row, column=1, columnspan=2, sticky='ew') row = row + 1 tipText = 'The NMRPipe template for the data files, if you want to use these to fetch the point values from' button = Button(frame, text='NMRPipe template: ', command=self.chooseFile) button.grid(row=row, column=0, sticky='e') self.templateEntry = Entry(frame, text=template, tipText=tipText) self.templateEntry.grid(row=row, column=1, columnspan=2, sticky='ew') for n in range(row): frame.rowconfigure(n, weight=1) frame.columnconfigure(1, weight=1) buttons = UtilityButtonList(master, closeText='Ok', doClone=False, closeCmd=self.updateParams, helpUrl=self.help_url) buttons.grid(row=2, column=0, sticky='ew')
class EditContourFilesPopup(BasePopup): """ **Manage Contour Files in Project** The purpose of this dialog is to allow the user to manage contour files. A contour file stores contours calculated at specified contour levels in a specified region of a spectrum, as an alternative to calculating contours on the fly. You cannot pick peaks using contour files but after peaks have been picked, contour files are a reasonable alternative to contours for large 3D and 4D data sets, since the spectrum data does not need to be read from disk. This dialog lists the contour files that are in the project. To create a new contour file click on the "Create New File" button and to add a contour file that already exists on disk (e.g. from another project) then click on the "Find Existing File" button. When a contour file is created for a spectrum then by default it is used to display contours rather than having them calculated on the fly. This can be changed in the main `Spectra`_ dialog in the Display Options tab. See also: `Creating Contour Files`_, `Add Existing Contour Files`_. .. _`Spectra`: EditSpectrumPopup.html .. _`Creating Contour Files`: CreateContourFilePopup.html .. _`Add Existing Contour Files`: AddContourFilePopup.html """ def __init__(self, parent, *args, **kw): self.waiting = False self.contourFileDir = None BasePopup.__init__(self, parent=parent, title='Spectrum Contour Files', **kw) def body(self, master): self.geometry('650x200') master.grid_columnconfigure(0, weight=1) row = 0 master.grid_rowconfigure(row, weight=1) self.storedContourTable = None headings = ('#', 'Experiment', 'Spectrum', 'Dims', 'Directory', 'File') ###self.urlWidget = Entry(self, returnCallback=self.setUrl, width=10) ###self.pathWidget = Entry(self, returnCallback=self.setPath, width=10) ###editWidgets = [ None, None, None, None, self.urlWidget, self.pathWidget ] ###editGetCallbacks = [ None, None, None, None, self.getUrl, self.getPath ] ###editSetCallbacks = [ None, None, None, None, self.setUrl, self.setPath ] tipTexts = [ 'Row number', 'The experiment that contains the spectrum to which the contour file relates', 'The spectrum to which the contour file relates', 'The projected spectrum dimensions which are represented by the contour file, i.e. to form the X-Y plane of the screen', 'Directory in which the contour file is saved', 'The name of the file in which contours for thei spectrum projection are saved' ] editWidgets = 6 * [None] editGetCallbacks = 6 * [None] editSetCallbacks = 6 * [None] self.storedContourTable = ScrolledMatrix( master, headingList=headings, callback=self.setButtonState, editWidgets=editWidgets, multiSelect=True, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, deleteFunc=self.deleteContourFile, tipTexts=tipTexts) self.storedContourTable.grid(row=row, column=0, sticky='nsew') row = row + 1 tipTexts = [ 'Locate an exiting file on disk and use that as a spectrum contour file', 'Create a new spectrum contour file; requires that the spectrum data matrix is accessible', 'Remove the selected contour file from the CCPN project and optionally delete the file from disk' ] texts = ['Find Existing File', 'Create New File', 'Delete'] commands = [ self.addContourFile, self.createContourFile, self.deleteContourFile ] self.buttons = UtilityButtonList(master, texts=texts, doClone=False, commands=commands, helpUrl=self.help_url) self.buttons.grid(row=row, column=0, sticky='ew') self.updateAfter() for clazz in ('ccp.nmr.Nmr.Experiment', 'ccp.nmr.Nmr.DataSource'): self.registerNotify(self.updateAfter, clazz, 'setName') for func in ('__init__', 'delete', ''): self.registerNotify(self.updateAfter, 'ccpnmr.Analysis.StoredContour', func) ###self.registerNotify(self.updateAfter, 'memops.Implementation.Url', 'setPath') def open(self): self.updateAfter() BasePopup.open(self) def destroy(self): for clazz in ('ccp.nmr.Nmr.Experiment', 'ccp.nmr.Nmr.DataSource'): self.registerNotify(self.updateAfter, clazz, 'setName') for func in ('__init__', 'delete', ''): self.unregisterNotify(self.updateAfter, 'ccpnmr.Analysis.StoredContour', func) ###self.unregisterNotify(self.updateAfter, 'memops.Implementation.Url', 'setPath') BasePopup.destroy(self) def updateAfter(self, *extra): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def update(self): self.updateStoredContourTable() self.setButtonState() self.waiting = False def updateStoredContourTable(self, *extra): analysisSpectra = self.analysisProject.analysisSpectra objectList = [] textMatrix = [] n = 0 for analysisSpectrum in analysisSpectra: spectrum = analysisSpectrum.dataSource for storedContour in analysisSpectrum.storedContours: if storedContour.isDeleted: continue n = n + 1 dims = ', '.join(['%d' % dim for dim in storedContour.dims]) text = [ n, spectrum.experiment.name, spectrum.name, dims, analysisSpectrum.contourDir.dataLocation, storedContour.path ] objectList.append(storedContour) textMatrix.append(text) self.storedContourTable.update(objectList=objectList, textMatrix=textMatrix) """ def getUrl(self, storedContour): self.urlWidget.set(storedContour.url.path) def setUrl(self, *extra): storedContour = self.getStoredContour() if not storedContour: return path = self.urlWidget.get() if not path: return url = storedContour.url project = self.project analysisProject = self.analysisProject if len(analysisProject.findAllStoredContours(url=url)) > 1 or \ project.findAllStorages(url=url) or project.findAllDataLocations(url=url): # create a new url with new path url = project.newUrl(name='storedContourUrl', path=path) else: # just change url path since (hopefully) nobody else is using it try: url.path = path except Implementation.ApiError, e: showError('Setting url path', e.error_msg, parent=self) def getPath(self, storedContour): self.pathWidget.set(storedContour.path) def setPath(self, *extra): storedContour = self.getStoredContour() if not storedContour: return path = self.pathWidget.get() if not path: return try: storedContour.path = path except Implementation.ApiError, e: showError('Setting stored contour path', e.error_msg, parent=self) """ def setButtonState(self, *extra): if self.storedContourTable.objectList: state = 'normal' else: state = 'disabled' self.buttons.buttons[2].config(state=state) def getSpectrum(self): storedContour = self.getStoredContour() if storedContour: try: spectrum = storedContour.dataSource except: spectrum = None else: spectrum = None return spectrum def getStoredContour(self): if self.storedContourTable: storedContour = self.storedContourTable.currentObject if storedContour and storedContour.isDeleted: storedContour = None else: storedContour = None return storedContour def getStoredContours(self): if (self.storedContourTable): storedContours = self.storedContourTable.currentObjects return storedContours def addContourFile(self, *extra): spectrum = self.getSpectrum() self.parent.addSpectrumContourFile(spectrum) def createContourFile(self, *extra): spectrum = self.getSpectrum() self.parent.createSpectrumContourFile(spectrum) def deleteContourFile(self, *extra): storedContours = self.getStoredContours() if not storedContours: return if len(storedContours) == 1: s = t = '' else: s = ' %d ' % len(storedContours) t = 's' if (showYesNo( 'Delete stored contour%s from project' % t, 'Are you sure you want to delete selected %sstored contour%s from the project?' % (s, t), parent=self)): if (showYesNo( 'Delete underlying contour file%s on disk' % t, 'Do you also want to delete underlying contour file%s on disk (normally yes)?' % t, parent=self)): for storedContour in storedContours: path = storedContour.fullPath try: os.remove(path) except: print 'Warning: could not remove %s' % path for storedContour in storedContours: storedContour.delete()
def body(self, guiFrame): guiFrame.grid_columnconfigure(3, weight=1) self.progressBar = TypingEnsemblePopup(self,total=100) self.progressBar.close() row = 0 label = Label(guiFrame, text=' Chain: ', grid=(row,0)) tipText = 'Selects which molecular chain the spin system residue types will be predicted for; determines which range of types are available' self.chainPulldown = PulldownList(guiFrame, self.changeChain, grid=(row,1), tipText=tipText) tipText = 'Selects which shift list will be used as the source of chemical shift information to make the residue type predictions' label = Label(guiFrame, text='Shift List: ', grid=(row,2)) self.shiftListPulldown = PulldownList(guiFrame, callback=self.setShiftList, grid=(row,3), tipText=tipText) utilButtons = UtilityButtonList(guiFrame, helpUrl=self.help_url) utilButtons.grid(row=row, column=4, sticky='w') row += 1 frame = LabelFrame(guiFrame, text='Options', grid=(row,0), gridSpan=(1,5)) frame.grid_columnconfigure(3, weight=1) frow = 0 label = Label(frame, text='Keep existing types?', grid=(frow,0), sticky='e') tipText = 'Whether any existing residue type information should be preserved, when predicting the type of others' self.preserveTypesSelect = CheckButton(frame, grid=(frow,1), selected=False, callback=self.selectPreserveTypes, tipText=tipText) label = Label(frame, text='Assignment threshold: ', grid=(frow,2), sticky='e') tipText = 'The lower limit for the predicted residue type to be set with "Assign Types"; needs to be adjusted according to result statistics and amount of shift data' self.thresholdEntry = FloatEntry(frame, text=self.threshold, width=8, grid=(frow,3), tipText=tipText) frow += 1 label = Label(frame, text='Ensemble size: ', grid=(frow,0), sticky='e') tipText = 'The number of best scoring residue type mappings, from the Monte Carlo search, to use un the prediction' self.ensembleEntry = IntEntry(frame,text=20,width=4, grid=(frow,1), tipText=tipText) label = Label(frame, text='Num Search Steps: ', grid=(frow,2), sticky='e') tipText = 'The number of iterative steps that will be used in the Monte Carlo search of best spin system to residue type mappings' self.stepsEntry = IntEntry(frame, text=100000, width=8, tipText=tipText, grid=(frow,3)) frow += 1 label = Label(frame, text='Isotope shifts to consider:', grid=(frow,0), gridSpan=(1,4)) frow += 1 self.isotopes = ['1H','13C'] isos = ['1H','13C','15N'] colors = [COLOR_DICT[x] for x in isos] tipText = 'Selects which kinds of resonances, in terms of isotope, the residue type predictions will be made with' self.isotopeCheckButtons = PartitionedSelector(frame, labels=isos, objects=isos, colors=colors, callback=self.toggleIsotope, selected=self.isotopes, grid=(frow,0), gridSpan=(1,4), tipText=tipText) row += 1 guiFrame.grid_rowconfigure(row, weight=1) labelFrame = LabelFrame(guiFrame, text='Spin Systems', grid=(row,0), gridSpan=(1,5)) labelFrame.expandGrid(0,0) tipTexts = ['The spin system serial number', 'The residue to which the spin system may currently be assigned', 'Set whether to include a particular spin system in the type predictions', 'The spin system to residue type match score for a prediction; higher (less negative) is better', 'The predicted types of residue that the spin system may be', 'The chemical shifts in the spin system that will be used in the analysis'] headingList = ['#','Residue','Use?','Score','Types','Shifts'] justifyList = ['center','center','center','center','center','left'] editWidgets = [None, None, None, None, None, None] editGetCallbacks = [None, None, self.toggleInclude, None, None, None] editSetCallbacks = [None, None, None, None, None, None] self.scrolledMatrix = ScrolledMatrix(labelFrame, headingList=headingList, justifyList=justifyList, editSetCallbacks=editSetCallbacks, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, callback=self.selectCell, grid=(0,0), tipTexts=tipTexts) row += 1 tipTexts = ['Execute the Monte Carlo search that will make the residue type predictions for the spin systems', 'Assign the residue type of spin systems with a unique type prediction and prediction score above the stated threshold', 'Show a residue type prediction for the selected spin system alone; only considers that spin system of shifts, not how all spin systems fit to the sequence', 'Show a table of peaks that are assigned to the resonances of the selected spin system'] texts = ['Run\nTyping','Assign\nTypes', 'Show Individual\nClassification', 'Show\nPeaks'] commands = [self.run, self.assign, self.individualScore, self.showPeaks] bottomButtons = ButtonList(guiFrame, texts=texts, commands=commands, grid=(row,0), gridSpan=(1,5), tipTexts=tipTexts) self.runButton = bottomButtons.buttons[0] self.assignButton = bottomButtons.buttons[1] self.scoreButton = bottomButtons.buttons[2] self.peaksButton = bottomButtons.buttons[2] self.runButton.config(bg='#B0FFB0') for func in ('__init__','delete'): self.registerNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) self.registerNotify(self.updateShiftLists, 'ccp.nmr.Nmr.ShiftList', func) for func in ('__init__','delete','setCcpCode', 'setResidue','addResonance', 'setName', 'removeResonance','setResonances'): self.registerNotify(self.updateSpinSystemsAfter, 'ccp.nmr.Nmr.ResonanceGroup', func) self.updateChains() self.updateShiftLists() self.updateSpinSystems()
class UpdatePopup(BasePopup, UpdateAgent): """ **Install Patches and Updates to CCPN Software** This popup window allows the user to view and automatically install the latest updates and patches to CcpNmr software. This is the normal mechanism of receiving incremental changes and fixes to bug reports between numbered CCPN releases. It should be noted that this system generally only provides fixes for the most recent version of the CcpNmr Software. If your version is older (but not as old as version 1.0) or if there has been a recent new release then the updating mechanism will automatically upgrade the whole CCPN distribution to the newest one. It should be noted that this mechanism will not automatically update some of the really old versions, e.g. from version 1.0 to 2.0. Updates from 2.0 onwards ought to work seamlessly though. In normal operation the user clicks [Select All] then [Install Selected], whereupon the software should be restarted (not forgetting to save any data). Naturally, viewing and receiving updates requires that the user's computer has a working connection to the Internet. Although the user may toggle individual file updates on or off by double-clicking in the "Install?" column, it is generally not a good idea to choose only a subset of file updates unless there is a specific reason to do so. Choosing only some file updates risks getting problems where two or more files rely upon the most recent versions of one another. **Caveats & Tips** Using [Refresh List] will cause the system to re-query the CCPN update server if the user is awaiting an imminent fix. When an updated file is installed the old version is not removed; it is renamed with the "_old" suffix. If for any reason this popup window cannot be opened the user may update the software using the "updateAll" script that sits alongside the main "analysis" program executable (usually in the $CCPN_HOME/bin/ directory). """ def __init__(self, parent, serverLocation=UPDATE_SERVER_LOCATION, serverDirectory=UPDATE_DIRECTORY, dataFile=UPDATE_DATABASE_FILE, exitOnClose=False, helpUrl=None): self.exitOnClose = exitOnClose self.helpUrl = helpUrl UpdateAgent.__init__(self, serverLocation, serverDirectory, dataFile, isStandAlone=exitOnClose) self.fileUpdate = None if exitOnClose: quitFunc = sys.exit else: quitFunc = None BasePopup.__init__(self, parent=parent, title='CcpNmr Software Updates', quitFunc=quitFunc) def body(self, guiParent): self.geometry('600x300') guiParent.grid_columnconfigure(1, weight=1) url = '' if self.server: url = self.server.url label = Label(guiParent, text='Server location: %s' % url) label.grid(row=0, column=0, sticky='w', columnspan=2) label = Label(guiParent, text='Installation root: %s%s' % (self.installRoot, os.sep)) label.grid(row=1, column=0, sticky='w', columnspan=2) editWidgets = [None] * 5 editGetCallbacks = [None, self.toggleSelected, None, None, None] editSetCallbacks = [None] * 5 guiParent.grid_rowconfigure(2, weight=1) headingList = [ 'File', 'Install?', 'Date', 'Relative Path', 'Priority', 'Comments' ] tipTexts = [ 'The name of the file for which an update is available', 'Whether the file will be replaced when the user commits the upgrade', 'The data that the new file version was posted on the CCPN server', 'The path that the file will be installed at, relative to the CCPN installation', 'The priority number of the installation; commonly not configured away from "1"', 'Any comments added by the CCPN developers' ] self.scrolledMatrix = ScrolledMatrix(guiParent, headingList=headingList, highlightType=0, tipTexts=tipTexts, editWidgets=editWidgets, callback=self.selectCell, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.scrolledMatrix.grid(row=2, column=0, columnspan=2, sticky='nsew') if self.exitOnClose: #txt = 'Quit' cmd = sys.exit else: #txt = 'Close' cmd = self.close texts = ['Refresh List', 'Select All', 'Install Selected'] commands = [self.updateFiles, self.selectAll, self.install] tipTexts = [ 'Refresh the list of file updates by querying the CCPN update server, assuming an Internet connection is present', 'Select all of the file updates for installation (recommended)', 'Install newest versions of the selected files' ] self.buttonList = UtilityButtonList(guiParent, texts=texts, doClone=False, helpUrl=self.helpUrl, commands=commands, closeCmd=cmd, tipTexts=tipTexts) self.buttonList.grid(row=3, column=0, columnspan=2, sticky='ew') if self.server: for fileUpdate in self.server.fileUpdates: fileUpdate.isSelected = False #self.update() # need self.updateFiles, not just self.update # because otherwise the 2.0.5 to 2.0.6 upgrades do not work # (self.server not set on first pass so need call to updateFiles here) self.updateFiles() def toggleSelected(self, fileUpdate): boolean = fileUpdate.isSelected fileUpdate.isSelected = not boolean self.update() def install(self): if self.server: self.installUpdates() self.updateFiles() def selectAll(self): if self.server: for fileUpdate in self.scrolledMatrix.objectList: fileUpdate.isSelected = True self.update() def selectCell(self, object, row, col): self.fileUpdate = object def updateButtons(self): buttons = self.buttonList.buttons if self.server: selected = False if self.server and self.server.fileUpdates: for fileUpdate in self.scrolledMatrix.objectList: if fileUpdate.isSelected: selected = True break buttons[1].enable() else: buttons[1].disable() if selected: buttons[2].enable() buttons[2].config(bg='#A0FFA0') else: buttons[2].disable() buttons[2].config(bg=buttons[1].cget('bg')) else: for button in buttons[:-1]: button.disable() def updateFiles(self): if self.server: if not self.server.fileUpdates: self.server.getFileUpdates() for fileUpdate in self.server.fileUpdates: fileUpdate.isSelected = False self.update() def update(self): self.updateButtons() self.fileUpdate = None textMatrix = [] objectList = [] colorMatrix = [] if self.server: for fileUpdate in self.server.fileUpdates: if fileUpdate.getIsUpToDate(): continue color = [None, '#A04040', None, None, None] yesNo = 'No' if fileUpdate.isSelected: color = [None, '#A0FFA0', None, None, None] yesNo = 'Yes' datum = [] datum.append(fileUpdate.fileName) datum.append(yesNo) datum.append(fileUpdate.date) datum.append(fileUpdate.filePath + os.sep) datum.append(fileUpdate.priority) datum.append(fileUpdate.details) colorMatrix.append(color) textMatrix.append(datum) objectList.append(fileUpdate) self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix)
def body(self, master): master.grid_columnconfigure(1, weight=1) master.grid_rowconfigure(0, weight=1) view = self.spectrumWindowView spectrum = view.analysisSpectrum.dataSource dataDims = spectrum.sortedDataDims() self.ndim = spectrum.numDim self.prev_label = self.ndim * [ None ] self.redraw = False row = 0 label = Label(master, text='Window:') label.grid(row=row, column=0, sticky='w') name = getWindowPaneName(self.spectrumWindowView.spectrumWindowPane) tipText = 'The name of the window where the dimension mapping is changing ' label = Label(master, text=name, tipText=tipText) label.grid(row=row, column=1, sticky='w') row += 1 label = Label(master, text='Experiment:') label.grid(row=row, column=0, sticky='w') tipText = 'The NMR experiment to change dimension mapping for' label = Label(master, text=spectrum.experiment.name, tipText=tipText) label.grid(row=row, column=1, sticky='w') row += 1 label = Label(master, text='Spectrum:') label.grid(row=row, column=0, sticky='w') tipText = 'The spectrum data to change the dimension mapping for' label = Label(master, text=spectrum.name, tipText=tipText) label.grid(row=row, column=1, sticky='w') self.axis_lists = self.ndim * [0] for n in range(self.ndim): row += 1 callback = lambda entry_index, entry, dim=n: self.callback(dim, entry) dataDim = dataDims[n] axisMapping = findDataDimAxisMapping(view, dataDim) entries = self.validAxisLabels(dataDim) selected = axisMapping.label if selected not in entries: label = Label(master, text='Dimension %d:\n(sampled)' % (n+1,)) label.grid(row=row, column=0, sticky='w') else: label = Label(master, text='Dimension %d:' % (n+1,)) label.grid(row=row, column=0, sticky='w') selected_index = entries.index(selected) tipText = 'Selects which numbered spectrum dimension goes with which window axis' self.axis_lists[n] = PulldownMenu(master, callback=callback, entries=entries, tipText=tipText, selected_index=selected_index) self.axis_lists[n].grid(row=row, column=1, sticky='w') row += 1 texts = commands = [] tipTexts = ['Commit any changes to the spectrum dimension to window axis mapping and close the popup',] texts = [ ' Commit ',] commands = [ self.ok,] buttons = UtilityButtonList(master, texts=texts, tipTexts=tipTexts, commands=commands, doClone=False, helpUrl=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky='ew')
class EditResStructuresPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.structure = None self.constraintSet = None self.cloud = None self.cloudRmsdDict = {} self.strucRmsdDict = {} self.waiting = False BasePopup.__init__(self, parent=parent, title="Resonance Cloud Structures", **kw) def body(self, guiFrame): row = 0 guiFrame.grid_columnconfigure(1, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=1) self.generationLabel = Label(guiFrame, text='Structure Generation:') constraintSets = [] constraintSetNames = [] index = -1 for constraintSet in self.project.nmrConstraintStores: index += 1 constraintSets.append(constraintSet) constraintSetNames.append(str(constraintSet.serial)) self.constraintSet = constraintSet self.constrSetPulldown = PulldownMenu(guiFrame, self.changeConstraintSet, constraintSetNames, selected_index=index, do_initial_callback=False) self.generationLabel.grid(row=row, column=0, columnspan=1, sticky='e') self.constrSetPulldown.grid(row=row, column=1, columnspan=1, sticky='w') strucLabel = Label(guiFrame, text='Comparison structure') strucLabel.grid(row=row, column=2, sticky='e') self.strucPulldown = PulldownMenu(guiFrame, entries=self.getStructures(), callback=self.setStructure, selected_index=0, do_initial_callback=False) self.strucPulldown.grid(row=row, column=3, sticky='w') sdTolLabel = Label(guiFrame, text='Tolerance (SDs):') sdTolLabel.grid(row=row, column=4, sticky='e') self.sdToleranceEntry = FloatEntry(guiFrame, text=2.0, width=6) self.sdToleranceEntry.grid(row=row, column=5, stick='w') row += 1 colHeadings = ['#', 'File name', 'RMSD to mean', 'RMSD to structure'] self.scrolledMatrix = ScrolledMatrix(guiFrame, initialRows=10, headingList=colHeadings, callback=self.selectCell, objectList=[], textMatrix=[ [], ]) self.scrolledMatrix.grid(row=row, column=0, columnspan=6, sticky='nsew') row += 1 texts = [ 'Calc\nRMSD', 'Make Cloud\nfrom structure', 'Delete', 'Delete\nbad' ] commands = [ self.calcRmsd, self.makeStrucCloud, self.deleteCloud, self.filterClouds ] self.bottomButtons = UtilityButtonList(guiFrame, texts=texts, expands=False, commands=commands, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, columnspan=6, sticky='nsew') self.update() for func in ('__init__', 'delete'): self.registerNotify(self.updateStructureGen, 'ccp.nmr.Nmr.StructureGeneration', func) def open(self): self.updateAfter() BasePopup.open(self) def getStructures(self): names = [ '<None>', ] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): names.append('%s:%d' % (molSystem.name, structure.ensembleId)) return names def setStructure(self, index, name=None): if index < 1: self.structure = None else: structures = [] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): structures.append(structure) self.structure = structures[index - 1] def filterClouds(self): if self.constraintSet: sdTolerance = self.sdToleranceEntry.get() or 2.0 keptClouds = [] clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') meanGroupRmsds = [] for cloud in clouds: rmsd = self.cloudRmsdDict.get(cloud) if rmsd is not None: meanGroupRmsds.append(rmsd) meanRmsd = 0.0 N = 0 for rmsd in meanGroupRmsds: meanRmsd += rmsd N += 1 if N > 0: meanRmsd /= float(N) sd = 0.0 for rmsd in meanGroupRmsds: sd += (rmsd - meanRmsd) * (rmsd - meanRmsd) if N > 0: sd /= float(N - 1) sd = sqrt(sd) print meanRmsd, '+/-', sd n = 0 for cloud in clouds: rmsd = self.cloudRmsdDict.get(cloud) if rmsd is None: keptClouds.append(cloud) elif abs(rmsd - meanRmsd) > (sdTolerance * sd): print 'Cloud %s is bad' % (cloud) else: keptClouds.append(cloud) self.guiParent.application.setValues(self.constraintSet, 'clouds', values=keptClouds) self.updateAfter() def makeStrucCloud(self): if self.structure: serials = self.guiParent.application.getValues( self.constraintSet, 'cloudsResonances') pdbFileName = 'CloudForStructure.pdb' #from ccpnmr.clouds.AtomCoordList import AtomCoordList from ccpnmr.c.AtomCoordList import AtomCoordList atomCoordList = AtomCoordList() resDict = {} hmass = 25 print "L1", len(serials) for resonance in self.nmrProject.resonances: resDict[resonance.serial] = resonance print "L2", len(resDict) resonances = [] for serial in serials: if resDict.get(serial) is not None: resonances.append(resDict[serial]) print "L3", len(resonances) C = 0 for resonance in resonances: resonanceSet = resonance.resonanceSet if resonanceSet: i = resonanceSet.sortedResonances().index(resonance) atomSet = resonance.resonanceSet.sortedAtomSets()[i] coords = getAtomSetCoords(atomSet, self.structure) coord = coords[0] atomCoordList.add(hmass, coord.x, coord.y, coord.z) C += 1 print "L4", len(atomCoordList) from ccpnmr.clouds.FilterClouds import writeTypedPdbCloud writeTypedPdbCloud(atomCoordList, pdbFileName, resonances) clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') clouds.append(pdbFileName) self.guiParent.application.setValues(self.constraintSet, 'clouds', values=clouds) self.updateAfter() def calcRmsd(self): if self.constraintSet: clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') from ccpnmr.clouds.FilterClouds import filterClouds rmsds = filterClouds(clouds) n = len(clouds) for i in range(n): cloud = clouds[i] rmsd = rmsds[i] self.cloudRmsdDict[cloud] = rmsd self.updateAfter() def changeConstraintSet(self, i, name): project = self.project if project.nmrConstraintStores: constraintSet = project.nmrConstraintStores[i] else: constraintSet = None if constraintSet is not self.constraintSet: self.constraintSet = constraintSet self.cloud = None self.updateAfter() def deleteCloud(self): if self.constraintSet and self.cloud and showOkCancel( 'Confirm', 'Really delete resonance cloud?', parent=self): clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') if clouds: clouds.remove(self.cloud) self.cloud = None self.guiParent.application.setValues(self.constraintSet, 'clouds', values=clouds) self.updateAfter() def selectCell(self, cloud, row, col): self.cloud = cloud self.bottomButtons.buttons[1].enable() def updateAfter(self, *opt): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def getConstraintSetNames(self): names = [] constraintSets = self.project.nmrConstraintStores for set in constraintSets: names.append('%d' % set.serial) return names def updateStructureGen(self, *opt): project = self.project constraintSets = self.project.sortedNmrConstraintStores if constraintSets: constraintSetNames = self.getConstraintSetNames() # set defaults if self.constraintSet not in constraintSets: self.constraintSet = constraintSets[0] self.cloud = None i = constraintSets.index(self.constraintSet) self.constrSetPulldown.setup(constraintSetNames, i) else: self.constraintSet = None self.cloud = None self.constrSetPulldown.setup([], -1) def destroy(self): for func in ('__init__', 'delete'): self.unregisterNotify(self.updateStructureGen, 'ccp.nmr.Nmr.StructureGeneration', func) BasePopup.destroy(self) def update(self): objectList = [] textMatrix = [] if self.constraintSet: clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') if clouds: objectList = list(clouds) i = 0 for cloud in objectList: i += 1 datum = [] datum.append(i) datum.append(cloud) datum.append(self.cloudRmsdDict.get(cloud) or '-') datum.append(self.strucRmsdDict.get(cloud) or '-') textMatrix.append(datum) if not self.cloud: self.bottomButtons.buttons[1].disable() self.scrolledMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False
def body(self, master): pseudoExpts = getSampledDimExperiments(self.parent.nmrProject) master.rowconfigure(0, weight=1) master.rowconfigure(1, weight=1) master.columnconfigure(0, weight=1) tipTexts = ['The experiment is pseudo-N dimensional, with a sampled axis', 'The experiment is the regular kind with only NMR frequency axes'] self.pseudoEntries = [x % len(self.params.npts) for x in PSEUDO_ENTRIES] self.pseudoButton = RadioButtons(master, entries=self.pseudoEntries, select_callback=self.changedPseudoMode, grid=(0,0), sticky='nw', tipTexts=tipTexts) frame = self.pseudoFrame = Frame(master) self.pseudoFrame.grid(row=1, column=0, sticky='nsew') row = 0 if pseudoExpts: tipText = 'Select from existing pseudo nD experiments to copy sampled axis values from' texts = [x.name for x in pseudoExpts] label = Label(frame, text='Existing pseudo expts: ') label.grid(row=row, column=0, sticky='e') self.pseudoList = PulldownList(frame, texts=texts, objects=pseudoExpts, tipText=tipText) self.pseudoList.grid(row=row, column=1, sticky='w') tipText = 'Transfer the sampled axis values from the existing experiment to the new one' Button(frame, text='Copy values down', command=self.copyValues, tipText=tipText, grid=(row,2)) row += 1 npts = self.params.npts[self.dim] tipText = 'Number of data points (planes) along sampled axis' label = Label(frame, text='Number of points: ') label.grid(row=row, column=0, sticky='e') self.nptsEntry = IntEntry(frame, text=npts, tipText=tipText, width=8, grid=(row,1)) tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values' Button(frame, text='Load File', command=self.loadValues, tipText=tipText, grid=(row,2), sticky='ew') row += 1 tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis' label = Label(frame, text='Point values: ') label.grid(row=row, column=0, sticky='e') self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText) #minRows = self.params.npts[self.dim] #self.valueEntry = MultiWidget(frame, FloatEntry, callback=None, minRows=minRows, maxRows=None, # options=None, values=[], useImages=False) self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew') row += 1 label = Label(frame, text='(requires comma-separated list, of length number of points)') label.grid(row=row, column=1, columnspan=2, sticky='w') row += 1 for n in range(row): frame.rowconfigure(n, weight=1) frame.columnconfigure(1, weight=1) buttons = UtilityButtonList(master, closeText='Ok', closeCmd=self.updateParams, helpUrl=self.help_url) buttons.grid(row=row, column=0, sticky='ew')
def body(self, guiFrame): self.fileSelect = None names, objects = self.getShiftLists() self.shiftListPulldown = PulldownList(self, callback=self.setShiftList, texts=names, objects=objects) self.windowPulldown = PulldownList(self, texts=WINDOW_OPTS, callback=self.setWindow) self.experimentEntry = Entry(self, width=16, returnCallback=self.setExperiment) self.spectrumEntry = Entry(self, width=16, returnCallback=self.setSpectrum) guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) leftFrame = LabelFrame(guiFrame, text='File Selection') leftFrame.grid(row=0, column=0, sticky='nsew') leftFrame.grid_columnconfigure(3, weight=1) row = 0 label = Label(leftFrame, text='File format:') label.grid(row=row, column=0, sticky='w') tipText = 'Selects which kind of spectrum file is being loaded; what its data matrix format is' self.formatPulldown = PulldownList(leftFrame, callback=self.chooseFormat, texts=file_formats, tipText=tipText, grid=(row, 1)) self.detailsLabel = Label(leftFrame, text='Show details:') tipText = 'Whether to show an annotation that describes the spectrum in the file selection; currently only uses comment fields from Bruker spectra' self.detailsSelect = CheckButton(leftFrame, selected=False, callback=self.showDetails, tipText=tipText) self.titleRow = row self.detailsSelected = False row = row + 1 leftFrame.grid_rowconfigure(row, weight=1) file_types = [FileType('All', ['*'])] self.fileSelect = FileSelect(leftFrame, multiSelect=True, file_types=file_types, single_callback=self.chooseFiles, extraHeadings=('Details', ), extraJustifies=('left', ), displayExtra=False, getExtraCell=self.getDetails, manualFileFilter=True) self.fileSelect.grid(row=row, column=0, columnspan=6, sticky='nsew') rightFrame = LabelFrame(guiFrame, text='Spectra To Open') rightFrame.grid(row=1, column=0, sticky='nsew') rightFrame.grid_columnconfigure(3, weight=1) row = 0 label = Label(rightFrame, text='Skip verification dialogs:', grid=(row, 0)) tipText = 'Whether to allow the user to check file interpretation and referencing information before the spectrum is loaded' self.verifySelect = CheckButton(rightFrame, selected=False, grid=(row, 1), tipText=tipText) label = Label(rightFrame, text='Use shared experiment:', grid=(row, 2)) tipText = 'When selecting multiple spectrum files, whether the loaded spectra will all belong to (derive from) the same experiment; useful for projection spectra etc.' self.sharedExpSelect = CheckButton(rightFrame, selected=False, tipText=tipText, callback=self.useShared, grid=(row, 3)) row = row + 1 rightFrame.grid_rowconfigure(row, weight=1) tipTexts = [ 'A short textual name for the experiment record that the loaded spectrum will belong to; may be a new experiment or the name of an existing one', 'A short textual name to identify the spectrum within its experiment; typically a few characters or spectrum number, rather than a repeat of the experiment name', 'The location of the file, relative to the current directory, that the spectrum data will be loaded from', 'Sets which window or windows the spectrum will initially appear within once loaded', 'Sets which shift list the experiment (and hence loaded spectrum) will use to curate chemical shift information; can be changed after load time' ] headingList = [ 'Experiment', 'Spectrum', 'File', 'Windows', 'Shift List' ] editWidgets = [ self.experimentEntry, self.spectrumEntry, None, self.windowPulldown, self.shiftListPulldown ] editGetCallbacks = [ self.getExperiment, self.getSpectrum, None, self.getWindow, self.getShiftList ] editSetCallbacks = [ self.setExperiment, self.setSpectrum, None, self.setWindow, self.setShiftList ] self.scrolledMatrix = ScrolledMatrix(rightFrame, headingList=headingList, callback=self.selectCell, editWidgets=editWidgets, multiSelect=True, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts, grid=(row, 0), gridSpan=(1, 4)) row = row + 1 tipTexts = [ 'Load spectrum or spectra into the CCPN project using the selected file(s)', ] texts = ['Open Spectrum'] commands = [self.openSpectra] bottomButtons = UtilityButtonList(guiFrame, texts=texts, tipTexts=tipTexts, doClone=False, commands=commands, helpUrl=self.help_url) bottomButtons.grid(row=row, column=0, columnspan=1, sticky='ew') self.openButton = bottomButtons.buttons[0] self.chooseFormat('Azara') self.message()
class CalcCouplingPopup(BasePopup): def __init__(self, parent, *args, **kw): self.waiting = False self.peakList = None self.peakLists = [] self.windowPane = None self.cluster = None self.clusters = {} self.multiplet = None self.guiParent = parent BasePopup.__init__(self, parent=parent, title='Measure Couplings', **kw) self.updateWindows() self.updateAfter() def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = LabelFrame(guiFrame, text='Options') frame.grid(row=row, column=0, sticky='ew') frame.grid_columnconfigure(1, weight=1) frame.grid_rowconfigure(1, weight=1) label = Label(frame, text='Window:') label.grid(row=0, column=0, sticky='nw') self.windowPulldown = PulldownList(frame, callback=self.changeWindow) self.windowPulldown.grid(row=0, column=1, sticky='nw') label = Label(frame, text='Multiplet Pattern:') label.grid(row=1, column=0, columnspan=2, sticky='nw') self.multipletButtons = PartitionedSelector(frame, callback=self.setMultiplet, radio=True) self.multipletButtons.grid(row=2, column=0, columnspan=2, sticky='ew') row += 1 frame = LabelFrame(guiFrame, text='Active Peak Lists') frame.grid(row=row, column=0, sticky='ew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = [ 'Experiment', 'Spectrum', 'List', 'Coupled Dims', 'Experiment Type' ] self.peakListMatrix = ScrolledMatrix(frame, headingList=headingList, callback=None, multiSelect=False) self.peakListMatrix.grid(row=0, column=0, sticky='nsew') row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Multiplet Peak Clusters') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = [ '#', 'Main\nAssignment', 'Num\nPeaks', 'Coupling\nAssignment', 'Value', 'Value' ] self.clusterMatrix = ScrolledMatrix(frame, headingList=headingList, callback=self.selectCluster, multiSelect=True) self.clusterMatrix.grid(row=0, column=0, sticky='nsew') row += 1 texts = [ 'Cluster Selected\nPeaks', 'Assign\nCouplings', 'List\nPeaks', 'Find\nPeaks', 'Delete\nClusters' ] commands = [ self.clusterSelectedPeaks, self.assignCouplings, self.showPeaks, self.findPeaks, self.deleteClusters ] self.bottomButtons = UtilityButtonList(guiFrame, texts=texts, expands=True, commands=commands, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, sticky='ew') self.administerNotifiers(self.registerNotify) def administerNotifiers(self, notifyFunc): for clazz in ('ccp.nmr.Nmr.DataSource', 'ccp.nmr.Nmr.Experiment'): notifyFunc(self.updatePeakListsAfter, clazz, 'setName') for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindow', func) for func in ('__init__', 'delete'): notifyFunc(self.updatePeakListsAfter, 'ccp.nmr.Nmr.PeakList', func) for func in ('__init__', 'delete', 'addPeak', 'setPeaks', 'removePeak', 'setAnnotation'): notifyFunc(self.updateAfter, 'ccp.nmr.Nmr.PeakCluster', func) def deleteClusters(self): clusters = self.clusterMatrix.currentObjects for cluster in clusters: deleteCluster(cluster) def findPeaks(self): if self.windowPane and self.cluster: peaks = list(self.cluster.peaks) if not peaks: return spectrum = peaks[0].peakList.dataSource analysisSpectrum = spectrum.analysisSpectrum view = self.windowPane.findFirstSpectrumWindowView( analysisSpectrum=analysisSpectrum) windowFrame = self.windowPane.getWindowFrame() position = {} n = float(len(peaks)) for axisMapping in view.axisMappings: dim = axisMapping.analysisDataDim.dataDim.dim xyz = axisMapping.label mean = 0.0 for peak in peaks: peakDim = peak.findFirstPeakDim(dim=dim) mean += peakDim.realValue mean /= n position[xyz] = mean windowFrame.gotoPosition(position) def updatePeakListsAfter(self, object): if object.className == 'Experiment': for spectrum in object.dataSources: for peakList in spectrum.peakLists: if peakList in self.peakLists: self.updatePeakLists() elif object.className == 'DataSource': for peakList in object.peakLists: if peakList in self.peakLists: self.updatePeakLists() else: if object in self.peakLists: self.updatePeakLists(object) def open(self): BasePopup.open(self) self.updateWindows() self.updateAfter() def showPeaks(self): peaks = {} for peakCluster in self.clusterMatrix.currentObjects: for peak in peakCluster.peaks: peaks[peak] = True if peaks: self.parent.viewPeaks(peaks.keys()) def getWindows(self): windowPanes = [] for window in self.analysisProject.sortedSpectrumWindows(): for windowPane in window.sortedSpectrumWindowPanes(): for view in windowPane.spectrumWindowViews: if view.isPosVisible or view.isNegVisible: spectrum = view.analysisSpectrum.dataSource if self.getCoupledExpDims(spectrum.experiment): windowPanes.append(windowPane) break return windowPanes def getCoupledExpDims(self, experiment): """ Descrn: List the dimensions (ExpDims) of an experiment which carry couplings. Inputs: Nmr.Experiment Output: List of Nmr.ExpDims """ COUPLING_TYPES = ('JCoupling', 'Rdc', 'DipolarCoupling') expDims = [] refExperiment = experiment.refExperiment if refExperiment: for expDim in experiment.expDims: refExpDim = expDim.refExpDim if not refExpDim: # Could be sampled dim continue for refExpDimRef in refExpDim.refExpDimRefs: if refExpDimRef.coupledIsotopeCodes: expDims.append(expDim) break if not expDims: for expDim in experiment.expDims: for expDimRef in expDim.expDimRefs: if expDimRef.measurementType in COUPLING_TYPES: expDims.append(expDim) break return expDims def changeWindow(self, windowPane): if windowPane is not self.windowPane: self.windowPane = windowPane self.updatePeakLists() def updateWindows(self, *object): panes = self.getWindows() index = 0 names = [] pane = self.windowPane if panes: names = [getWindowPaneName(wp) for wp in panes] if pane not in panes: pane = panes[0] index = panes.index(pane) if pane is not self.windowPane: self.windowPane = pane self.updatePeakLists() self.windowPulldown.setup(names, panes, index) def getPeakLists(self): peakLists = [] if self.windowPane: for view in self.windowPane.spectrumWindowViews: try: spectrum = view.analysisSpectrum.dataSource except: continue if spectrum.peakLists: peakList = spectrum.activePeakList if not peakList: peakList = spectrum.findFirstPeakList() peakLists.append(peakList) return peakLists def updatePeakLists(self, peakList=None): objectList = self.getPeakLists() textMatrix = [] spectra = {} for peakList0 in objectList: spectrum = peakList0.dataSource experiment = spectrum.experiment spectra[spectrum] = True refExperiment = experiment.refExperiment coupledDims = [] if refExperiment: experimentType = refExperiment.name for expDim in experiment.expDims: refExpDim = expDim.refExpDim isotopes = {} for refExpDimRef in refExpDim.refExpDimRefs: for isotope in refExpDimRef.coupledIsotopeCodes: isotopes[isotope] = True if isotopes: isoString = ','.join(isotopes) coupledDims.append('%d (%s)' % (expDim.dim, isoString)) else: experimentType = None if not coupledDims: coupledDims = None else: coupledDims = ' '.join(coupledDims) datum = [ experiment.name, spectrum.name, peakList0.serial, coupledDims, experimentType ] textMatrix.append(datum) self.peakLists = objectList self.peakListMatrix.update(objectList=objectList, textMatrix=textMatrix) self.multiplet = None for spectrum in spectra.keys(): multiplet = self.getSpectrumMultiplet(spectrum) if multiplet: self.multiplet = MULTIPLET_PEAK_DICT.get(multiplet) break self.updateMultipletButtons() self.updateAfter() def setMultiplet(self, pattern): for peakList in self.peakLists: spectrum = peakList.dataSource for name in MULTIPLET_PEAK_DICT.keys(): if MULTIPLET_PEAK_DICT[name] == pattern: setSpectrumMultipletPattern(spectrum, name) break self.multiplet = pattern def setSpectrumMultiplet(self, spectrum, pattern): prevPattern = getSpectrumMultipletPattern(spectrum) if prevPattern and (prevPattern != pattern): if showOkCancel('Query', 'Really change multiplet pattern?', parent=self): setSpectrumMultipletPattern(spectrum, pattern) def getSpectrumMultiplet(self, spectrum): name = getSpectrumMultipletPattern(spectrum) if not name: name = self.predictSpectrumMultiplet(spectrum) setSpectrumMultipletPattern(spectrum, name) return name def predictSpectrumMultiplet(self, spectrum): name = None refExperiment = spectrum.experiment.refExperiment if refExperiment: name = EXPT_MULTIPLETS.get(refExperiment.name) return name def updateMultipletButtons(self): import re labels = [] objects = [] colors = [] selected = None if self.windowPane: coupledAxes = [] spectra = {} for peakList in self.peakLists: spectra[peakList.dataSource] = True multiplet = self.getSpectrumMultiplet(peakList.dataSource) selected = MULTIPLET_PEAK_DICT[multiplet] for spectrum in spectra.keys(): mapping = getDataDimAxisMapping(spectrum, self.windowPane) for axisLabel in ('x', 'y'): dataDim = mapping[axisLabel] for expDimRef in dataDim.expDim.expDimRefs: if expDimRef.refExpDimRef and expDimRef.refExpDimRef.coupledIsotopes: if axisLabel not in coupledAxes: coupledAxes.append(axisLabel) break else: coupledAxes = ['x', 'y'] for name in MULTIPLET_PEAK_DICT.keys(): pattern = MULTIPLET_PEAK_DICT[name] if type(pattern[0]) in (type(()), type([])): if 'y' not in coupledAxes: continue if len(pattern[0]) > 1: # x & y if 'x' not in coupledAxes: continue else: # y only if 'x' in coupledAxes: continue else: # x only if 'x' not in coupledAxes: continue if 'y' in coupledAxes: continue label = re.sub('\|', '\n', name) objects.append(pattern) labels.append(label) colors.append('#8080FF') self.multipletButtons.update(objects=objects, colors=colors, labels=labels) self.multipletButtons.setSelected([ selected, ]) def selectPeakList(self, object, row, col): self.peakList = object self.updateButtons() def selectCluster(self, object, row, col): self.cluster = object self.updateButtons() def assignCouplings(self): for cluster in self.clusterMatrix.currentObjects: assignPrimaryClusterCoupling(cluster) def assignAllCouplings(self): for cluster in self.clusters.keys(): assignPrimaryClusterCoupling(cluster) def clusterSelectedPeaks(self): peaks0 = self.parent.currentPeaks peaks = [] for peak in peaks0: if peak.peakList in self.peakLists: peaks.append(peak) if not peaks: showWarning('Cluster Failure', 'No peaks selected from active peak lists', parent=self) return if not self.multiplet: showWarning('Cluster Failure', 'No multiplet pattern selected', parent=self) return cluster = makeMultipletPeakCluster(peaks, self.multiplet, self.windowPane) if cluster: self.clusterMatrix.selectObject(cluster) def getActiveClusterCouplings(self): clusters = {} if self.peakLists: dims = {} for peakList in self.peakLists: experiment = peakList.dataSource.experiment for expDim in getCoupledExpDims(experiment): dims[expDim.dim] = True dims = dims.keys() for cluster in getPeakListsPeakClusters(self.peakLists): values = [] for dim in dims: values.append(getClusterCoupling(cluster, dim)) # Allow Nones? clusters[cluster] = values self.clusters = clusters return clusters def updateButtons(self): pass def updateAfter(self, cluster=None): if self.waiting: return if cluster: for peak in cluster.peaks: if peak.peakList in self.peakLists: self.waiting = True self.after_idle(self.update) break else: self.waiting = True self.after_idle(self.update) def update(self): clusters = self.getActiveClusterCouplings() textMatrix = [] objectList = [] headingList = [ '#', 'Main\nAssignment', 'Num\nPeaks', 'Coupling\nAssignment' ] if clusters: cluster0 = clusters.keys()[0] i = 1 for value in clusters[cluster0]: headingList.append('F%d Value\n(Hz)' % i) i += 1 else: headingList.append('Value') for cluster in clusters.keys(): couplingAssign = ','.join(getCouplingAnnotations(cluster)) datum = [ cluster.serial, cluster.annotation, len(cluster.peaks), couplingAssign ] values = clusters[cluster] for value in values: datum.append(value) textMatrix.append(datum) objectList.append(cluster) self.clusterMatrix.update(headingList=headingList, textMatrix=textMatrix, objectList=objectList) self.updateButtons() self.waiting = False def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self)
class PredictKarplusPopup(BasePopup): def __init__(self, parent, *args, **kw): self.waiting = False self.molSystem = None self.residue = None self.jCouplings = [] self.atomNames = [] self.measureJCouplingList = None self.predictJCouplingList = None self.coeffAtomNames = [] self.coefficients = {} self.coefficient = None for i in range(3): self.coefficients[i] = {} BasePopup.__init__( self, parent=parent, title='Predict Karplus Coefficients from J Coupling', **kw) self.updateJCouplingLists() self.updateMolSystems() self.updateAfter() def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1, minsize=500) row = 0 frame = LabelFrame(guiFrame, text='General Options') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(1, weight=1) label = Label(frame, text='Molecular System:') label.grid(row=0, column=0, sticky='w') self.molSystemPulldown = PulldownMenu(frame, self.changeMolSystem, do_initial_callback=False) self.molSystemPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Measured J coupling list:') label.grid(row=0, column=2, sticky='w') self.measureCouplingListPulldown = PulldownMenu( frame, self.changeMeasureCouplingList) self.measureCouplingListPulldown.grid(row=0, column=3, sticky='w') label = Label(frame, text='Predicted J coupling list:') label.grid(row=0, column=4, sticky='w') self.predictCouplingListPulldown = PulldownMenu( frame, self.changePredictCouplingList) self.predictCouplingListPulldown.grid(row=0, column=5, sticky='w') row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Angles & 3J Couplings') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = ['Residue', 'Phi', 'Chi^2'] editWidgets = [None, None, None] editGetCallbacks = [None, None, None] editSetCallbacks = [None, None, None] self.jCouplingEntry = FloatEntry( self, width=8, returnCallback=lambda event: self.setJCoupling()) i = 0 for names in couplingAtoms: headingList.extend( ['Pred\nJ(%s,%s)' % names, 'Expt\nJ(%s,%s)' % names]) editWidgets.extend([None, self.jCouplingEntry]) editGetCallbacks.extend( [None, lambda obj, i=i: self.getJCoupling(obj, i)]) editSetCallbacks.extend( [None, lambda event, i=i: self.setJCoupling(i)]) i += 1 self.couplingMatrix = ScrolledMatrix(frame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectJCoupling, multiSelect=False) self.couplingMatrix.grid(row=0, column=0, sticky='nsew') self.couplingMatrix.doEditMarkExtraRules = self.doEditMarkExtraRules row += 1 frame = LabelFrame(guiFrame, text='Karplus Coefficients') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = ['Phase'] editWidgets = [ None, ] editGetCallbacks = [ None, ] editSetCallbacks = [ None, ] self.coefficientEntry = FloatEntry( self, width=8, returnCallback=lambda event: self.setCoefficient()) for names in couplingAtoms: headingList.append('J(%s,%s)' % names) editWidgets.append(self.coefficientEntry) editGetCallbacks.append( lambda obj, n=names: self.getCoefficient(obj, n)) editSetCallbacks.append( lambda event, n=names: self.setCoefficient(n)) headingList = [ 'Phase', 'J(H,HA)', 'J(H,C)', 'J(H,CB)', 'J(C,HA)', 'J(C,C)', 'J(C,CB)' ] self.coefficientMatrix = ScrolledMatrix( frame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectCoefficient, maxRows=3, multiSelect=False) self.coefficientMatrix.grid(row=0, column=0, sticky='nsew') row += 1 texts = [] commands = [] self.bottomButtons = UtilityButtonList(guiFrame, commands=commands, texts=texts, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, sticky='ew') for func in ('__init__', 'delete', 'setValue', 'setError'): for clazz in ('ccp.nmr.Nmr.JCoupling', ): self.registerNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.JCouplingList', ): self.registerNotify(self.updateJCouplingLists, clazz, func) def getJCouplingLists(self, isSimulated=False): jCouplingLists = self.nmrProject.findAllMeasurementLists( className='JCouplingList', isSimulated=isSimulated) return jCouplingLists def updateJCouplingLists(self, *obj): jCouplingLists = self.getJCouplingLists(isSimulated=False) names = [ '%d:%s' % (jcl.serial, jcl.name or '') for jcl in jCouplingLists ] names.append('<New>') index = -1 if jCouplingLists: if self.measureJCouplingList in jCouplingLists: index = jCouplingLists.index(self.measureJCouplingList) else: self.measureJCouplingList = jCouplingLists[0] index = 0 else: self.measureJCouplingList = None self.measureCouplingListPulldown.setup(names, index) jCouplingLists = self.getJCouplingLists(isSimulated=True) names = ['%d:%s' % (jcl.serial, jcl.name) for jcl in jCouplingLists] names.append('<New>') index = -1 if jCouplingLists: if self.predictJCouplingList in jCouplingLists: index = jCouplingLists.index(self.predictJCouplingList) else: self.predictJCouplingList = jCouplingLists[0] index = 0 else: self.predictJCouplingList = None self.predictCouplingListPulldown.setup(names, index) def changeMeasureCouplingList(self, index, name): if name == '<New>': self.measureJCouplingList = None else: jCouplingLists = self.getJCouplingLists() jCouplingList = jCouplingLists[index] if jCouplingList is not self.measureJCouplingList: self.measureJCouplingList = jCouplingList if self.predictJCouplingList is self.measureJCouplingList: for jCouplingList2 in jCouplingLists: if self.measureJCouplingList is not jCouplingList2: self.predictJCouplingList = jCouplingList2 break else: self.predictJCouplingList = None self.updateAfter() def changePredictCouplingList(self, index, name): if name == '<New>': self.predictJCouplingList = None self.updateAfter() else: jCouplingLists = self.getJCouplingLists() jCouplingList = jCouplingLists[index] if jCouplingList is not self.predictJCouplingList: self.predictJCouplingList = jCouplingList if self.predictJCouplingList is self.measureJCouplingList: for jCouplingList2 in jCouplingLists: if self.predictJCouplingList is not jCouplingList2: self.measureJCouplingList = jCouplingList2 break else: self.measureJCouplingList = None self.updateAfter() def doEditMarkExtraRules(self, obj, row, col): i = (col - 3) / 2 if i > -1: atoms = couplingAtoms[i] residue = obj[0] for atomName in atoms: if not residue.findFirstAtom(name=atomName): return False return True def open(self): self.updateMolSystems() BasePopup.open(self) def selectJCoupling(self, object, row, col): self.residue = object[0] self.jCouplings = object[1:] def selectCoefficient(self, object, row, col): self.coefficient = object def getCoefficient(self, object, atomNames): self.coeffAtomNames = atomNames coefficient = self.coefficients[object].get(atomNames) self.coefficientEntry.set(coefficient) def setCoefficient(self, atomNames=None): if not atomNames: atomNames = self.coeffAtomNames value = self.coefficientEntry.get() if atomNames and (self.coefficient is not None): self.coefficients[self.coefficient][atomNames] = value #print self.coefficient, atomNames, value self.updateCoefficients() def getJCoupling(self, object, index): atomNames = couplingAtoms[index] self.atomNames = atomNames coupling = object[index + 1] if not coupling: residue = object[0] coupling = self.getResidueJCoupling(self.measureJCouplingList, residue, atomNames) if coupling: value = coupling.value else: value = None self.jCouplingEntry.set(value) def setJCoupling(self, index=None): if not index: atomNames = self.atomNames index = couplingAtoms.index(atomNames) else: atomNames = couplingAtoms[index] value = self.jCouplingEntry.get() if self.residue and atomNames: coupling = self.jCouplings[index] if value is None: if coupling: if showOkCancel('Confirm', 'Really remove J coupling?', parent=self): coupling.delete() else: if not coupling: self.setResidueJCoupling(self.measureJCouplingList, self.residue, atomNames, value, isSimulated=False) else: coupling.setValue(value) def getResidueJCoupling(self, jCouplingList, residue, atomNames): if jCouplingList: return getResidueJCoupling(jCouplingList, residue, atomNames) def setResidueJCoupling(self, jCouplingList, residue, atomNames, value, isSimulated=False): if jCouplingList is None: jCouplingList = self.nmrProject.newJCouplingList( isSimulated=isSimulated) if isSimulated: self.predictJCouplingList = jCouplingList else: self.measureJCouplingList = jCouplingList setResidueJCoupling(jCouplingList, self.residue, atomNames, value) def updateMolSystems(self, *obj): index = -1 names = [] molSystems = self.project.sortedMolSystems() if molSystems: if self.molSystem not in molSystems: self.molSystem = molSystems[0] names = [ms.code for ms in molSystems] index = molSystems.index(self.molSystem) self.molSystemPulldown.setup(names, index) def changeMolSystem(self, index, name): molSystems = self.project.sortedMolSystems() if molSystems: molSystem = molSystems[index] else: molSystem = None if molSystem is not self.molSystem: self.molSystem = molSystem self.updateAfter() def updateAfter(self, object=None): current = False if object and (object.className == 'JCoupling'): for resonance in object.resonances: resonanceSet = resonance.resonanceSet if resonanceSet: molSystem = resonanceSet.findFirstAtomSet().findFirstAtom( ).topObject if molSystem is self.molSystem: current = True break else: current = True if self.waiting or (not current): return else: self.waiting = True self.after_idle(self.update) def update(self): textMatrix = [] objectList = [] if self.molSystem: chains = self.molSystem.sortedChains() if len(chains) > 1: doChains = False else: doChains = True for chain in chains: if doChains: chainCode = chain.code else: chainCode = '' for residue in chain.sortedResidues(): name = '%s%d%s' % (chainCode, residue.seqCode, getResidueCode(residue)) phi = 0.0 chiSq = 0.0 datum = [name, phi, chiSq] object = [ residue, ] for atomNames in couplingAtoms: couplingM = self.getResidueJCoupling( self.measureJCouplingList, residue, atomNames) couplingP = self.getResidueJCoupling( self.predictJCouplingList, residue, atomNames) pred = None expt = None if couplingM: expt = couplingM.value if couplingP: pred = couplingP.value datum.append(pred) datum.append(expt) object.append(couplingM) objectList.append(object) textMatrix.append(datum) self.couplingMatrix.update(textMatrix=textMatrix, objectList=objectList) self.updateCoefficients() self.waiting = False def updateCoefficients(self): textMatrix = [] objectList = [] for i in range(3): name = 'C%d' % i datum = [ name, ] for atomNames in couplingAtoms: datum.append(self.coefficients[i].get(atomNames)) textMatrix.append(datum) objectList.append(i) self.coefficientMatrix.update(textMatrix=textMatrix, objectList=objectList) def destroy(self): for func in ('__init__', 'delete', 'setValue', 'setError'): for clazz in ('ccp.nmr.Nmr.JCoupling', ): self.unregisterNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.JCouplingList', ): self.unregisterNotify(self.updateJCouplingLists, clazz, func) BasePopup.destroy(self)
class EditPeakPopup(BasePopup): """ **Edit Position, Intensity & Details for a Peak** This popup window provides an means of editing peak information as an alternative to editing values in the main peak tables. This popup is also used to specify parameters for when a new peak is explicitly added to a peak list using a tabular display. The user can specify the position of the peak's dimensions in ppm, Hz or data point units. Also, the user can adjust the height and volume peak intensity values and a textual "Details" field, ,which can carry the user's comments about the peak. When editing an existing peak, no changes are made to the peak until the [Update] button is pressed. Likewise for a new peak the [Add Peak] button commits the changes. If the popup window is closed before the changes are committed then the entire editing or peak addition operation is cancelled. """ def __init__(self, parent, peak=None, peakList=None, *args, **kw): self.titleColor = '#000080' self.numDims = 0 self.peak = peak kw['borderwidth'] = 6 BasePopup.__init__(self, parent=parent, title='Edit Peak', **kw) self.registerNotify(self.deletedPeak, 'ccp.nmr.Nmr.Peak', 'delete') for func in ('setAnnotation', 'setDetails', 'setFigOfMerit'): self.registerNotify(self.updatePeak, 'ccp.nmr.Nmr.Peak', func) for func in ('setAnnotation', 'setPosition', 'setNumAliasing'): self.registerNotify(self.updatePeak, 'ccp.nmr.Nmr.PeakDim', func) for func in ('__init__', 'delete', 'setValue'): self.registerNotify(self.updatePeak, 'ccp.nmr.Nmr.PeakIntensity', func) self.dimensionLabels = [] self.dimensionEntries = [] self.update(self.peak, peakList) def body(self, guiParent): self.geometry("+150+150") guiParent.grid_columnconfigure(0, weight=1) self.master_frame = guiParent units = ('ppm', 'point', 'Hz') self.unit = 'ppm' self.specLabel = Label(guiParent, fg=self.titleColor, grid=(0, 0), sticky='ew') self.peakLabel = Label(guiParent, grid=(0, 1), sticky='ew') self.unit_frame = frame = Frame(guiParent, grid=(1, 1), gridSpan=(1, 2)) self.unitLabel = Label(frame, text='Current units: ', grid=(0, 0)) tipText = 'Selects which unit of measurement to display peak dimension positions with' self.unitSelect = PulldownList(frame, callback=self.changeUnit, texts=units, grid=(0, 1), tipText=tipText) self.heightLabel = Label(guiParent, text='Height', borderwidth=2, relief='groove') tipText = 'Sets the peak height; the value of the spectrum point intensity (albeit often interpolated)' self.heightEntry = FloatEntry(guiParent, borderwidth=1, tipText=tipText) self.volumeLabel = Label(guiParent, text='Volume', borderwidth=2, relief='groove') tipText = 'Sets the peak volume integral; normally a summation of data point values' self.volumeEntry = FloatEntry(guiParent, borderwidth=1, tipText=tipText) self.detailLabel = Label(guiParent, text='Details', borderwidth=2, relief='groove') tipText = 'A user-configurable textual comment for the peak, which appears an tables and occasionally on spectrum displays' self.detailEntry = Entry(guiParent, borderwidth=1, tipText=tipText) tipTexts = [ 'Commits the specified values to update the peak and closes the popup', ] texts = ['Update'] commands = [self.commit] self.buttons = UtilityButtonList(guiParent, texts=texts, commands=commands, doClone=False, helpUrl=self.help_url, tipTexts=tipTexts) def open(self): self.updatePeak() BasePopup.open(self) def updatePeak(self, object=None): peak = None if object: if object.className == 'Peak': peak = object elif object.className == 'PeakDim': peak = object.peak elif object.className == 'PeakIntensity': peak = object.peak if (peak is None) or (peak is self.peak): self.update(peak=self.peak) def update(self, peak=None, peakList=None): # first destroy old labels and entries (saves grid hassles) for label in self.dimensionLabels: label.destroy() for entry in self.dimensionEntries: entry.destroy() # now setup required data if peak: title = 'Edit Peak' self.buttons.buttons[0].config(text='Update') else: title = 'Add Peak' self.buttons.buttons[0].config(text='Add Peak') self.setTitle(title) self.peak = peak self.peakList = peakList if not peakList: if peak: self.peakList = peak.peakList else: return peakList = self.peakList spectrum = peakList.dataSource.name self.numDims = peakList.dataSource.numDim self.posn = self.numDims * [0] self.dataDims = peakList.dataSource.sortedDataDims() if self.peak: serial = self.peak.serial dims = self.peak.sortedPeakDims() details = self.peak.details if not details: details = '' if self.peak.annotation: annotn = '%0.16s' % self.peak.annotation else: annotn = '' heightIntensity = self.peak.findFirstPeakIntensity( intensityType='height') volumeIntensity = self.peak.findFirstPeakIntensity( intensityType='volume') if heightIntensity: height = heightIntensity.value else: height = 0.0 if volumeIntensity: volume = volumeIntensity.value else: volume = 0.0 for i in range(self.numDims): peakDim = dims[i] dataDimRef = peakDim.dataDimRef if dataDimRef: self.posn[i] = peakDim.position + ( peakDim.numAliasing * dataDimRef.dataDim.numPointsOrig) else: self.posn[i] = peakDim.position else: dict = peakList.__dict__.get('serialDict') if dict is None: serial = 1 else: serial = dict.get('peaks', 0) + 1 height = 0.0 volume = 0.0 details = '' annotn = '' self.specLabel.set( text='Experiment: %s Spectrum: %s PeakList: %d' % (peakList.dataSource.experiment.name, spectrum, peakList.serial)) self.peakLabel.set(text='Peak: %d' % serial) self.dimensionLabels = self.numDims * [''] self.dimensionEntries = self.numDims * [''] for i in range(self.numDims): pos = self.posn[i] if self.unit != 'point': dataDim = self.dataDims[i] if dataDim.className == 'FreqDataDim': pos = unit_converter[('point', self.unit)]( pos, getPrimaryDataDimRef(dataDim)) self.dimensionLabels[i] = Label(self.master_frame, text='F%d' % (i + 1), borderwidth=2, relief='groove') tipText = 'The peak position in dimension %d, in the specified units' % ( i + 1) self.dimensionEntries[i] = FloatEntry(self.master_frame, borderwidth=1, text='%8.4f' % pos, tipText=tipText) self.heightEntry.set(text='%f' % height) self.volumeEntry.set(text='%f' % volume) self.detailEntry.set(text=details) row = 0 self.specLabel.grid(row=row, column=0, columnspan=2, sticky='nsew') row = row + 1 self.peakLabel.grid(row=row, column=0, sticky='nsew') self.unit_frame.grid(row=row, column=1, columnspan=2, sticky='nsew') for i in range(self.numDims): row = row + 1 self.dimensionLabels[i].grid(row=row, column=0, sticky='nsew') self.dimensionEntries[i].grid(row=row, column=1, columnspan=3, sticky='e') row = row + 1 self.heightLabel.grid(row=row, column=0, sticky='nsew') self.heightEntry.grid(row=row, column=1, columnspan=3, sticky='e') row = row + 1 self.volumeLabel.grid(row=row, column=0, sticky='nsew') self.volumeEntry.grid(row=row, column=1, columnspan=3, sticky='e') row = row + 1 self.detailLabel.grid(row=row, column=0, sticky='nsew') self.detailEntry.grid(row=row, column=1, columnspan=3, sticky='e') row = row + 1 self.buttons.grid(row=row, column=0, columnspan=4, sticky='nsew') def changeUnit(self, unit): posDisp = self.numDims * [None] for i in range(self.numDims): posDisp[i] = float(self.dimensionEntries[i].get()) if self.unit != 'point': dataDim = self.dataDims[i] if dataDim.className == 'FreqDataDim': posDisp[i] = unit_converter[(self.unit, 'point')]( posDisp[i], getPrimaryDataDimRef(dataDim)) self.unit = unit if self.unit != 'point': for i in range(self.numDims): dataDim = self.dataDims[i] if dataDim.className == 'FreqDataDim': posDisp[i] = unit_converter[('point', self.unit)]( posDisp[i], getPrimaryDataDimRef(dataDim)) for i in range(self.numDims): value = posDisp[i] if value is None: self.dimensionEntries[i].set('None') else: self.dimensionEntries[i].set('%8.4f' % posDisp[i]) def commit(self): posDisp = self.numDims * [0] for i in range(self.numDims): posDisp[i] = float(self.dimensionEntries[i].get()) if self.unit != 'point': dataDim = self.dataDims[i] if dataDim.className == 'FreqDataDim': self.posn[i] = unit_converter[(self.unit, 'point')]( posDisp[i], getPrimaryDataDimRef(dataDim)) else: self.posn[i] = posDisp[i] if self.peak: movePeak(self.peak, self.posn) else: self.peak = pickPeak(self.peakList, self.posn) height = self.heightEntry.get() volume = self.volumeEntry.get() setManualPeakIntensity(self.peak, height, intensityType='height') setManualPeakIntensity(self.peak, volume, intensityType='volume') details = self.detailEntry.get() or None self.peak.setDetails(details) self.close() def deletedPeak(self, peak): if self.peak is peak: self.close() def destroy(self): self.unregisterNotify(self.deletedPeak, 'ccp.nmr.Nmr.Peak', 'delete') for func in ('setAnnotation', 'setDetails', 'setFigOfMerit'): self.unregisterNotify(self.updatePeak, 'ccp.nmr.Nmr.Peak', func) for func in ('setAnnotation', 'setPosition', 'setNumAliasing'): self.unregisterNotify(self.updatePeak, 'ccp.nmr.Nmr.PeakDim', func) for func in ('__init__', 'delete', 'setValue'): self.unregisterNotify(self.updatePeak, 'ccp.nmr.Nmr.PeakIntensity', func) BasePopup.destroy(self)
class BrowseStrucGenPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.strucGen = None self.violList = None self.constrList = None self.waiting = 0 BasePopup.__init__(self, parent=parent, title="Structure Generation Runs", **kw) #self.geometry("+150+150") def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 strucGenFrame = LabelFrame(guiFrame, text='Generation Runs') strucGenFrame.grid(row=row, column=0, columnspan=1, sticky='nsew') strucGenFrame.grid_columnconfigure(0, weight=1) strucGenFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_rowconfigure(row, weight=0) #self.editDetailsEntry = Entry(self,text='',returnCallback = self.setDetails, width=12) #editWidgets = [None, None, None, None, None, self.editDetailsEntry] #editGetCallbacks = [None, None, None, None, None, self.getDetails] #editSetCallbacks = [None, None, None, None, None, self.setDetails] colHeadings = [ '#', 'Constraint\nLists', 'Violation\nLists', 'Structures', 'Fixed\nAtom Sets', 'Fixes\nResonance Sets', 'Chain\nStates', 'Database\nEntries', 'Resonance\nClouds' ] editWidgets = [None, None, None, None, None, None, None, None, None] editGetCallbacks = [ None, None, None, None, None, None, None, None, None ] editSetCallbacks = [ None, None, None, None, None, None, None, None, None ] self.structGenMatrix = ScrolledMatrix( strucGenFrame, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, initialRows=3, initialCols=6, headingList=colHeadings, callback=self.selectStructGenCell, objectList=[], textMatrix=[ [], ]) self.structGenMatrix.grid(row=0, column=0, sticky='nsew') texts = ['View Structures', 'Delete'] commands = [self.viewStructures, self.deleteStrucGen] self.structGenButtons = ButtonList(strucGenFrame, texts=texts, expands=True, commands=commands) self.structGenButtons.grid(row=1, column=0, sticky='ew') row += 1 constrFrame = LabelFrame(guiFrame, text='Constraint Lists') constrFrame.grid(row=row, column=0, columnspan=1, sticky='nsew') constrFrame.grid_columnconfigure(0, weight=1) constrFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_rowconfigure(row, weight=1) colHeadings = [ '#', 'Type', 'Name', 'Constraints', 'Experiments', 'Details', 'Unit' ] editWidgets = [None, None, None, None, None, None, None] editGetCallbacks = [None, None, None, None, None, None, None] editSetCallbacks = [None, None, None, None, None, None, None] self.constrListMatrix = ScrolledMatrix( constrFrame, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, initialRows=10, headingList=colHeadings, callback=self.selectConstrListCell, objectList=[], textMatrix=[ [], ]) self.constrListMatrix.grid(row=0, column=0, sticky='nsew') texts = ['View Constraints', 'Create List', 'Delete List'] commands = [ self.viewConstraints, self.createConstraints, self.deleteConstraints ] self.constrListButtons = ButtonList(constrFrame, texts=texts, expands=True, commands=commands) self.constrListButtons.grid(row=1, column=0, sticky='ew') self.constrListButtons.buttons[1].disable() row += 1 violFrame = LabelFrame(guiFrame, text='Violation Lists') violFrame.grid(row=row, column=0, columnspan=1, sticky='nsew') violFrame.grid_columnconfigure(0, weight=1) violFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_rowconfigure(row, weight=1) colHeadings = [ '#', 'Violations', 'Structures', 'Details', ] editWidgets = [None, None, None, None] editGetCallbacks = [None, None, None, None] editSetCallbacks = [None, None, None, None] self.violListMatrix = ScrolledMatrix(violFrame, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, initialRows=10, headingList=colHeadings, callback=self.selectViolListCell, objectList=[], textMatrix=[ [], ]) self.violListMatrix.grid(row=0, column=0, sticky='nsew') texts = ['View Violations', 'Delete List'] commands = [self.viewViolations, self.deleteViolations] self.violListButtons = ButtonList(violFrame, texts=texts, expands=True, commands=commands) self.violListButtons.grid(row=1, column=0, sticky='ew') row += 1 self.bottomButtons = UtilityButtonList(guiFrame, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, columnspan=1, sticky='ew') self.update() for func in ('__init__', 'delete', 'setName', 'setDetails', 'setUnit', 'setExperiments', 'addExperiment', 'removeExperiment'): for clazz in ('ccp.nmr.Nmr.ChemShiftConstraintList', 'ccp.nmr.Nmr.DihedralConstraintList', 'ccp.nmr.Nmr.DistanceConstraintList', 'ccp.nmr.Nmr.HBondConstraintList', 'ccp.nmr.Nmr.JCouplingConstraintList', 'ccp.nmr.Nmr.RdcConstraintList'): self.registerNotify(self.updateAfter, clazz, func) for func in ( '__init__', 'delete', ): for clazz in ('ccp.nmr.Nmr.ChemShiftConstraint', 'ccp.nmr.Nmr.DihedralConstraint', 'ccp.nmr.Nmr.DistanceConstraint', 'ccp.nmr.Nmr.HBondConstraint', 'ccp.nmr.Nmr.JCouplingConstraint', 'ccp.nmr.Nmr.RdcConstraint'): self.registerNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete', 'setChainStates', 'addChainState', 'removeChainState', 'addEntry', 'removeEntry', 'setResStructures', 'addResStructure', 'setEntries', 'removeResStructure', 'setStructures', 'addStructure', 'removeStructure'): self.registerNotify(self.updateAfter, 'ccp.nmr.Nmr.StructureGeneration', func) for func in ('__init__', 'delete', 'setDetails'): for clazz in ('ccp.nmr.Nmr.ViolationList', ): self.registerNotify(self.updateAfter, clazz, func) for func in ( '__init__', 'delete', ): for clazz in ('ccp.nmr.Nmr.Violation', ): self.registerNotify(self.updateAfter, clazz, func) def open(self): self.updateAfter() BasePopup.open(self) def deleteViolations(self): if self.violList and showOkCancel( 'Confirm', 'Really delete violation list?', parent=self): self.violList.delete() self.violList = None self.violListButtons.buttons[0].disable() self.violListButtons.buttons[1].disable() def deleteConstraints(self): if self.constrList and showOkCancel( 'Confirm', 'Really delete constraint list?', parent=self): self.constrList.delete() self.constrList = None self.constrListButtons.buttons[0].disable() self.constrListButtons.buttons[2].disable() def createConstraints(self): pass def viewViolations(self): self.guiParent.browseViolations() popup = self.guiParent.popups['browse_violations'] popup.structGen = self.strucGen popup.violList = self.violList popup.updateAfter() def viewConstraints(self): self.guiParent.browseConstraints() popup = self.guiParent.popups['browse_constraints'] popup.structGen = self.strucGen popup.constrList = self.constrList popup.updateAfter() def viewStructures(self): self.guiParent.editStructures() popup = self.guiParent.popups['edit_structures'] popup.structGen = self.strucGen popup.updateAfter() def deleteStrucGen(self): if self.strucGen and showOkCancel( 'Confirm', 'Really delete structure generation run?', parent=self): self.strucGen.delete() self.strucGen = None self.constrList = None self.violist = None self.structGenButtons.buttons[0].disable() self.structGenButtons.buttons[1].disable() def selectStructGenCell(self, strucGen, row, col): self.strucGen = strucGen if strucGen: self.structGenButtons.buttons[1].enable() if len(strucGen.molStructures) > 0: self.structGenButtons.buttons[0].enable() if self.constrList and (self.constrList.structureGeneration is not self.strucGen): self.constrList = None self.updateConstrLists(self.strucGen) def selectConstrListCell(self, constrList, row, col): self.constrList = constrList if constrList: self.constrListButtons.buttons[0].enable() self.constrListButtons.buttons[2].enable() def selectViolListCell(self, violList, row, col): self.violList = violList if violList: self.violListButtons.buttons[0].enable() self.violListButtons.buttons[1].enable() def updateAfter(self, object=None): if self.waiting: return strucGen = None name = object.className if name == 'StructureGeneration': self.waiting = True self.after_idle(self.update) return elif name == 'ViolationList': strucGen = object.structureGeneration elif name == 'Violation': strucGen = object.violationList.structureGeneration elif name[-14:] == 'ConstraintList': strucGen = object.structureGeneration elif name[-10:] == 'Constraint': strucGen = object.parentList.structureGeneration if (object is None) or (strucGen is self.strucGen): self.waiting = True self.after_idle(self.update) def destroy(self): for func in ('__init__', 'delete', 'setName', 'setDetails', 'setUnit', 'setExperiments', 'addExperiment', 'removeExperiment'): for clazz in ('ccp.nmr.Nmr.ChemShiftConstraintList', 'ccp.nmr.Nmr.DihedralConstraintList', 'ccp.nmr.Nmr.DistanceConstraintList', 'ccp.nmr.Nmr.HBondConstraintList', 'ccp.nmr.Nmr.JCouplingConstraintList', 'ccp.nmr.Nmr.RdcConstraintList'): self.unregisterNotify(self.updateAfter, clazz, func) for func in ( '__init__', 'delete', ): for clazz in ('ccp.nmr.Nmr.ChemShiftConstraint', 'ccp.nmr.Nmr.DihedralConstraint', 'ccp.nmr.Nmr.DistanceConstraint', 'ccp.nmr.Nmr.HBondConstraint', 'ccp.nmr.Nmr.JCouplingConstraint', 'ccp.nmr.Nmr.RdcConstraint'): self.unregisterNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete', 'setChainStates', 'addChainState', 'removeChainState', 'addEntry', 'removeEntry', 'setResStructures', 'addResStructure', 'setEntries', 'removeResStructure', 'setStructures', 'addStructure', 'removeStructure'): self.unregisterNotify(self.updateAfter, 'ccp.nmr.Nmr.StructureGeneration', func) for func in ('__init__', 'delete', 'setDetails'): for clazz in ('ccp.nmr.Nmr.ViolationList', ): self.unregisterNotify(self.updateAfter, clazz, func) for func in ( '__init__', 'delete', ): for clazz in ('ccp.nmr.Nmr.Violation', ): self.unregisterNotify(self.updateAfter, clazz, func) BasePopup.destroy(self) def updateConstrLists(self, *opt): strucGen = self.strucGen objectList = [] textMatrix = [] if strucGen: for constraintList in strucGen.constraintLists: objectList.append(constraintList) else: textMatrix.append([]) for constrList in objectList: datum = [] expText = '' for e in constrList.experiments: if expText: expText += ' ' expText += e.name datum.append(constrList.serial) datum.append(constrList.className[0:-14]) datum.append(constrList.name) datum.append(len(constrList.constraints)) datum.append(expText) datum.append(constrList.details) datum.append(constrList.unit) textMatrix.append(datum) if self.constrList: self.constrListButtons.buttons[0].enable() self.constrListButtons.buttons[2].enable() else: self.constrListButtons.buttons[0].disable() self.constrListButtons.buttons[2].disable() self.constrListMatrix.update(objectList=objectList, textMatrix=textMatrix) def updateViolLists(self, *opt): strucGen = self.strucGen objectList = [] textMatrix = [] if strucGen: for violationList in strucGen.violationLists: objectList.append(violationList) else: textMatrix.append([]) for violationList in objectList: datum = [] datum.append(violationList.serial) datum.append(len(violationList.violations)) datum.append(len(violationList.molStructures)) datum.append(violationList.details) textMatrix.append(datum) if self.violList: self.violListButtons.buttons[0].enable() self.violListButtons.buttons[1].enable() else: self.violListButtons.buttons[0].disable() self.violListButtons.buttons[1].disable() self.violListMatrix.update(objectList=objectList, textMatrix=textMatrix) def update(self): objectList = [] textMatrix = [] project = self.project for strucGen in self.nmrProject.structureGenerations: objectList.append(strucGen) if not objectList: textMatrix.append([]) for strucGen in objectList: datum = [] datum.append(strucGen.serial) datum.append(len(strucGen.constraintLists)) datum.append(len(strucGen.violationLists)) datum.append(len(strucGen.molStructures)) datum.append(len(strucGen.fixedAtomSets)) datum.append(len(strucGen.fixedResonanceSets)) datum.append(len(strucGen.chainStates)) datum.append(len(strucGen.entries)) datum.append(len(strucGen.resStructures)) textMatrix.append(datum) if not self.strucGen: self.structGenButtons.buttons[0].disable() self.structGenButtons.buttons[1].disable() self.structGenMatrix.update(objectList=objectList, textMatrix=textMatrix) self.updateConstrLists() self.updateViolLists() self.waiting = False
def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = Frame(guiFrame) frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(3, weight=1) label = Label(frame, text='Shift List:') label.grid(row=0, column=0, sticky='w') self.shiftListPulldown = PulldownMenu(frame, callback=self.setShiftList) self.shiftListPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Sequential Link Type:') label.grid(row=0, column=2, sticky='w') entries = ['-1', '-1,+1', '+1'] self.linkPulldown = PulldownMenu(frame, callback=self.setLink, entries=entries, do_initial_callback=False, selected_index=entries.index( self.link)) self.linkPulldown.grid(row=0, column=3, sticky='w') row += 1 frame = LabelFrame(guiFrame, text='Link Atoms:') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) labels = ['C', 'CA', 'CB', 'CG', 'CD', 'H', 'HA', 'HB', 'HG', 'HD'] selected = ['CA', 'CB'] self.atomSelector = PartitionedSelector(frame, objects=labels, labels=labels, selected=selected, toggledBg='#808080', callback=self.changeAtoms, maxRowObjects=10) self.atomSelector.grid(row=0, column=0, sticky='ew') row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Predicted Residue Assignments') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = [ '#', 'Predicted\nResidue', 'Prob.', 'Links', 'CA', 'CA -1', 'CB', 'CB -1' ] self.spinSystemMatrix = ScrolledMatrix(frame, headingList=headingList, callback=self.selectSpinSystem, multiSelect=1) self.spinSystemMatrix.grid(row=0, column=0, sticky='nsew') row += 1 texts = ['Link Selected', 'Link All', 'Commit Assignment'] commands = [ self.linkSelectedSpinSystems, self.linkAllSpinSystems, self.commitAssignments ] buttonList = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url) buttonList.grid(row=row, column=0, sticky='ew') self.buttons = buttonList.buttons for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.ShiftList', ): self.registerNotify(self.updateShiftLists, clazz, func) for func in ('__init__', 'delete', 'setNmrChains', 'setResidue', 'setResonances', 'addResonance', 'removeResonance'): self.registerNotify(self.updateSpinSystemsAfter, 'ccp.nmr.Nmr.ResonanceGroup', func) self.updateShiftLists()
def body(self, guiFrame): self.geometry('700x700') guiFrame.expandGrid(0,0) options = ['Peak Lists & Settings','Peak Intensity Comparison'] tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.changeTab) tabbedFrame.grid(row=0, column=0, sticky='nsew') self.tabbedFrame = tabbedFrame frameA, frameB = tabbedFrame.frames row = 0 frameA.grid_columnconfigure(1, weight=1) frameA.grid_columnconfigure(3, weight=1) frameA.grid_columnconfigure(5, weight=1) frameA.grid_rowconfigure(5, weight=1) tipText = 'Number of reference peaks (no saturation)' self.peaksALabel = Label(frameA, text='Number of Ref Peaks: ', tipText=tipText) self.peaksALabel.grid(row=1,column=0,columnspan=2,sticky='w') tipText = 'Number of NOE saturation peaks' self.peaksBLabel = Label(frameA, text='Number of Sat Peaks: ', tipText=tipText) self.peaksBLabel.grid(row=1,column=2,columnspan=2,sticky='w') tipText = 'Number of peaks in assigned list' self.peaksCLabel = Label(frameA, text='Number of Assign Peaks: ', tipText=tipText) self.peaksCLabel.grid(row=1,column=4,columnspan=2,sticky='w') tipText = 'Selects which peak list is considered the NOE intensity reference (no saturation)' specALabel = Label(frameA, text='Ref Peak List: ') specALabel.grid(row=0,column=0,sticky='w') self.specAPulldown = PulldownList(frameA, callback=self.setRefPeakList, tipText=tipText) self.specAPulldown.grid(row=0,column=1,sticky='w') tipText = 'Selects which peak list is considered as NOE saturated.' specBLabel = Label(frameA, text='Sat Peak List: ') specBLabel.grid(row=0,column=2,sticky='w') self.specBPulldown = PulldownList(frameA, callback=self.setSatPeakList, tipText=tipText) self.specBPulldown.grid(row=0,column=3,sticky='w') tipText = 'Selects a peak list with assignments to use as a positional reference' specCLabel = Label(frameA, text='Assignment Peak List: ') specCLabel.grid(row=0,column=4,sticky='w') self.specCPulldown = PulldownList(frameA, callback=self.setAssignPeakList, tipText=tipText) self.specCPulldown.grid(row=0,column=5,sticky='w') frame0a = Frame(frameA) frame0a.grid(row=2,column=0,columnspan=6,sticky='nsew') frame0a.grid_columnconfigure(9, weight=1) tipText = '1H ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolHLabel = Label(frame0a, text='Tolerances: 1H') tolHLabel.grid(row=0,column=0,sticky='w') self.tolHEntry = FloatEntry(frame0a,text='0.02', width=6, tipText=tipText) self.tolHEntry .grid(row=0,column=1,sticky='w') tipText = '15N ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolNLabel = Label(frame0a, text=' 15N') tolNLabel .grid(row=0,column=2,sticky='w') self.tolNEntry = FloatEntry(frame0a,text='0.1', width=6, tipText=tipText) self.tolNEntry .grid(row=0,column=3,sticky='w') tipText = 'Whether to peak new peaks in reference & NOE saturated lists (at assignment locations)' label = Label(frame0a, text=' Pick new peaks?', grid=(0,4)) self.pickPeaksSelect = CheckButton(frame0a, tipText=tipText, grid=(0,5), selected=True) tipText = 'Whether to assign peaks in the peaks in the reference & NOE saturation lists, if not already assigned' label = Label(frame0a, text=' Assign peaks?') label.grid(row=0,column=6,sticky='w') self.assignSelect = CheckButton(frame0a, tipText=tipText) self.assignSelect.set(1) self.assignSelect.grid(row=0,column=7,sticky='w') tipText = 'Whether to consider peak height or volume in the heteronuclear NOE calculation' intensLabel = Label(frame0a, text=' Intensity Type:') intensLabel .grid(row=0,column=8,sticky='w') self.intensPulldown = PulldownList(frame0a, texts=['height','volume'], callback=self.setIntensityType, tipText=tipText) self.intensPulldown.grid(row=0,column=9,sticky='w') divider = LabelDivider(frameA, text='Peaks', grid=(3,0), gridSpan=(1,6)) tipTexts = ['Show the selected intensity reference peaks in the below table', 'Show the selected NOE saturation peaks in the below table', 'Show the selected assigned peak list in the below table', 'Show the displayed peaks in a separate peak table, where assignments etc. may be adjusted'] texts = ['Show Ref Peaks','Show Sat Peaks', 'Show Assign Peaks', 'Separate Peak Table'] commands = [self.viewRefPeakList, self.viewSatPeakList, self.viewAssignPeakList, self.viewSeparatePeakTable] self.viewPeaksButtons = ButtonList(frameA, expands=True, tipTexts=tipTexts, texts=texts, commands=commands) self.viewPeaksButtons.grid(row=4,column=0,columnspan=6,sticky='nsew') self.peakTable = PeakTableFrame(frameA, self.guiParent, grid=(5,0), gridSpan=(1,6)) self.peakTable.bottomButtons1.grid_forget() self.peakTable.bottomButtons2.grid_forget() #self.peakTable.topFrame.grid_forget() self.peakTable.topFrame.grid(row=2, column=0, sticky='ew') # Next tab frameB.expandGrid(0,0) tipTexts = ['Row number', 'Assignment annotation for NOE saturation peak', 'Assignment annotation for reference peak (no saturation)', '1H chemical shift of NOE saturation peak', '1H chemical shift of reference peak', '15N chemical shift of NOE saturation peak', '15N chemical shift of reference peak', 'The separation between compared peaks: square root of the sum of ppm differences squared', 'The intensity if the NOE saturation peak', 'The intensity of the reference peak (no saturation)', 'Ratio of peak intensities: saturated over reference', 'Residue(s) for reference peak'] colHeadings = ['#','Sat Peak','Ref Peak','1H shift A', '1H shift B','15N shift A','15N shift B', 'Closeness\nScore','Intensity A','Intensity B', 'Intensity\nRatio','Residue'] self.scrolledMatrix = ScrolledMatrix(frameB, multiSelect=True, headingList=colHeadings, callback=self.selectCell, tipTexts=tipTexts, grid=(0,0), deleteFunc=self.removePair) tipTexts = ['Force a manual update of the table; pair-up NOE saturation and reference peaks according to assigned peak positions', 'Remove the selected rows of peak pairs', 'Show peaks corresponding to the selected row in a table', 'Save the Heteronuclear NOE values in the CCPN project as a data list'] texts = ['Refresh Table','Remove Pairs', 'Show Peak Pair','Create Hetero NOE List'] commands = [self.matchPeaks,self.removePair, self.showPeakPair,self.makeNoeList] self.pairButtons = ButtonList(frameB, tipTexts=tipTexts, grid=(1,0), texts=texts, commands=commands) bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url) bottomButtons.grid(row=0, column=0, sticky='e') self.updatePulldowns() self.updateAfter() self.administerNotifiers(self.registerNotify)
class AddContourFilePopup(BasePopup): """ **Add Existing Contour Files to Project** The purpose of this dialog is to allow the user to add pre-existing contour files to the project. Contour files only depend on the spectrum data so the same contour files can be used across multiple projects, and that is the reason this dialog might be used. See also: `Spectrum Contour Files`_, `Creating Contour Files`_. .. _`Spectrum Contour Files`: EditContourFilesPopup.html .. _`Creating Contour Files`: CreateContourFilePopup.html """ def __init__(self, parent, *args, **kw): self.spectrum = None BasePopup.__init__(self, parent=parent, title='Add existing contour file', **kw) def body(self, master): self.geometry('600x130') master.grid_columnconfigure(1, weight=1) for n in range(5): master.grid_rowconfigure(n, weight=1) row = 0 label = Label(master, text='Spectrum: ') label.grid(row=row, column=0, sticky='e') tipText = 'The spectrum for which the contour file is being added' self.expt_spectrum = PulldownList(master, callback=self.updateContourDir, tipText=tipText) self.expt_spectrum.grid(row=row, column=1, sticky='w') row = row + 1 tipText = 'The location of the directory where contour files are stored on disk' label = Label(master, text='Contour dir: ') label.grid(row=row, column=0, sticky='e') self.dir_label = Label(master, text='', tipText=tipText) self.dir_label.grid(row=row, column=1, sticky='w') row = row + 1 label = Label( master, text= '(file will be copied into Contour dir if it is not already in there)' ) label.grid(row=row, column=1, sticky='w') row = row + 1 tipText = 'Browse for a file store contour data' button = Button(master, text='File name: ', command=self.selectFile, tipText=tipText) button.grid(row=row, column=0, sticky='e') tipText = 'Enter the name of the file to store contour data' self.file_entry = Entry(master, tipText=tipText) self.file_entry.grid(row=row, column=1, sticky='ew') row = row + 1 texts = ['Add File'] commands = [self.addFile] tipTexts = [ 'Use the selected contour file in the current project, copying it to the contour directory if required', ] self.buttons = UtilityButtonList(master, texts=texts, doClone=False, tipTexts=tipTexts, commands=commands, helpUrl=self.help_url) self.buttons.grid(row=row, column=0, columnspan=2, sticky='ew') self.curateNotifiers(self.registerNotify) self.updateSpectrum() def destroy(self): self.curateNotifiers(self.unregisterNotify) BasePopup.destroy(self) def curateNotifiers(self, notifyFunc): for clazz in ('Experiment', 'DataSource'): for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateNotifier, 'ccp.nmr.Nmr.%s' % clazz, func) def updateSpectrum(self, spectrum=None): if not spectrum: spectrum = self.spectrum spectra = self.parent.getSpectra() if spectra: if spectrum not in spectra: spectrum = spectra[0] index = spectra.index(spectrum) names = ['%s:%s' % (x.experiment.name, x.name) for x in spectra] else: index = 0 names = [] self.expt_spectrum.setup(names, spectra, index) self.updateContourDir(spectrum) def updateNotifier(self, *extra): self.updateSpectrum() def updateContourDir(self, spectrum): if spectrum is self.spectrum: return self.spectrum = spectrum if spectrum: path = spectrum.analysisSpectrum.contourDir.dataLocation else: path = '' self.dir_label.set(path) def selectFile(self): spectrum = self.spectrum if spectrum: directory = spectrum.analysisSpectrum.contourDir.dataLocation else: directory = os.getcwd() popup = FileSelectPopup(self, directory=directory) fileName = popup.getFile() popup.destroy() if fileName: self.file_entry.set(fileName) def addFile(self): spectrum = self.spectrum if not spectrum: return dataStore = spectrum.dataStore if not dataStore: showError('No dataStore', 'Spectrum does not have associated dataStore', parent=self) return if not isinstance(dataStore, BlockedBinaryMatrix): showError('No blockedBinaryMatrix', 'Spectrum dataStore is not a blockedBinaryMatrix', parent=self) return if not dataStore.blockSizes: showError('No blockSize', 'Spectrum dataStore does not have blockSize set', parent=self) return blockSize = list(dataStore.blockSizes) fileName = self.file_entry.get() if not fileName: showError('No filename', 'No filename given', parent=self) return fileName = normalisePath(fileName, makeAbsolute=True) contourDir = spectrum.analysisSpectrum.contourDir.dataLocation if fileName.startswith(contourDir): path = fileName[len(contourDir) + 1:] else: path = os.path.basename(fileName) if not os.path.exists(contourDir): os.makedirs(contourDir) print 'Copying %s to %s' % (fileName, contourDir) shutil.copy(fileName, contourDir) try: header = getStoredContourHeader(fileName) except Exception, e: showError('File error', str(e), parent=self) return if header['ndim'] != spectrum.numDim: showError( 'Number of dimensions', 'Number of dimensions in file (%d) does not match spectrum (%d)' % (header['ndim'], spectrum.numDim), parent=self) return dataDims = spectrum.sortedDataDims() npoints = [x.numPoints for x in dataDims] if header['npoints'] != npoints: showError( 'Number of points', 'Number of points in file (%s) does not match spectrum (%s)' % (header['npoints'], npoints), parent=self) return if header['blockSize'] != blockSize: showError('Block size', 'Block size in file (%s) does not match spectrum (%s)' % (header['blockSize'], blockSize), parent=self) return createStoredContour(spectrum, path, header['xdim'], header['ydim']) showInfo('Added file', 'Successfully added stored contour file', parent=self)