def body(self, guiFrame): self.geometry('700x400') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=1) interfaceGroups, interfaceGroupDict = self.getInterfaceGroups() if len(interfaceGroups) > 1: mainFrame = TabbedFrame(guiFrame, options=interfaceGroups, grid=(0, 0)) frames = mainFrame.frames else: mainFrame = Frame(guiFrame, grid=(0, 0)) frames = [mainFrame] for n, interfaceGroup in enumerate(interfaceGroups): frame = frames[n] interfaceObjects = interfaceGroupDict[interfaceGroup] for interfaceObject in interfaceObjects: self.makeInterfaceWidget(frame, interfaceObject) texts = ('Ok', 'Cancel') commands = (self.setupRun, self.cancelRun) buttonList = ButtonList(guiFrame, texts=texts, commands=commands, grid=(1, 0))
def body(self): frame = self.frame self.resultsResidueNumber = 1 frame.expandGrid(5, 0) resultTopFrame = LabelFrame(frame, text='Which results to show') resultTopFrame.grid(row=0, column=0, sticky='ew') self.resultsResidueNumber = 3 texts = [' < '] commands = [self.resultsPrevResidue] self.resultsPreviousButton = ButtonList(resultTopFrame, commands=commands, texts=texts) self.resultsPreviousButton.grid(row=0, column=1, sticky='nsew') tipText = 'The Number of the residue in the sequence to display results for' self.resultsResidueNumberEntry = IntEntry( resultTopFrame, grid=(0, 2), width=7, text=3, returnCallback=self.resultsUpdateAfterEntry, tipText=tipText) #self.resultsResidueNumberEntry.bind('<Leave>', self.resultsUpdateAfterEntry, '+') texts = [' > '] commands = [self.resultsNextResidue] self.resultsNextButton = ButtonList(resultTopFrame, commands=commands, texts=texts) self.resultsNextButton.grid(row=0, column=3, sticky='nsew') selectCcpCodes = ['residue'] + AMINO_ACIDS self.resultsSelectedCcpCode = 'residue' tipText = 'Instead of going through the sequence residue by residue, jump directly to next amino acid of a specific type.' resultsSelectCcpCodeLabel = Label( resultTopFrame, text='Directly jump to previous/next:', grid=(0, 4)) self.resultsSelectCcpCodePulldown = PulldownList( resultTopFrame, callback=self.resultsChangeSelectedCcpCode, texts=selectCcpCodes, index=selectCcpCodes.index(self.resultsSelectedCcpCode), grid=(0, 5), tipText=tipText) self.selectedSolution = 1 runLabel = Label(resultTopFrame, text='run:') runLabel.grid(row=0, column=6) texts = [' < '] commands = [self.resultsPrevSolution] self.resultsPreviousSolutionButton = ButtonList(resultTopFrame, commands=commands, texts=texts) self.resultsPreviousSolutionButton.grid(row=0, column=7, sticky='nsew') tipText = 'If you ran the algorithm more than once, you can select the solution given by the different runs.' self.resultsSolutionNumberEntry = IntEntry( resultTopFrame, grid=(0, 8), width=7, text=1, returnCallback=self.solutionUpdateAfterEntry, tipText=tipText) #self.resultsSolutionNumberEntry.bind('<Leave>', self.solutionUpdateAfterEntry, '+') texts = [' > '] commands = [self.resultsNextSolution] self.resultsNextSolutionButton = ButtonList(resultTopFrame, commands=commands, texts=texts) self.resultsNextSolutionButton.grid(row=0, column=9, sticky='nsew') self.energyLabel = Label(resultTopFrame, text='energy:') self.energyLabel.grid(row=0, column=10) texts = ['template for puzzling'] commands = [self.adoptSolution] self.adoptButton = ButtonList(resultTopFrame, commands=commands, texts=texts) self.adoptButton.grid(row=0, column=11, sticky='nsew') # LabelFrame(frame, text='Spin Systems') resultsSecondFrame = Frame(frame) resultsSecondFrame.grid(row=2, column=0, sticky='nsew') resultsSecondFrame.grid_columnconfigure(0, weight=1) resultsSecondFrame.grid_columnconfigure(1, weight=1) resultsSecondFrame.grid_columnconfigure(2, weight=1) resultsSecondFrame.grid_columnconfigure(3, weight=1) resultsSecondFrame.grid_columnconfigure(4, weight=1) headingList = ['#', '%'] tipTexts = [ 'Spinsystem number {} indicates serial of the spinsystem. If the spinsystem was already assigned to a residue, the residue number is shown aswell', 'percentage of the solutions that connected this spinsystem to this residue' ] editWidgets = [None, None, None] self.displayResultsTables = [] self.residueLabels = [] for i in range(5): label = Label(resultsSecondFrame, text='residue') label.grid(row=0, column=i) #editGetCallbacks = [createCallbackFunction(i)]*3 displayResultsTable = ScrolledMatrix( resultsSecondFrame, headingList=headingList, multiSelect=False, tipTexts=tipTexts, callback=self.selectSpinSystemForTable, passSelfToCallback=True) displayResultsTable.grid(row=2, column=i, sticky='nsew') displayResultsTable.sortDown = False self.residueLabels.append(label) self.displayResultsTables.append(displayResultsTable) # LabelFrame(frame, text='Sequence Fragment') resultsFirstFrame = Frame(resultsSecondFrame) resultsFirstFrame.grid(row=1, column=0, sticky='ew', columnspan=5) resultsFirstFrame.grid_rowconfigure(0, weight=1) resultsFirstFrame.grid_rowconfigure(1, weight=1) resultsFirstFrame.grid_columnconfigure(0, weight=1) texts = [ ' res 1 ', ' links ', ' res 2 ', ' links ', ' res 3 ', ' links ', ' res 4 ', ' links ', ' res 5 ' ] commands = [ lambda: self.selectRelativeResidue(1, True), lambda: self.selectLink(1, True), lambda: self.selectRelativeResidue(2, True), lambda: self.selectLink(2, True), lambda: self.selectRelativeResidue(3, True), lambda: self.selectLink(3, True), lambda: self.selectRelativeResidue(4, True), lambda: self.selectLink(4, True), lambda: self.selectRelativeResidue(5, True) ] self.sequenceButtons = ButtonList(resultsFirstFrame, commands=commands, texts=texts) self.sequenceButtons.grid(row=0, column=0, sticky='nsew') for n, button in enumerate(self.sequenceButtons.buttons): if n % 2: button.grid(column=n, sticky='ns') self.sequenceButtons.grid_columnconfigure(n, weight=0) else: self.sequenceButtons.grid_columnconfigure(n, uniform=2) spacer = Spacer(resultsFirstFrame) spacer.grid(row=1, column=0, sticky='nsew') texts = [ ' res 1 ', ' links ', ' res 2 ', ' links ', ' res 3 ', ' links ', ' res 4 ', ' links ', ' res 5 ' ] commands = commands = [ lambda: self.selectRelativeResidue(1, False), lambda: self.selectLink(1, False), lambda: self.selectRelativeResidue(2, False), lambda: self.selectLink(2, False), lambda: self.selectRelativeResidue(3, False), lambda: self.selectLink(3, False), lambda: self.selectRelativeResidue(4, False), lambda: self.selectLink(4, False), lambda: self.selectRelativeResidue(5, False) ] self.sequenceButtonsB = ButtonList(resultsFirstFrame, commands=commands, texts=texts) self.sequenceButtonsB.grid(row=2, column=0, sticky='nsew') for n, button in enumerate(self.sequenceButtonsB.buttons): if n % 2: button.grid(column=n, sticky='ns') self.sequenceButtonsB.grid_columnconfigure(n, weight=0) else: self.sequenceButtonsB.grid_columnconfigure(n, uniform=2) frame.grid_rowconfigure(3, weight=2) resultsThirdFrame = Frame(frame) resultsThirdFrame.grid(row=3, column=0, sticky='nsew') resultsThirdFrame.grid_rowconfigure(0, weight=1) resultsThirdFrame.grid_columnconfigure(0, weight=1) tabbedFrameB = TabbedFrame(resultsThirdFrame, options=['Peaks', 'Spin System'], callback=self.toggleTab, grid=(0, 0)) #self.tabbedFrameB = tabbedFrame PeakFrame, SpinSystemFrame = tabbedFrameB.frames SpinSystemFrame.grid_rowconfigure(0, weight=1) PeakFrame.grid_rowconfigure(1, weight=1) SpinSystemFrame.grid_columnconfigure(0, weight=1) PeakFrame.grid_columnconfigure(0, weight=1) headingList = [ 'residue', 'assigned to in project', 'user defined sequence', 'selected annealing result', '%' ] tipTexts = [None, None, None, None, None] editWidgets = [None, None, None, None, None] editGetCallbacks = [None, None, None, None, None] editSetCallbacks = [None, None, None, None, None] self.spinSysTable = ScrolledMatrix(SpinSystemFrame, headingList=headingList, editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.spinSysTable.grid(row=0, column=0, sticky='nsew') buttonFrameinPeakFrame = Frame(PeakFrame) buttonFrameinPeakFrame.grid(sticky='ew') self.findButton = Button( buttonFrameinPeakFrame, text=' Go to Peak ', borderwidth=1, padx=2, pady=1, command=self.findPeak, tipText='Locate the currently selected peak in the specified window' ) self.findButton.grid(row=0, column=0, sticky='e') label = Label(buttonFrameinPeakFrame, text='in window:') label.grid(row=0, column=1, sticky='w') self.windowPulldown = PulldownList( buttonFrameinPeakFrame, callback=self.selectWindowPane, tipText='Choose the spectrum window for locating peaks or strips') self.windowPulldown.grid(row=0, column=2, sticky='w') self.assignSelectedPeaksButton = Button( buttonFrameinPeakFrame, text='Assign Resonances to Peak(s)', borderwidth=1, padx=2, pady=1, command=self.assignSelectedPeaks, tipText= 'Assign resonances to peak dimensions, this of course only works when the peak is found in the spectrum.' ) self.assignSelectedPeaksButton.grid(row=0, column=3, sticky='ew') self.assignSelectedSpinSystemsToResiduesButton = Button( buttonFrameinPeakFrame, text='Assign Spinsystems to Residues', borderwidth=1, padx=2, pady=1, command=self.assignSelectedSpinSystemsToResidues, tipText='Assign spinsystems to residues') self.assignSelectedSpinSystemsToResiduesButton.grid(row=0, column=4, sticky='ew') headingList = [ '#', 'spectrum', 'Dim1', 'Dim2', 'Dim3', 'c.s. dim1', 'c.s. dim2', 'c.s. dim3', 'colabelling' ] tipTexts = [ 'Peak number, only present when the peak was actually found in the spectrum.', 'Name of the spectrum', 'Name of atomSet measured in this dimension. Dimension number corresponds to Ref Exp Dim as indicated by going in the main menu to Experiment-->Experiments-->Experiment Type', 'Name of atomSet measured in this dimension. Dimension number corresponds to Ref Exp Dim as indicated by going in the main menu to Experiment-->Experiments-->Experiment Type', 'Name of atomSet measured in this dimension. Dimension number corresponds to Ref Exp Dim as indicated by going in the main menu to Experiment-->Experiments-->Experiment Type', 'Chemical Shift', 'Chemical Shift', 'Chemical Shift', 'Colabbeling fraction over all nuclei that are on the magnetization transfer pathway during the experiment that gave rise to the peak, including visited nuclei that were not measured in any of the peak dimensions' ] #editWidgets = [None, None, None, None, None, None, None, None, None] editGetCallbacks = [ None, None, None, None, None, None, None, None, None ] #editGetCallbacks = [self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak, self.selectPeak] editSetCallbacks = [ None, None, None, None, None, None, None, None, None ] self.displayPeakTable = ScrolledMatrix(PeakFrame, headingList=headingList, multiSelect=True, tipTexts=tipTexts) #editWidgets=editWidgets, multiSelect=True, # editGetCallbacks=editGetCallbacks, # editSetCallbacks=editSetCallbacks, # tipTexts=tipTexts) self.displayPeakTable.grid(row=1, column=0, sticky='nsew') self.windowPane = None self.updateWindows()
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)
class RelaxationAnalysisPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.t1List = None self.t2List = None self.noeList = None self.waiting = False BasePopup.__init__(self, parent, title="Relaxation Analyses", **kw) periodicTable = self.project.currentChemElementStore nitrogen = periodicTable.findFirstChemElement(elementSymbol='N') hydrogen = periodicTable.findFirstChemElement(elementSymbol='H') def body(self, guiFrame): self.geometry('700x840') guiFrame.expandGrid(1,0) # Top frame frame = Frame(guiFrame, grid=(0,0)) frame.expandGrid(None,8) label = Label(frame, text=u' %s List:' % T1, grid=(0,0)) self.t1Pulldown = PulldownList(frame, callback=self.selectT1List, grid=(0,1)) label = Label(frame, text=u' %s List:' % T2, grid=(0,2)) self.t2Pulldown = PulldownList(frame, callback=self.selectT2List, grid=(0,3)) label = Label(frame, text=' NOE List:', grid=(0,4)) self.noePulldown = PulldownList(frame, callback=self.selectNoeList, grid=(0,5)) label = Label(frame, text=' Spectrometer Freq (MHz):', grid=(0,6)) self.sfEntry = FloatEntry(frame, grid=(0,7), text=600.00, width=6) UtilityButtonList(frame, grid=(0,9), sticky='e') # Tabs options = [u'%s vs %s Scatter' % (T1, T2), u'%s,%s & NOE Graphs' % (T1, T2) , u'%s/%s Graph' % (T1, T2), u'%s Estimate Graph' % S2, 'Options'] self.tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.toggleTab, grid=(1,0)) frameA, frameD, frameC, frameE, frameB = self.tabbedFrame.frames # T1 vs T2 Graph frameA.expandGrid(0,0) self.t1t2Graph = T1VersesT2Plot(frameA, grid=(0,0)) # T1 & T2 Graph frameD.expandGrid(0,0) frameD.expandGrid(1,0) frameD.expandGrid(2,0) self.t1Graph = MeasurementPlot(frameD, T1, grid=(0,0)) self.t2Graph = MeasurementPlot(frameD, T2, grid=(1,0)) self.noeGraph = NoePlot(frameD, 'NOE', grid=(2,0)) # T1 over T2 Graph frameC.expandGrid(0,0) self.t1t2GraphB = T1OverT2Plot(frameC, grid=(0,0)) # Order params graph frameE.expandGrid(0,0) frameE.expandGrid(1,0) frameE.expandGrid(2,0) self.s2Graph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % S2, xLabel='Residue number', yLabel=S2, width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(0,0), dataColors=['#0000A0','#808000'], dataNames=['Isotropic',]) self.teGraph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % Te, xLabel='Residue number', yLabel=u'%s (ps)' % Te, width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(1,0), dataColors=['#008000',]) self.rexGraph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % 'Rex', xLabel='Residue number', yLabel='Rex', width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(2,0), dataColors=['#900000',]) # Options frameB.expandGrid(4,2) frame = LabelFrame(frameB, text='Physical Params', grid=(0,0)) frame.expandGrid(None,3) label = Label(frame, text=u'N-H bond length (\u00C5)', grid=(0,0)) self.lenNhEntry = FloatEntry(frame, text=1.015, grid=(0,1), width=8) label = Label(frame, text=u'Internal correlation\ntime, \u03C4e (ps)', grid=(1,0)) self.ictEntry = FloatEntry(frame, text=50.0, grid=(1,1), width=8) label = Label(frame, text=u'15N Chemical Shift\nAnisotopy,\u0394N (ppm)', grid=(2,0)) self.csaNEntry = FloatEntry(frame, text=-160.0, grid=(2,1), width=8) frame = LabelFrame(frameB, text=u'%s vs %s Scatter' % (T1, T2), grid=(1,0)) label = Label(frame, text='Max cluster difference (ms):', grid=(0,0)) self.clusterDictEntry = FloatEntry(frame, text=20.0, grid=(0,1), width=8) label = Label(frame, text='Min cluster size:', grid=(1,0)) self.clusterSizeEntry = FloatEntry(frame, text=5, grid=(1,1), width=8) label = Label(frame, text=u'Min graph %s (ms):' % T1, grid=(2,0)) self.minT1Entry = FloatEntry(frame, text=300.0, grid=(2,1), width=8) label = Label(frame, text=u'Max graph %s (ms):' % T1, grid=(3,0)) self.maxT1Entry = FloatEntry(frame, text=1000.0, grid=(3,1), width=8) label = Label(frame, text=u'Min graph %s (ms):' % T2, grid=(4,0)) self.minT2Entry = FloatEntry(frame, text=0.0, grid=(4,1), width=8) label = Label(frame, text=u'Max graph %s (ms):' % T2, grid=(5,0)) self.maxT2Entry = FloatEntry(frame, text=600.0, grid=(5,1), width=8) frame = LabelFrame(frameB, text=u'%s Contours' % S2, grid=(0,1)) frame.expandGrid(4,3) label = Label(frame, text='(Order Parameter Lines)', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Min value:', grid=(1,0)) self.minS2Entry = FloatEntry(frame, text=0.3, grid=(1,1), width=8) label = Label(frame, text='Max value:', grid=(2,0)) self.maxS2Entry = FloatEntry(frame, text=1.0, grid=(2,1), width=8) label = Label(frame, text='Step:', grid=(3,0)) self.stepS2Entry = FloatEntry(frame, text=0.1, grid=(3,1), width=8) frame = LabelFrame(frameB, text=u'\u03C4m Contours', grid=(1,1)) frame.expandGrid(4,3) label = Label(frame, text='(Rotational Correlation Time Lines)', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Min value (ns):', grid=(1,0)) self.minRctEntry = FloatEntry(frame, text=5.0, grid=(1,1), width=8) label = Label(frame, text='Max value (ns):', grid=(2,0)) self.maxRctEntry = FloatEntry(frame, text=14.0, grid=(2,1), width=8) label = Label(frame, text='Step (ns):', grid=(3,0)) self.stepRctEntry = FloatEntry(frame, text=1.0, grid=(3,1), width=8) # Bottom frame texts = [u'Show %s Table' % T1,u'Show %s Table' % T2, u'Estimate %s' % S2] commands = [self.showT1List, self.showT2List, self.mc] buttonList = ButtonList(guiFrame, grid=(2,0), texts=texts, commands=commands) # Update self.updateRelaxationLists() self.drawAfter() self.administerNotifiers(self.registerNotify) def open(self): self.updateRelaxationLists() self.drawAfter() BasePopup.open(self) def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self) def getSanitisedParams(self): cDist = self.clusterDictEntry.get() or 0.0 lenNh = max(min(self.lenNhEntry.get() or 1.015, 1.2), 0.8) ict = self.ictEntry.get() or 0.0 csaN = self.csaNEntry.get() or -180.0 if csaN > 0: csaN *= -1.0 minS2 = max(min(self.minS2Entry.get() or 0.0, 0.9), 0.0) maxS2 = max(min(self.maxS2Entry.get() or 1.0, 1.0), 0.1) if minS2 > maxS2: maxS2, minS2 = minS2, maxS2 stepS2 = max(self.stepS2Entry.get() or 0.1, (maxS2-minS2)/100) minRct = self.minRctEntry.get() maxRct = self.maxRctEntry.get() if minRct > maxRct: maxRct, minRct = minRct, maxRct stepRct = max(self.stepRctEntry.get() or 0.1, (maxRct-minRct)/100) cluster = max(abs(self.clusterSizeEntry.get() or 10), 1) minT1 = self.minT1Entry.get() or 300.0 maxT1 = self.maxT1Entry.get() or 1000.0 minT2 = self.minT2Entry.get() or 0.0 maxT2 = self.maxT2Entry.get() or 600.0 if minT1 < 0: minT1 = 0.0 if minT2 < 0: minT2 = 0.0 if maxT1 < 0: maxT1 = 0.0 if maxT2 < 0: maxT2 = 0.0 if minT1 > maxT1: minT1, maxT1 = maxT1, minT1 if minT2 > maxT2: minT2, maxT2 = maxT2, minT2 if minT1 == maxT1: maxT1 += 100 if minT2 == maxT2: maxT2 += 100 self.clusterSizeEntry.set(cluster) self.minT1Entry.set(minT1) self.maxT1Entry.set(maxT1) self.minT2Entry.set(minT2) self.maxT2Entry.set(maxT2) self.clusterDictEntry.set(cDist) self.lenNhEntry.set(lenNh) self.ictEntry.set(ict) self.csaNEntry.set(csaN) self.minS2Entry.set(minS2) self.maxS2Entry.set(maxS2) self.stepS2Entry.set(stepS2) self.minRctEntry.set(minRct) self.maxRctEntry.set(maxRct) self.stepRctEntry.set(stepRct) paramsS2 = (minS2, maxS2, stepS2) paramsRct = (minRct, maxRct, stepRct) tBounds = (minT1, maxT1, minT2, maxT2) return cluster, cDist, lenNh, ict, csaN, paramsS2, paramsRct, tBounds def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete','setName'): for clazz in ('ccp.nmr.Nmr.T1List','ccp.nmr.Nmr.T2List'): notifyFunc(self.updateRelaxationLists,clazz, func) for func in ('__init__', 'delete', 'setValue'): notifyFunc(self.updateMeasurementAfter,'ccp.nmr.Nmr.T1', func) notifyFunc(self.updateMeasurementAfter,'ccp.nmr.Nmr.T2', func) def showT1List(self): if self.t1List: self.guiParent.editMeasurements(self.t1List) def showT2List(self): if self.t2List: self.guiParent.editMeasurements(self.t2List) def toggleTab(self, index): if index == 0: self.drawAfter() def updateMeasurementAfter(self, measurement): if measurement.parentList in (self.t1List, self.t2List): self.drawAfter() def updateRelaxationLists(self, obj=None): mLists = self.nmrProject.sortedMeasurementLists() # T1 t1List = self.t1List t1Lists = [ml for ml in mLists if ml.className == 'T1List'] index = 0 names = [] if t1Lists: if t1List not in t1Lists: t1List = t1Lists[0] index = t1Lists.index(t1List) names = [ml.name or 'List %d' % ml.serial for ml in t1Lists] else: t1List = None self.selectT1List(t1List) self.t1Pulldown.setup(names, t1Lists, index) # T2 t2List = self.t2List t2Lists = [ml for ml in mLists if ml.className == 'T2List'] index = 0 names = [] if t2Lists: if t2List not in t2Lists: t2List = t2Lists[0] index = t2Lists.index(t2List) names = [ml.name or 'List %d' % ml.serial for ml in t2Lists] else: t2List = None self.selectT2List(t2List) self.t2Pulldown.setup(names, t2Lists, index) # NOE noeList = self.noeList noeLists = [ml for ml in mLists if ml.className == 'NoeList'] index = 0 names = [] if noeLists: if noeList not in noeLists: noeList = noeLists[0] index = noeLists.index(noeList) names = [ml.name or 'List %d' % ml.serial for ml in noeLists] else: noeList = None self.selectNoeList(noeList) self.noePulldown.setup(names, noeLists, index) def drawAfter(self): if self.waiting: return self.waiting = True self.after_idle(self.draw) def selectT1List(self, t1List): if t1List is not self.t1List: self.t1List = t1List self.sfEntry.set(t1List.sf) values = [m.value for m in t1List.measurements] values.sort() minVal = self.minT1Entry.get() maxVal = self.maxT1Entry.get() minVal0 = values[0]*MS_UNIT_MULTIPLIERS[t1List.unit] maxVal0 = values[-1]*MS_UNIT_MULTIPLIERS[t1List.unit] if minVal0 < minVal: self.minT1Entry.set(max(minVal0 - 100, 0)) if maxVal0 > maxVal: self.maxT1Entry.set(maxVal0 + 100) self.drawAfter() def selectT2List(self, t2List): if t2List is not self.t2List: self.t2List = t2List self.sfEntry.set(t2List.sf) values = [m.value for m in t2List.measurements] values.sort() values.sort() minVal = self.minT2Entry.get() maxVal = self.maxT2Entry.get() minVal0 = values[0]*MS_UNIT_MULTIPLIERS[t2List.unit] maxVal0 = values[-1]*MS_UNIT_MULTIPLIERS[t2List.unit] if minVal0 < minVal: self.minT2Entry.set(max(minVal0 - 50, 0)) if maxVal0 > maxVal: self.maxT2Entry.set(maxVal0 + 50) self.drawAfter() def selectNoeList(self, noeList): if noeList is not self.noeList: self.noeList = noeList self.sfEntry.set(noeList.sf) #self.drawAfter() def draw(self): params = self.getSanitisedParams() cSize, cDist, lenNh, ict, csaN, paramsS2, paramsRct, tBounds = params sf = abs(self.sfEntry.get() or 500.010) self.t1t2Graph.update(self.t1List, self.t2List, cSize, cDist, sf, lenNh, ict, csaN, paramsS2, paramsRct, tBounds) self.t1t2GraphB.update(self.t1List, self.t2List) self.t1Graph.update(self.t1List) self.t2Graph.update(self.t2List) self.noeGraph.update(self.noeList) self.waiting = False def mc(self): sf = abs(self.sfEntry.get() or 500.010) if not self.t1List and self.t2List: return chains = set([]) t1t2Points = {} resonancesT1 = {} resonancesNoe = {} residueResonances = {} t1Unit = MS_UNIT_MULTIPLIERS[self.t1List.unit] t2Unit = MS_UNIT_MULTIPLIERS[self.t2List.unit] if self.noeList: for noe in self.noeList.measurements: for resonance in noe.resonances: resonancesNoe[resonance] = noe for t1 in self.t1List.measurements: resonancesT1[t1.resonance] = t1 for t2 in self.t2List.measurements: resonance = t2.resonance if not resonance.resonanceSet: continue residue = resonance.resonanceSet.findFirstAtomSet().findFirstAtom().residue t1 = resonancesT1.get(resonance) noe = resonancesNoe.get(resonance) if t1 and noe: t1t2Points[residue] = 1e-3*t1Unit*t1.value, 1e-3*t2Unit*t2.value, noe.value chains.add(residue.chain) residueResonances[residue] = resonance if t1: t1t2Points[residue] = 1e-3*t1Unit*t1.value, 1e-3*t2Unit*t2.value, None chains.add(residue.chain) residueResonances[residue] = resonance for chain in chains: residues = chain.sortedResidues() t1Values = [] t2Values = [] noeValues = [] n = len(residues) n2 = n-1 jj = range(n) s2Best = [0.0] * n teBest = [0.0] * n rexBest = [0.0] * n print '' for residue in residues: t1,t2, noe = t1t2Points.get(residue, (None, None, None)) t1Values.append(t1) t2Values.append(t2) noeValues.append(noe) t1s = [v for v in t1Values if v] t2s = [v for v in t2Values if v] noes = [v for v in noeValues if v] m = len(t1s) t1 = sum(t1s)/float(m) t2 = sum(t2s)/float(m) noe = sum(noes)/float(m) t12 = [v/t2s[i] for i, v in enumerate(t1s) if v] t12m = sum(t12)/float(len(t12)) deltas = [abs(v-t12m)/t12m for v in t12] w = [1.0/(v*v) for v in deltas] t1 = sum([ t1s[j]*w[j] for j in range(m)])/sum(w) t2 = sum([ t2s[j]*w[j] for j in range(m)])/sum(w) if noes: noe = sum([ noes[j]*w[j] for j in range(m)])/sum(w) else: noe = None i, ensemble = self.fitT1T2(t1, t2, noe, sf, tmFix=None, teFix=None, s2Fix=None, tmMin=1e-9, tmMax=100e-9, teMin=1e-12, teMax=1e-10, rexFix=0.0) ensemble.sort() score, s2, te0, tm0, rex, t1t, t2t, noet = ensemble[0] data = (s2, te0*1e12, tm0*1e9, rex, t1, t1t, t2, t2t, noe or 0.0, noet, score, i) print 'Mean A S2:%5.3f Te:%5.1f Tm:%5.3f Rex:%5.3f T1:%5.3f %5.3f T2:%5.3f %5.3f NOE:%5.3f %5.3f %e %6d' % data rexCheck = 999 # 1.40 * t1/t2 # Prior is mean, then region for j in jj: t1 = t1Values[j] t2 = t2Values[j] noe = noeValues[j] if t1 is None: continue residue = residues[j] print '%3d%s' % (residue.seqCode, residue.ccpCode), i, ensemble = self.fitT1T2(t1, t2, noe, sf, tmFix=tm0, teFix=None, s2Fix=None, tmMin=tm0*0.1, tmMax=tm0*5, teMin=te0/100, teMax=te0*20, rexFix=0.0, rexMax=15.0) ensemble.sort() score, s2, te, tm, rex, t1t, t2t, noet = ensemble[0] if s2 > 0.995: i, ensemble = self.fitT1T2(t1, t2, noe, sf, tmFix=tm0, teFix=None, s2Fix=None, teMin=te/10, teMax=te*10, rexFix=None, rexMax=15.0) ensemble.sort() score, s2, te, tm, rex, t1t, t2t, noet = ensemble[0] teBest[j] = te s2Best[j] = s2 rexBest[j] = rex data = (s2, te*1e12, tm*1e9, rex, t1, t1t, t2, t2t, noe or 0.0, noet, score, i) print 'S2:%5.3f Te:%5.1f Tm:%5.3f Rex:%5.3f T1:%5.3f %5.3f T2:%5.3f %5.3f NOE:%5.3f %5.3f %e %6d' % data dataSet1 = [] dataSet2 = [] dataSet3 = [] for j in jj: residue = residues[j] resonance = residueResonances.get(residue) if not resonance: continue dataSet1.append((residue.seqCode, s2Best[j])) dataSet2.append((residue.seqCode, teBest[j]*1e9)) dataSet3.append((residue.seqCode, rexBest[j])) self.s2Graph.update([dataSet1,]) self.teGraph.update([dataSet2,]) self.rexGraph.update([dataSet3,]) self.tabbedFrame.select(3) def fitT1T2(self, t1, t2, noe, sf, tmFix=None, teFix=None, s2Fix=None, tmMin=1e-9, tmMax=100e-9, teMin=1e-12, teMax=1e-9, rexFix=None, rexMax=15.0, niter=10000): # Could have multiple sf rNH = 1.015 csaN = 160*1e-6 # 160 ppm omegaH = sf * 2 * PI * 1e6 # Rad/s omegaN = omegaH * GAMMA_N/GAMMA_H gammaHN = GAMMA_H/GAMMA_N A = REDUCED_PERM_VACUUM * REDUCED_PLANK * GAMMA_N * GAMMA_H * 1e30 # Cubic Angstrom adjust A /= rNH**3.0 A = A*A/4.0 C = omegaN * omegaN * csaN * csaN C /= 3.0 # Init params if s2Fix is None: s2Start = [x*0.05 for x in range(1,20)] else: s2Start = [s2Fix,] if teFix is None: teStart = [x*1e-12 for x in [10,30,70,100,300,700,1000]] else: teStart = [teFix,] if tmFix is None: tmStart = [x*1e-9 for x in range(1,30)] else: tmStart = [tmFix,] if rexFix is None: rexStart = [float(x) for x in range(int(rexMax))] else: rexStart = [rexFix,] # Init ensemble of solutions ensemble = [] for s2 in s2Start: for te in teStart: for tm in tmStart: for rex in rexStart: ensemble.append((None, s2, te, tm, rex)) # Init scores for k, (score, s2, te, tm, rex) in enumerate(ensemble): jH = getSpectralDensity(s2, tm, te, omegaH) jN = getSpectralDensity(s2, tm, te, omegaN) jHpN = getSpectralDensity(s2, tm, te, omegaH+omegaN) jHmN = getSpectralDensity(s2, tm, te, omegaH-omegaN) j0 = getSpectralDensity(s2, tm, te, 0.0) r1 = A*( (3*jN) + (6*jHpN) + jHmN ) + C*jN r2 = 0.5*A*( (4*j0) + (3*jN) + (6*jHpN) + (6*jH) + jHmN ) + C*( 2*j0/3.0 + 0.5*jN ) + rex t1p = 1.0/r1 t2p = 1.0/r2 d1 = (t1p-t1)/t1 d2 = (t2p-t2)/t2 score = (d1*d1) + (d2*d2) if noe is None: noep = 0.0 else: noep = 1.0 + ( A * gammaHN * t1 * ((6*jHpN)-jHmN) ) dn = (noep-noe)/2.0 score += (dn*dn) ensemble[k] = (score, s2, te, tm, rex, t1p, t2p, noep) # Matrix # # Pred Jh # R1 # R2 # NOE # r = 1.0/rct + 1.0/ict # t = 1.0/r # j = (s2*rct) / (1.0 + w*w*rct*rct) # j += ((1.0-s2)*t) / (1.0 + w*w*t*t) # # return j*0.4 ensemble.sort() ensemble = ensemble[:10] ensembleSize = len(ensemble) bestScore = 1e99 for i in xrange(niter): f = i/float(niter) f = exp(-10.0*f) # Mutate ensemble.sort() prevScore, s2, te, tm, rex, t1p, t2p, noep = ensemble[-1] #Biggest is worst if ensemble[0][0] < 1e-10: break if not s2Fix: #d = ((random() + 0.618 - 1.0) * f) + 1.0 d = ((random() - 0.382) * f) + 1.0 s2 = max(0.0, min(1.0, s2*d)) if not tmFix: d = ((random() - 0.382) * f) + 1.0 tm = max(tmMin, min(tmMax, tm*d)) if not teFix: d = ((random() - 0.382) * f) + 1.0 te = max(teMin, min(teMax, te*d)) d = ((random() - 0.382) * f) + 1.0 rex = max(0.0, min(rexMax, rex*d)) jH = getSpectralDensity(s2, tm, te, omegaH) jN = getSpectralDensity(s2, tm, te, omegaN) jHpN = getSpectralDensity(s2, tm, te, omegaH+omegaN) jHmN = getSpectralDensity(s2, tm, te, omegaH-omegaN) j0 = getSpectralDensity(s2, tm, te, 0.0) r1 = A*( (3*jN) + (6*jHpN) + jHmN ) + C*jN r2 = 0.5*A*( (4*j0) + (3*jN) + (6*jHpN) + (6*jH) + jHmN ) + C*( 2*j0/3.0 + 0.5*jN ) + rex t1p = 1.0/r1 t2p = 1.0/r2 d1 = (t1p-t1)/t1 d2 = (t2p-t2)/t2 score = (d1*d1) + (d2*d2) if noe is None: noep = 0.0 else: noep = 1.0 + ( A * gammaHN * t1 * ((6*jHpN)-jHmN) ) dn = (noep-noe)/2.0 score += (dn*dn) ratio = exp(prevScore-score) if ratio > 1.0: # random(): ensemble[-1] = (score, s2, te, tm, rex, t1p, t2p, noep) else: k = randint(0,ensembleSize-1) score, s2, te, tm, rex, t1p, t2p, noep = ensemble[k] ensemble[-1] = (score, s2, te, tm, rex, t1p, t2p, noep) if score < bestScore: bestScore = score #print bestScore, ', '.join(['%.3e' % x[0] for x in ensemble]) return i, ensemble
class ExtendNmrFrame(Frame): def __init__(self, guiParent, basePopup, project=None): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # FIXME JMCI # need to work through this far more carefully self.project = project # shortcuts to this layer self.basePopup.frameShortcuts['Task'] = self # shortcuts to layer below. We should set these in the # initMethod methods self.frameShortcuts = {} # TODO understand what these are doing self.registerNotify = basePopup.registerNotify self.unregisterNotify = basePopup.unregisterNotify Frame.__init__(self, guiParent) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(0, weight=1) # Logos. Code nicked from ExtendNMR GUI ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') # basically nicked from Extend-NMR softwareOpts = [ 'Test1Task', 'ARIA 2', 'Auremol', 'CING', ' ECI ', 'HADDOCK', ' ISD ', 'PRODECOMP' ] self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0) self.tabbedFrame.grid(row=1, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'Fp6Logo.gif') self.fp6Logo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CingLogo.gif') self.cingLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AriaLogo.gif') self.ariaLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'IsdLogo.gif') self.isdLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'HaddockLogo.gif') self.haddockLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AuremolLogo.gif') self.auremolLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'ProdecompLogo.gif') self.prodecompLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MddLogo.gif') self.mddLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'BrukerLogo.gif') self.brukerLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MsdLogo.gif') self.msdLogo = Tkinter.PhotoImage(file=imageFile) # don't know what this does self.updateFuncs = [] self.projButtons = [] # basically nicked from Extend-NMR self.initTest1(frames[0]) self.initAria(frames[1]) self.initAuremol(frames[2]) self.initCing(frames[3]) #self.initEci(frames[4]) #self.initHaddock(frames[5]) self.initIsd(frames[6]) self.initProdecomp(frames[7]) def initTest1(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) # FIXME JMCI # Provide the basePopup for navigation purposes right now However, # there is a strong case for not making the method-specific Frames # dependent on the master. It might therefore be better to pass # the critical information directly, rather than passing a # reference to the basePopup which can then be used to extract it # indirectly test1Frame = Test1Frame(frame, self.basePopup) test1Frame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['Test1'] = test1Frame #self.projButtons.extend(cingFrame.buttonBar.buttons) self.updateFuncs.append(test1Frame.updateAll) def initAria(self, frame): welcomeMessage = \ """ARIA Version 2.2. Authors: Benjamin Bardiaux, Michael Habeck, Jens Linge, Therese Malliavin, Sean O'Donoghue, Wolfgang Rieping, and Michael Nilges. Rieping W., Habeck M., Bardiaux B., Bernard A., Malliavin T.E., Nilges M.(2007) ARIA2: automated NOE assignment and data integration in NMR structure calculation. Bioinformatics 23:381-382""" frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=700, height=114, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.ariaLogo) canvas.create_text(250, 10, anchor='nw', text=welcomeMessage) ariaFrame = AriaFrame(frame, self) ariaFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['ARIA'] = ariaFrame #self.projButtons.extend(ariaFrame.buttons) self.updateFuncs.append(ariaFrame.updateAll) def initAuremol(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) auremolFrame = AuremolFrame(frame, self.project) auremolFrame.grid(row=0, column=0, sticky='nsew') self.frameShortcuts['AUREMOL'] = auremolFrame #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(auremolFrame.updateAll) def initCing(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=702, height=77) canvas.grid(row=0, column=0) canvas.create_image(0, 0, anchor='nw', image=self.cingLogo) cingFrame = CingFrame(frame, self.project) cingFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['CING'] = cingFrame #self.projButtons.extend(cingFrame.buttonBar.buttons) self.updateFuncs.append(cingFrame.updateAll) def initEci(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.parent = self # For notifiers canvas = Tkinter.Canvas(frame, width=753, height=73, bg='#FFFFFF') canvas.grid(row=0, column=0) canvas.create_image(10, 10, anchor='nw', image=self.msdLogo) eciFrame = EntryCompletionFrame(frame, basePopup=self) eciFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['ECI'] = eciFrame #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(eciFrame.updateAll) def initHaddock(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.parent = self # For notifiers canvas = Tkinter.Canvas(frame, width=753, height=92) canvas.grid(row=0, column=0) canvas.create_image(0, 0, anchor='nw', image=self.haddockLogo) haddockFrame = HaddockFrame(frame, self.project) haddockFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['HADDOCK'] = haddockFrame #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(haddockFrame.updateAll) def initIsd(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=700, height=91, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.isdLogo) isdFrame = IsdFrame(frame, self.project) isdFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['ISD'] = isdFrame #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(isdFrame.updateAll) def initProdecomp(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=700, height=90, bg='#FFFFFF') canvas.grid(row=0, column=0) canvas.create_image(0, 0, anchor='nw', image=self.prodecompLogo) prodecompFrame = ProdecompFrame(frame, basePopup=self, ccpnProject=self.project) prodecompFrame.grid(row=1, column=0, sticky='nsew') self.frameShortcuts['PRODECOMP'] = prodecompFrame #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(prodecompFrame.updateAll) # need to understand this method a little bit better def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.Experiment', func) notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.DataSource', func) def updateAllAfter(self, obj): self.after_idle(self.updateAll) def updateAll(self, project=None): if project: self.project = project self.nmrProject = project.currentNmrProject if not self.nmrProject: self.nmrProject = project.newNmrProject(name=project.name) if not self.project: return def quit(self): self.guiParent.parent.destroy() def destroy(self): self.administerNotifiers(self.basePopup.unregisterNotify) Frame.destroy(self)
def __init__(self, guiParent, ccpnProject=None, **kw): self.guiParent = guiParent self.project = ccpnProject self.spectrum = None self.peakMode = 0 if ccpnProject: self.nmrProject = ccpnProject.currentNmrProject else: self.nmrProject = None Frame.__init__(self, guiParent, **kw) self.expandGrid(0,0) options = ['Peak Picking',] #,'About Auremol' 'NOE assignment','Homology Modelling',] self.tabbedFrame = TabbedFrame(self, options=options) self.tabbedFrame.grid(row=0,column=0,sticky='nsew') frameA = self.tabbedFrame.frames[0] #frameC.grid_columnconfigure(0, weight=1) #frameC.grid_rowconfigure(0, weight=1) #frameD.grid_columnconfigure(0, weight=1) #frameD.grid_rowconfigure(0, weight=1) # # Frame A # frameA.expandGrid(2,0) frameA.expandGrid(3,0) frameA.expandGrid(4,0) frameA.expandGrid(5,0) frame = Frame(frameA, grid=(0,0)) frame.expandGrid(0,4) label = Label(frame, text='Spectrum:', grid=(0,0)) self.spectrumPulldown = PulldownList(frame, self.changeSpectrum, grid=(0,1)) label = Label(frame, text=' Use Peak Sign:', grid=(0,2)) self.peakModePulldown = PulldownList(frame, self.changePeakMode, texts=PEAK_MODES, objects=[0,1,2], grid=(0,3)) frame = Frame(frameA, grid=(1,0)) frame.expandGrid(0,4) label = Label(frame, text='Integration Depth (Relative to max):', grid=(1,0)) self.segLevelEntry = FloatEntry(frame, text=0.1, grid=(1,1), width=8) label = Label(frame, text='Threshold (Threshold only):', grid=(1,3)) self.thresholdEntry = IntEntry(frame, text=100000, grid=(1,4), width=8) label = Label(frame, text='Keep Peaks (Adaptive only):', grid=(1,5)) self.keepPeakEntry = IntEntry(frame, text=4000, grid=(1,6), width=8) texts = ['Threshold\nPeak Pick','Adaptive\nPeak Pick'] commands = [self.pickThreshold, self.pickAdaptive] self.buttons = ButtonList(frameA, texts=texts, commands=commands, grid=(2,0), sticky='NSEW') frame = Frame(frameA, grid=(3,0)) frame.expandGrid(0,0) frame = Frame(frameA, grid=(4,0)) frame.expandGrid(0,0) frame = Frame(frameA, grid=(5,0)) frame.expandGrid(0,0) # # About """ frameB.expandGrid(4,0) label = Label(frameB, text='References', font='Helvetica 12 bold') label.grid(row=0, column=0, sticky='w') text = * Gronwald W, Brunner K, Kirchhofer R, Nasser A, Trenner J, Ganslmeier B, Riepl H, Ried A, Scheiber J, Elsner R, Neidig K-P, Kalbitzer HR AUREMOL, a New Program for the Automated Structure Elucidation of Biological Macromolecules Bruker Reports 2004; 154/155: 11-14 * Ried A, Gronwald W, Trenner JM, Brunner K, Neidig KP, Kalbitzer HR Improved simulation of NOESY spectra by RELAX-JT2 including effects of J-coupling, transverse relaxation and chemical shift anisotrophy J Biomol NMR. 2004 Oct;30(2):121-31 * Gronwald W, Moussa S, Elsner R, Jung A, Ganslmeier B, Trenner J, Kremer W, Neidig KP, Kalbitzer HR Automated assignment of NOESY NMR spectra using a knowledge based method (KNOWNOE) J Biomol NMR. 2002 Aug;23(4):271-87 * Gronwald W, Kirchhofer R, Gorler A, Kremer W, Ganslmeier B, Neidig KP, Kalbitzer HR RFAC, a program for automated NMR R-factor estimation J Biomol NMR. 2000 Jun;17(2):137-51 label = Label(frameB, text=text) label.grid(row=1, column=0, sticky='w') """ # # Frame C # # # Frame D # self.updateAll()
def __init__(self, guiParent, basePopup): self.guiParent = guiParent self.basePopup = basePopup # selection hash. This needs to be stored so that we can # refresh with the same criteria self.select = None # should the screen autorefresh self.autoRefresh = False # add this to shortcuts to ease navigation self.basePopup.frameShortcuts['Tasks'] = self #self.registerNotify=basePopup.registerNotify #self.unregisterNotify=basePopup.unregisterNotify #self.frames = [] # FIXME JMCI # This frame is specific for a single repository so we need a # method for identifying one from the whole set (or could have # subtabs) Frame.__init__(self, guiParent) # set up the grid self.grid_columnconfigure(0, weight=0, minsize=20) self.grid_columnconfigure(1, weight=1, minsize=30) self.grid_columnconfigure(2, weight=0, minsize=40) self.grid_rowconfigure(0, weight=0, minsize=20) self.grid_rowconfigure(1, weight=0, minsize=10) self.grid_rowconfigure(2, weight=0, minsize=0) self.grid_rowconfigure(3, weight=0, minsize=0) self.grid_rowconfigure(4, weight=0, minsize=0) self.grid_rowconfigure(5, weight=1, minsize=0) self.grid_rowconfigure(6, weight=0, minsize=10) self.grid_rowconfigure(7, weight=0, minsize=10) initial_cols = ['ID','Task','User','Status'] self.task_matrix = ScrolledMatrix(self, headingList=initial_cols, initialRows=15, doubleCallback=self.goto_task_tab) # Filters for narrowing down tasks. should probably code this # specifically inside this package #self.filter = FilterFrame(self, self.basePopup, text='Filter') self.filter = TaskFilterFrame(self, self.basePopup, text='Filter') # Frame for controlling the main client side daemon # seems to be a problem. add a simple button for now opts = ['Client','Server'] self.daemonFrame = TabbedFrame(self, options=opts, toggleOff=False, selected=0) self.daemonSwitchLabel = Label(self, text= 'Task Daemon') self.daemonSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_daemon, selected_index = 1) sel = 1 if self.autoRefresh: sel = 0 self.autoRefreshSwitchLabel = Label(self, text= 'Auto Refresh') self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_refresh, selected_index = sel) self.label_rep = Label(self, text='', font='Helvetica16') # set up a loop self.refresh()
def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=1) options = ['Parameters','Restraints','Alignment Media & Tensors','About Meccano'] tabbedFrame = TabbedFrame(guiFrame, options=options) tabbedFrame.grid(row=0, column=0, sticky='nsew') frameA, frameB, frameC, frameD = tabbedFrame.frames frameA.grid_columnconfigure(1, weight=1) frameA.grid_rowconfigure(13, weight=1) frameB.grid_columnconfigure(1, weight=1) frameB.grid_rowconfigure(1, weight=1) frameC.grid_columnconfigure(0, weight=1) frameC.grid_rowconfigure(1, weight=1) frameD.grid_columnconfigure(0, weight=1) frameD.grid_rowconfigure(0, weight=1) texts = ['Run MECCANO!'] commands = [self.runMeccano] bottomButtons = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, expands=True) bottomButtons.grid(row=1, column=0, sticky='ew') if not Meccano: bottomButtons.buttons[0].disable() # Parameters row = 0 label = Label(frameA, text='Calculation Run:') label.grid(row=row,column=0,sticky='w') self.runPulldown = PulldownList(frameA, callback=self.selectRun) self.runPulldown.grid(row=row,column=1,sticky='w') row += 1 label = Label(frameA, text='Shift List (for CO):') label.grid(row=row,column=0,sticky='w') self.shiftListPulldown = PulldownList(frameA, callback=self.selectShiftList) self.shiftListPulldown.grid(row=row,column=1,sticky='w') row += 1 label = Label(frameA, text='Keep Copy of Used Shifts:') label.grid(row=row,column=0,sticky='w') self.toggleCopyShifts = CheckButton(frameA) self.toggleCopyShifts.grid(row=row,column=1,sticky='w') self.toggleCopyShifts.set(True) row += 1 label = Label(frameA, text='Molecular System:') label.grid(row=row,column=0,sticky='w') self.molSystemPulldown = PulldownList(frameA, callback=self.selectMolSystem) self.molSystemPulldown.grid(row=row,column=1,sticky='w') row += 1 label = Label(frameA, text='Chain:') label.grid(row=row,column=0,sticky='w') self.chainPulldown = PulldownList(frameA, callback=self.selectChain) self.chainPulldown.grid(row=row,column=1,sticky='w') self.chainPulldown.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='First Peptide Plane:') label.grid(row=row,column=0,sticky='w') self.firstResEntry = IntEntry(frameA, text=None, width=8) self.firstResEntry.grid(row=row,column=1,sticky='w') self.firstResEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Last Peptide Plane:') label.grid(row=row,column=0,sticky='w') self.lastResEntry = IntEntry(frameA, text=None, width=8) self.lastResEntry.grid(row=row,column=1,sticky='w') self.lastResEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Max Num Optimisation Steps:') label.grid(row=row,column=0,sticky='w') self.maxOptStepEntry = IntEntry(frameA, text=500, width=8) self.maxOptStepEntry.grid(row=row,column=1,sticky='w') self.maxOptStepEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Num Optimisation Peptide Planes:') label.grid(row=row,column=0,sticky='w') self.numOptPlaneEntry = IntEntry(frameA, text=2, width=8) self.numOptPlaneEntry.grid(row=row,column=1,sticky='w') self.numOptPlaneEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Min Num Optimisation Hits:') label.grid(row=row,column=0,sticky='w') self.numOptHitsEntry = IntEntry(frameA, text=5, width=8) self.numOptHitsEntry.grid(row=row,column=1,sticky='w') self.numOptHitsEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='File Name Prefix:') label.grid(row=row,column=0,sticky='w') self.pdbFileEntry = Entry(frameA, text='Meccano', width=8) self.pdbFileEntry.grid(row=row,column=1,sticky='w') self.pdbFileEntry.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Write Output File (.out):') label.grid(row=row,column=0,sticky='w') self.toggleWriteOutFile = CheckButton(frameA) self.toggleWriteOutFile.grid(row=row,column=1,sticky='w') self.toggleWriteOutFile.set(False) self.toggleWriteOutFile.bind('<Leave>', self.updateRunParams) row += 1 label = Label(frameA, text='Write PDB File (.pdb):') label.grid(row=row,column=0,sticky='w') self.toggleWritePdbFile = CheckButton(frameA) self.toggleWritePdbFile.grid(row=row,column=1,sticky='w') self.toggleWritePdbFile.set(True) self.toggleWritePdbFile.bind('<Leave>', self.updateRunParams) if not Meccano: row += 1 label = Label(frameA, text='The Meccano executable is not available (it needs to be compiled)', fg='red') label.grid(row=row,column=0,columnspan=2,sticky='w') # Restraints label = Label(frameB, text='Constraint Set:') label.grid(row=0,column=0,sticky='w') self.constraintSetPulldown = PulldownList(frameB, callback=self.selectConstraintSet) self.constraintSetPulldown.grid(row=0,column=1,sticky='w') self.alignMediumPulldown= PulldownList(self, callback=self.setAlignMedium) headingList = ['#','List Type','Use?','Alignment\nMedium','Num\nRestraints'] editWidgets = [None,None,None,self.alignMediumPulldown,None] editGetCallbacks = [None,None,self.toggleUseRestraints,self.getAlignMedium,None] editSetCallbacks = [None,None,None,self.setAlignMedium,None] self.restraintMatrix = ScrolledMatrix(frameB, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=None, multiSelect=True) self.restraintMatrix.grid(row=1,column=0,columnspan=2,sticky='nsew') # Alignment Media div = LabelDivider(frameC,text='Alignment Media') div.grid(row=0,column=0,sticky='ew') self.mediumNameEntry = Entry(self, returnCallback=self.setMediumName) self.mediumDetailsEntry = Entry(self, returnCallback=self.setMediumDetails) headingList = ['#','Name','Details','Static Tensor','Dynamic Tensor'] editWidgets = [None, self.mediumNameEntry, self.mediumDetailsEntry, None, None] editGetCallbacks = [None, self.getMediumName, self.getMediumDetails, None, None] editSetCallbacks = [None, self.setMediumName, self.setMediumDetails, None, None] self.mediaMatrix = ScrolledMatrix(frameC, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectAlignMedium, multiSelect=True) self.mediaMatrix.grid(row=1,column=0,sticky='nsew') texts = ['Add Alignment medium','Remove Alignment Medium'] commands = [self.addAlignMedium,self.removeAlignMedium] buttonList = ButtonList(frameC, texts=texts, commands=commands, expands=True) buttonList.grid(row=2,column=0,sticky='nsew') self.editAxialEntry = FloatEntry(self, returnCallback=self.setAxial) self.editRhombicEntry = FloatEntry(self, returnCallback=self.setRhombic) self.editAlphaEulerEntry = FloatEntry(self, returnCallback=self.setEulerAlpha) self.editBetaEulerEntry = FloatEntry(self, returnCallback=self.setEulerBeta) self.editGammaEulerEntry = FloatEntry(self, returnCallback=self.setEulerGamma) div = LabelDivider(frameC,text='Alignment Tensors') div.grid(row=3,column=0,sticky='ew') headingList = ['Type', u'Axial (\u03B6)',u'Rhombic (\u03B7)', u'Euler \u03B1',u'Euler \u03B2',u'Euler \u03B3'] editWidgets = [None,self.editAxialEntry, self.editRhombicEntry,self.editAlphaEulerEntry, self.editBetaEulerEntry,self.editGammaEulerEntry] editSetCallbacks = [None,self.setAxial,self.setRhombic, self.setEulerAlpha,self.setEulerBeta,self.setEulerGamma] editGetCallbacks = [None,self.getAxial,self.getRhombic, self.getEulerAlpha,self.getEulerBeta,self.getEulerGamma] self.tensorMatrix = ScrolledMatrix(frameC, maxRows=2, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectTensor, multiSelect=True) self.tensorMatrix.grid(row=4,column=0,sticky='nsew') texts = ['Add Static Tensor','Add Dynamic Tensor','Remove Tensor'] commands = [self.addStaticTensor,self.addDynamicTensor,self.removeTensor] buttonList = ButtonList(frameC,texts=texts, commands=commands, expands=True) buttonList.grid(row=5,column=0,sticky='ew') # About label = Label(frameD, text='About Meccano...') label.grid(row=0,column=0,sticky='w') # self.geometry('500x400') self.updateShiftLists() self.updateMolSystems() self.updateResidueRanges() self.updateConstraintSets() self.updateAlignMedia() self.updateRuns()
def body(self, guiFrame): self.geometry('700x600') guiFrame.expandGrid(0, 0) tipTexts = [ 'A table of all of the reference isotope scheme definitions available to the project', 'A list of the residue isotopomers that comprise the selected isotope labelling scheme', 'A three-dimensional representation of residues and their isotopomer labelling' ] options = ['Reference Schemes', 'Isotopomers', 'Isotopomer Structure'] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0), tipTexts=tipTexts) self.tabbedFrame = tabbedFrame frameA, frameB, frameC = tabbedFrame.frames # # Schemes # frameA.expandGrid(0, 0) tipTexts = [ 'A short textual code that identifies the reference isotope scheme in graphical displays', 'The full name for the isotope scheme', 'A detailed description of the isotope scheme including user comments', 'The name of the CCPN data repository in which the isotope scheme is saved; "refData" is in the CCPn installation' ] headingList = ['Code', 'Name', 'Description', 'Save Location'] self.schemeNameEntry = Entry(self, text='', returnCallback=self.setSchemeName, width=20) self.schemeDetailsEntry = Entry(self, text='', returnCallback=self.setSchemeDetails, width=20) editWidgets = [ None, self.schemeNameEntry, self.schemeDetailsEntry, None ] editGetCallbacks = [ None, self.getSchemeName, self.getSchemeDetails, None ] editSetCallbacks = [ None, self.setSchemeName, self.setSchemeDetails, None ] self.schemeMatrix = ScrolledMatrix(frameA, headingList=headingList, callback=self.selectScheme, editWidgets=editWidgets, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, multiSelect=False, grid=(0, 0), tipTexts=tipTexts) self.schemeMatrix.doEditMarkExtraRules = self.schemeEditRules tipTexts = [ 'Make a new reference isotope scheme definition based on a copy of the scheme currently selected', 'Delete the selected isotope scheme', 'Make a new, blank isotope scheme' ] texts = ['Copy', 'Delete', 'New'] commands = [self.copyScheme, self.removeScheme, self.makeNewScheme] self.schemeButtons = ButtonList(frameA, texts=texts, commands=commands, grid=(1, 0), tipTexts=tipTexts) # # Isotopomers # frameB.expandGrid(3, 0) row = 0 frame = Frame(frameB, grid=(row, 0)) frame.expandGrid(0, 2) tipText = 'Selects which of the available isotope schemes to view/edit' label = Label(frame, text='Reference Scheme:', grid=(0, 0)) self.schemePulldown = PulldownList(frame, callback=self.setLabellingScheme, grid=(0, 1), tipText=tipText) row += 1 div = LabelDivider(frameB, text='Isotopomers', grid=(row, 0)) row += 1 frame = Frame(frameB, grid=(row, 0)) frame.expandGrid(1, 2) self.isotopomerFrame = frame self.abundanceWidget = MultiWidget(self, FloatEntry, relief='raised', borderwidth=2, callback=self.setDefaultAbundances, useImages=False) tipText = 'Opens a panel that allows you to set the basis/default abundances for C, H & N isotopes; used as the starting point for new isotopomer definitions' self.abundanceButton = Button(frame, text='Set Default\nAbundances', borderwidth=1, command=self.enterDefaultAbundances, grid=(0, 0), tipText=tipText) tipText = 'Sets the basis/default abundances for C, H & N isotopes to their natural abundance proportions' button = Button(frame, text='Set Natural\nAbundance Default', borderwidth=1, command=self.resetDefaultAbundance, grid=(0, 1), sticky='ew', tipText=tipText) label = Label(frame, text='Molecule Type:', grid=(0, 2), sticky='e') entries = standardResidueCcpCodes.keys() entries.sort() entries.reverse() tipText = 'Selects which type of bio-polymer to define residue isotopomer labelling for' self.molTypePulldown = PulldownList(frame, callback=self.setMolType, texts=entries, grid=(0, 3), tipText=tipText) row += 1 tipTexts = [ 'The CCPN code that identifies the kind of residue the isotopomer relates to', 'The number of the particular isotopomer (isotope pattern) within its residue type', 'The fraction of the total residues, of its kind, that the isotopomer make up' ] headingList = ['Ccp Code', 'Variant', 'Weight'] self.isotopomerWeightEntry = FloatEntry( self, text='', returnCallback=self.setIsotopomerWeight, width=6) editWidgets = [None, None, self.isotopomerWeightEntry] editGetCallbacks = [None, None, self.getIsotopomerWeight] editSetCallbacks = [None, None, self.setIsotopomerWeight] self.isotopomerMatrix = ScrolledMatrix( frameB, tipTexts=tipTexts, headingList=headingList, callback=self.selectIsotopomer, editWidgets=editWidgets, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, multiSelect=True, grid=(row, 0)) self.isotopomerMatrix.doEditMarkExtraRules = self.isotopomerEditRules row += 1 frame = Frame(frameB, grid=(row, 0), sticky='ew') frame.expandGrid(0, 0) tipTexts = [ 'Delete the selected residue isotopomers from the current isotope scheme', 'Make a new residue isotopomer definition by copying the details of the last selected isotopomer', 'Add a complete set of isotopomers to the isotope scheme, one for each residue type, based on the states default isotope abundances', 'For all residue isotopomers in the scheme, set the labelling of one kind of atom (the user is prompted) to its default isotopic incorporation ', 'Add a new residue isotopomer definition that uses the default isotopic incorporation' ] texts = [ 'Delete\nSelected', 'Copy\nSelected', 'Add Default\nAbundance Set', 'Set Atom Type\nTo Default', 'Add\nNew:' ] commands = [ self.removeIsotopomers, self.duplicateResidues, self.addDefaultIsotopomers, self.setAtomTypeDefault, self.addNewIsotopomer ] self.isotopomerButtons = ButtonList(frame, texts=texts, commands=commands, grid=(0, 0), tipTexts=tipTexts) tipText = 'Selects which kind of residue isotopomer may be added to the current isotope scheme' self.ccpCodePulldown = PulldownList(frame, callback=None, grid=(0, 1), sticky='e', tipText=tipText) row += 1 div = LabelDivider(frameB, text='Atom Labels', grid=(row, 0)) row += 1 frame = Frame(frameB, grid=(row, 0)) frame.expandGrid(1, 3) label = Label(frame, text='Chemical Element:', grid=(0, 0)) tipText = 'Selects which kind of atoms to select from the selected residue isotopomer; to display isotopic incorporation in the below table' self.elementPulldown = PulldownList(frame, callback=self.changeChemElement, grid=(0, 1), tipText=tipText) self.updateChemElements() label = Label(frame, text='Water Exchangeable Atoms:', grid=(0, 2)) tipText = 'Sets whether to show atoms considered as being "water exchangeable"; their isotopic labelling will rapidly equilibrate with aqueous solvent' self.exchangeCheck = CheckButton(frame, callback=self.updateAtomLabelsAfter, grid=(0, 3), selected=False, tipText=tipText) row += 1 # Tip texts set on update headingList = [ 'Atom\nName', 'Weighting\n13C' 'Weighting\n12C', '%12C', '%13C' ] self.atomLabelTupleWeightEntry = FloatEntry( self, text='', width=6, returnCallback=self.setAtomLabelWeight) self.atomsMatrix = ScrolledMatrix(frameB, headingList=headingList, callback=self.selectAtomLabel, multiSelect=True, grid=(row, 0)) self.atomsMatrix.doEditMarkExtraRules = self.atomsEditRules row += 1 tipTexts = [ 'For the selected atom sites, in the current isotopomer, set their isotopic incorporation to the default values', 'Spread the isotopic incorporation values from the last selected atom site to all selected atoms sites' ] texts = ['Reset Selected to Default Abundance', 'Propagate Abundances'] commands = [self.setAtomLabelsDefault, self.propagateAbundances] self.atomButtons = ButtonList(frameB, texts=texts, commands=commands, grid=(row, 0), tipTexts=tipTexts) # # View Frame # frameC.expandGrid(1, 0) row = 0 frame = Frame(frameC, grid=(row, 0), sticky='ew') frame.grid_columnconfigure(3, weight=1) label = Label(frame, text='Residue Type:', grid=(0, 0)) tipText = 'Selects which kind of residue, within the current isotope scheme, to show isotopomer structures for' self.viewCcpCodePulldown = PulldownList( frame, callback=self.selectViewCcpcode, grid=(0, 1), tipText=tipText) label = Label(frame, text='Isotopomer:', grid=(0, 2)) tipText = 'Selects which kind of isotopomer (labelling pattern) to display, from the selected residue type.' self.viewIsotopomerPulldown = PulldownList( frame, callback=self.selectViewIsotopomer, grid=(0, 3), tipText=tipText) row += 1 self.viewIsotopomerFrame = ViewIsotopomerFrame(frameC, None, grid=(row, 0)) # # Main # tipTexts = [ 'Save all changes to the reference isotope scheme to disk; the saves ALL changes to the CCPN installation for all projects to use', ] texts = ['Save Schemes'] commands = [self.saveSchemes] self.bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, texts=texts, commands=commands, helpUrl=self.help_url, grid=(0, 0), sticky='e', tipTexts=tipTexts) self.updateChemElements() self.updateCcpCodes() self.updateSchemes() self.administerNotifiers(self.registerNotify)
def body(self, guiFrame): self.geometry('600x700') self.noeMatrix = None self.xMol = None self.yMol = None guiFrame.expandGrid(0, 0) tipTexts = [ 'The main colour density matrix that displays residue-residue interaction strength', 'Selects which peak lists to show residue-residue interactions for', 'Selects which distance restraint lists to show residue-residue interactions for', 'Specifies which molecular chains and residue ranges to consider on the matrix axes' ] options = [ 'Interaction Matrix', 'Peak Lists', 'Restraint Lists', 'Residues' ] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0), tipTexts=tipTexts) frameA, frameB, frameC, frameD = tabbedFrame.frames # # Matrix # frameA.expandGrid(0, 0) self.noeMatrix = NoeMatrix(frameA, borderwidth=1, relief='flat', background='darkGrey', labelAxes=False) self.noeMatrix.grid(row=0, column=0, sticky='nsew') self.noeMatrix.updateAfter() # # Peak Lists # frameB.expandGrid(0, 0) tipTexts = [ 'The experiment:spectrum name of the peak list that may be considered', 'The serial number of the peak lists within its spectrum', 'Sets whether or not the peak list will be used as a source of residue interaction information' ] headingList = ['Spectrum', 'PeakList', 'Use?'] editWidgets = [None, None, None] editGetCallbacks = [None, None, self.togglePeakList] editSetCallbacks = [None, None, None] self.peakMatrix = ScrolledMatrix(frameB, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, multiSelect=False, grid=(0, 0), tipTexts=tipTexts) # # Restraints # frameC.expandGrid(1, 1) label = Label(frameC, text='Restraint Set: ', grid=(0, 0)) tipText = 'Selects which set of restraints to select restraint connectivity information from' self.constraintSetPulldown = PulldownList(frameC, self.changeConstraintSet, grid=(0, 1), tipText=tipText) tipTexts = [ 'The serial number, within the restraint set, and name of the restraint list', 'Whether the restraint list is a Distance restraint list or an H-Bond restraint list', 'Sets whether or not the restraint list will be used as a source of residue interaction information' ] headingList = ['List', 'Type', 'Use?'] editWidgets = [None, None, None] editGetCallbacks = [None, None, self.toggleConstraintList] editSetCallbacks = [None, None, None] self.constraintMatrix = ScrolledMatrix( frameC, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, multiSelect=False, grid=(1, 0), tipTexts=tipTexts, gridSpan=(1, 2)) # # Residues # frameD.expandGrid(2, 5) label = Label(frameD, text='X axis: ', grid=(0, 0)) label = Label(frameD, text='Y axis: ', grid=(1, 0)) tipText = 'Selects which molecular chain to use as the sequence along the horizontal axis of the interaction matrix' self.xMolPulldown = PulldownList(frameD, callback=self.changeMolX, grid=(0, 1), tipText=tipText) tipText = 'Selects which molecular chain to use as the sequence along the vertical axis of the interaction matrix' self.yMolPulldown = PulldownList(frameD, callback=self.changeMolY, grid=(1, 1), tipText=tipText) tipText = 'Sets the number of the first residue that appears at the start (left) of the horizontal matrix axis' self.xEntryStart = IntEntry(frameD, text='', returnCallback=self.setMolRanges, width=5, grid=(0, 2), tipText=tipText) tipText = 'Sets the number of the first residue that appears at the start (bottom) of the vertical matrix axis' self.yEntryStart = IntEntry(frameD, text='', returnCallback=self.setMolRanges, width=5, grid=(1, 2), tipText=tipText) label = Label(frameD, text=' to ', grid=(0, 3)) label = Label(frameD, text=' to ', grid=(1, 3)) tipText = 'Sets the number of the last residue that appears at the end (right) of the horizontal matrix axis' self.xEntryStop = IntEntry(frameD, text='', returnCallback=self.setMolRanges, width=5, grid=(0, 4), tipText=tipText) tipText = 'Sets the number of the last residue that appears at the end (top) of the vertical matrix axis' self.yEntryStop = IntEntry(frameD, text='', returnCallback=self.setMolRanges, width=5, grid=(1, 4), tipText=tipText) # # Main # tipTexts = [ 'Using the selected peak lists, restraint lists and residue ranges draw a colour density residue interaction matrix', 'Zoom in on the matrix view; make the boxes larger', 'Zoom out on the matrix view; make the boxes smaller' ] commands = [self.updateNoes, self.zoomIn, self.zoomOut] texts = ['Draw', '[+]', '[-]'] bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, commands=commands, texts=texts, helpUrl=self.help_url, grid=(0, 0), sticky='e', tipTexts=tipTexts) self.updateConstraintSets() self.updateMols() self.update() #self.updateNoes() self.administerNotifiers(self.registerNotify)
def body(self, guiParent): self.geometry('380x250') analysisProject = self.analysisProject self.smallFont = '-schumacher-clean-medium-r-normal--14-140-75-75-c-70-iso646.1991-irv' guiParent.grid_columnconfigure(0, weight=1) guiParent.grid_rowconfigure(0, weight=1) row = 0 tipTexts = ['Options specifying how peak annotations are drawn in spectrum windows and in tables etc.', 'Options to specify how large the peak crosses/symbols are drawn in spectrum windows', 'Enables the user to specify special symbols to annotate peaks according to quality'] options=['Annotation Style','Draw Size','Merit Symbols'] tabbedFrame = TabbedFrame(guiParent, options=options, grid=(row,0), tipTexts=tipTexts) frame1, frame2, frame3 = tabbedFrame.frames frame1.expandGrid(7,1) frame2.expandGrid(2,0) frame3.expandGrid(3,1) self.drawFrame = frame2 # Annotations tipText = 'Whether to show unassigned spin system numbers like "{123}" in peak annotations; does not affect the display of full residue assignments' self.spinSystAnnoSelect = CheckButton(frame1, callback=self.setSpinSystAnno, grid=(0,0), selected=analysisProject.doSpinSystemAnnotations, tipText=tipText) spinSystAnnoLabel = Label(frame1, text='Spin System Info', grid=(0,1)) tipText = 'Whether to show assigned atom names in peak annotations rather than resonance numbers, e.g. "21LeuH,N" or "21Leu[55],[56]"' self.resonanceAnnoSelect = CheckButton(frame1, callback=self.setResonanceAnno, grid=(1,0), selected=analysisProject.doAssignmentAnnotations, tipText=tipText) resonanceAnnoLabel = Label(frame1, text='Atom Assignment', grid=(1,1)) tipText = 'Whether to show the molecular chain code letter in peak annotations, e.g. "21LeuH,N" or "A21LeuH,N"' self.chainAnnoSelect = CheckButton(frame1, callback=self.setChainAnno, grid=(2,0), selected=analysisProject.doChainAnnotations, tipText=tipText) chainAnnoLabel = Label(frame1, text='Chain Assignment', grid=(2,1)) tipText = 'Whether to show the molecular system code name in peak annotations, e.g. "MS1:21LeuH,N" or "21LeuH,N"' self.molSysAnnoSelect = CheckButton(frame1, callback=self.setMolSysAnno, grid=(3,0), selected=analysisProject.doMolSysAnnotations, tipText=tipText) molSysAnnoLabel = Label(frame1, text='Molecular System', grid=(3,1)) tipText = 'Whether to show a symbol indicating the quality of a peak; these symbols must be set in the "Merit Symbols" tab' self.meritAnnoSelect = CheckButton(frame1, callback=self.setMeritAnno, grid=(4,0), selected=analysisProject.doMeritAnnotations, tipText=tipText) meritAnnoLabel = Label(frame1, text='Merit Symbol', grid=(4,1)) tipText = 'Whether to show the details text for a peak in spectrum windows (set in the peak tables)' self.detailAnnoSelect = CheckButton(frame1, callback=self.setDetailAnno, grid=(5,0), selected=analysisProject.doDetailAnnotations, tipText=tipText) detailAnnoLabel = Label(frame1, text='Details', grid=(5,1)) tipText = 'Whether to ignore above settings, and use a short peak annotation using only residue numbers and one-letter codes, e.g. "21L"' self.simpleAnnoSelect = CheckButton(frame1, callback=self.setSimpleAnnotations, grid=(6,0), tipText=tipText, selected=analysisProject.doMinimalAnnotations) simpleAnnoLabel = Label(frame1, text='Minimal Annotations (overriding option)', grid=(6,1)) tipText = 'Manually cause an update of all peak annotations; may take some time but recommended to see the immediate effect of changes' self.updateFullAnnoButton = Button(frame1, text='Update Full Annotations', command=self.updateAnnotations, grid=(7,0), gridSpan=(1,2), sticky='nsew', tipText=tipText) # Size tipText = 'The width of the displayed peak cross/symbol in screen pixels; the number of pixels from the centre point' self.pixel_entry = LabeledEntry(frame2, label='Number of pixels', entry=analysisProject.peakPixelSize, returnCallback=self.updatePixelSize, entry_width=8, tipText=tipText) tipText = 'Specifies which peak height corresponds to the specific per-isotope ppm size; actual peak symbol sizes are scaled, according to relative height (and volume)' self.intensity_entry = LabeledEntry(frame2, label='Height scale', entry=analysisProject.peakIntensityScale, returnCallback=self.updateIntensityScale, entry_width=8, tipText=tipText) tipText = 'Specifies which peak volume corresponds to the specific per-isotope ppm size; actual peak symbol sizes are scaled, according to relative volume (and height)' self.volume_entry = LabeledEntry(frame2, label='Volume scale', entry=analysisProject.peakVolumeScale, returnCallback=self.updateVolumeScale, entry_width=8, tipText=tipText) tipTexts = ['The kind of nuclear isotope, as found on the axis if a spectrum window', 'The ppm width of the peak cross/symbol along the specific kind of isotope axis'] headings = ['Isotope', 'Peak Size (ppm)'] self.peakSizeEntry = FloatEntry(self, returnCallback=self.setPeakSize, width=10) editWidgets = [None, self.peakSizeEntry] editGetCallbacks = [None, self.getPeakSize] editSetCallbacks = [None, self.setPeakSize] self.peak_size_table = ScrolledMatrix(frame2, headingList=headings, initialRows=5, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.selected_method = None self.method_widgets = {} self.method_widgets[peak_draw_methods[0]] = [self.pixel_entry] self.method_widgets[peak_draw_methods[1]] = [self.peak_size_table] self.method_widgets[peak_draw_methods[2]] = [self.intensity_entry, self.volume_entry, self.peak_size_table] self.method_widgets[peak_draw_methods[3]] = [self.peak_size_table] self.method_widgets[peak_draw_methods[4]] = [] self.method_widgets[peak_draw_methods[5]] = [] selected_index = peak_draw_methods.index(analysisProject.peakDrawMethod) tipText = 'Selects which mode to use for determining peak cross/symbol sizes; a fixed pixel/ppm value or scaled by intensity for all peaks or just one peak list' self.method_menu = PulldownList(frame2, texts=peak_draw_methods, gridSpan=(1,2), grid=(0,0), tipText=tipText, callback=self.setMethod, index=selected_index) # Merit symbol label = Label(frame3, text='Good merit (>0.66)', grid=(0,0)) tipText = 'Although typically blank, sets a symbol to display for good quality peaks (merit value > 0.66), if the relevant option is selected in the "Annotation Style" tab' self.meritGoodEntry = Entry(frame3, text=analysisProject.meritAnnotationGood, width=8, grid=(0,1), sticky='ew', tipText=tipText, returnCallback=self.setMeritAnnotation) label = Label(frame3, text='Medium merit', grid=(1,0)) tipText = 'Sets a symbol to display for mediocre quality peaks (merit value between 0.34 & 0.66), if the relevant option is selected in the "Annotation Style" tab' self.meritUglyEntry = Entry(frame3, text=analysisProject.meritAnnotationMediocre, width=8, grid=(1,1), sticky='ew', tipText=tipText, returnCallback=self.setMeritAnnotation) label = Label(frame3, text='Poor merit (<0.34)', grid=(2,0)) tipText = 'Sets a symbol to display for poor quality peaks (merit value < 0.34), if the relevant option is selected in the "Annotation Style" tab' self.meritBadEntry = Entry(frame3, text=analysisProject.meritAnnotationBad, width=8, grid=(2,1), sticky='ew', tipText=tipText, returnCallback=self.setMeritAnnotation) tipText = 'Commit the changes to the merit symbols; this will not automatically update the display - see the "Annotation Style" tab' setButton = Button(frame3, text='Set symbols', command=self.setMeritAnnotation, grid=(3,0), gridSpan=(1,2), tipText=tipText, sticky='nsew') buttons = UtilityButtonList(tabbedFrame.sideFrame, grid=(0,0), helpUrl=self.help_url, sticky='e') self.updatePeakSizeTable() self.updateMethod() for func in ('__init__', 'delete', ''): self.registerNotify(self.updatePeakSizeTable, 'ccpnmr.Analysis.AxisType', func) self.registerNotify(self.changedDoSpinSystemAnnotations, 'ccpnmr.Analysis.AnalysisProject', 'setDoSpinSystemAnnotations') self.registerNotify(self.changedDoAssignmentAnnotations, 'ccpnmr.Analysis.AnalysisProject', 'setDoAssignmentAnnotations') self.registerNotify(self.changedDoChainAnnotations, 'ccpnmr.Analysis.AnalysisProject', 'setDoChainAnnotations') self.registerNotify(self.changedPeakDrawMethod, 'ccpnmr.Analysis.AnalysisProject', 'setPeakDrawMethod') self.registerNotify(self.changedPeakPixelSize, 'ccpnmr.Analysis.AnalysisProject', 'setPeakPixelSize')
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)
def __init__(self, parent, basePopup, *args, **kw): # # Variable initialisation # self.fcWrapper = basePopup.fcWrapper self.project = basePopup.project self.basePopup = basePopup # TODO necessary? if self.project: self.nmrProject = self.project.currentNmrProject self.entry = self.project.currentNmrEntryStore.findFirstEntry() if not self.entry: self.entry = self.project.currentNmrEntryStore.newEntry( name=self.project.name) else: self.nmrProject = None self.sequenceCoordinatesLoaded = False self.shiftsLoaded = False self.linkResDone = False self.currentShiftList = None self.shiftListChainPairs = [] self.moleculeList = [] self.moleculeDict = {} # # Frame setup # Frame.__init__(self, parent, **kw) self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(1, weight=1) options = ['Import', 'Deposition'] tabbedFrame = TabbedFrame(self, options=options, callback=self.selectTab) tabbedFrame.grid(row=1, column=0, columnspan=2, sticky='nsew') self.tabbedFrame = tabbedFrame frameA, frameD = tabbedFrame.frames # # Main # frameA.grid_columnconfigure(0, weight=1) #frameA.grid_columnconfigure(1, weight=1) # Change to 2 if want 2 columns frameA.grid_rowconfigure(12, weight=1) #frameA.grid_rowconfigure(12, weight=1) row = 0 div = LabelDivider( frameA, text= 'Select the full coordinate file or a sequence file (with info for a single molecule).', justify='center', grid=(row, 0), gridSpan=(1, 1)) row += 1 self.sequenceCoordinatesImport = Button( frameA, text=self.defaultSelectText, command=self.importSequenceOrCoords, foreground=self.fontDefaultColor) self.sequenceCoordinatesImport.grid(row=row, column=0, sticky='ew') row += 1 label = Label(frameA, text="") label.grid(row=row, column=0, sticky='ew') row += 1 div = LabelDivider( frameA, text='Select the molecule relevant for your chemical shift file.', justify='center', grid=(row, 0), gridSpan=(1, 1)) row += 1 self.moleculeSelect = Label( frameA, text="None available yet - import valid file first", foreground=self.fontBadColor) self.moleculeSelect.grid(row=row, column=0, sticky='ew') self.moleculeSelectRow = row row += 1 label = Label(frameA, text="") label.grid(row=row, column=0, sticky='ew') row += 1 div = LabelDivider( frameA, text= 'Select a chemical shift file with values only for the above molecule.', justify='center', grid=(row, 0), gridSpan=(1, 1)) row += 1 self.shiftImport = Button(frameA, text=self.defaultSelectText, command=self.importShifts, foreground=self.fontDefaultColor) self.shiftImport.grid(row=row, column=0, sticky='ew') row += 1 label = Label(frameA, text="") label.grid(row=row, column=0, sticky='ew') row += 1 div = LabelDivider( frameA, text='Consistency check between molecule and shift information.', justify='center', grid=(row, 0), gridSpan=(2, 1)) row += 1 self.linkResCheckInfo = Label(frameA, text='') self.linkResCheckInfo.grid(row=row, column=0, sticky='ew') row += 1 div = Separator(frameA, grid=(row, 0), gridSpan=(1, 1)) row += 1 texts = ['Import new sequence', 'Import new set of shifts'] commands = [self.resetSequenceImport, self.resetShiftImport] self.mainButtons = ButtonList(frameA, texts=texts, commands=commands) self.mainButtons.grid(row=row, column=0, columnspan=2, sticky='ew') self.mainButtons.buttons[0].config(foreground=self.fontDefaultColor) #print row self.frameA = frameA # # Not in use... # #frameX.grid_columnconfigure(0, weight=1) #frameX.grid_columnconfigure(1, weight=1) #frameX.grid_rowconfigure(1, weight=1) #frameX.grid_rowconfigure(3, weight=1) # # Deposition, is updated after each successful import run. # frameD.grid_columnconfigure(0, weight=1) frameD.grid_rowconfigure(5, weight=1) self.frameD = frameD row = 0 div = LabelDivider(frameD, text='Imported data.', justify='center', grid=(row, 0), gridSpan=(1, 2)) row += 1 self.depositionImportText = "\nImported %d shift list(s) for a total of %d shifts.\n\nImported %d molecule(s) and %d chain(s).\n\nImported %d model(s) for a total of %d atom coordinates.\n\nLinked %.2f%% of imported NMR information to %d chain(s)." self.depositionImportLoc = (row, 0) # These used for setting text above... self.depositionImportNums = [0, 0, 0, 0, 0, 0, 0.0, 0] self.importedShiftLists = [] self.connectedChains = [] self.depositionImportLabel = Label(frameD, text=self.depositionImportText % tuple(self.depositionImportNums), foreground=self.fontBadColor) self.depositionImportLabel.grid(row=row, column=0, sticky='ew') row += 1 label = Label(frameD, text="") label.grid(row=row, column=0, sticky='ew') # # Finalize the import part, proceed to ECI. # row += 1 div = LabelDivider( frameD, text= 'Import completed, save project and start Entry Completion Interface.', justify='center', grid=(row, 0), gridSpan=(1, 1)) row += 1 self.eciStart = Button(frameD, text="Finalise import", command=self.finaliseImport, foreground=self.fontBadColor) self.eciStart.grid(row=row, column=0, sticky='ew')
def body(self, guiFrame): self.geometry('600x350') guiFrame.expandGrid(0, 0) options = ['Axis Units', 'Axis Types', 'Panel Types'] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0)) frameA, frameB, frameC = tabbedFrame.frames self.tabbedFrame = tabbedFrame # # Units # frameA.expandGrid(0, 0) tipTexts = [ 'Row number', 'Short text name for the unit of measurement, for graphical display', 'Whether the axis values decrease left to right & bottom to top. For example "ppm" does, but most other units do not' ] headings = ('#', 'Name', 'Is backwards?') self.axis_unit_table = ScrolledMatrix(frameA, headingList=headings, callback=self.selectAxisUnit, deleteFunc=self.deleteAxisUnit, tipTexts=tipTexts, grid=(0, 0)) tipTexts = [ 'Create a new specification of a unit of measurement', 'Delete the selected measurement unit' ] texts = ['Create', 'Delete'] commands = [self.createAxisUnit, self.deleteAxisUnit] self.axis_unit_buttons = ButtonList(frameA, texts=texts, tipTexts=tipTexts, grid=(1, 0), commands=commands) # # Types # frameB.expandGrid(0, 0) tipTexts = [ 'Row number', 'Name of window axis type, for graphical interface etc.', 'Which isotopes the axis definition covers', 'What kind of physical property is measured along the window axis', 'Whether the axis represents discretely sampled values or a continuum of values (albeit fixed to a data grid)', 'The upper and lower bounds for numerical values allowed on the axis', 'The number of decimal places used to round axis values in graphical displays', 'The relative scale for the peak symbol (i.e the "X" shape) size compared to other axes', 'Units of measurement allowed for this kind of axis' ] headingList = ('#', 'Name', 'Isotope\ncodes', 'Measurement\nType', 'Dim\nSampled?', 'Region', 'Decimal\nplaces', 'Peak\nSize', 'Allowed\nUnits') self.regionEntry = FloatEntry(self, isArray=True, returnCallback=self.setRegion, width=12) self.decimalEntry = IntEntry(self, returnCallback=self.setDecimal, width=5) self.peakSizeEntry = FloatEntry(self, returnCallback=self.setPeakSize, width=5) editWidgets = [ None, None, None, None, None, self.regionEntry, self.decimalEntry, self.peakSizeEntry, None ] editGetCallbacks = [ None, None, None, None, None, self.getRegion, self.getDecimal, self.getPeakSize, self.addUnit ] editSetCallbacks = [ None, None, None, None, None, self.setRegion, self.setDecimal, self.setPeakSize, None ] self.axisTypeMatrix = ScrolledMatrix(frameB, tipTexts=tipTexts, headingList=headingList, initialRows=5, grid=(0, 0), callback=self.selectAxisType, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, deleteFunc=self.deleteAxisType) tipTexts = [ 'Create a new kind of axis to use in spectrum windows', 'Delete the selected window axis type specification' ] texts = ['Create', 'Delete'] commands = [self.createAxisType, self.deleteAxisType] self.axis_type_buttons = ButtonList(frameB, texts=texts, tipTexts=tipTexts, commands=commands, grid=(1, 0)) # # Types # frameC.expandGrid(0, 0) tipTexts = [ 'Row number', 'Name of panel type specification', 'Which kind of axis the panel is a subtype of' ] headings = ('#', 'Name', 'AxisType') self.panelTypeMatrix = ScrolledMatrix(frameC, tipTexts=tipTexts, headingList=headings, initialRows=5, callback=self.selectPanelType, deleteFunc=self.deletePanelType) self.panelTypeMatrix.grid(row=0, column=0, sticky='nsew') tipTexts = [ 'Add a new panel type specification (a subtype of a given kind of axis)', 'Delete the selected panel type specification' ] texts = ['Create', 'Delete'] commands = [self.createPanelType, self.deletePanelType] self.panel_type_buttons = ButtonList(frameC, texts=texts, grid=(1, 0), commands=commands, tipTexts=tipTexts) # # Main # buttons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url, grid=(0, 0), sticky='e') self.updateAxisUnitTable() self.updateAxisTypeTable() self.updatePanelTypeTable() self.selectAxisUnit() self.selectAxisType() self.selectPanelType() self.administerNotifiers(self.registerNotify)
class ApplicationPopup(BasePopup): help_url = 'http://www.ccpn.ac.uk' def __init__(self, root, programName='Ccpn Workflow Management System'): self.programName = programName self.font = DEFAULT_FONT # Application object needed to store application-specific data with project self.application = Application(name=PROGRAM_NAME) self.versionInfo = 'Version ' + VERSION self.ariaProjectFile = None self.username = None # what do these do?? self.updateFuncs = [] self.projButtons = [] # may need these in the end self.ariaPaths = [] self.isdPaths = [] # FIXME JMCI # hard code this for now. this should be initialised from file # read during GUI login and then extended using the menu options # should set a placeholder. In fact, this placeholder will also have # a default user (guest) so that there is always a structure to # extend should the user wish to start from scratch and not log in self.repList = RepositoryList() self.currentTask = None # going to stick in shortcuts to frames for quick access self.frameShortcuts = {} # Application popup is a superclass of memops.editor.BasePoup BasePopup.__init__(self, parent=root, title=PROGRAM_NAME, location='+100+100', class_=self.application.name) self.setTitle(PROGRAM_NAME) def body(self, guiParent): self.geometry('700x600') # Ensure that the first row and column in popup expand guiParent.grid_rowconfigure(0, weight=1) guiParent.grid_columnconfigure(0, weight=1, minsize=200) frame = Frame(guiParent) # Body widgets can be put in this frame frame.grid() # this is going to set up the options on the tabs. Really we need # stronger bookeeping between the options and the frames. it # might make sense to define a master dictionary with option_name # => index. We can use this dictionary to build up the software # options and can also use it to define any refreshes etc (although # these would be better done through notifiers) softwareOpts = [ 'Repository', 'Project', 'Process', 'Client Tasks', 'Server Tasks', 'Data Exchange', 'Workflow', 'Protocols', 'User' ] # FIXME JMCI # we should have a tidier tabbed frame. ned to discuss rules with # tjs but it would seem to make sense to have the tabs stretch # across the entire top of the frame. Check the existing options # first, though self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0) self.tabbedFrame.grid(row=0, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) # Dictionary to store popups opened by this application - e.g. need to close upon quit self.popups = {} # Default font self.font = 'Helvetica 10' # Closing the window from the desktop environment calls the proper quit self.protocol('WM_DELETE_WINDOW', self.quit) # jmci we are going to have to change these drastically self.mainMenu = Menu(self) self.userMenu = self.makeUserMenu() self.repositoryMenu = self.makeRepositoryMenu() self.otherMenu = self.makeOtherMenu() # Put the top level menu self.config(menu=self.mainMenu) self.initRepository(frames[0]) self.initProjectFrame(frames[1]) self.initWms(frames[2]) self.initTasks(frames[3]) self.initDataExch(frames[5]) self.initWorkflow(frames[6]) self.initProtocol(frames[7]) self.initUserFrame(frames[8]) self.initProject() if not self.project: for button in self.projButtons: button.disable() # the main client side daemon. This is going to run in the background # and control the task processing self.taskDaemon = TaskManager(self) self.taskDaemon.active = False self.taskDaemon.start() ## THE TABBED FRAMES ## def initRepository(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) repositoryFrame = RepositoryFrame(frame, basePopup=self) repositoryFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(repositoryFrame.updateAll) def initProjectFrame(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) self.projectFrame = ProjectFrame(frame, basePopup=self) self.projectFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(self.projectFrame.updateAll) def initWms(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) extendNmrFrame = ExtendNmrFrame(frame, basePopup=self) extendNmrFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(extendNmrFrame.updateAll) def initTasks(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) tasksFrame = TasksFrame(frame, self) tasksFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(tasksFrame.updateAll) def initDataExch(self, frame): row = 0 frame.config(bg='#E6E6E6') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) dataExchFrame = DataExchFrame(frame, basePopup=self) dataExchFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(dataExchFrame.updateAll) def initWorkflow(self, frame): row = 0 frame.config(bg='#FFFFFF') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) workflowFrame = WorkflowFrame(frame, basePopup=self) workflowFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(workflowFrame.updateAll) def initProtocol(self, frame): row = 0 frame.config(bg='#FFFFFF') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) protocolFrame = ProtocolFrame(frame, basePopup=self) protocolFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(protocolFrame.updateAll) def initUserFrame(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) row = 0 frame.config(bg='#FFFFFF') userFrame = UserFrame(frame, basePopup=self) userFrame.grid(row=1, column=0, sticky='nsew') self.updateFuncs.append(userFrame.updateAll) ## The Menu ## def makeUserMenu(self): menu = Menu(self.mainMenu, tearoff=0) menu.add_command(label='Log In', shortcut='I', command=self.openLoginPopup) menu.add_command(label='Log Out', shortcut='O', command=self.logout) menu.add_command(label='Save Profile', shortcut='S', command=self.tmpCall) menu.add_command(label='View Profile', shortcut='V', command=self.tmpCall) menu.add_command(label='Create Profile', shortcut='C', command=self.tmpCall) menu.add_command(label='Edit Profile', shortcut='E', command=self.tmpCall) self.mainMenu.add_cascade(label='User', shortcut='U', menu=menu) menu.options = [ 'Log In', 'Log Out', 'Save Profile', 'View Profile', 'Create Profile', 'Edit Profile' ] return menu def makeRepositoryMenu(self): self.repMenu = Menu(self.mainMenu, tearoff=0) # Add various options to the menu and state the functions they call self.repMenu.add_command(label='Manager', shortcut='M', command=self.tmpCall) self.repMenu.add_command(label='Connect', shortcut='C', command=self.openRepository) # doesn't really work to have a disconnect; we do not have a list # of repositories and so would it refer to? Better to do this from # within the RepositoryFrame self.repMenu.add_command(label='Disconnect', shortcut='D', command=self.tmpCall) # again, this is functionality that would make sense but which it is hard to put # in the top level menu because it is not obvious which repository it refers # to self.repMenu.add_command(label='Import Project', shortcut='I', command=self.tmpCall) self.repMenu.add_command(label='Export Project', shortcut='E', command=self.tmpCall) # FIXME JMCI # the quit option needs to be tied to a dialogue box that asks whether # the current connection state should be saved. This will have to be # secured and so means that the GUI should have a login itself (beyond # the logins for the various resources). self.repMenu.add_command(label='Quit', shortcut='Q', command=self.quit) self.mainMenu.add_cascade(label='Repository', shortcut='R', menu=self.repMenu) self.repMenu.options = [ 'Connect', 'Disconnect', 'Import Project', 'Export Project', 'Quit' ] return self.repMenu def makeProjectMenu(self): # Submenu of the min menu menu = Menu(self.mainMenu, tearoff=0) # Add various options to the menu and state the functions they call menu.add_command(label='New', shortcut='N', command=self.newProject) menu.add_command(label='Open', shortcut='O', command=self.openProject) menu.add_command(label='Close', shortcut='C', command=self.closeProject) menu.add_command(label='Save', shortcut='S', command=self.saveProject) menu.add_command(label='Save As', shortcut='A', command=self.saveAsProject) menu.add_command(label='Quit', shortcut='Q', command=self.quit) menu.add_command(label='Version', shortcut='V', command=self.showVersion) self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu) menu.options = [ 'New', 'Open', 'Close', 'Save', 'Save As', 'Quit', 'Version' ] return menu def makeOtherMenu(self): # The fonts menu is a pre-created widget fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8, 10, 12), doItalic=0, doBoldItalic=0, tearoff=0) # Submenu of the min menu menu = Menu(self.mainMenu, tearoff=0) # Only Fonts option so far menu.add_cascade(label='Fonts', shortcut='F', menu=fontsMenu) self.mainMenu.add_cascade(label='Options', shortcut='O', menu=menu) menu.options = [ 'Fonts', ] return menu def makeCcpNmrMenu(self): try: from ccpnmr.analysis.AnalysisPopup import AnalysisPopup haveAnalysis = True except ImportError: haveAnalysis = False try: from ccpnmr.format.gui.FormatConverter import FormatConverter from ccpnmr.format.gui.DataShifter import DataShifter haveFormatConv = True except ImportError: haveFormatConv = False menu = Menu(self.mainMenu, tearoff=0) if haveAnalysis: menu.add_command(label='Analysis', shortcut='A', command=self.ccpNmrAnalysis) else: menu.add_command(label='Analysis ** NOT INSTALLED **', shortcut='A', command=None) if haveFormatConv: menu.add_command(label='Format Converter', shortcut='F', command=self.ccpNmrFormatConverter) menu.add_command(label='Data Shifter', shortcut='D', command=self.ccpNmrDataShifter) else: menu.add_command(label='Format Converter ** NOT INSTALLED **', shortcut='F', command=None) menu.add_command(label='Data Shifter ** NOT INSTALLED **', shortcut='D', command=None) self.mainMenu.add_cascade(label='CcpNmr', shortcut='C', menu=menu) menu.options = ['Analysis', 'Format Converter', 'Data Shifter'] return menu def ccpNmrAnalysis(self, cacheSize=64): from ccpnmr.analysis.AnalysisPopup import AnalysisPopup analysis = AnalysisPopup(self, cache_size=cacheSize, glDirect=None) analysis.update_idletasks() # fast if self.project: analysis.initProject(self.project) def ccpNmrFormatConverter(self): from ccpnmr.format.gui.FormatConverter import FormatConverter fc = FormatConverter(self, threading=False, project=self.project) fc.open() if self.project: fc.initProject(self.project) def ccpNmrDataShifter(self): from ccpnmr.format.gui.DataShifter import DataShifter ds = DataShifter(self) ds.open() def newProject(self): if self.project: # Project already present if not self.closeProject(): # If we don't close the current project do nothing return name = askString(title='Project name', prompt='Enter project name:', parent=self) if name: # Make the API Project object project = Implementation.MemopsRoot(name=name) nmrProject = project.newNmrProject(name=name) self.initProject(project) # placeholder method until we write code def tmpCall(self): return def openProject(self): if self.project: if not self.closeProject(): return self.openPopup('open_project', OpenProjectPopup, callback=self.initProject) def openLoginPopup(self): # at the moment we do this through methods in the popup. It # would be much more sensible to do this through some # sort of callback. login_popup = LoginPopup(self) # really we want to imoblise the rest. how to do? def setRepository(self, rep): self.repList.currentRepository = rep if self.frameShortcuts.has_key('Repository'): self.frameShortcuts['Repository'].drawFrame() if self.frameShortcuts.has_key('Tasks'): self.frameShortcuts['Tasks'].drawFrame() #for ff in self.tabbedFrame.frames[0].children.values(): # ff.draw() #for ff in self.tabbedFrame.frames[3].children.values(): # ff.draw() for ff in self.tabbedFrame.frames[8].children.values(): ff.draw() def openRepository(self): rep_popup = RepositoryPropertiesPopup(self) def closeRepository(self): pass def logout(self): self.setUsername(None) self.repList = RepositoryList() print 'in logout ', self.repList print '#########################' print self.tabbedFrame.frames[0].__dict__ print '#########################' if self.frameShortcuts.has_key('Repository'): self.frameShortcuts['Repository'].drawFrame() #for ff in self.tabbedFrame.frames[0].children.values(): # ff.draw() for ff in self.tabbedFrame.frames[8].children.values(): ff.draw() def openPopup(self, popup_name, clazz, oldStyle=False, *args, **kw): popup = self.popups.get(popup_name) if (popup): popup.open() else: if self.project: analysisProfile = self.analysisProfile else: analysisProfile = None if analysisProfile: transient = analysisProfile.transientDialogs else: transient = True name = popup_name if (oldStyle): popup = self.popups[popup_name] = clazz(self, transient=transient, *args, **kw) else: popup = self.popups[popup_name] = clazz(self, project=self.project, popup_name=name, transient=transient, *args, **kw) # above automatically opens popup return popup def closeProject(self, queryClose=True, querySave=True): if queryClose: if not showYesNo( 'Close project', 'Close current project?', parent=self): return False if querySave: if not self.checkSaving(): return False self.destroyPopups() self.initProject() return True def saveProject(self): self.saveFile() # NBNB Rasmus 22/8/08 changed to fit AnalysisPopup (and removed 'isStored' bug) #if (self.project.isStored): # self.saveFile() #else: # self.askSaveFile() def saveAsProject(self): self.askSaveFile() def showVersion(self): showInfo('Version', self.versionInfo, parent=self) def changeFont(self, analysisProfile): if analysisProfile is self.analysisProfile: if self.font != analysisProfile.font: self.font = analysisProfile.font or DEFAULT_FONT self.setFont() def selectFont(self, font): # Only called from main menu option if self.project: self.analysisProfile.font = font def setFont(self, font=None, popup=None): if font is None: font = self.font or DEFAULT_FONT else: self.font = font if not popup: popup = self childList = popup.children.values() classes = [ Tkinter.Button, Tkinter.Label, Tkinter.Menu, Tkinter.Entry, Tkinter.Checkbutton, Tkinter.Radiobutton ] for child in childList: for clazz in classes: if isinstance(child, clazz): if hasattr(child, 'font'): if not child.font: child.config(font=font) else: child.config(font=font) break if isinstance(child, Tkinter.Frame): child.font = font elif isinstance(child, ScrolledMatrix): child.setFont(font) if hasattr(child, 'children'): childList.extend(child.children.values()) def initProject(self, project=None): self.project = project if project: self.initTopObjects(self.project) self.project.application = self.application self.setFont() webBrowser = ProjectWebBrowser(self.top, popup=self, project=project) #self.helpButton.config(command = lambda url=self.help_url: webBrowser.open(url) ) for i, func in enumerate(self.updateFuncs): func(project) for button in self.projButtons: button.enable() self.setupSoftware() else: for button in self.projButtons: button.disable() self.setMenuState() def setUsername(self, name): self.username = name print 'set username ', self.username # jmci FIXME # need to look into this carefully and analyse the possible # states def setMenuState(self): if self.project: state = Tkinter.NORMAL else: state = Tkinter.DISABLED # Disable bits of the project menu if there's no project #for option in ('Save','Save As','Close'): # i = self.projectMenu.options.index(option) # self.projectMenu.entryconfig(i, state=state) # Disable other manus if there's no project #for menu in [self.otherMenu,]: # Include more menus in this list # for i in range(len(menu.options)): # menu.entryconfig(i, state=state) def setupSoftware(self): project = self.project methodStore = project.currentMethodStore or \ project.findFirstMethodStore() or \ project.newMethodStore(name=project.name) software = methodStore.findFirstSoftware(name=PROGRAM_NAME, version=VERSION) if not software: software = methodStore.newSoftware(name=PROGRAM_NAME, version=VERSION) #software.vendorName = 'PDBe & CCPN' #software.vendorAddress = '' #software.vendorWebAddress = 'http:' #software.details = '' def askSaveFile(self): popup = self.openPopup('save_project', SaveProjectPopup) popup.refresh() def modalAskSaveFile(self): popup = SaveProjectPopup(self, project=self.project, dismiss_text='Cancel Quit', modal=True) did_save = popup.did_save popup.destroy() return did_save def quitSaveProject(self): if (self.project.activeRepositories): return self.saveFile() else: return self.modalAskSaveFile() def destroyPopups(self): for key in self.popups.keys(): popup = self.popups[key] popup.destroy() self.popups = {} ## WMS methods # should maybe merge this with setUsername # this will read a config file that stores user setups. How this # is done TBD so hack for now and just return def readConfig(self, userName): # this should return the full RepositoryList structure. In reality this # will parse from file. set it by hand from here for now for speed repList = RepositoryList(userName) rep1 = repList.newRepository('remote', 'localhost:8080/HalxService', 'ccpn', 'remote') repList.currentRepository = rep1 # should these be directory objects? repList.current_export_dir = '/home/jionides/work/CCPN/test_JMCI_data' repList.current_import_dir = '/home/jionides/work/CCPN/test_EXP_data' self.repList = repList print 'in readconfig ' self.setRepository(rep1) # really should be done through notifiers if self.frameShortcuts.has_key('Repository'): self.frameShortcuts['Repository'].drawFrame() if self.frameShortcuts.has_key('Tasks'): self.frameShortcuts['Tasks'].drawFrame() if self.frameShortcuts.has_key('DataExch'): self.frameShortcuts['DataExch'].drawFrame() for ff in self.tabbedFrame.frames[8].children.values(): ff.draw() # want to update the top menu. The idea should be to add a bar item # and then to list all the repositories underneath. Clicking on a given # repository will set the home repository as current. That seems to # be a good sensible way of simplifying the interface in a expected # way. We could, alternatively, use tabs. opts = {} self.repMenu.add('separator', **opts) for rep in repList.repositories: item = { 'command': lambda rep=rep: self.setRepository(rep), 'label': rep.name } self.repMenu.add('comman', **item) self.repMenu.config() ## end WMS methods def copyModifiedStorages(self): modifiedStorages = [ storage for storage in self.project.storages if storage.isModified ] if (self.project.isModified): modifiedStorages.append(self.project) for storage in modifiedStorages: self.copyStorage(storage) def saveFile(self): if not self.project: return False try: saveProject(self.project, createFallback=True) print 'successfully saved project' return True except IOError, e: showError('Saving file', str(e), parent=self) return False
def body(self, guiFrame): self.geometry('600x600') guiFrame.expandGrid(0, 0) tipTexts = [ 'A table of all the NMR measurement lists in the project, including shift lists, T1 lists, J-coupling lists etc.', 'A table listing all of the individual measurements within an NMR measurement list' ] options = ['Measurement Lists', 'Measurements Table'] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0), tipTexts=tipTexts) self.tabbedFrame = tabbedFrame frameA, frameB = tabbedFrame.frames # Measurement Lists frameA.expandGrid(1, 0) self.detailsEntry = Entry(self, text='', returnCallback=self.setDetails, width=12) self.nameEntry = Entry(self, text='', returnCallback=self.setName, width=12) row = 0 frame0 = Frame(frameA, grid=(row, 0), gridSpan=(1, 2)) frame0.grid_columnconfigure(2, weight=1) label = Label(frame0, text='Experiment:', grid=(0, 0), sticky='e') tipText = 'Selects an experiment, if required, to restrict the measurement list table display; showing only lists which were derived using the experiment' self.experimentPulldown = PulldownList(frame0, callback=self.setExperiment, grid=(0, 1), tipText=tipText) row += 1 tipTexts = [ 'The serial number of measurement list', 'The type of measurement list, e.g. shift list, T1 list, J coupling list', 'A short identifying name for the list, for graphical displays', 'The number of measurements contained within the list', 'The unit of measurement used for the values in the list', 'The names of the experiments which were used to derive the measurements', 'A user-specified textual comment for the measurement list' ] justifyList = [ 'center', 'center', 'center', 'center', 'center', 'left' ] #colHeadings = ['List Type','Name','Size','Unit','Experiments','Other Info','Details'] colHeadings = [ '#', 'List Type', 'Name', 'Size', 'Unit', 'Experiments', 'Details' ] editWidgets = [ None, None, self.nameEntry, None, None, None, None, self.detailsEntry ] editGetCallbacks = [ None, None, self.getName, None, None, None, None, self.getDetails ] editSetCallbacks = [ None, None, self.setName, None, None, None, None, self.setDetails ] self.listsMatrix = ScrolledMatrix( frameA, grid=(row, 0), gridSpan=(1, 2), justifyList=justifyList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=colHeadings, callback=self.selectListCell, deleteFunc=self.deleteMeasurementList, tipTexts=tipTexts) row += 1 tipTexts = [ 'Show a table of the individual measurements within the selected measurement list', 'Make a new, blank chemical shift list within the project', 'Make a synthetic chemical shift list using random coil values, adjusting protein backbone values for sequence where approprate', 'Delete the selected measurement list' ] texts = [ 'Show Measurements', 'New Shift List', 'Make Random Coil Shift List', 'Delete' ] commands = [ self.showMeasurements, self.addShiftList, self.makeRandomCoilShiftList, self.deleteMeasurementList ] self.listButtons = ButtonList(frameA, texts=texts, commands=commands, grid=(row, 0), gridSpan=(1, 2), tipTexts=tipTexts) # Measurements self.measurementDetailsEntry = Entry( self, text='', returnCallback=self.setMeasurementDetails, width=12) self.measurementMeritEntry = FloatEntry( self, returnCallback=self.setMeasurementMerit, width=6) row = 0 frame0 = Frame(frameB, grid=(row, 0)) frame0.grid_columnconfigure(2, weight=1) label = Label(frame0, text='Measurement List:', grid=(0, 0), sticky='e') tipText = 'Selects the measurement list to display measurements for' self.listPulldown = PulldownList(frame0, callback=self.setMeasurementList, grid=(0, 1), tipText=tipText) row += 1 frameB.expandGrid(row, 0) tipTexts = [ 'The serial number of the measurement within its containing list', 'The number or assignment of the NMR resonance(s) to which the measurement applies', 'The numeric value of the NMR measurement on the specified resonance(s), and the unit of measurement', 'The standard deviation error in the measured value', 'The molecular chain, if any, to which the measurement relates by virtue of atom assigned resonances', 'The isotope type(s) of the measures resonance(s)', 'A figure-of-merit value for the measurement indicating its quality or reliability', 'The number of peaks in the CCPN project used to take the measurement', 'A user-defined textual comment for the measurement' ] justifyList = [ 'center', 'center', 'center', 'center', 'center', 'center', 'center', 'center', 'center', 'left' ] colHeadings = [ '#', 'Resonance', 'Value', 'SD', 'Chain', 'Isotope', 'Fig of\nMerit', 'Peaks', 'Details' ] editWidgets = [ None, None, None, None, None, None, self.measurementMeritEntry, None, self.measurementDetailsEntry ] editGetCallbacks = [ None, None, None, None, None, None, self.getMeasurementMerit, self.showPeaks, self.getMeasurementDetails ] editSetCallbacks = [ None, None, None, None, None, None, self.setMeasurementMerit, None, self.setMeasurementDetails ] self.measurementsMatrix = ScrolledMatrix( frameB, grid=(row, 0), multiSelect=True, tipTexts=tipTexts, justifyList=justifyList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=colHeadings, callback=self.selectMeasurementCell) row += 1 tipTexts = [ 'Show a table containing peaks that were used to derive the selected measurements', 'For some measurement lists (currently only shift lists) manually trigger a recalculation of values', 'Show a table containing the resonances that relate to the selected measurements', 'Delete the selected measurement records; cannot be done for chemical shift values still ties to peaks via assignment' ] texts = ['Show Peaks', 'Recalculate', 'Show Resonances', 'Delete'] commands = [ self.showPeaks, self.recalculateMeasurements, self.showResonances, self.deleteMeasurements ] self.measurementButtons = ButtonList(frameB, texts=texts, grid=(row, 0), commands=commands, tipTexts=tipTexts) # Main Frame self.bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url, grid=(0, 0), gridSpan=(1, 2), sticky='e') self.updateMeasurementListAfter() self.updateMeasurementsAfter() self.administerNotifiers(self.registerNotify)
def body(self, guiParent): self.geometry('700x600') # Ensure that the first row and column in popup expand guiParent.grid_rowconfigure(0, weight=1) guiParent.grid_columnconfigure(0, weight=1, minsize=200) frame = Frame(guiParent) # Body widgets can be put in this frame frame.grid() # this is going to set up the options on the tabs. Really we need # stronger bookeeping between the options and the frames. it # might make sense to define a master dictionary with option_name # => index. We can use this dictionary to build up the software # options and can also use it to define any refreshes etc (although # these would be better done through notifiers) softwareOpts = [ 'Repository', 'Project', 'Process', 'Client Tasks', 'Server Tasks', 'Data Exchange', 'Workflow', 'Protocols', 'User' ] # FIXME JMCI # we should have a tidier tabbed frame. ned to discuss rules with # tjs but it would seem to make sense to have the tabs stretch # across the entire top of the frame. Check the existing options # first, though self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0) self.tabbedFrame.grid(row=0, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) # Dictionary to store popups opened by this application - e.g. need to close upon quit self.popups = {} # Default font self.font = 'Helvetica 10' # Closing the window from the desktop environment calls the proper quit self.protocol('WM_DELETE_WINDOW', self.quit) # jmci we are going to have to change these drastically self.mainMenu = Menu(self) self.userMenu = self.makeUserMenu() self.repositoryMenu = self.makeRepositoryMenu() self.otherMenu = self.makeOtherMenu() # Put the top level menu self.config(menu=self.mainMenu) self.initRepository(frames[0]) self.initProjectFrame(frames[1]) self.initWms(frames[2]) self.initTasks(frames[3]) self.initDataExch(frames[5]) self.initWorkflow(frames[6]) self.initProtocol(frames[7]) self.initUserFrame(frames[8]) self.initProject() if not self.project: for button in self.projButtons: button.disable() # the main client side daemon. This is going to run in the background # and control the task processing self.taskDaemon = TaskManager(self) self.taskDaemon.active = False self.taskDaemon.start()
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)
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)
class ApplicationPopup(AnalysisPopup): help_url = 'http://www.ccpn.ac.uk' allowedCallbackFuncnames = ('init', 'save', 'close') def __init__(self, root, programName='Extend-NMR Interface'): self.font = DEFAULT_FONT # Application object needed to store application-specific data with project self.application = Application(name=PROGRAM_NAME) self.versionInfo = 'Version' + VERSION self.ariaProjectFile = None self.doneAnalysisInfo = False self.updateFuncs = [] self.projButtons = [] self.ariaPaths = [] self.isdPaths = [] AnalysisPopup.__init__(self, root) self.program_name = PROGRAM_NAME self.setTitle(PROGRAM_NAME) def printAnalysisCommandLineInfo(self, event): if not self.doneAnalysisInfo: Analysis.printCommandLineInfo(self) self.doneAnalysisInfo = True def printCommandLineInfo(self): print """ For program documentation see: http://www.extend-nmr.eu """ def body(self, guiParent): self.menus = {} self.menu_items = {} self.fixedActiveMenus = {} self.popups = {} self.callbacksDict = {} self.selected_objects = [] self.menubar = menubar = Menu(guiParent) self.font = DEFAULT_FONT self.setProjectMenu() # menu = Menu(self.menubar, tearoff=0) menu.bind('<Button>', self.printAnalysisCommandLineInfo) self.menubar.add_cascade(label='CcpNmr Analysis', shortcut='C', menu=menu) self.menubar.add_command(label='FormatConverter', shortcut='F', command=self.runFormatConverter) self.menubar = menu self.initProject() self.setPeaksMenu() self.setMoleculeMenu() self.setAssignMenu() self.setResonanceMenu() self.setDataMenu() self.setStructureMenu() self.setChartMenu() self.setMacroMenu() self.setOtherMenu() self.setMenuState() # need to do it again because of OtherMenu state # Help Submenu helpMenu = Menu(self.menubar, tearoff=0) helpMenu.add_command(label='Version', shortcut='V', command=self.showVersion) helpMenu.add_command(label='About', shortcut='A', command=self.showAbout) helpMenu.add_command(label='Help', shortcut='H', command=self.showHelp) menu.add_separator() menu.add_command(label='CCPN Updates', shortcut='U', image=self.iconRefresh, compound='left', command=self.updateAnalysis, tipText='Get any new patches and updates to CcpNmr') menu.add_cascade(label='CCPN Help', shortcut='H', image=self.iconHelp, compound='left', menu=helpMenu) self.config(menu=menubar) # Ensure that the first row and column in popup expand guiParent.grid_rowconfigure(0, weight=1) guiParent.grid_columnconfigure(0, weight=1, minsize=200) frame = Frame(guiParent) # Body widgets can be put in this frame frame.grid() softwareOpts = [ 'Extend-NMR', 'ARIA 2', 'Auremol', 'CING', ' ECI ', 'HADDOCK', ' ISD ', 'PRODECOMP' ] self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0, callback=self.toggleTab) self.tabbedFrame.grid(row=0, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'Fp6Logo.gif') self.fp6Logo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CingLogo.gif') self.cingLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AriaLogo.gif') self.ariaLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'IsdLogo.gif') self.isdLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'HaddockLogo.gif') self.haddockLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AuremolLogo.gif') self.auremolLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'ProdecompLogo.gif') self.prodecompLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MddLogo.gif') self.mddLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'BrukerLogo.gif') self.brukerLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MsdLogo.gif') self.msdLogo = Tkinter.PhotoImage(file=imageFile) self.initExtendNmr(frames[0]) self.initAria(frames[1]) self.initAuremol(frames[2]) self.initCing(frames[3]) self.initEci(frames[4]) self.initHaddock(frames[5]) self.initIsd(frames[6]) self.initProdecomp(frames[7]) self.initProject(self.project) if not self.project: for button in self.projButtons: button.disable() self.geometry('680x670') def setProjectMenu(self): ProjectMenu = 'Project' # Imports submenu importsMenu = Menu(self.menubar, tearoff=False) importsMenu.add_command(label='Via Format Converter', shortcut='F', command=self.runFormatConverter) importsMenu.add_command(label='NMR-STAR 2.1.1', command=self.importNmrStar211) importsMenu.add_command(label='NMR-STAR 3.1', shortcut='N', command=self.importNmrStar31) importsMenu.add_command(label='PDB 3.20', shortcut='P', command=self.importPdb) importsMenu.add_command(label='Coordinates (PDB-style)', shortcut='C', command=self.importCoordinates) # Preferences submenu fontsMenu = FontMenu(self.menubar, self.selectFont, sizes=(8, 10, 12), doItalic=False, doBoldItalic=False, tearoff=0) prefsMenu = Menu(self.menubar, tearoff=False) prefsMenu.add_cascade( label='Fonts', shortcut='F', image=self.iconFont, compound='left', menu=fontsMenu, tipText='Select font to use in the graphical interface') prefsMenu.add_command(label='Colour Schemes', image=self.iconTable, compound='left', shortcut='C', tipText='Edit and create colour schemes', command=self.editColorSchemes) prefsMenu.add_command( label='Residue Codes', image=self.iconTable, compound='left', shortcut='R', tipText= 'User-specified codes that override the standard residue names', command=self.editResidueCodes) prefsMenu.add_command(label='User Options', image=self.iconTable, compound='left', shortcut='U', tipText='General options for Analysis behaviour', command=self.editProfiles) # menu = Menu(self.menubar, tearoff=0) menu.add_command( label='New', shortcut='N', image=self.iconNewWindow, compound='left', command=self.newProject, tipText='Create a new, blank CCPN project (closes any open project)' ) menu.add_command( label='Open Project', shortcut='O', image=self.iconOpen, compound='left', command=self.openProject, tipText= 'Open a new CCPN project by selecting a project directory on disk') menu.add_command( label='Open Spectra', shortcut='p', image=self.iconOpenFile, compound='left', command=self.openSpectrum, tipText= 'Open spectrum data fom disk, creating a default CCPN project if needed' ) menu.add_command(label='Save', shortcut='S', image=self.iconSave, compound='left', command=self.saveProject, tipText='Save the current CCPN project on disk') menu.add_command( label='Save As', shortcut='A', image=self.iconSaveAs, compound='left', command=self.saveAsProject, tipText= 'Save the current CCPN project under a different name (project directory)' ) menu.add_cascade(label='Import', shortcut='I', image=self.iconImport, compound='left', menu=importsMenu) menu.add_command(label='Close', shortcut='C', image=self.iconClose, compound='left', command=self.closeProject, tipText='Close the current CCPN project') menu.add_command( label='Quit', shortcut='Q', image=self.iconQuit, compound='left', command=self.quit, tipText='Quit Extend-NMR, closing any open CCPN project') menu.add_separator() menu.add_cascade(label='Preferences', shortcut='P', image=self.iconPrefs, compound='left', menu=prefsMenu) menu.add_command( label='Validate', shortcut='V', image=self.iconTool, compound='left', command=self.validateProject, tipText= 'Check the current CCPN project for data model consistency errors') menu.add_command( label='Backup', shortcut='B', image=self.iconTool, compound='left', command=self.backupProject, tipText='Setup options for automated backup of CCPN project data') menu.add_command( label='Archive', shortcut='r', image=self.iconTool, compound='left', command=self.archiveProject, tipText= 'Save the current CCPN project in an archived form, e.g. tar gzipped' ) self.menubar.add_cascade(label=ProjectMenu, shortcut='j', menu=menu) self.menus[ProjectMenu] = menu self.menu_items[ProjectMenu] = [ 'New', 'Open Project', 'Open Spectra', 'Save', 'Save As', 'Import', 'Close', 'Quit', 'Preferences', 'Validate', 'Backup', 'Archive', ] # Menus that area ctive in absence of a project #for ii in (0,1,2,7,13,15): for ii in ( 0, 1, 2, 7, ): self.fixedActiveMenus[(ProjectMenu, ii)] = True def setPopupGeometries(self): for key in self.popups.keys(): popup = self.popups[key] if not key.startswith(window_popup_prefix): # bit of a hack not self.setPopupGeometry(popup, key) def toggleTab(self, index): if (index > 0) and not self.project: showWarning('Warning', 'No active project', parent=self) self.tabbedFrame.select(0) return frame = self.tabbedFrame.frames[index] if hasattr(frame, 'printOutDocString'): print frame.printOutDocString # only print it once del frame.printOutDocString def initCing(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=702, height=77) canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.cingLogo) cingFrame = CingFrame(frame, self) cingFrame.grid(row=1, column=0, sticky='nsew') #self.projButtons.extend(cingFrame.buttonBar.buttons) self.updateFuncs.append(cingFrame.updateAll) def initProdecomp(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.configure(bg='#FFFFFF') canvas = Tkinter.Canvas(frame, width=1024, height=90, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.prodecompLogo) prodecompFrame = ProdecompFrame(frame, basePopup=self, ccpnProject=self.project) prodecompFrame.grid(row=1, column=0, sticky='nsew') # set printOutDocString: frame.printOutDocString = prodecompFrame.printOutDocString #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(prodecompFrame.updateAll) def initAuremol(self, frame): frame.expandGrid(1, 0) refText = """Gronwald W, Brunner K, Kirchhofer R, Nasser A, Trenner J, Ganslmeier B, Riepl H, Ried A, Scheiber J, Elsner R, Neidig K-P, Kalbitzer HR AUREMOL, a New Program for the Automated Structure Elucidation of Biological Macromolecules. Bruker Reports 2004; 154/155: 11-14 """ canvas = Tkinter.Canvas(frame, width=700, height=160, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(12, 12, anchor='nw', image=self.auremolLogo) canvas.create_text(200, 10, anchor='nw', text=refText) auremolFrame = AuremolFrame(frame, self.project, grid=(1, 0)) #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(auremolFrame.updateAll) def initEci(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.parent = self # For notifiers frame.configure(bg='#FFFFFF') canvas = Tkinter.Canvas(frame, width=800, height=73, bd=3, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(10, 10, anchor='nw', image=self.msdLogo) eciFrame = EntryCompletionFrame(frame, basePopup=self) eciFrame.grid(row=1, column=0, sticky='nsew') #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(eciFrame.updateAll) def initHaddock(self, frame): frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.parent = self # For notifiers canvas = Tkinter.Canvas(frame, width=753, height=92) canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.haddockLogo) haddockFrame = HaddockFrame(frame, self.project) haddockFrame.grid(row=1, column=0, sticky='nsew') #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(haddockFrame.updateAll) def initIsd(self, frame): global isd frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) frame.configure(bg='#FFFFFF') canvas = Tkinter.Canvas(frame, width=800, height=91, bd=3, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew', padx=0) canvas.create_image(0, 0, anchor='nw', image=self.isdLogo) isdFrame = IsdFrame(frame, self.project) isdFrame.grid(row=1, column=0, sticky='nsew') self.isd = isdFrame isd = self.isd #self.projButtons.extend(isdFrame.buttons) self.updateFuncs.append(isdFrame.updateAll) def initExtendNmr(self, frame): row = 0 frame.config(bd=5) canvas = Tkinter.Canvas(frame, width=640, height=600, bg='#FFFFFF', bd=5) canvas.grid(row=row, column=0, sticky='nsew') canvas.create_image(15, 15, anchor='nw', image=self.fp6Logo) canvas.create_image(330, 15, anchor='nw', image=self.prodecompLogo) canvas.create_image(330, 115, anchor='nw', image=self.mddLogo) canvas.create_image(20, 200, anchor='nw', image=self.ccpnLogo) canvas.create_image(230, 220, anchor='nw', image=self.msdLogo) canvas.create_image(450, 200, anchor='nw', image=self.brukerLogo) canvas.create_image(5, 310, anchor='nw', image=self.isdLogo) canvas.create_image(230, 300, anchor='nw', image=self.ariaLogo) canvas.create_image(450, 290, anchor='nw', image=self.auremolLogo) canvas.create_image(5, 420, anchor='nw', image=self.haddockLogo) canvas.create_image(5, 520, anchor='nw', image=self.cingLogo) #row += 1 #l1 = Label(frame, text='Welcome to the Extend NMR suite') #l1.grid(row=row, column=0, sticky='ew') def initAria(self, frame): welcomeMessage = \ """ARIA Version 2.3. Authors: Benjamin Bardiaux, Michael Habeck, Jens Linge, Therese Malliavin, Sean O'Donoghue, Wolfgang Rieping, and Michael Nilges. Rieping W., Habeck M., Bardiaux B., Bernard A., Malliavin T.E., Nilges M.(2007) ARIA2: automated NOE assignment and data integration in NMR structure calculation. Bioinformatics 23:381-382""" frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(1, weight=1) canvas = Tkinter.Canvas(frame, width=700, height=114, bg='#FFFFFF') canvas.grid(row=0, column=0, sticky='ew') canvas.create_image(0, 0, anchor='nw', image=self.ariaLogo) canvas.create_text(250, 10, anchor='nw', text=welcomeMessage) ariaFrame = AriaFrame(frame, self) ariaFrame.grid(row=1, column=0, sticky='nsew') self.projButtons.extend(ariaFrame.buttons) self.updateFuncs.append(ariaFrame.updateAll) def openPopup(self, popup_name, clazz, oldStyle=False, *args, **kw): popup = self.popups.get(popup_name) if (popup): popup.open() else: if self.project: analysisProfile = self.analysisProfile else: analysisProfile = None if analysisProfile: if popup_name.startswith(window_popup_prefix): # bit of a hack transient = analysisProfile.transientWindows else: transient = analysisProfile.transientDialogs else: transient = True name = popup_name if (oldStyle): popup = self.popups[popup_name] = clazz(self, transient=transient, *args, **kw) else: popup = self.popups[popup_name] = clazz(self, project=self.project, popup_name=name, transient=transient, *args, **kw) # above automatically opens popup return popup def initProject(self, project=None): AnalysisPopup.initProject(self, project, False) self.project = project if project: for i, func in enumerate(self.updateFuncs): func(project) for button in self.projButtons: button.enable() else: for button in self.projButtons: button.disable() def setupSoftware(self): return project = self.project methodStore = project.currentMethodStore or \ project.findFirstMethodStore() or \ project.newMethodStore(name=project.name) software = methodStore.findFirstSoftware(name=PROGRAM_NAME, version=VERSION) if not software: software = methodStore.newSoftware(name=PROGRAM_NAME, version=VERSION) software.task = 'data pipeline' software.vendorName = 'The Extend-NMR Project' #software.vendorAddress = '' software.vendorWebAddress = 'http://www.extend-nmr.eu'
def body(self, guiFrame): self.geometry('600x350') project = self.project analysisProject = self.analysisProject guiFrame.grid_columnconfigure(1, weight=1) row = 0 frame = Frame(guiFrame, grid=(0,0)) label = Label(frame, text=' Window:', grid=(0,0)) self.windowPulldown = PulldownList(frame, grid=(0,1), tipText='The window that will be printed out', callback=self.selectWindow) tipTexts = ['For the window pulldown, show all of the spectrum windows in the current project, irrespective of the active group', 'For the window pulldown, show only spectrum windows that are in the currently active window group'] self.whichWindows = RadioButtons(frame, grid=(0,2), entries=ACTIVE_OPTIONS, tipTexts=tipTexts, select_callback=self.updateWindows) texts = [ 'Save Print File' ] tipTexts = [ 'Save the printout to the specified file' ] commands = [ self.saveFile ] buttons = UtilityButtonList(guiFrame, helpUrl=self.help_url, grid=(row,2), commands=commands, texts=texts, tipTexts=tipTexts) self.buttons = buttons buttons.buttons[0].config(bg='#B0FFB0') row += 1 guiFrame.grid_rowconfigure(row, weight=1) options = ['Options', 'Spectra', 'Peak Lists', 'Region'] tipTexts = ['Optional settings for spectra', 'Optional settings for peak lists', 'Optional settings for the region'] tabbedFrame = TabbedFrame(guiFrame, options=options, tipTexts=tipTexts) tabbedFrame.grid(row=row, column=0, columnspan=3, sticky='nsew') self.tabbedFrame = tabbedFrame optionFrame, spectrumFrame, peakListFrame, regionFrame = tabbedFrame.frames optionFrame.expandGrid(0, 0) getOption = lambda key, defaultValue: PrintBasic.getPrintOption(analysisProject, key, defaultValue) setOption = lambda key, value: PrintBasic.setPrintOption(analysisProject, key, value) self.printFrame = PrintFrame(optionFrame, getOption=getOption, grid=(0,0), gridSpan=(1,1), setOption=setOption, haveTicks=True, doOutlineBox=False) spectrumFrame.expandGrid(0, 0) frame = Frame(spectrumFrame, grid=(0,0), gridSpan=(1,1)) frame.expandGrid(1,0) self.overrideSpectrum = CheckButton(frame, text='Use below settings when printing', tipText='Use below settings when printing instead of the window values', grid=(0,0), sticky='w') tipText = 'Change the settings of the selected spectra back to their window values' button = Button(frame, text='Reset Selected', tipText=tipText, command=self.resetSelected, grid=(0,1), sticky='e') self.posColorPulldown = PulldownList(self, callback=self.setPosColor) self.negColorPulldown = PulldownList(self, callback=self.setNegColor) headings = ['Spectrum', 'Pos. Contours\nDrawn', 'Neg. Contours\nDrawn', 'Positive\nColours', 'Negative\nColours'] tipTexts = ['Spectrum in window', 'Whether the positive contours should be drawn', 'Whether the negative contours should be drawn', 'Colour scheme for positive contours (can be a single colour)', 'Colour scheme for negative contours (can be a single colour)'] editWidgets = [ None, None, None, self.posColorPulldown, self.negColorPulldown] editGetCallbacks = [ None, self.togglePos, self.toggleNeg, self.getPosColor, self.getNegColor] editSetCallbacks = [ None, None, None, self.setPosColor, self.setNegColor] self.spectrumTable = ScrolledMatrix(frame, headingList=headings, tipTexts=tipTexts, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(1,0), gridSpan=(1,2)) peakListFrame.expandGrid(0, 0) frame = Frame(peakListFrame, grid=(0,0), gridSpan=(1,3)) frame.expandGrid(1,0) self.overridePeakList = CheckButton(frame, text='Use below settings when printing', tipText='Use below settings when printing instead of the window values', grid=(0,0)) tipText = 'Change the settings of the selected peak lists back to their window values' button = Button(frame, text='Reset Selected', tipText=tipText, command=self.resetSelected, grid=(0,1), sticky='e') colors = Color.standardColors self.peakColorPulldown = PulldownList(self, callback=self.setPeakColor, texts=[c.name for c in colors], objects=[c.hex for c in colors], colors=[c.hex for c in colors]) headings = [ 'Peak List', 'Symbols Drawn', 'Peak Font', 'Peak Colour'] self.fontMenu = FontList(self, mode='Print', extraTexts=[no_peak_text]) editWidgets = [ None, None, self.fontMenu, self.peakColorPulldown] editGetCallbacks = [ None, self.togglePeaks, self.getPeakFont, self.getPeakColor ] editSetCallbacks = [ None, None, self.setPeakFont, self.setPeakColor ] self.peakListTable = ScrolledMatrix(frame, headingList=headings, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(1,0), gridSpan=(1,2)) regionFrame.expandGrid(0, 0) frame = Frame(regionFrame, grid=(0,0), gridSpan=(1,3)) frame.expandGrid(3,0) tipText = 'Use the specified override region when printing rather than the window values' self.overrideButton = CheckButton(frame, text='Use override region when printing', tipText=tipText, callback=self.toggledOverride, grid=(0,0)) tipTexts = ('Use min and max to specify override region', 'Use center and width to specify override region') self.use_entry = USE_ENTRIES[0] self.useButtons = RadioButtons(frame, entries=USE_ENTRIES, tipTexts=tipTexts, select_callback=self.changedUseEntry, grid=(1,0)) texts = ('Set Region from Window', 'Set Center from Window', 'Set Width from Window') tipTexts = ('Set the override region to be the current window region', 'Set the center of the override region to be the center of the current window region', 'Set the width of the override region to be the width of the current window region') commands = (self.setRegionFromWindow, self.setCenterFromWindow, self.setWidthFromWindow) self.setRegionButton = ButtonList(frame, texts=texts, tipTexts=tipTexts, commands=commands, grid=(2,0)) self.minRegionWidget = FloatEntry(self, returnCallback=self.setMinRegion, width=10) self.maxRegionWidget = FloatEntry(self, returnCallback=self.setMaxRegion, width=10) headings = MIN_MAX_HEADINGS editWidgets = [ None, None, self.minRegionWidget, self.maxRegionWidget ] editGetCallbacks = [ None, None, self.getMinRegion, self.getMaxRegion ] editSetCallbacks = [ None, None, self.setMinRegion, self.setMaxRegion ] self.regionTable = RegionScrolledMatrix(frame, headingList=headings, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(3,0)) self.updateWindows() self.updateAfter() self.administerNotifiers(self.registerNotify)
def body(self, guiParent): self.menus = {} self.menu_items = {} self.fixedActiveMenus = {} self.popups = {} self.callbacksDict = {} self.selected_objects = [] self.menubar = menubar = Menu(guiParent) self.font = DEFAULT_FONT self.setProjectMenu() # menu = Menu(self.menubar, tearoff=0) menu.bind('<Button>', self.printAnalysisCommandLineInfo) self.menubar.add_cascade(label='CcpNmr Analysis', shortcut='C', menu=menu) self.menubar.add_command(label='FormatConverter', shortcut='F', command=self.runFormatConverter) self.menubar = menu self.initProject() self.setPeaksMenu() self.setMoleculeMenu() self.setAssignMenu() self.setResonanceMenu() self.setDataMenu() self.setStructureMenu() self.setChartMenu() self.setMacroMenu() self.setOtherMenu() self.setMenuState() # need to do it again because of OtherMenu state # Help Submenu helpMenu = Menu(self.menubar, tearoff=0) helpMenu.add_command(label='Version', shortcut='V', command=self.showVersion) helpMenu.add_command(label='About', shortcut='A', command=self.showAbout) helpMenu.add_command(label='Help', shortcut='H', command=self.showHelp) menu.add_separator() menu.add_command(label='CCPN Updates', shortcut='U', image=self.iconRefresh, compound='left', command=self.updateAnalysis, tipText='Get any new patches and updates to CcpNmr') menu.add_cascade(label='CCPN Help', shortcut='H', image=self.iconHelp, compound='left', menu=helpMenu) self.config(menu=menubar) # Ensure that the first row and column in popup expand guiParent.grid_rowconfigure(0, weight=1) guiParent.grid_columnconfigure(0, weight=1, minsize=200) frame = Frame(guiParent) # Body widgets can be put in this frame frame.grid() softwareOpts = [ 'Extend-NMR', 'ARIA 2', 'Auremol', 'CING', ' ECI ', 'HADDOCK', ' ISD ', 'PRODECOMP' ] self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0, callback=self.toggleTab) self.tabbedFrame.grid(row=0, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'Fp6Logo.gif') self.fp6Logo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CingLogo.gif') self.cingLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AriaLogo.gif') self.ariaLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'IsdLogo.gif') self.isdLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'HaddockLogo.gif') self.haddockLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AuremolLogo.gif') self.auremolLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'ProdecompLogo.gif') self.prodecompLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MddLogo.gif') self.mddLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'BrukerLogo.gif') self.brukerLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MsdLogo.gif') self.msdLogo = Tkinter.PhotoImage(file=imageFile) self.initExtendNmr(frames[0]) self.initAria(frames[1]) self.initAuremol(frames[2]) self.initCing(frames[3]) self.initEci(frames[4]) self.initHaddock(frames[5]) self.initIsd(frames[6]) self.initProdecomp(frames[7]) self.initProject(self.project) if not self.project: for button in self.projButtons: button.disable() self.geometry('680x670')
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)
def body(self, guiFrame): self.geometry("775x500") guiFrame.expandGrid(0,0) options = ['1D Graphs','Amino Acid CA CB'] tipTexts = ['Simple graphs of how chemical shift values are distributed for a given atom type', 'Density plots of alpha a & beta carbon shift distributions for common amnio acids'] tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0,0), tipTexts=tipTexts) frameA, frameB = tabbedFrame.frames # # # # # # # 1D GRAPHS # # # # # # # row = 0 MolType = self.project.metaclass.metaObjFromQualName('ccp.molecule.ChemComp.MolType') molTypes = MolType.enumeration molTypes.remove('other') molTypes.remove('carbohydrate') self.molType = 'protein' ccpCodes = self.getCcpCodes(self.molType) or [None,] self.ccpCode = 'Ala' self.atomType = ATOM_TYPES[0] self.atomNamesDict = {} self.chemAtomNmrRefs = self.getCcpCodeData(self.ccpCode, atomType=self.atomType) tipText = 'Which of the common bio-polymer types to show data for' self.molTypeLabel = Label(frameA, text = 'Molecule Type:', grid=(row,0)) self.molTypePulldown = PulldownList(frameA, callback=self.changeMolType, texts=molTypes, grid=(row,1), tipText=tipText) tipText = 'Which residue code to show chemical shift distributions for' self.ccpCodeLabel = Label(frameA, text = 'Residue Code:', grid=(row,2)) self.ccpCodePulldown = PulldownList(frameA, callback=self.changeCcpCode, texts=ccpCodes, index=ccpCodes.index(self.ccpCode), grid=(row,3), tipText=tipText) tipText = 'Whether to show distributions for hydrogen atoms or other atoms' self.atomTypeLabel = Label(frameA, text = 'Atom Type:', grid=(row,4)) self.atomTypePulldown = PulldownList(frameA, callback=self.changeAtomType, texts=ATOM_TYPES, tipText=tipText, grid=(row,5)) row += 1 tipText = 'The selection of atom name to display distributions for' self.atomSelector = PartitionedSelector(frameA, self.toggleAtom, tipText=tipText, maxRowObjects=20) self.atomSelector.grid(row=row, column=0, columnspan=6, sticky='ew') row += 1 frameA.expandGrid(row,5) self.scrolledGraph = ScrolledGraph(frameA, symbolSize=2, reverseX=True, width=650, height=300, title='Chemical shift distribution', xLabel='Chemical shift', yLabel='proportion', motionCallback=self.updateCrosshairs) self.scrolledGraph.grid(row=row, column=0, columnspan=6, sticky='nsew') # # # # # # # PROTEIN CA CB # # # # # # # frameB.expandGrid(0,0) matrix, ppms = self.getCaCbMatrix() title = 'Amino Acid CA & CB Chemical Shifts' self.cacbMatrix = ScrolledDensityMatrix(frameB, matrix=matrix, boxSize=14, title=title, xLabels=ppms, yLabels=AMINO_ACIDS, borderColor='grey', zoom=1.0, labelAxes=True, barPlot=False, doLegend=False, grid=(0,0)) sdm = self.cacbMatrix font = sdm.boldFont x0, y0 = (470,370) sdm.canvas.create_rectangle(x0+170,y0-6,x0+182,y0+6,fill='#4040A0', outline=sdm.borderColor, width=1) sdm.canvas.create_text(x0+200, y0, text='CA', font=font) sdm.canvas.create_rectangle(x0+220,y0-6,x0+232,y0+6,fill='#A04040', outline=sdm.borderColor, width=1) sdm.canvas.create_text(x0+250, y0, text='CB', font=font) sdm.canvas.create_text(x0, y0, text='13C PPM +/- 0.5', font=font) # # # # # # # M A I N # # # # # # # tipText = 'Whether to use chemical shift data from the BMRB (unfiltered) or RefDB sets' label = Label(tabbedFrame.sideFrame, text='Source Database:', grid=(0,0), sticky='e') index = SOURCE_NAMES.index(self.sourceName) self.sourcePulldown = PulldownList(tabbedFrame.sideFrame, self.changeSource, texts=SOURCE_NAMES, index=index, grid=(0,1), sticky='e', tipText=tipText) self.bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, expands=True, helpUrl=self.help_url, sticky='e', grid=(0,2)) self.waiting = False self.updateAfter() for func in ('__init__', 'delete'): self.registerNotify(self.updateAfter, 'ccp.nmr.NmrReference.NmrReferenceStore', func)
def __init__(self, guiParent, basePopup, project=None): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # FIXME JMCI # need to work through this far more carefully self.project = project # shortcuts to this layer self.basePopup.frameShortcuts['Task'] = self # shortcuts to layer below. We should set these in the # initMethod methods self.frameShortcuts = {} # TODO understand what these are doing self.registerNotify = basePopup.registerNotify self.unregisterNotify = basePopup.unregisterNotify Frame.__init__(self, guiParent) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(0, weight=1) # Logos. Code nicked from ExtendNMR GUI ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') # basically nicked from Extend-NMR softwareOpts = [ 'Test1Task', 'ARIA 2', 'Auremol', 'CING', ' ECI ', 'HADDOCK', ' ISD ', 'PRODECOMP' ] self.tabbedFrame = TabbedFrame(guiParent, options=softwareOpts, toggleOff=False, selected=0) self.tabbedFrame.grid(row=1, column=0, sticky='nsew') frames = self.tabbedFrame.frames # Logos ccpnDir = getTopDirectory() imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images') imageFile = os.path.join(imageDir, 'Fp6Logo.gif') self.fp6Logo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CingLogo.gif') self.cingLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AriaLogo.gif') self.ariaLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'IsdLogo.gif') self.isdLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'HaddockLogo.gif') self.haddockLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'AuremolLogo.gif') self.auremolLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'CcpnLogo.gif') self.ccpnLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'ProdecompLogo.gif') self.prodecompLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MddLogo.gif') self.mddLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'BrukerLogo.gif') self.brukerLogo = Tkinter.PhotoImage(file=imageFile) imageFile = os.path.join(imageDir, 'MsdLogo.gif') self.msdLogo = Tkinter.PhotoImage(file=imageFile) # don't know what this does self.updateFuncs = [] self.projButtons = [] # basically nicked from Extend-NMR self.initTest1(frames[0]) self.initAria(frames[1]) self.initAuremol(frames[2]) self.initCing(frames[3]) #self.initEci(frames[4]) #self.initHaddock(frames[5]) self.initIsd(frames[6]) self.initProdecomp(frames[7])
def body(self, guiFrame): self.geometry('700x840') guiFrame.expandGrid(1,0) # Top frame frame = Frame(guiFrame, grid=(0,0)) frame.expandGrid(None,8) label = Label(frame, text=u' %s List:' % T1, grid=(0,0)) self.t1Pulldown = PulldownList(frame, callback=self.selectT1List, grid=(0,1)) label = Label(frame, text=u' %s List:' % T2, grid=(0,2)) self.t2Pulldown = PulldownList(frame, callback=self.selectT2List, grid=(0,3)) label = Label(frame, text=' NOE List:', grid=(0,4)) self.noePulldown = PulldownList(frame, callback=self.selectNoeList, grid=(0,5)) label = Label(frame, text=' Spectrometer Freq (MHz):', grid=(0,6)) self.sfEntry = FloatEntry(frame, grid=(0,7), text=600.00, width=6) UtilityButtonList(frame, grid=(0,9), sticky='e') # Tabs options = [u'%s vs %s Scatter' % (T1, T2), u'%s,%s & NOE Graphs' % (T1, T2) , u'%s/%s Graph' % (T1, T2), u'%s Estimate Graph' % S2, 'Options'] self.tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.toggleTab, grid=(1,0)) frameA, frameD, frameC, frameE, frameB = self.tabbedFrame.frames # T1 vs T2 Graph frameA.expandGrid(0,0) self.t1t2Graph = T1VersesT2Plot(frameA, grid=(0,0)) # T1 & T2 Graph frameD.expandGrid(0,0) frameD.expandGrid(1,0) frameD.expandGrid(2,0) self.t1Graph = MeasurementPlot(frameD, T1, grid=(0,0)) self.t2Graph = MeasurementPlot(frameD, T2, grid=(1,0)) self.noeGraph = NoePlot(frameD, 'NOE', grid=(2,0)) # T1 over T2 Graph frameC.expandGrid(0,0) self.t1t2GraphB = T1OverT2Plot(frameC, grid=(0,0)) # Order params graph frameE.expandGrid(0,0) frameE.expandGrid(1,0) frameE.expandGrid(2,0) self.s2Graph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % S2, xLabel='Residue number', yLabel=S2, width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(0,0), dataColors=['#0000A0','#808000'], dataNames=['Isotropic',]) self.teGraph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % Te, xLabel='Residue number', yLabel=u'%s (ps)' % Te, width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(1,0), dataColors=['#008000',]) self.rexGraph = ScrolledGraph(frameE, title=u'%s vs Residue Sequence' % 'Rex', xLabel='Residue number', yLabel='Rex', width=500, height=150, graphType='histogram', xGrid=True, yGrid=False, grid=(2,0), dataColors=['#900000',]) # Options frameB.expandGrid(4,2) frame = LabelFrame(frameB, text='Physical Params', grid=(0,0)) frame.expandGrid(None,3) label = Label(frame, text=u'N-H bond length (\u00C5)', grid=(0,0)) self.lenNhEntry = FloatEntry(frame, text=1.015, grid=(0,1), width=8) label = Label(frame, text=u'Internal correlation\ntime, \u03C4e (ps)', grid=(1,0)) self.ictEntry = FloatEntry(frame, text=50.0, grid=(1,1), width=8) label = Label(frame, text=u'15N Chemical Shift\nAnisotopy,\u0394N (ppm)', grid=(2,0)) self.csaNEntry = FloatEntry(frame, text=-160.0, grid=(2,1), width=8) frame = LabelFrame(frameB, text=u'%s vs %s Scatter' % (T1, T2), grid=(1,0)) label = Label(frame, text='Max cluster difference (ms):', grid=(0,0)) self.clusterDictEntry = FloatEntry(frame, text=20.0, grid=(0,1), width=8) label = Label(frame, text='Min cluster size:', grid=(1,0)) self.clusterSizeEntry = FloatEntry(frame, text=5, grid=(1,1), width=8) label = Label(frame, text=u'Min graph %s (ms):' % T1, grid=(2,0)) self.minT1Entry = FloatEntry(frame, text=300.0, grid=(2,1), width=8) label = Label(frame, text=u'Max graph %s (ms):' % T1, grid=(3,0)) self.maxT1Entry = FloatEntry(frame, text=1000.0, grid=(3,1), width=8) label = Label(frame, text=u'Min graph %s (ms):' % T2, grid=(4,0)) self.minT2Entry = FloatEntry(frame, text=0.0, grid=(4,1), width=8) label = Label(frame, text=u'Max graph %s (ms):' % T2, grid=(5,0)) self.maxT2Entry = FloatEntry(frame, text=600.0, grid=(5,1), width=8) frame = LabelFrame(frameB, text=u'%s Contours' % S2, grid=(0,1)) frame.expandGrid(4,3) label = Label(frame, text='(Order Parameter Lines)', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Min value:', grid=(1,0)) self.minS2Entry = FloatEntry(frame, text=0.3, grid=(1,1), width=8) label = Label(frame, text='Max value:', grid=(2,0)) self.maxS2Entry = FloatEntry(frame, text=1.0, grid=(2,1), width=8) label = Label(frame, text='Step:', grid=(3,0)) self.stepS2Entry = FloatEntry(frame, text=0.1, grid=(3,1), width=8) frame = LabelFrame(frameB, text=u'\u03C4m Contours', grid=(1,1)) frame.expandGrid(4,3) label = Label(frame, text='(Rotational Correlation Time Lines)', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Min value (ns):', grid=(1,0)) self.minRctEntry = FloatEntry(frame, text=5.0, grid=(1,1), width=8) label = Label(frame, text='Max value (ns):', grid=(2,0)) self.maxRctEntry = FloatEntry(frame, text=14.0, grid=(2,1), width=8) label = Label(frame, text='Step (ns):', grid=(3,0)) self.stepRctEntry = FloatEntry(frame, text=1.0, grid=(3,1), width=8) # Bottom frame texts = [u'Show %s Table' % T1,u'Show %s Table' % T2, u'Estimate %s' % S2] commands = [self.showT1List, self.showT2List, self.mc] buttonList = ButtonList(guiFrame, grid=(2,0), texts=texts, commands=commands) # Update self.updateRelaxationLists() self.drawAfter() self.administerNotifiers(self.registerNotify)