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'
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