def body(self, guiFrame): self.geometry('600x350') guiFrame.expandGrid(0, 0) tipTexts = ['', '', '', ''] options = [ 'Find Parameters', 'Spectrum Widths', 'Diagonal Exclusions', 'Region Peak Find' ] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0)) frameA, frameB, frameC, frameD = tabbedFrame.frames self.tabbedFrame = tabbedFrame # Find Params frameA.expandGrid(2, 0) row = 0 label = LabelFrame(frameA, text='Extrema to search for:', grid=(row, 0), gridSpan=(1, 2)) label.expandGrid(0, 1) entries = ['positive and negative', 'positive only', 'negative only'] tipTexts = [ 'Sets whether peak picking within spectra find intensity maxima, minima or both maxima and minima', ] self.extrema_buttons = RadioButtons(label, entries=entries, select_callback=self.apply, direction='horizontal', grid=(0, 0), tipTexts=tipTexts) row += 1 label = LabelFrame(frameA, text='Nearby points to check:', grid=(row, 0), gridSpan=(1, 2)) label.expandGrid(None, 1) entries = ['+-1 in at most one dim', '+-1 allowed in any dim'] tipTexts = [ 'Sets how permissive the peak picking in when searching for intensity extrema; by adding extra points to the selected search region', ] self.adjacent_buttons = RadioButtons(label, entries=entries, select_callback=self.apply, direction='horizontal', grid=(0, 0), tipTexts=tipTexts) row += 1 labelFrame = LabelFrame(frameA, text='Other parameters:', grid=(row, 0), gridSpan=(1, 2)) labelFrame.expandGrid(5, 2) frow = 0 label = Label(labelFrame, text='Scale relative to contour levels:', grid=(frow, 0), sticky='e') tipText = 'Threshold above which peaks are picked, relative to the lowest displayed contour; 1.0 means picking exactly what is visible' self.scale_entry = FloatEntry(labelFrame, grid=(frow, 1), tipText=tipText, returnCallback=self.apply, width=10) self.scale_entry.bind('<Leave>', self.apply, '+') frow += 1 label = Label(labelFrame, text='Exclusion buffer around peaks (in points):', grid=(frow, 0), sticky='e') tipText = 'The size of the no-pick region, in data points, around existing picked peaks; eliminates duplicate picking' self.buffer_entry = IntEntry(labelFrame, returnCallback=self.apply, grid=(frow, 1), width=10, tipText=tipText) self.buffer_entry.bind('<Leave>', self.apply, '+') frow += 1 label = Label(labelFrame, text='Extra thickness in orthogonal dims (in points):', grid=(frow, 0), sticky='e') tipText = 'Sets whether to consider any additional planes (Z dimension) when calculating peak volume integrals' self.thickness_entry = IntEntry(labelFrame, returnCallback=self.apply, width=10, grid=(frow, 1), tipText=tipText) self.thickness_entry.bind('<Leave>', self.apply, '+') frow += 1 label = Label(labelFrame, text='Minimum drop factor (0.0-1.0):', grid=(frow, 0), sticky='e') tipText = '' self.drop_entry = FloatEntry(labelFrame, returnCallback=self.apply, width=10, grid=(frow, 1), tipText=tipText) self.drop_entry.bind('<Leave>', self.apply, '+') frow += 1 label = Label(labelFrame, text='Volume method:', grid=(frow, 0), sticky='e') tipText = 'Selects which method to use to calculate peak volume integrals when peaks are picked; box sizes are specified in "Spectrum Widths"' self.method_menu = PulldownList(labelFrame, texts=PeakBasic.PEAK_VOLUME_METHODS, grid=(frow, 1), callback=self.apply, tipText=tipText) # Spectrum widths frameB.expandGrid(1, 1) label = Label(frameB, text='Spectrum: ') label.grid(row=0, column=0, sticky='e') tipText = 'The spectrum which determines the widths being shown' self.expt_spectrum = PulldownList(frameB, tipText=tipText, callback=self.setSpectrumProperties) self.expt_spectrum.grid(row=0, column=1, sticky='w') self.editLinewidthEntry = FloatEntry(self, text='', returnCallback=self.setLinewidth, width=10) self.editBoxwidthEntry = FloatEntry(self, text='', returnCallback=self.setBoxwidth, width=10) tipTexts = [ 'The number of the spectrum dimension to which the settings apply', 'The nuclear isotope measures in the spectrum dimension', 'The smallest value for the linewidth of a peak for it to be picked', 'The size of the spectrum region to perform the volume integral over' ] headingList = [ 'Dimension', 'Isotope', 'Minimum Linewidth (Hz)', 'Boxwidth' ] editSetCallbacks = [None, None, self.setLinewidth, self.setBoxwidth] editGetCallbacks = [None, None, self.getLinewidth, self.getBoxwidth] editWidgets = [ None, None, self.editLinewidthEntry, self.editBoxwidthEntry ] self.spectrumMatrix = ScrolledMatrix(frameB, initialRows=6, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, callback=self.selectCell, tipTexts=tipTexts) self.spectrumMatrix.grid(row=1, column=0, columnspan=2, sticky='nsew') # Diagonal Exclusions frameC.expandGrid(0, 0) tipTexts = [ 'The isotope as measures on the axis of a spectrum window', 'The distance from the homonuclear diagonal line within which no peak picking can occur' ] self.exclusionEntry = FloatEntry(self, text='', returnCallback=self.setExclusion, width=10) headingList = ['Isotope', 'Diagonal Exclusion (ppm)'] editSetCallbacks = [None, self.setExclusion] editGetCallbacks = [None, self.getExclusion] editWidgets = [None, self.exclusionEntry] self.isotopeMatrix = ScrolledMatrix(frameC, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, grid=(0, 0), tipTexts=tipTexts) # Region peak find self.regionFindPeakList = None self.regionCondition = None self.regionConditions = [] self.regionCol = 1 row = 0 label = Label(frameD, text='Peak List: ', grid=(0, 0)) tipText = 'Selects which peak list to perform region-wide peak picking for' self.regionPeakListPulldown = PulldownList( frameD, callback=self.changeRegionPeakList, grid=(0, 1), tipText=tipText) row += 1 frameD.expandGrid(row, 1) self.regionEntry = FloatEntry(self, text='', returnCallback=self.setRegion, width=10) self.conditionMenu = PulldownList(self, texts=('include', 'exclude'), callback=self.setCondition) tipTexts = [ 'Whether to include or exclude the states region from region-wide peak picking', ] headingList = ['Condition'] editSetCallbacks = [None] editGetCallbacks = [None] editWidgets = [self.conditionMenu] self.regionFindMatrix = ScrolledMatrix( frameD, headingList=headingList, callback=self.selectRegionCell, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(row, 0), gridSpan=(1, 2)) row += 1 tipTexts = [ 'Sets the currently selected region row to cover the whole spectrum', 'Add a new region row, which may them be set for exclusion or inclusion when peak picking large areas', 'Remove the selected region specification', 'Go to the panel for setting the parameters that control how peaks extrema are picked', 'Using the stated regions and parameters, perform region-wide peak picking' ] texts = [ 'Whole Region', 'Add Region', 'Delete Region', 'Adjust Params', 'Find Peaks!' ] commands = [ self.wholeRegion, self.addCondition, self.deleteCondition, self.adjustParams, self.regionFindPeaks ] buttons = ButtonList(frameD, texts=texts, commands=commands, grid=(row, 0), gridSpan=(1, 2), tipTexts=tipTexts) buttons.buttons[4].config(bg='#B0FFB0') utilButtons = UtilityButtonList(tabbedFrame.sideFrame, grid=(0, 0), helpUrl=self.help_url, sticky='e') self.dataDim = None self.setParamsEntries() self.updateSpectrum() self.setIsotopeProperties() self.updateRegionPeakLists() self.administerNotifiers(self.registerNotify)
def body(self, guiFrame): fixedSpectrum = self.fixedPeak.peakList.dataSource moveSpectrum = self.movePeak.peakList.dataSource guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = LabelFrame(guiFrame, text='Working Spectra', grid=(row, 0), sticky='ew') frame.grid_columnconfigure(1, weight=1) s = '%s:%-20s' % (fixedSpectrum.experiment.name, fixedSpectrum.name) Label(frame, text='Fixed:', grid=(0, 0), sticky='e') tipText = 'The experiment:spectrum name of the reference spectrum, which will not be moved' Label(frame, text=s, grid=(0, 1), tipText=tipText) s = '%s:%-20s' % (moveSpectrum.experiment.name, moveSpectrum.name) Label(frame, text='Moving:', grid=(0, 2), sticky='e') tipText = 'The experiment:spectrum name of the spectrum which will be re-referenced using peak positions' Label(frame, text=s, grid=(0, 3), tipText=tipText) row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Peak Position Mapping', grid=(row, 0)) frame.expandGrid(0, 0) tipText = 'Whether the more than one moving spectrum dimension may be mapped to the same fixed spectrum dimension; typically not used but can be useful for re-referencing with a diagonal peak' self.fixedDimsButton = CheckButton( frame, text='Allow repeated fixed dim', selected=False, grid=(0, 0), callback=self.changedFixedDimsButton, tipText=tipText) self.dimPulldown = PulldownList(self, callback=self.setDimMapping) editWidgets = [None, None, self.dimPulldown, None, None, None] editGetCallbacks = [None, None, self.getDimMapping, None, None, None] editSetCallbacks = [None, None, self.setDimMapping, None, None, None] tipTexts = [ 'The dimension number of the spectrum being re-referenced', 'The isotope type that corresponds to both the fixed and re-reference spectrum dimensions', 'The dimension number of the fixed spectrum, used as a reference', 'The position of the moving peak in the relevant dimension, before any changes (for the spectrum being re-referenced)', 'The position of the fixed peak in the relevant dimension; potential new position of the moving peak after re-referencing changes', 'The chemical shift difference between the two peak positions on one dimension' ] headingList = [ 'Moving\nDim', 'Isotope', 'Fixed\nDim', 'Original\nPosition', 'New\nPosition', u'\u0394' ] self.scrolledMatrix = ScrolledMatrix(frame, headingList=headingList, callback=self.selectPeakDim, editWidgets=editWidgets, maxRows=5, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, grid=(1, 0), tipTexts=tipTexts) row += 1 tipTexts = [ 'Use the stated mapping of dimensions to re-reference the moving spectrum so that the selected peaks lie at the same position', ] texts = ['Commit'] commands = [self.ok] buttons = UtilityButtonList(guiFrame, texts=texts, commands=commands, closeText='Cancel', helpUrl=self.help_url, grid=(row, 0), tipTexts=tipTexts) self.update()
if __name__ == '__main__': import Tkinter from memops.gui.Entry import Entry from memops.gui.LabelFrame import LabelFrame from memops.gui.ScrolledFrame import ScrolledFrame root = Tkinter.Tk() root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(1, weight=1) root.geometry('900x600') frame = LabelFrame(root, text='Prototypes', grid=(0, 0)) frame.expandGrid(0, 0) linkChartA = LinkChart(frame, background='#8080B0', height=160) linkChartA.grid(row=0, column=0, sticky='nsew') linkChartB = LinkChart(root) linkChartB.grid(row=1, column=0, sticky='nsew') tkWidget = Entry(root, text='', width=8) def setupFunc(obj): # This function creates widget contents # from the underlying node object return obj[0] def commitFunc(obj, value):
def body(self, guiFrame): guiFrame.grid_columnconfigure(3, weight=1) row = 0 label = Label(guiFrame, text='Spin System: ', grid=(row,0)) tipText = 'Indicates which spin system the residue type prediction is done for' self.spinSystemLabel = Label(guiFrame, text='Serial: Assignment:', grid=(row,1), gridSpan=(1,3), tipText=tipText) row += 1 label = Label(guiFrame, text='Shift List: ', grid=(row,0)) tipText = 'Selects which shift list is the source of chemical shift information to make the residue type prediction' self.shiftListPulldown = PulldownList(guiFrame, tipText=tipText, callback=self.setShiftList, grid=(row,1)) label = Label(guiFrame, text='Chain: ', grid=(row,2)) tipText = 'Selects which molecular chain the prediction is for; sets prior probabilities for the various residue types' self.chainPulldown = PulldownList(guiFrame, self.changeChain, grid=(row,3), tipText=tipText) row += 1 labelFrame = LabelFrame(guiFrame, text='Resonances', grid=(row,0), gridSpan=(1,4)) labelFrame.expandGrid(0,0) self.atomTypePulldown = PulldownList(self, callback=self.setAtomType) editWidgets = [ None, None, None, None, self.atomTypePulldown ] editGetCallbacks = [ None, None, None, None, self.getAtomType] editSetCallbacks = [ None, None, None, None, self.setAtomType] tipTexts = ['The nuclear isotope type of the resonance within the current spin system', 'The assignment annotation for the spin system resonance within the current spin system', 'The chemical shift of the resonance in the stated shift list', 'The weighted standard deviation of the resonance chemical shift', 'The current atom type of the resonance; when set this helps refine residue type prediction'] headingList = ['Isotope','Name','Shift\nValue','Shift\nError','Atom\nType'] self.resonanceMatrix = ScrolledMatrix(labelFrame, editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, headingList=headingList, callback=self.selectResonance, grid=(0,0), tipTexts=tipTexts) tipTexts = ['Remove the selected resonance from the current spin system', 'Remove residue type information from the current spin system', 'Show a table of information for the selected resonance, including a list of all peak dimension positions', 'Show a table of the peaks to which the selected resonance is assigned'] texts = ['Remove From\nSpin System', 'Deassign\nResidue Type', 'Resonance\nInfo', 'Show\nPeaks'] commands = [self.removeResonance, self.deassignType, self.showResonanceInfo, self.showPeaks] buttonList = ButtonList(labelFrame, texts=texts, commands=commands, grid=(1,0), tipTexts=tipTexts) self.resButtons = buttonList.buttons row += 1 guiFrame.grid_rowconfigure(row, weight=1) labelFrame = LabelFrame(guiFrame, text='Type Scores', grid=(row,0), gridSpan=(1,4)) labelFrame.expandGrid(0,0) tipTexts = ['The ranking of the residue type possibility for the current spin system', 'The CCPN residue code for the type', 'The estimated percentage probability of the spin system being the residue type'] headingList = ['Rank','Ccp Code','% Probability'] self.scoresMatrix = ScrolledMatrix(labelFrame, headingList=headingList, callback=self.selectCcpCode, grid=(0,0), tipTexts=tipTexts) row += 1 tipTexts = ['Assign the residue type of the current spin system to the kind selected in the lower table',] texts = ['Assign Spin System Type'] commands = [self.assign] bottomButtons = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url, grid=(row,0), gridSpan=(1,4), tipTexts=tipTexts) self.assignButton = bottomButtons.buttons[0] self.updateShiftLists() self.updateChains() self.getChainAtomTypes() self.update() self.curateNotifiers(self.registerNotify)
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()
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('800x530') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=2) guiFrame.grid_rowconfigure(2, weight=1) isotopeFrame = LabelFrame(guiFrame, text='Isotope Shift Correction CA and CB') isotopeFrame.grid(row=0, column=0, sticky='nsew') frameA = LabelFrame(guiFrame, text='Spin Systems') frameA.grid(row=1, column=0, sticky='nsew') frameA.grid_rowconfigure(0, weight=1) frameA.grid_columnconfigure(0, weight=1) frameA.grid_columnconfigure(1, weight=1) frameA1 = LabelFrame(frameA, text='Spin System 1') frameA1.grid(row=0, column=0, sticky='nsew') frameA1.grid_columnconfigure(0, weight=1) frameA1.grid_rowconfigure(0, weight=1) frameA2 = LabelFrame(frameA, text='Spin System 2') frameA2.grid(row=0, column=1, sticky='nsew') frameA2.grid_columnconfigure(0, weight=1) frameA2.grid_rowconfigure(0, weight=1) frameB = LabelFrame(guiFrame, text='Comparison') frameB.grid(row=2, column=0, sticky='nsew') frameB.grid_rowconfigure(0, weight=1) frameB.grid_columnconfigure(0, weight=1) frameB.grid_columnconfigure(1, weight=2) frameB.grid_columnconfigure(2, weight=1) frameB1 = LabelFrame(frameB, text='Unique to Spin System 1') frameB1.grid(row=0, column=0, sticky='nsew') frameB1.expandGrid(0, 0) frameB2 = LabelFrame(frameB, text='Intersection') frameB2.grid(row=0, column=1, sticky='nsew') frameB2.expandGrid(0, 0) frameB3 = LabelFrame(frameB, text='Unique to Spin System 2') frameB3.grid(row=0, column=2, sticky='nsew') frameB3.expandGrid(0, 0) # Settings for isotope shift correction shiftLists = getShiftLists(self.nmrProject) self.protonatedShiftList = shiftLists[0] self.deuteratedShiftList = shiftLists[1] shiftListNames = [ '{}: {}'.format(shiftList.serial, shiftList.name) for shiftList in shiftLists ] Label(isotopeFrame, text='Correct for isotope shift:', grid=(0, 0)) self.correctCheck = CheckButton(isotopeFrame, selected=True, callback=self.setCorrection, grid=(0, 1)) Label(isotopeFrame, text='Protonated shift list:', grid=(1, 0)) self.protonatedPulldown = PulldownList( isotopeFrame, callback=self.setProtonatedShiftList, texts=shiftListNames, objects=shiftLists, grid=(1, 1), index=0) Label(isotopeFrame, text='Deuterated shift list:', grid=(2, 0)) self.deuteratedPulldown = PulldownList( isotopeFrame, callback=self.setDeuteratedShiftList, texts=shiftListNames, objects=shiftLists, grid=(2, 1), index=1) # Table A1 headingList = ['#', 'shift lists', 'Assignment'] tipTexts = [ 'Spin System Serial', 'shift lists', 'The residue (tentatively) assigned to this spin system', 'The amount of spin systems that overlap with this spin system and have no violations' ] editGetCallbacks = [self.setSpinSystem1] * 3 editSetCallbacks = [None] * 3 self.tableA1 = ScrolledMatrix(frameA1, headingList=headingList, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA1.grid(row=0, column=0, sticky='nsew') # Table A2 headingList = ['#', 'shift lists', 'Assignment', 'offset'] tipTexts = [ 'Spin System Serial', 'The residue (tentatively) assigned to this spin system', 'Root mean squared deviation of this spin system to the spin system selected in the table on the left.' ] editGetCallbacks = [self.setSpinSystem2] * 4 editSetCallbacks = [None] * 4 self.tableA2 = ScrolledMatrix( frameA2, headingList=headingList, #editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA2.grid(row=0, column=0, sticky='nsew') # Table B1 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift'] self.tableB1 = ScrolledMatrix(frameB1, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB1.grid(row=0, column=0, sticky='nsew') # Table B 2 headingList = ['atom', 'c.s. 1', 'c.s. 2', 'delta c.s.'] tipTexts = [ 'name of the atom', 'chemical shift of atom with this name in spin system 1', 'chemical shift of atom with this name in spin system 2', 'difference between the chemical shift of spin systems 1 and 2' ] self.tableB2 = ScrolledMatrix(frameB2, headingList=headingList, tipTexts=tipTexts) self.tableB2.grid(row=0, column=0, sticky='nsew') # Table B 3 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift.'] self.tableB3 = ScrolledMatrix(frameB3, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB3.grid(row=0, column=0, sticky='nsew') self.matchMatrix = {} self.amountOfMatchesPerSpinSystem = {} self.updateTableA1()
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('800x530') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=2) guiFrame.grid_rowconfigure(2, weight=1) isotopeFrame = LabelFrame(guiFrame, text='Isotope Shift Correction CA and CB') isotopeFrame.grid(row=0, column=0, sticky='nsew') frameA = LabelFrame(guiFrame, text='Spin Systems') frameA.grid(row=1, column=0, sticky='nsew') frameA.grid_rowconfigure(0, weight=1) frameA.grid_columnconfigure(0, weight=1) frameA.grid_columnconfigure(1, weight=1) frameA1 = LabelFrame(frameA, text='Spin System 1') frameA1.grid(row=0, column=0, sticky='nsew') frameA1.grid_columnconfigure(0, weight=1) frameA1.grid_rowconfigure(0, weight=1) frameA2 = LabelFrame(frameA, text='Spin System 2') frameA2.grid(row=0, column=1, sticky='nsew') frameA2.grid_columnconfigure(0, weight=1) frameA2.grid_rowconfigure(0, weight=1) frameB = LabelFrame(guiFrame, text='Comparison') frameB.grid(row=2, column=0, sticky='nsew') frameB.grid_rowconfigure(0, weight=1) frameB.grid_columnconfigure(0, weight=1) frameB.grid_columnconfigure(1, weight=2) frameB.grid_columnconfigure(2, weight=1) frameB1 = LabelFrame(frameB, text='Unique to Spin System 1') frameB1.grid(row=0, column=0, sticky='nsew') frameB1.expandGrid(0, 0) frameB2 = LabelFrame(frameB, text='Intersection') frameB2.grid(row=0, column=1, sticky='nsew') frameB2.expandGrid(0, 0) frameB3 = LabelFrame(frameB, text='Unique to Spin System 2') frameB3.grid(row=0, column=2, sticky='nsew') frameB3.expandGrid(0, 0) # Settings for isotope shift correction shiftLists = getShiftLists(self.nmrProject) self.protonatedShiftList = shiftLists[0] self.deuteratedShiftList = shiftLists[1] shiftListNames = ['{}: {}'.format(shiftList.serial, shiftList.name) for shiftList in shiftLists] Label(isotopeFrame, text='Correct for isotope shift:', grid=(0, 0)) self.correctCheck = CheckButton(isotopeFrame, selected=True, callback=self.setCorrection, grid=(0, 1)) Label(isotopeFrame, text='Protonated shift list:', grid=(1, 0)) self.protonatedPulldown = PulldownList(isotopeFrame, callback=self.setProtonatedShiftList, texts=shiftListNames, objects=shiftLists, grid=(1, 1), index=0) Label(isotopeFrame, text='Deuterated shift list:', grid=(2, 0)) self.deuteratedPulldown = PulldownList(isotopeFrame, callback=self.setDeuteratedShiftList, texts=shiftListNames, objects=shiftLists, grid=(2, 1), index=1) # Table A1 headingList = ['#', 'shift lists', 'Assignment'] tipTexts = ['Spin System Serial', 'shift lists', 'The residue (tentatively) assigned to this spin system', 'The amount of spin systems that overlap with this spin system and have no violations'] editGetCallbacks = [self.setSpinSystem1]*3 editSetCallbacks = [None]*3 self.tableA1 = ScrolledMatrix(frameA1, headingList=headingList, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA1.grid(row=0, column=0, sticky='nsew') # Table A2 headingList = ['#', 'shift lists', 'Assignment', 'offset'] tipTexts = ['Spin System Serial', 'The residue (tentatively) assigned to this spin system', 'Root mean squared deviation of this spin system to the spin system selected in the table on the left.'] editGetCallbacks = [self.setSpinSystem2]*4 editSetCallbacks = [None]*4 self.tableA2 = ScrolledMatrix(frameA2, headingList=headingList, #editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA2.grid(row=0, column=0, sticky='nsew') # Table B1 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift'] self.tableB1 = ScrolledMatrix(frameB1, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB1.grid(row=0, column=0, sticky='nsew') # Table B 2 headingList = ['atom', 'c.s. 1', 'c.s. 2', 'delta c.s.'] tipTexts = ['name of the atom', 'chemical shift of atom with this name in spin system 1', 'chemical shift of atom with this name in spin system 2', 'difference between the chemical shift of spin systems 1 and 2'] self.tableB2 = ScrolledMatrix(frameB2, headingList=headingList, tipTexts=tipTexts) self.tableB2.grid(row=0, column=0, sticky='nsew') # Table B 3 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift.'] self.tableB3 = ScrolledMatrix(frameB3, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB3.grid(row=0, column=0, sticky='nsew') self.matchMatrix = {} self.amountOfMatchesPerSpinSystem = {} self.updateTableA1()
def __init__(self, parent, project, closeButton=False, tempFiles=False, *args, **kw): ########################################################################### # INIT VARIABLES self.parent = parent self.project = project try: self.nmrProject = (project.currentNmrProject or project.newNmrProject(name='BLACKLEDGE_MODULE')) except: print '&&& Running MODULE popup from outside CCPN Analysis - debug only - no NmrCalc' self.nmrProject = None if self.nmrProject: self.calcStore = project.findFirstNmrCalcStore(name=MODULE, nmrProject=self.nmrProject) or \ project.newNmrCalcStore(name=MODULE, nmrProject=self.nmrProject) else: self.calcStore = None self.run = None self.inputStructure = None self.inputRdcConstraintList = None self.inputDistanceConstraintList = [None] self.inputUserDescriptionText = None # path to the module executable modPath = subprocess.Popen( ['which', 'module'], stdout=subprocess.PIPE).communicate()[0].strip() self.moduleExePath = modPath or ' NB. MODULE executable not found ' self.waiting = False # for debug this could be False if tempFiles: self.useTempFiles = True else: self.useTempFiles = False # create temp files for MODULE if self.useTempFiles: self.moduleTempDir = tempfile.mkdtemp(prefix='MODULE-') else: self.moduleTempDir = os.getcwd() #djo35# self.calcStore = self.resetCalcStore(name='BLACKLEDGE_MODULE') # END INIT OF VARIABLES ########################################################################### ########################################################################### # START GUI CODE Frame.__init__(self, parent, *args, **kw) self.expandGrid(0, 0) ## Single Frame # frame = Frame(self, grid=(0,0)) # or with Tabs? options = ['Launch', 'Output', 'Runs'] tabbedFrame = TabbedFrame(self, options=options, grid=(0, 0)) frameA, frameB, frameC = tabbedFrame.frames self.tabbedFrame = tabbedFrame frameA.expandGrid(14, 2) row = 0 div = LabelDivider(frameA, text='MODULE Setup', grid=(row, 0), gridSpan=(1, 4)) row += 1 # allow the user to choose MODULE if either the one in PATH is incorrect or not found button = Button(frameA, text='Select MODULE executable:',bd=1, \ command=self.selectExecutable, grid=(row,0), sticky="ew") self.moduleExeEntry = Entry(frameA, text=self.moduleExePath, grid=(row,1), gridSpan=(1,3), \ width=32, sticky="ew", bd=1) self.moduleExePath = self.moduleExeEntry.get() # separator "MODULE input" row += 1 div = LabelDivider(frameA, text='MODULE input', grid=(row, 0), gridSpan=(1, 5)) row += 1 label = Label(frameA, text='Structure:', grid=(row, 1)) self.inputStructurePulldown = PulldownList(frameA, self.changeInputStructure, \ grid=(row,2)) # self.constraintsFileEntry.bind('<Leave>', self.updateEntryParams) row += 1 label = Label(frameA, text='RDC constraints:', grid=(row, 1)) self.inputRdcConstraintsPulldown = PulldownList(frameA, self.changeInputRdcConstraintList, \ grid=(row,2)) #self.constraintsFileEntry.bind('<Leave>', self.updateEntryParams) row += 1 label = Label(frameA, text='(Optional input)', grid=(row, 0)) label = Label(frameA, text='Distance constraints:', \ grid=(row,1)) self.inputDistanceConstraintsPulldown = PulldownList(frameA, self.changeInputDistanceConstraintList, \ grid=(row,2)) #self.constraintsFileEntry.bind('<Leave>', self.updateEntryParams) row += 1 subFrameDepth = 4 subframe = LabelFrame(frameA, text='MODULE User Notes (store notes about how MODULE was run here)', \ grid=(row,0), gridSpan=(1,4)) subframe.expandGrid(subFrameDepth, 0) self.moduleUserText = ScrolledText(subframe) self.moduleUserText.grid(row=subFrameDepth, column=0, columnspan=4, sticky='nsew') # View Results row += subFrameDepth # row += 1 # div = LabelDivider(frameA, text='MODULE launch', grid=(row,0), gridSpan=(1,4)) row += 1 button = Button(frameA, text='Run MODULE', bd=1, command=self.executeModule, \ grid=(row,0), gridSpan=(1,4), sticky="ew", bg=MODULE_GREEN) # grid=(row,0), gridSpan=(1,2), sticky="ew", bg=MODULE_GREEN) ########################################################################### # Frame B (tab 2) Ouput frameB.expandGrid(4, 1) row = 0 subFrameDepth = 6 subframe = LabelFrame(frameB, text='MODULE Output', \ grid=(row,0), gridSpan=(1,5)) #subframe.grid_columnconfigure(2, weight=1) subframe.expandGrid(subFrameDepth, 0) self.moduleOutputText = ScrolledText(subframe) self.moduleOutputText.setState(state=Tkinter.DISABLED) self.moduleOutputText.grid(row=subFrameDepth, column=0, columnspan=4, sticky='nsew') # separator "MODULE input" row += 1 div = LabelDivider(frameB, text='MODULE RDC Back Values', grid=(row, 0), gridSpan=(1, 5)) row += 1 button = Button(frameB, text='Import MODULE Back Values file', bd=1, command=self.importModuleBackValues, \ grid=(row,0), gridSpan=(1,4), sticky="ew", bg=MODULE_BLUE) # grid=(row,0), gridSpan=(2,4), sticky="ew", bg=MODULE_BLUE) row += 1 self.rdcOutputTable = None frameB.grid_rowconfigure(row, weight=1) headings = ('#', 'Resonances', 'Value', 'Back Value', 'Diff.', 'Error') editWidgets = [None, None, None, None, None, None] editGetCallbacks = [None, None, None, None, None, None] editSetCallbacks = [None, None, None, None, None, None] self.rdcOutputTable = ScrolledMatrix(frameB, headingList=headings, multiSelect=False, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, initialRows=4) self.rdcOutputTable.grid(row=row, column=0, columnspan=4, sticky='nsew') row += 1 button = Button(frameB, text='Import MODULE Structure', bd=1, command=self.importModuleStructure, \ grid=(row,0), gridSpan=(1,4), sticky="ew", bg=MODULE_BLUE) # grid=(row,0), gridSpan=(2,4), sticky="ew", bg=MODULE_BLUE) ########################################################################### # Frame C (tab 3) NMR Calc display bits frameC.expandGrid(4, 1) row = 0 div = LabelDivider(frameC, text='Stored MODULE Runs', grid=(row, 0), gridSpan=(1, 5)) # NmrCalc Run scrolled matrix row += 1 self.runTable = None frameC.grid_rowconfigure(row, weight=1) headings = ('Run ID', 'notes', 'Status') # self.editRunNotes = DataEntry.askString('Run Notes', 'Edit notes about Run', tipText='Notes about Run', parent=self) # editWidgets = [None, self.editRunNotes, None] editWidgets = [None, None, None] editGetCallbacks = [None, None, None] editSetCallbacks = [None, None, None] self.runTable = ScrolledMatrix(frameC, headingList=headings, multiSelect=False, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, initialRows=4) self.runTable.grid(row=row, column=0, columnspan=4, sticky='nsew') row += 4 tipTexts = ['Load Selected Run', 'Delete Selected Run'] texts = ['Load Selected Run', 'Delete Selected'] commands = [self.loadRun, self.deleteRun] colours = [MODULE_GREEN, MODULE_RED] self.runButtons = ButtonList(frameC, texts=texts, tipTexts=tipTexts, commands=commands, grid=(row, 0), gridSpan=(1, 4)) self.runButtons.buttons[0].config(bg=MODULE_GREEN) self.runButtons.buttons[1].config(bg=MODULE_RED) ########################################################################### # Keep GUI up to date self.updateAfter() self.administerNotifiers(self.parent.registerNotify)
class ResidueInfoPopup(BasePopup): """ **Residue Assignment Information** This popup is designed to give an alternative view of residue assignment status to the `Atom Browser`_. The idea is that the user selects a particular molecular chain from the upper-left pulldown menu and then a *type* of residue from that chain in the adjacent pulldown. The left hand table then shows all the residues of that type within the selected chain's sequence. The left hand table lists residues of the selected type in the middle column. The first and last columns show the previous and next residue in the sequence for each central residue, thus showing a little of the sequence context for the selected kind of residue. If a row of this table is clicked, the central "i" residue is selected and the assignments are displayed in a 3D structural view in the right hand panel. The right hand panel contains a structural display for the kind of residue selected, using *idealised* coordinates; not coordinates from a particular structure. With the "Show Assignment" option selected, this 3D view has the chemical shifts of the assigned atoms within the selected residue superimposed in the view. The chemical shifts are listed after the name of each atom, but naturally only if it has a resonance assignment in the selected shift list. It should be noted that where atoms are deemed to be equivalent, like the three hydrogens in a fast rotating methyl atom set, the same chemical shift values will be used for all of the atoms within the set, although strictly speaking the value only really applies to the set as a whole. Also, for assignments that are non-stereospecific, e.g. there may be an assignment to Ser HBa which doesn't commit to either HB2 or HB3 specifically, the display will show both possible chemical shift values (should they exist) for a given atom. For example, a Ser HB2 atom may be labeled as "HB" 3.72/3.85" because it potentially relates to either the "HBa" resonance at 3.72 ppm or the "HBb" resonance at 3.85 ppm. **3D View Controls** To move and rotate the three-dimensional residue display the following keyboard controls may be used: * Rotate: Arrow keys * Zoom: Page Up & Page Down keys * Translate: Arrow keys + Control key Or altenatively the following mouse controls: * Rotate: Middle button click & drag * Zoom: Mouse wheel or middle button click + Shift key & drag up/down * Translate: Middle button click & drag + Control key _`Atom Browser`: BrowseAtomsPopup.html """ def __init__(self, parent, *args, **kw): self.residue = None self.chain = None self.shiftList = None BasePopup.__init__(self, parent=parent, title="Molecule : Residue Information", **kw) def open(self): self.updateChains() BasePopup.open(self) def body(self, guiFrame): self.refresh = False self.hilightColor = 'lightBlue' self.matrixCellGrey = 'grey82' self.chain = None self.ccpCode = None row = 0 label = Label(guiFrame, text='Molecule Chain:', grid=(row, 0)) tipText = 'Selects which molecular chain to select and show residues from' self.chainPulldown = PulldownList(guiFrame, callback=self.changeChain, grid=(row, 1), tipText=tipText) label = Label(guiFrame, text='Ccp Residue Code:', grid=(row, 2)) tipText = 'Selects which kind of residue to display sequence and assignment information for' self.ccpCodePulldown = PulldownList(guiFrame, callback=self.changeCcpCode, grid=(row, 3), tipText=tipText) label = Label(guiFrame, text='Shift List:', grid=(row, 4)) tipText = 'Selects which shiftlist to get chemical shift values from' self.shiftListPulldown = PulldownList(guiFrame, callback=self.changeShiftList, grid=(row, 5), tipText=tipText) row += 1 guiFrame.expandGrid(row, 6) self.residueFrame = LabelFrame(guiFrame, text='%s Information' % (self.ccpCode), grid=(row, 0), gridSpan=(1, 3)) self.residueFrame.expandGrid(1, 0) self.atomsFrame = LabelFrame( guiFrame, text='Atom Information & Idealised Structure', grid=(row, 3), gridSpan=(1, 5)) self.atomsFrame.expandGrid(0, 0) self.assignedText = 'Assigned:' tipText = 'How many residues of the selected kind are assigned out of the total number available' self.assignedLabel = Label(self.residueFrame, text=self.assignedText, grid=(0, 0), sticky='ew', tipText=tipText) tipTexts = [ 'Identity of the previous residue in the sequence', 'Locations of the selected kind of residue, considering the selected molecular chain', 'Identity of the next residue in the sequence' ] headingList = ['i-1', 'i', 'i+1'] self.neighbourMatrix = ScrolledMatrix(self.residueFrame, initialRows=8, headingList=headingList, minCellWidth=6, sorting=0, highlightType=1, callback=self.selectResidue, grid=(1, 0), gridSpan=(1, 3), tipTexts=tipTexts) self.viewResidueFrame = ViewResidueFrame(self.atomsFrame, residue=self.residue, project=self.project, grid=(0, 0), tipText=tipText) tipTexts = [ 'Print the three-dimensional coordinate display to a PostScript, EPS or PDF file', ] texts = ['Print'] commands = [self.viewResidueFrame.printStructure] self.utilButtons = UtilityButtonList(guiFrame, helpUrl=self.help_url, commands=commands, texts=texts, grid=(0, 7), tipTexts=tipTexts) self.updateChains() self.updateShiftLists() self.updateAfter() self.administerNotifiers(self.registerNotify) def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.ResonanceSet', ): notifyFunc(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): for clazz in ('ccp.molecule.MolSystem.Chain', ): notifyFunc(self.updateChains, clazz, func) for func in ('__init__', 'delete', 'setName'): for clazz in ('ccp.nmr.Nmr.ShiftList', ): notifyFunc(self.updateShiftLists, clazz, func) notifyFunc(self.updateAfter, 'ccp.molecule.MolSystem.Residue', 'setSeqCode') def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self) def selectResidue(self, residue, row, col): self.residue = residue self.updateAfter() def getChains(self, project): chains = [] chainCodes = [] for molSystem in self.project.sortedMolSystems(): for chain in molSystem.sortedChains(): chains.append(chain) chainCodes.append(self.getChainName(chain)) return [chains, chainCodes] def getCcpCodes(self, chain): if not chain: return [] dict = {} for residue in chain.residues: dict[residue.molResidue.ccpCode] = residue.molResidue.molType codes = [] codesTemp = dict.keys() codesTemp.sort() for code in codesTemp: codes.append(code) return codes def getChainName(self, chain): return '%s:%s(%s)' % (chain.molSystem.name, chain.code, chain.molecule.molType) def changeChain(self, chain): if self.chain is not chain: self.chain = chain self.updateCcpCodes() self.residue = None def changeCcpCode(self, ccpCode): if self.ccpCode != ccpCode: self.ccpCode = ccpCode self.residue = None self.updateAfter() def changeShiftList(self, shiftList): if shiftList is not self.shiftList: self.shiftList = shiftList self.updateAfter() def updateChains(self, *opt): index = [] chain = self.chain [chains, chainCodes] = self.getChains(self.project) if chains: if chain not in chains: chain = chains[0] index = chains.index(chain) else: chain = None if self.chain is not chain: self.chain = chain self.updateCcpCodes() self.chainPulldown.setup(chainCodes, chains, index) def updateCcpCodes(self, *opt): index = 0 ccpCodes = [] if self.chain: ccpCodes = self.getCcpCodes(self.chain) if self.ccpCode not in ccpCodes: self.ccpCode = ccpCodes[0] self.residue = None index = ccpCodes.index(self.ccpCode) if self.residue and (self.residue.chain is not self.chain): self.residue = None self.ccpCodePulldown.setup(ccpCodes, ccpCodes, index) self.updateAfter() def updateShiftLists(self, *opt): index = 0 names = [] shiftLists = getShiftLists(self.nmrProject) shiftList = self.shiftList if shiftLists: if shiftList not in shiftLists: shiftList = shiftLists[0] names = ['%d:%s' % (sl.serial, sl.name) for sl in shiftLists] index = shiftLists.index(shiftList) else: shiftList = None if shiftList is not self.shiftList: self.changeShiftList(shiftList) self.shiftListPulldown.setup(names, shiftLists, index) def updateAfter(self, *opt): if self.refresh: return else: self.refresh = True self.after_idle(self.update) def update(self): # problem is that selectCell updates on old residue list # selecting a cell doesn't normally update the matrix if not self.chain: self.refresh = False return chain = self.chain ccpCode = self.ccpCode sameTypeResidues = [] seqNeighbours = [] neighbourData = [] colorData = [] assigned = 0 residues = chain.sortedResidues() for residue in residues: if residue.molResidue.ccpCode == ccpCode: if self.residue is None: self.residue = residue sameTypeResidues.append(residue) neighbourData.append([None, None, None]) colorData.append([ self.matrixCellGrey, self.matrixCellGrey, self.matrixCellGrey ]) if self.residue and (self.residue.molResidue.molType == 'protein'): tlc = ccpCode[:1] + ccpCode[1:].lower() else: tlc = ccpCode i = 0 for residue in sameTypeResidues: j = residues.index(residue) neighbourData[i][1] = '%d %s' % (residue.seqCode, tlc) if isResidueAssigned(residue): assigned += 1 colorData[i][1] = self.hilightColor if j >= residues[0].seqId: prevRes = residues[j - 1] tlc1 = prevRes.molResidue.ccpCode if prevRes.molResidue.molType == 'protein': tlc1 = tlc1[:1] + tlc1[1:].lower() neighbourData[i][0] = '%d %s' % (prevRes.seqCode, tlc1) if isResidueAssigned(prevRes): colorData[i][0] = self.hilightColor if j + 1 < residues[-1].seqId: nextRes = residues[j + 1] tlc2 = nextRes.molResidue.ccpCode if nextRes.molResidue.molType == 'protein': tlc2 = tlc2[:1] + tlc2[1:].lower() neighbourData[i][2] = '%d %s' % (nextRes.seqCode, tlc2) if isResidueAssigned(nextRes): colorData[i][2] = self.hilightColor i += 1 self.residueFrame.setText('%s Information' % tlc) self.assignedLabel.set(self.assignedText + ' %d' % assigned + ' of' + ' %d' % len(sameTypeResidues)) self.neighbourMatrix.update(objectList=sameTypeResidues, textMatrix=neighbourData, colorMatrix=colorData) if self.residue: #self.specificLabel.set('Chain %s Residue %s %s' % (chain.code,tlc,str(self.residue.seqCode))) self.neighbourMatrix.hilightObject(self.residue) self.viewResidueFrame.update(self.residue, self.shiftList) self.refresh = False
def __init__(self, parent, application, *args, **kw): project = application.project self.nmrProject = nmrProject = application.nmrProject if project: calcStore = project.findFirstNmrCalcStore(name=APP_NAME, nmrProject=nmrProject) or \ project.newNmrCalcStore(name=APP_NAME, nmrProject=nmrProject) else: calcStore = None self.application = application self.residue = None self.structure = None self.serverCredentials = None self.iCingBaseUrl = DEFAULT_URL self.resultsUrl = None self.chain = None self.serverDone = False NmrCalcRunFrame.__init__(self, parent, project, calcStore, *args, **kw) # # # # # # New Structure Frame # # # # # self.structureTable.grid_forget() self.structureButtons.grid_forget() self.ensemblePulldown.grid_forget() self.modelButtons.grid_forget() self.modelPulldown.grid_forget() frame = self.inputTabs.frames[0] frame.grid_rowconfigure(0, weight=0) frame.grid_rowconfigure(1, weight=1) label = Label(frame, text='Ensemble: ', grid=(0, 0)) self.structurePulldown = PulldownList( frame, callback=self.changeStructure, grid=(0, 1), tipText='The structure ensemble coordinates to submit') tipTexts = [ 'Conformational model number', 'Whether analyse this model' ] headingList = ['Model', 'Use'] editWidgets = [None, None] editGetCallbacks = [None, self.toggleModel] editSetCallbacks = [ None, None, ] self.modelTable = ScrolledMatrix(frame, grid=(1, 0), gridSpan=(1, 2), callback=self.selectStructModel, multiSelect=True, tipTexts=tipTexts, editWidgets=editWidgets, initialRows=2, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, headingList=headingList) tipTexts = [ 'Activate the selected models so that they will be consedered in the analysis', 'Deactivate the selected models so that they will not be considered in the analysis' ] texts = ['Activate Selected', 'Inactivate Selected'] commands = [self.activateModels, self.disableModels] buttons = ButtonList(frame, texts=texts, commands=commands, grid=(2, 0), gridSpan=(1, 2), tipTexts=tipTexts) # # # # # # Submission frame # # # # # # tab = self.tabbedFrame.frames[1] tab.expandGrid(1, 0) frame = LabelFrame(tab, text='Server Job Submission', grid=(0, 0)) frame.expandGrid(None, 2) srow = 0 label = Label(frame, text='iCing URL:', grid=(srow, 0)) self.iCingBaseUrlPulldown = PulldownList( frame, texts=URLS, objects=URLS, index=0, grid=(srow, 1), tipText='Web location of iCING server to use') srow += 1 label = Label(frame, text='Results File:', grid=(srow, 0)) self.resultFileEntry = Entry( frame, bd=1, text='', grid=(srow, 1), width=50, tipText='Name of file to store compressed CING results in') self.setZipFileName() button = Button(frame, text='Choose File', bd=1, sticky='ew', command=self.chooseZipFile, grid=(srow, 2), tipText='Select file to overwrite with CING results') srow += 1 label = Label(frame, text='Results URL:', grid=(srow, 0)) self.resultUrlEntry = Entry( frame, bd=1, text='', grid=(srow, 1), width=50, tipText='Web location where CING results will be posted') button = Button(frame, text='View Results HTML', bd=1, sticky='ew', command=self.viewHtmlResults, grid=(srow, 2), tipText='Open the HTML CING results in a web browser') srow += 1 tipTexts = [ 'Submit the CCPN project to the CING server', 'Determin whether the iCING job is complete, pending or has failed', 'Remove all trace of the last submissionfrom the iCING server', 'Download the compressed CING results, including HTML' ] texts = [ 'Submit Project!', 'Check Run Status', 'Purge Server Result', 'Download Results' ] commands = [ self.runCingServer, self.checkStatus, self.purgeCingServer, self.downloadResults ] self.buttonBar = ButtonList(frame, texts=texts, commands=commands, grid=(srow, 0), gridSpan=(1, 3), tipTexts=tipTexts) for button in self.buttonBar.buttons[:1]: button.config(bg=CING_BLUE) # # # # # # Residue frame # # # # # # frame = LabelFrame(tab, text='Residue Options', grid=(1, 0)) frame.expandGrid(1, 1) label = Label(frame, text='Chain: ') label.grid(row=0, column=0, sticky='w') self.chainPulldown = PulldownList( frame, callback=self.changeChain, tipText='Select the molecular system chain to consider') self.chainPulldown.grid(row=0, column=1, sticky='w') headingList = ['#', 'Residue', 'Linking', 'Decriptor', 'Use?'] tipTexts = [ 'Sequence number', 'Residue type code', 'In-chain connectivity of residue', 'Protonation and steriochemical state', 'Whether to consider the residue in the analysis' ] editWidgets = [None, None, None, None, None] editGetCallbacks = [None, None, None, None, self.toggleResidue] editSetCallbacks = [ None, None, None, None, None, ] self.residueMatrix = ScrolledMatrix(frame, headingList=headingList, multiSelect=True, tipTexts=tipTexts, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectResidue) self.residueMatrix.grid(row=1, column=0, columnspan=2, sticky='nsew') tipTexts = [ 'Use the selected residues in the analysis', 'Do not use the selected residues in the analysis' ] texts = ['Activate Selected', 'Inactivate Selected'] commands = [self.activateResidues, self.deactivateResidues] self.resButtons = ButtonList(frame, texts=texts, commands=commands, tipTexts=tipTexts) self.resButtons.grid(row=2, column=0, columnspan=2, sticky='ew') """ # # # # # # Validate frame # # # # # # frame = LabelFrame(tab, text='Validation Options', grid=(2,0)) frame.expandGrid(None,2) srow = 0 self.selectCheckAssign = CheckButton(frame) self.selectCheckAssign.grid(row=srow, column=0,sticky='nw' ) self.selectCheckAssign.set(True) label = Label(frame, text='Assignments and shifts') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckResraint = CheckButton(frame) self.selectCheckResraint.grid(row=srow, column=0,sticky='nw' ) self.selectCheckResraint.set(True) label = Label(frame, text='Restraints') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckQueen = CheckButton(frame) self.selectCheckQueen.grid(row=srow, column=0,sticky='nw' ) self.selectCheckQueen.set(False) label = Label(frame, text='QUEEN') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckScript = CheckButton(frame) self.selectCheckScript.grid(row=srow, column=0,sticky='nw' ) self.selectCheckScript.set(False) label = Label(frame, text='User Python script\n(overriding option)') label.grid(row=srow,column=1,sticky='nw') self.validScriptEntry = Entry(frame, bd=1, text='') self.validScriptEntry.grid(row=srow,column=2,sticky='ew') scriptButton = Button(frame, bd=1, command=self.chooseValidScript, text='Browse') scriptButton.grid(row=srow,column=3,sticky='ew') """ # # # # # # # # # # self.update(calcStore) self.administerNotifiers(application.registerNotify)
def body(self, guiFrame): self.doUpdateForm = True self.spectrum = None guiFrame.grid_columnconfigure(1, weight=1) row = 0 specFrame = LabelFrame(guiFrame, text='Spectrum', grid=(row, 0)) tipText = 'The spectrum for which you are setting the contour levels' self.expt_spectrum = PulldownList(specFrame, grid=(0, 0), tipText=tipText, callback=self.setSpectrumDetails) tipText = 'Open the edit spectrum table to view and change other properties associated with the selected spectrum' button = Button(specFrame, text='Spectrum Properties', command=self.editProperties, borderwidth=1, grid=(1, 0), sticky='ew', tipText=tipText) globalFrame = LabelFrame(guiFrame, text='Global scale') globalFrame.grid(row=row, column=1, sticky='nsew') globalFrame.grid_columnconfigure(0, weight=1) tipText = 'The value by which all contour levels in all spectra are multiplied; to give the actual contour level in terms of the stored spectrum data' self.global_entry = FloatEntry( globalFrame, width=10, tipText=tipText, text=self.analysisProject.globalContourScale, returnCallback=self.applyAuto, grid=(0, 0), gridSpan=(1, 2), sticky='ew') tipText = 'Divide the global scaling factor by two; moving all contour for all spectra levels closer to zero' button = Button(globalFrame, borderwidth=1, text='/2', sticky='ew', tipText=tipText, command=lambda: self.changeGlobalScale(0.5), grid=(0, 2)) tipText = 'Multiple the global scaling factor by two; moving all contour for all spectra levels away from zero' button = Button(globalFrame, borderwidth=1, text='*2', sticky='ew', tipText=tipText, command=lambda: self.changeGlobalScale(2.0), grid=(0, 3)) tipText = 'Set the global contour scale for all spectra to the default of 100,000' button = Button(globalFrame, borderwidth=1, text='10^5', tipText=tipText, command=self.defaultGlobalScale, grid=(1, 0)) tipText = 'Click to decrease "-" or increase "+" the global contour scale by small amounts' frame = ValueRamp(globalFrame, callback=self.changeGlobalScale, tipText=tipText) frame.grid(row=1, column=1, columnspan=3, sticky='e') row += 1 self.autoFrame = LabelFrame(guiFrame, text='Auto contour levels') self.autoFrame.grid(row=row, column=0, columnspan=5, sticky='nsew') self.autoFrame.grid_columnconfigure(1, weight=1) frow = 0 label = Label(self.autoFrame, text='Base level:', grid=(frow, 0), sticky='e') tipText = 'The first contour level (closest to zero) for an automated series of levels: the start of a geometric or arithmetic series defining levels' self.base_entry = FloatEntry(self.autoFrame, returnCallback=self.applyAuto, width=10, grid=(frow, 1), sticky='ew', tipText=tipText) command = lambda: self.changeBaseLevel(0.5) tipText = 'Lower the base contour level so that it is half of the previous value; moving the series of contour levels closer to zero' button = Button(self.autoFrame, borderwidth=1, text='/2', tipText=tipText, command=command, grid=(frow, 2), sticky='ew') command = lambda: self.changeBaseLevel(2.0) tipText = 'Raise the base contour level so that it is double the previous value; moving the series of contour levels further from zero' button = Button(self.autoFrame, borderwidth=1, text='*2', tipText=tipText, command=command, grid=(frow, 3), sticky='ew') tipText = 'Click to decrease "-" or increase "+" the base contour level by small amounts' frame = ValueRamp(self.autoFrame, callback=self.changeBaseLevel, tipText=tipText) frame.grid(row=frow, column=4, columnspan=3, sticky='ew') frow += 1 label = Label(self.autoFrame, text='Number of levels:', grid=(frow, 0), sticky='e') #self.numberEntry = IntEntry(guiFrame, text=numberLevels, # returnCallback=self.applyAuto) tipText = 'The number of contour levels to make in the automated series' self.numberEntry = IntEntry(self.autoFrame, returnCallback=self.applyAuto, width=10, grid=(frow, 1), sticky='ew', tipText=tipText) command = lambda w=-1: self.changeNumberLevels(w) tipText = 'Decrease the number of contour levels in the series by one' button = Button(self.autoFrame, borderwidth=1, text='-1', tipText=tipText, command=command, grid=(frow, 2), sticky='ew') command = lambda w=1: self.changeNumberLevels(w) tipText = 'Increase the number of contour levels in the series by one' button = Button(self.autoFrame, borderwidth=1, text='+1', tipText=tipText, command=command, grid=(frow, 3), sticky='ew') n = 4 for w in (5, 10, 15, 20): tipText = 'Set the number of contour levels in the series to %d' % w command = lambda w=w: self.setNumberLevels(w) button = Button(self.autoFrame, borderwidth=1, text='%d' % w, command=command, grid=(frow, n), sticky='ew', tipText=tipText) n += 1 frow += 1 self.change_label = Label(self.autoFrame, text='%s:' % multiplier_text, grid=(frow, 0), sticky='e') tipText = 'The multiplication factor (or increment if adding levels) to repetitively apply to the base level to generate the series of levels' self.change_entry = FloatEntry(self.autoFrame, returnCallback=self.applyAuto, width=10, grid=(frow, 1), sticky='ew', tipText=tipText) self.change_level_buttons = [] n = 2 for w in multiplier_changes: tipText = 'Set the automated series multiplication factor or increment to %f' % w command = lambda w=w: self.setChange(w) button = Button(self.autoFrame, borderwidth=1, text=str(w), command=command, grid=(frow, n), sticky='ew', tipText=tipText) self.change_level_buttons.append(button) n += 1 frow += 1 frame = Frame(self.autoFrame, grid=(frow, 0), gridSpan=(1, 7), sticky='ew') tipTexts = [ 'Toggles whether positive contour levels from the automated series will be used. Overrides any manual settings', 'Toggles whether negative contour levels from the automated series will be used. Overrides any manual settings' ] entries = ('Positive', 'Negative') selected = (True, False) self.which_buttons = CheckButtons(frame, entries, selected=selected, select_callback=self.applyAuto, grid=(0, 0), sticky='w', tipTexts=tipTexts) tipTexts = [ 'Set the contour level generation to use a geometric series, starting from the base level and using the specified factor', 'Set the contour level generation to use an arithmetic series, starting from the base level and using the specified increment' ] entries = ('Multiply levels', 'Add levels') self.change_mode_buttons = RadioButtons( frame, entries, grid=(0, 1), sticky='ew', select_callback=self.modeChanged, tipTexts=tipTexts) row += 1 manualFrame = LabelFrame(guiFrame, text='Positive levels', grid=(row, 0), gridSpan=(1, 2)) manualFrame.expandGrid(None, 0) tipText = 'The positive contour levels that will be used for the spectrum; filled in by the automation or set/modified manually' self.posLevelsEntry = FloatEntry(manualFrame, isArray=True, width=60, returnCallback=self.applyManual, tipText=tipText, grid=(0, 0), sticky='ew') row += 1 manualFrame = LabelFrame(guiFrame, text='Negative levels', grid=(row, 0), gridSpan=(1, 2)) manualFrame.expandGrid(None, 0) tipText = 'The negative contour levels that will be used for the spectrum; filled in by the automation or set/modified manually' self.negLevelsEntry = FloatEntry(manualFrame, isArray=True, width=60, returnCallback=self.applyManual, tipText=tipText, grid=(0, 0), sticky='ew') row += 1 tipTexts = [ 'Set the spectrum contour levels, updating the display, to the automated series, ignoring any manual edits.', 'Set the spectrum contour levels, updating the display, to the values displayed in the level entry fields' ] texts = ['Apply Auto Levels', 'Apply Manual Edits'] commands = [self.applyAuto, self.applyManual] self.buttons = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url, grid=(row, 0), gridSpan=(1, 2), tipTexts=tipTexts) guiFrame.grid_rowconfigure(row, weight=1) self.curateNotifiers(self.registerNotify) self.update()
def __init__(self, parent, project, closeButton=False, *args, **kw): self.parent = parent self.project = project self.nmrProject = (project.currentNmrProject or project.newNmrProject(name='PALES')) self.calcStore = None self.run = None self.inpStructure = None self.inpConstraintList = None self.workingDir = None self.waiting = False self.palesMode = None self.resetCalcStore() Frame.__init__(self, parent, *args, **kw) self.expandGrid(0, 0) options = ['Input Data', 'Extra Input', 'View Results'] tabbedFrame = TabbedFrame(self, options=options, grid=(0, 0)) frameA, frameX, frameB = tabbedFrame.frames self.tabbedFrame = tabbedFrame label = Label(tabbedFrame.sideFrame, text='Run Number:', grid=(0, 0), sticky='e') tipText = 'Selects which calculation job or "run" is currently being viewed or edited' self.runPulldown = PulldownList(tabbedFrame.sideFrame, callback=self.changeRun, grid=(0, 1), sticky='e', tipText=tipText) tipTexts = ['Delete the current calculation run settings'] texts = ['Delete Run'] commands = [self.deleteRun] if closeButton: ButtonListClass = UtilityButtonList else: ButtonListClass = ButtonList runButtons = ButtonListClass(tabbedFrame.sideFrame, texts=texts, tipTexts=tipTexts, commands=commands, sticky='e', grid=(0, 2)) # Input data frameA.expandGrid(2, 1) row = 0 label = Label(frameA, text='Pales mode:', grid=(row, 0), sticky='w') self.palesModePulldown = PulldownList(frameA, callback=self.changePalesMode, grid=(row, 1)) tipTexts = [ 'Make a setup for a new calculation run', 'Make a new calculation run by copying the current one', ] texts = ['New Run', 'Copy Run'] commands = [self.newRun, self.copyRun] if closeButton: ButtonListClass = UtilityButtonList else: ButtonListClass = ButtonList runButtons = ButtonList(frameA, texts=texts, tipTexts=tipTexts, commands=commands, sticky='e', grid=(row, 2)) runButtons.buttons[0].config(bg='#B0FFB0') row += 1 subframe1 = LabelFrame(frameA, text='Description', grid=(row, 0), gridSpan=(1, 3)) subframe1.expandGrid(0, 1) self.modeDescription = Label(subframe1, grid=(row, 0), sticky='w') row += 1 # setup generic table headings, justification and widget getters/setters self.inputMatrix = GenericDataMatrix(frameA, progParameters) self.inputMatrix.grid(row=row, column=0, columnspan=3, sticky='nsew') row += 1 label = Label(frameA, text='Comments:', grid=(row, 0)) self.detailsEntryIn = Entry(frameA, grid=(row, 1), gridSpan=(1, 2), sticky="ew") self.detailsEntryIn.bind('<Leave>', self.changeDetailsIn) row += 1 button = Button(frameA, text='Select working dir:', bd=1, command=self.selectWorkingDir, grid=(row, 0), sticky="ew") self.workingDirEntry = Entry(frameA, text='.', grid=(row, 1), gridSpan=(1, 2), width=48, sticky="ew", bd=1) row += 1 button = Button(frameA, text='Execute Pales:', bd=1, command=self.executePales, grid=(row, 0), gridSpan=(1, 3), sticky="new") # Extra input # setup generic table headings, justification and widget getters/setters frameX.expandGrid(0, 0) self.extraInputMatrix = GenericDataMatrix(frameX, progParameters) self.extraInputMatrix.grid(row=0, column=0, sticky='nsew') # View Results frameB.expandGrid(7, 1) row = 0 subframe1 = LabelFrame(frameB, text='Command Options:', grid=(row, 0), gridSpan=(1, 4)) # gridSpan=(1,2)) subframe1.expandGrid(0, 1) self.palesOptionsLabel = Label(subframe1, grid=(row, 0), sticky='w') row += 1 div = LabelDivider(frameB, text='Data', grid=(row, 0), gridSpan=(1, 4)) row += 1 self.outputMatrix = GenericDataMatrix(frameB, progParameters, initialRows=4) self.outputMatrix.grid(row=0, column=0, sticky='nsew') self.outputMatrix.grid(row=row, column=0, columnspan=(4), sticky='nsew') row += 1 button = Button(frameB, text='View Selected', bd=1, command=self.viewPalesData, grid=(row, 0), gridSpan=(1, 4), sticky="ew") row += 1 label = Label(frameB, text='Comments:', grid=(row, 0), sticky="w") self.detailsEntry = Entry(frameB, grid=(row, 1), gridSpan=(1, 3), sticky="ew") self.detailsEntry.bind('<Leave>', self.changeDetails) row += 1 subframe2 = LabelFrame(frameB, text='Calculated Order Matrix:', grid=(row, 0), gridSpan=(1, 4)) #subframe2.grid_columnconfigure(5, weight=1) subframe2.expandGrid(1, 5) label = Label(subframe2, text='Daxial', grid=(0, 0), sticky='ew') label = Label(subframe2, text='Drhombic', grid=(0, 1), sticky='ew') label = Label(subframe2, text='Psi', grid=(0, 2), sticky='ew') label = Label(subframe2, text='Phi', grid=(0, 3), sticky='ew') label = Label(subframe2, text='Theta', grid=(0, 4), sticky='ew') self.outputTensorLabels = ll = [] for ii in range(5): label = Label(subframe2, text='<None>', grid=(1, ii), sticky='ew') ll.append(label) row += 1 div = LabelDivider(frameB, text='Program Output', grid=(row, 0), gridSpan=(1, 4), sticky='sew') #textFrame1 = LabelFrame(frameB, text='Pales Output File', grid=(5,0), # gridSpan=(1,6), sticky='nsew') #textFrame1.expandGrid(0,0) row += 1 self.palesOutputText = ScrolledText(frameB, xscroll=False) self.palesOutputText.grid(row=row, column=0, columnspan=4, sticky='nsew') self.updateAfter() self.administerNotifiers(self.parent.registerNotify)