class NamingSystemPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'NamingSystem.html') def __init__(self, parent, namingSysList=None, namingSysDict=None): # Constructor doesn't do much except call body # The parent is self.parent (parent of the popup) self.namingSys = None self.namingSysList = namingSysList self.namingSysDict = namingSysDict # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__(self, parent=parent, title='Choose namingSys', modal=False, transient=True) def body(self, master): # # Popup gui # # First row row = 0 label = Label(master, text="Choose a naming system:") label.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 label = Label(master, text="(% matches in brackets)") label.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 self.menu = PulldownMenu(master, entries=self.namingSysList) self.menu.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 texts = ['OK'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, column=0) def apply(self): self.namingSysName = self.namingSysDict[self.menu.getSelected()] return True
class ItemSelectPopup(BasePopup): def __init__(self, parent, entries, label='', message='', select_text='Select', *args, **kw): self.entries = entries self.label = label self.message = message self.select_text = select_text self.item = None kw['title'] = 'Select item' kw['transient'] = True kw['modal'] = True BasePopup.__init__(self, parent=parent, *args, **kw) def body(self, master): master.grid_rowconfigure(0, weight=1) master.grid_columnconfigure(1, weight=1) row = 0 if (self.message): label = Label(master, text=self.message) label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) row = row + 1 if (self.label): label = Label(master, text=self.label) label.grid(row=row, column=0, sticky=Tkinter.W) self.itemMenu = PulldownMenu(master, entries=self.entries) self.itemMenu.grid(row=row, column=1, sticky=Tkinter.EW) row = row + 1 texts = [self.select_text] commands = [self.ok] buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel') buttons.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) def apply(self): self.item = self.itemMenu.getSelected() return True
class WriteBmrbChemShiftDepPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'WriteBmrbChemShiftDep.html') def __init__(self, parent, project): self.project = project self.guiParent = parent self.selectedFormats = [] self.defaultText = 'Select file' self.chainDict = {} self.chainList = [] self.shiftListDict = {} self.shiftLists = [] for shiftList in self.project.currentNmrProject.findAllMeasurementLists( className='ShiftList'): if shiftList.measurements != (): label = str(shiftList.serial) + ':' + str(shiftList.name) self.shiftListDict[label] = shiftList self.shiftLists.append(label) if not self.shiftLists: showError('Error', 'No shift lists available!') return BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Write BMRB chemical shift deposition file', modal=False, transient=True) def body(self, master): row = 0 label = Label(master, text="BMRB chemical shift deposition file writer.") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) row += 1 label = Label(master, text="Shift lists:") label.grid(row=row, column=0, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=self.shiftLists, callback=self.setChainList, do_initial_callback=False) self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(master, text="Chains (only one per file):") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainListSelect = PulldownMenu(master, entries=self.chainList) self.chainListSelect.grid(row=row, column=1, sticky=Tkinter.EW) self.setChainList(0, self.shiftLists[0]) row += 1 label = Label(master, text="Chemical shift deposition file:") label.grid(row=row, column=0, sticky=Tkinter.W) self.fileButton = Tkinter.Button(master, text=self.defaultText, command=self.selectFile) self.fileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 texts = ['Write file'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, columnspan=2, column=0) def setChainList(self, shiftListIndex, shiftListLabel): # # Has to be done... very slow this. # shiftList = self.shiftListDict[shiftListLabel] self.chainDict = {} self.chainList = [] for shift in shiftList.measurements: if shift.resonance: rs = shift.resonance.resonanceSet if rs: atom = rs.findFirstAtomSet().findFirstAtom() chain = atom.residue.chain if chain not in self.chainDict.values(): label = chain.molSystem.code + ":'" + chain.code + "'" self.chainDict[label] = chain self.chainList.append(label) self.chainListSelect.clearMenuItems() if self.chainList: self.chainListSelect.setup(self.chainList, 0) def selectFile(self): fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: fileName = 'bmrb.csdep' popup = FormatFilePopup(self, file=fileName, component='csdep', format='bmrb') if popup.fileSelected: self.fileButton.config(text=popup.file) popup.destroy() def apply(self): shiftListLabel = self.shiftListSelect.getSelected() shiftList = self.shiftListDict[shiftListLabel] try: chainLabel = self.chainListSelect.getSelected() chain = self.chainDict[chainLabel] except: showError( "No chains", "No chains were present or selected. Try running linkResonances first." ) return False fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: return False fileCreated = writeBmrbChemShiftDeposition(self.guiParent, chain, shiftList, fileName) if fileCreated: showInfo("Success", "Succesfully wrote chemical shift deposition file") else: showError("Not written", "Error writing file %s. File not written" % fileName) return False return True
class SingleResonanceStatusPopup(BasePopup): def __init__(self, parent, message, nmrRes, optionList, title, urlFile=None): # Constructor doesn't do much except call body # The parent is self.parent (parent of the popup) self.singleResonanceStatus = None self.message = message self.optionList = optionList self.nmrRes = nmrRes if urlFile: self.help_url = joinPath(getHelpUrlDir(), urlFile + '.html') else: self.help_url = None # modal = true means that it won't continue unless this one returns value BasePopup.__init__(self, parent=parent, title=title, modal=True, transient=True) def body(self, master): master.grid_columnconfigure(0, weight=1) for i in range(3): master.grid_rowconfigure(i, weight=1) self.geometry('600x400') # Master is the owner widget (not self.parent) - parent of the widget here row = 0 label = Label(master, text="Residue %s-%d" % (self.nmrRes.molResidue.ccpCode, self.nmrRes.seqCode)) label.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 label = Label(master, text=self.message) label.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 self.menu = PulldownMenu(master, entries=self.optionList) self.menu.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 texts = ['OK'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, column=0) def apply(self): self.singleResonanceStatus = self.optionList.index( self.menu.getSelected()) return True
class AutoAssignIOCyclePopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'AutoAssignIOCycle.html') def __init__(self, parent, project): self.project = project self.guiParent = parent self.autoAssignFormat = AutoAssignFormat(project, guiParent=parent) self.format = 'autoAssign' self.chainStampSep = '-' self.dateTimeFlag = time.strftime("%Y%m%d.%H:%M") self.getPreviousDateTimeStamps() self.getChainsAndChainStamps() self.importFileName = self.exportFileName = None BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'AutoAssign export/import cycle.', modal=True, transient=True) def getPreviousDateTimeStamps(self): self.dateTimeStamps = [] appData = self.project.findAllApplicationData(application=self.format, keyword=dateTimeStamp_kw) for appDatum in appData: self.dateTimeStamps.append(appDatum.value) def getChainsAndChainStamps(self): self.chains = [] self.chainDateTimeStamps = [] self.chainDateTimeStampDict = {} for molSys in self.project.sortedMolSystems(): for chain in molSys.sortedChains(): self.chains.append(chain) appData = chain.findFirstApplicationData( application=self.format, keyword=dateTimeStamp_kw) if appData and appData.value in self.dateTimeStamps: (tlist, tdict) = createSelection([chain]) cdtsTag = "%s%s%s" % (tlist[0], self.chainStampSep, appData.value) self.chainDateTimeStamps.append(cdtsTag) self.chainDateTimeStampDict[cdtsTag] = chain def body(self, master): self.geometry('600x400') # # Quick check # if not self.chains: showError("No chains", "No chains available - cannot use export/import cycle.") self.destroy() # # Set it all up # columnspan = 2 row = 0 label = Label(master, text="AutoAssign export/import cycle.") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 label = Label( master, fg='red', text= "Popup to export %s data from the CCPN data model,\nrun %s, then re-import the output." % (self.format, self.format)) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Set up export file info # row += 1 label = Label(master, text="Export menu (using date/time label '%s')" % self.dateTimeFlag) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 (chainList, self.chainDict) = createSelection(self.chains) label = Label(master, text="Select chain to export:") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainSelect = PulldownMenu(master, entries=chainList) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(master, text="Export %s project file:" % self.format) label.grid(row=row, column=0, sticky=Tkinter.W) self.selectExportFileButton = Tkinter.Button( master, text='Select export file', command=(lambda: self.selectExportProjectFile())) self.selectExportFileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 self.exportButton = Tkinter.Button(master, text='Export', command=(lambda: self.doExport())) self.exportButton.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Set up import file info # row += 1 label = Label(master, text="Re-import menu") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 # # Select the right chain with the right date/time flag... # label = Label(master, text="Select chain with correct date/time flag:") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainDateTimeSelect = PulldownMenu( master, entries=self.chainDateTimeStamps) self.chainDateTimeSelect.grid(row=row, column=1, sticky=Tkinter.W) # TODO UPDATE THIS WHEN EXPORT BUTTON PRESSED AND GETTING OK FROM EXPORT ITSELF! # Probably also need just a message if no importDateTimeStamp available... row += 1 label = Label(master, text="Import %s output file:" % self.format) label.grid(row=row, column=0, sticky=Tkinter.W) self.selectImportFileButton = Tkinter.Button( master, text='Select import file', command=(lambda: self.selectImportShiftFile())) self.selectImportFileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 self.importButton = Tkinter.Button(master, text='Import', command=(lambda: self.doImport())) self.importButton.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 buttons = createDismissHelpButtonList(master, texts=[], commands=[], help_url=self.help_url) buttons.grid(row=row, columnspan=columnspan, column=0) def selectExportProjectFile(self): if self.exportFileName: fileName = self.exportFileName else: fileName = 'table.aat' popup = FormatFilePopup( self, file=fileName, component='project', format=self.format, title='Select name for %s project file to export.' % self.format) if popup.fileSelected: self.selectExportFileButton.config(text=popup.file) self.exportFileName = popup.file def selectImportShiftFile(self): if self.exportFileName: fileName = self.exportFileName else: fileName = 'autoAssign.out' popup = FormatFilePopup( self, file=fileName, component='shifts', format=self.format, title='Select name for %s output file to re-import.' % self.format) if popup.fileSelected: self.selectImportFileButton.config(text=popup.file) self.importFileName = popup.file def doExport(self): if self.exportFileName: chain = self.chainDict[self.chainSelect.getSelected()] returnValue = self.autoAssignFormat.writeProject( self.exportFileName, chain=chain, setTag=self.dateTimeFlag) if not returnValue: showError( "No export file written", "There were problems while exporting the %s project file." % self.format) else: showInfo("File written", "File written successfully") cdtsTag = "%s-%s" % (self.chainSelect.getSelected(), self.dateTimeFlag) if not cdtsTag in self.chainDateTimeSelect.entries: if "<None>" in self.chainDateTimeSelect.entries: self.chainDateTimeSelect.entries.pop( self.chainDateTimeSelect.entries.index("<None>")) self.chainDateTimeSelect.replace( [cdtsTag] + self.chainDateTimeSelect.entries) self.chainDateTimeStampDict[cdtsTag] = chain else: showError( "No export file defined", "Please define a name for the %s project file to export to." % self.format) def doImport(self): if self.importFileName: cdtsTag = self.chainDateTimeSelect.getSelected() if not self.chainDateTimeStampDict.has_key(cdtsTag): showError( "No import tag defined", "No chain with date/time stamp defined - cannot re-import." ) else: chain = self.chainDateTimeStampDict[cdtsTag] (chainText, curDateTimeStamp) = cdtsTag.split(self.chainStampSep) # # Get relevant info from data model (not immediately necessary but as example) # # Note that could in principle use the normal peakNum tag, but dangerous in case # multiple exports were done... this is more laborious though. # peakLists = [] rootPeakListTag = str((curDateTimeStamp, 'isRoot')) rootPeakNumToPeak = {} for nmrExp in self.project.currentNmrProject.sortedExperiments( ): for ds in nmrExp.sortedDataSources(): for peakList in ds.sortedPeakLists(): appData = peakList.findAllApplicationData( application=self.format, keyword=dateTimeStamp_kw) for appDatum in appData: if appDatum and appDatum.value == curDateTimeStamp: peakLists.append(peakList) if peakList.findFirstApplicationData( application=self.format, keyword=ioCycleTag_kw, value=rootPeakListTag): for peak in peakList.sortedPeaks(): appData = peak.findFirstApplicationData( application=self.format, keyword=ioCycleTag_kw) if appData: (curTag, peakNum) = eval(appData.value) if curTag == curDateTimeStamp: rootPeakNumToPeak[ peakNum] = peak # # Now get the actual chemical shift info from the AutoAssign output file # autoAssignChemShiftFile = AutoAssignChemShiftFile( self.importFileName) autoAssignChemShiftFile.read() # # Set the mapping between the chain residues and the seqCode in the chem shift file # residues = list(chain.sortedResidues()) seqCodeToResidue = {} for i in range(0, len(residues)): residue = residues[i] (seqCode, code1Letter) = autoAssignChemShiftFile.seqCodes[i] seqCode = returnInt(seqCode) seqCodeToResidue[seqCode] = residue for rawChemShift in autoAssignChemShiftFile.chemShifts: peak = None residue = None prevResidue = None seqCode = rawChemShift.seqCode atomName = rawChemShift.atomName #allValues = rawChemShift.allValues #rawChemShift.spinSystemId if seqCodeToResidue.has_key(seqCode): residue = seqCodeToResidue[seqCode] else: # THIS SHOULD NEVER HAPPEN! print " Error: no match for seqCode %d while re-importing project." % seqCode continue # # Set info on residue/atom level # atom = self.findMatchingAtom(residue, atomName) self.autoAssignFormat.setSeqAssignTag( atom, rawChemShift.value, AppDataClass=Implementation.AppDataFloat) # # Set info on peak level # if rawChemShift.peakId: (peakNum, rootName) = rawChemShift.peakId.split( '.') # TODO set this somewhere? peakNum = returnInt(peakNum) if rootPeakNumToPeak.has_key(peakNum): peak = rootPeakNumToPeak[peakNum] self.autoAssignFormat.setSeqAssignTag( peak, str((chain.code, residue.seqId))) else: showError( "No import file defined", "Please define a name for the %s shift output file to import." % self.format) def findMatchingAtom(self, residue, atomName): atom = residue.findFirstAtom(name=atomName) if not atom: # Rough search but should be OK for bb atoms namingSystem = residue.chemCompVar.chemComp.findFirstNamingSystem( name='XPLOR') chemAtomSysName = findChemAtomSysName(namingSystem, {'sysName': atomName}) atom = residue.findFirstAtom(name=chemAtomSysName.atomName) return atom def apply(self): if not 0: showError("No root spectrum", "Can't continue: need a root spectrum...") return False return True
class CloudsPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.project = parent.getProject() self.waiting = 0 self.specFreq = 800.13 self.maxIter = 50 self.mixTime = 60 self.corrTime = 11.5 self.leakRate = 2.0 self.peakListDict = {} self.noesyPeakList = None self.tocsyPeakList = None self.noesy3dPeakList = None self.hsqcPeakList = None self.maxIntens = 37000000 self.resonances = None self.origResonances = None self.noesyPeaks = None self.distanceConstraintList = None self.antiDistConstraintList = None self.numClouds = 100 self.filePrefix = 'cloud_' self.cloudsFiles = [] self.adcAtomTypes = 'HN' self.structure = None # step num, initial temp, final temp, cooling steps, MD steps, MD tau, rep scale self.coolingScheme = [] self.coolingScheme.append([1, 1, 1, 3, 500, 0.001, 0]) self.coolingScheme.append([2, 80000, 4000, 19, 1000, 0.001, 0]) self.coolingScheme.append([3, 4000, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([4, 15000, 1, 3, 1000, 0.001, 0]) self.coolingScheme.append([5, 1, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([6, 8000, 1, 3, 1000, 0.001, 0]) self.coolingScheme.append([7, 1, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([8, 3000, 25, 60, 2500, 0.001, 1]) self.coolingScheme.append([9, 25, 25, 1, 7500, 0.001, 1]) self.coolingScheme.append([10, 10, 10, 1, 7500, 0.001, 1]) self.coolingScheme.append([11, 0.01, 0.01, 1, 7500, 0.0005, 1]) self.coolingStep = None BasePopup.__init__(self, parent, title="Resonance Clouds Analysis", **kw) def body(self, guiFrame): self.specFreqEntry = IntEntry(self, text=self.specFreq, width=8, returnCallback=self.setSpecFreq) self.maxIterEntry = IntEntry(self, text=self.maxIter, width=8, returnCallback=self.setMaxIter) self.mixTimeEntry = FloatEntry(self, text=self.mixTime, width=8, returnCallback=self.setMixTime) self.corrTimeEntry = FloatEntry(self, text=self.corrTime, width=8, returnCallback=self.setCorrTime) self.leakRateEntry = FloatEntry(self, text=self.leakRate, width=8, returnCallback=self.setLeakRate) self.maxIntensEntry = IntEntry(self, text=self.maxIntens, width=8, returnCallback=self.setMaxIntens) self.mdInitTempEntry = FloatEntry(self, text='', returnCallback=self.setMdInitTemp) self.mdFinTempEntry = FloatEntry(self, text='', returnCallback=self.setMdFinTemp) self.mdCoolStepsEntry = IntEntry(self, text='', returnCallback=self.setMdCoolSteps) self.mdSimStepsEntry = IntEntry(self, text='', returnCallback=self.setMdSimSteps) self.mdTauEntry = FloatEntry(self, text='', returnCallback=self.setMdTau) self.mdRepScaleEntry = FloatEntry(self, text='', returnCallback=self.setMdRepScale) guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame0 = LabelFrame(guiFrame, text='Setup peak lists') frame0.grid(row=row, column=0, sticky=Tkinter.NSEW) frame0.grid(row=row, column=0, sticky=Tkinter.NSEW) frame0.grid_columnconfigure(1, weight=1) f0row = 0 label00 = Label(frame0, text='1H-1H NOESY spectrum') label00.grid(row=f0row, column=0, sticky=Tkinter.NW) self.noesyPulldown = PulldownMenu(frame0, entries=self.getNoesys(), callback=self.setNoesy, selected_index=0, do_initial_callback=0) self.noesyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW) f0row += 1 label01 = Label(frame0, text='15N HSQC spectrum') label01.grid(row=f0row, column=0, sticky=Tkinter.NW) self.hsqcPulldown = PulldownMenu(frame0, entries=self.getHsqcs(), callback=self.setHsqc, selected_index=0, do_initial_callback=0) self.hsqcPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW) f0row += 1 label02 = Label(frame0, text='15N HSQC TOCSY spectrum') label02.grid(row=f0row, column=0, sticky=Tkinter.NW) self.tocsyPulldown = PulldownMenu(frame0, entries=self.getTocsys(), callback=self.setTocsy, selected_index=0, do_initial_callback=0) self.tocsyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW) f0row += 1 label02 = Label(frame0, text='15N HSQC NOESY spectrum') label02.grid(row=f0row, column=0, sticky=Tkinter.NW) self.noesy3dPulldown = PulldownMenu(frame0, entries=self.getNoesy3ds(), callback=self.setNoesy3d, selected_index=0, do_initial_callback=0) self.noesy3dPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW) f0row += 1 texts = ['Setup resonances & peaks', 'Show Peaks', 'Show resonances'] commands = [self.setupResonances, self.showPeaks, self.showResonances] self.setupButtons = ButtonList(frame0, expands=1, texts=texts, commands=commands) self.setupButtons.grid(row=f0row, column=0, columnspan=2, sticky=Tkinter.NSEW) f0row += 1 self.label03a = Label(frame0, text='Resonances found: 0') self.label03a.grid(row=f0row, column=0, sticky=Tkinter.NW) self.label03b = Label(frame0, text='NOESY peaks found: 0') self.label03b.grid(row=f0row, column=1, sticky=Tkinter.NW) row += 1 frame1 = LabelFrame(guiFrame, text='Calculate distance constraints') frame1.grid(row=row, column=0, sticky=Tkinter.NSEW) frame1.grid_columnconfigure(3, weight=1) f1row = 0 frame1.grid_rowconfigure(f1row, weight=1) data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate, self.maxIntens ] colHeadings = [ 'Spectrometer\nfrequency', 'Max\niterations', 'Mixing\ntime (ms)', 'Correl.\ntime (ns)', 'Leak\nrate', 'Max\nintensity' ] editWidgets = [ self.specFreqEntry, self.maxIterEntry, self.mixTimeEntry, self.corrTimeEntry, self.leakRateEntry, self.maxIntensEntry, ] editGetCallbacks = [ self.getSpecFreq, self.getMaxIter, self.getMixTime, self.getCorrTime, self.getLeakRate, self.getMaxIntens, ] editSetCallbacks = [ self.setSpecFreq, self.setMaxIter, self.setMixTime, self.setCorrTime, self.setLeakRate, self.setMaxIntens, ] self.midgeParamsMatrix = ScrolledMatrix( frame1, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, maxRows=1, initialCols=5, headingList=colHeadings, callback=None, objectList=[ 'None', ], textMatrix=[ data, ]) self.midgeParamsMatrix.grid(row=f1row, column=0, columnspan=4, sticky=Tkinter.NSEW) f1row += 1 label10 = Label(frame1, text='Benchmark structure') label10.grid(row=f1row, column=0, sticky=Tkinter.NW) self.structurePulldown = PulldownMenu(frame1, entries=self.getStructures(), callback=self.setStructure, selected_index=0, do_initial_callback=0) self.structurePulldown.grid(row=f1row, column=1, sticky=Tkinter.NW) label11 = Label(frame1, text='ADC atom types:') label11.grid(row=f1row, column=2, sticky=Tkinter.NW) self.adcAtomsPulldown = PulldownMenu(frame1, entries=self.getAdcAtomTypes(), callback=self.setAdcAtomTypes, selected_index=0, do_initial_callback=0) self.adcAtomsPulldown.grid(row=f1row, column=3, sticky=Tkinter.NW) f1row += 1 texts = [ 'Calculate distances', 'Show distance\nconstraints', 'Show anti-distance\nconstraints' ] commands = [ self.calculateDistances, self.showConstraints, self.showAntiConstraints ] self.midgeButtons = ButtonList(frame1, expands=1, texts=texts, commands=commands) self.midgeButtons.grid(row=f1row, column=0, columnspan=4, sticky=Tkinter.NSEW) f1row += 1 self.distConstrLabel = Label(frame1, text='Distance constraints:') self.distConstrLabel.grid(row=f1row, column=0, columnspan=2, sticky=Tkinter.NW) self.antiConstrLabel = Label(frame1, text='Anti-distance constraints:') self.antiConstrLabel.grid(row=f1row, column=2, columnspan=2, sticky=Tkinter.NW) row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame2 = LabelFrame(guiFrame, text='Proton cloud molecular dynamics') frame2.grid(row=row, column=0, sticky=Tkinter.NSEW) frame2.grid_columnconfigure(1, weight=1) f2row = 0 frame2.grid_rowconfigure(f2row, weight=1) data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate ] colHeadings = [ 'Step', 'Initial temp.', 'Final temp.', 'Cooling steps', 'MD steps', 'MD tau', 'Rep. scale' ] editWidgets = [ None, self.mdInitTempEntry, self.mdFinTempEntry, self.mdCoolStepsEntry, self.mdSimStepsEntry, self.mdTauEntry, self.mdRepScaleEntry ] editGetCallbacks = [ None, self.getMdInitTemp, self.getMdFinTemp, self.getMdCoolSteps, self.getMdSimSteps, self.getMdTau, self.getMdRepScale ] editSetCallbacks = [ None, self.setMdInitTemp, self.setMdFinTemp, self.setMdCoolSteps, self.setMdSimSteps, self.setMdTau, self.setMdRepScale ] self.coolingSchemeMatrix = ScrolledMatrix( frame2, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, maxRows=9, initialRows=12, headingList=colHeadings, callback=self.selectCoolingStep, objectList=self.coolingScheme, textMatrix=self.coolingScheme) self.coolingSchemeMatrix.grid(row=f2row, column=0, columnspan=4, sticky=Tkinter.NSEW) f2row += 1 texts = ['Move earlier', 'Move later', 'Add step', 'Remove step'] commands = [ self.moveStepEarlier, self.moveStepLater, self.addCoolingStep, self.removeCoolingStep ] self.coolingSchemeButtons = ButtonList(frame2, expands=1, commands=commands, texts=texts) self.coolingSchemeButtons.grid(row=f2row, column=0, columnspan=4, sticky=Tkinter.EW) f2row += 1 label20 = Label(frame2, text='Number of clouds:') label20.grid(row=f2row, column=0, sticky=Tkinter.NW) self.numCloudsEntry = FloatEntry(frame2, text=100, returnCallback=self.setNumClouds, width=10) self.numCloudsEntry.grid(row=f2row, column=1, sticky=Tkinter.NW) label21 = Label(frame2, text='Cloud file prefix:') label21.grid(row=f2row, column=2, sticky=Tkinter.NW) self.filePrefixEntry = Entry(frame2, text='cloud_', returnCallback=self.setFilePrefix, width=10) self.filePrefixEntry.grid(row=f2row, column=3, sticky=Tkinter.NW) f2row += 1 texts = ['Start molecular dynamics', 'Show dynamics progress'] commands = [self.startMd, self.showMdProgress] self.mdButtons = ButtonList(frame2, expands=1, commands=commands, texts=texts) self.mdButtons.grid(row=f2row, column=0, columnspan=4, sticky=Tkinter.NSEW) row += 1 self.bottomButtons = createDismissHelpButtonList(guiFrame, expands=0, help_url=None) self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW) self.setButtonStates() def getStructures(self): names = [ '<None>', ] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): names.append('%s:%d' % (molSystem.name, structure.ensembleId)) return names def setStructure(self, index, name=None): if index < 1: self.structure = None else: structures = [] for molSystem in self.project.molSystems: for structure in molSystem.structureEnsembles: structures.append(structure) self.structure = structures[index - 1] def getAdcAtomTypes(self): return ['HN', 'HN HA', 'HN HA HB'] def setAdcAtomTypes(self, index, name=None): if name is None: name = self.adcAtomsPulldown.getSelected() self.adcAtomTypes = name def startMd(self): self.setNumClouds() self.setFilePrefix() if (self.distanceConstraintList and self.antiDistConstraintList and (self.numClouds > 0) and self.filePrefix): resDict = {} for resonance in self.guiParent.project.currentNmrProject.resonances: resDict[resonance.serial] = resonance resonances = [] for constraint in self.distanceConstraintList.constraints: for item in constraint.items: for fixedResonance in item.resonances: if resDict.get( fixedResonance.resonanceSerial) is not None: resonances.append( resDict[fixedResonance.resonanceSerial]) resDict[fixedResonance.resonanceSerial] = None startMdProcess(self.numClouds, self.distanceConstraintList, resonances, self.coolingScheme, self.filePrefix) #structGen = self.distanceConstraintList.structureGeneration serials = [] for resonance in resonances: serials.append(resonance.serial) clouds = [] for i in range(self.numClouds): clouds.append('%s%3.3d.pdb' % (self.filePrefix, i)) self.guiParent.application.setValues( self.distanceConstraintList.nmrConstraintStore, 'clouds', values=clouds) self.guiParent.application.setValues( self.distanceConstraintList.nmrConstraintStore, 'cloudsResonances', values=serials) # do better than this check for creation def showMdProgress(self): n = 0 m = self.numClouds for i in range(m): pdbFileName = '%s%3.3d.pdb' % (self.filePrefix, i) if os.path.exists(pdbFileName): n += 1 p = n * 100 / float(m) text = 'Done %d of %d clouds (%1.2f)%%' % (n, m, p) showInfo('MD Progress', text) def setFilePrefix(self, text=None): if not text: text = self.filePrefixEntry.get() if text: self.filePrefix = text def setNumClouds(self, n=None, *event): if not n: n = self.numCloudsEntry.get() if n: self.numClouds = int(n) def calculateDistances(self): # setup normalisation factor intensityMax # self.maxIter # what if failure ? resDict = {} for resonance in self.project.currentNmrProject.resonances: resDict[resonance.serial] = resonance self.resonances = self.origResonances intensityFactors = [1.0 for x in range(len(self.resonances))] # optimiseRelaxation will remove unconstrained resonances self.distanceConstraintList = optimiseRelaxation( self.resonances, self.noesyPeaks, intensityMax=self.maxIntens, intensityFactors=intensityFactors, tmix=self.mixTime, sf=self.specFreq, tcor=self.corrTime, rleak=self.leakRate) constrainSpinSystems(self.distanceConstraintList) # for testing calculate distances from structure overrides any resonances: uses assigned ones #(self.distanceConstraintList, self.resonances) = self.cheatForTesting() #self.antiDistConstraintList = self.distanceConstraintList protonNumbs = {'CH3': 3, 'Haro': 2, 'HN': 1, 'H': 1} PI = 3.1415926535897931 GH = 2.6752e4 HB = 1.05459e-27 CONST = GH * GH * GH * GH * HB * HB tc = 1.0e-9 * self.corrTime wh = 2.0 * PI * self.specFreq * 1.0e6 j0 = CONST * tc j1 = CONST * tc / (1.0 + wh * wh * tc * tc) j2 = CONST * tc / (1.0 + 4.0 * wh * wh * tc * tc) #jself = 6.0*j2 + 3.0*j1 + j0 jcross = 6.0 * j2 - j0 if self.distanceConstraintList: constraintStore = self.distanceConstraintList.nmrConstraintStore dict = { 'HN': ['H'], 'HN HA': ['H', 'HA', 'HA1', 'HA2'], 'HN HA HB': ['H', 'HA', 'HA1', 'HA2', 'HB', 'HB2', 'HB3'] } self.antiDistConstraintList = makeNoeAdcs( self.resonances, self.noesyPeakList.dataSource, constraintStore, allowedAtomTypes=dict[self.adcAtomTypes]) if self.structure: N = len(self.resonances) sigmas = [[] for i in range(N)] for i in range(N): sigmas[i] = [0.0 for j in range(N)] for constraint in self.distanceConstraintList.constraints: resonances = list(constraint, findFirstItem().resonances) ri = resDict[resonances[0].resonanceSerial] rj = resDict[resonances[1].resonanceSerial] i = self.resonances.index(ri) j = self.resonances.index(rj) atomSets1 = list(ri.resonanceSet.atomSets) atomSets2 = list(rj.resonanceSet.atomSets) if atomSets1 == atomSets2: ass = list(atomSets1) atomSets1 = [ ass[0], ] atomSets2 = [ ass[-1], ] distance = getAtomSetsDistance(atomSets1, atomSets2, self.structure) r = distance * 1e-8 nhs = protonNumbs[rj.name] sigma = 0.1 * jcross * nhs / (r**6) sigmas[i][j] = sigma constraint.setDetails('Known Dist: %4.3f' % (distance)) #for constraint in self.antiDistConstraintList.constraints: # atomSets1 = list(resonances[0].resonanceSet.atomSets) # atomSets2 = list(resonances[1].resonanceSet.atomSets) # distance = getAtomSetsDistance(atomSets1, atomSets2, self.structure) # constraint.setDetails('Known Dist: %4.3f' % (distance)) fp = open('sigmas.out', 'w') for i in range(N - 1): for j in range(i + 1, N): if sigmas[i][j] != 0.0: fp.write('%3.1d %3.1d %9.2e\n' % (i, j, sigmas[i][j])) #fp.write('\n') fp.close() self.setButtonStates() def cheatForTesting(self, atomSelection='H'): """ Makes a perfect cloud from a structure. """ project = self.project structure = self.guiParent.argumentServer.getStructure() constraintStore = makeNmrConstraintStore(project) distConstraintList = NmrConstraint.DistanceConstraintList( constraintStore) chain = structure.findFirstCoodChain() structureGeneration.hydrogenResonances = [] molSystem = structure.molSystem atomSets = [] resonances = [] i = 0 for resonance in project.currentNmrProject.resonances: if resonance.isotopeCode == '1H': if resonance.resonanceSet: atomSet = resonance.resonanceSet.findFirstAtomSet() atom = atomSet.findFirstAtom() seqId = atom.residue.seqId if (seqId < 9) or (seqId > 78): continue if atom.residue.chain.molSystem is molSystem: if atomSelection == 'methyl': if len(atomSet.atoms) == 3: if atom.residue.ccpCode not in ('Ala', 'Val', 'Ile', 'Leu', 'Thr', 'Met'): continue elif atom.name != 'H': continue elif atomSelection == 'amide': if atom.name != 'H': continue if atom.name == 'H': resonance.name = 'HN' else: resonance.name = 'H' resonances.append(resonance) atomSets.append(list(resonance.resonanceSet.atomSets)) i += 1 print "Found %d atomSets" % (len(atomSets)) weight = 1 adcWeight = 1 constrDict = {} N = len(atomSets) for i in range(N - 1): atomSets0 = atomSets[i] residue0 = atomSets0[0].findFirstAtom().residue.seqId print "R", residue0 for j in range(i + 1, N): if j == i: continue atomSets1 = atomSets[j] dist = getAtomSetsDistance(atomSets0, atomSets1, structure) if not dist: continue if dist < 5.5: fixedResonance0 = getFixedResonance( constraintStore, resonances[i]) fixedResonance1 = getFixedResonance( constraintStore, resonances[j]) constrDict[i] = 1 constrDict[j] = 1 constraint = NmrConstraint.DistanceConstraint( distConstraintList, weight=weight, targetValue=dist, upperLimit=dist + (dist / 10), lowerLimit=dist - (dist / 10), error=dist / 5) item = NmrConstraint.DistanceConstraintItem( constraint, resonances=[fixedResonance0, fixedResonance1]) elif (atomSets1[0].findFirstAtom().name == 'H') and (atomSets0[0].findFirstAtom().name == 'H') and (dist > 7): #else: fixedResonance0 = getFixedResonance( constraintStore, resonances[i]) fixedResonance1 = getFixedResonance( constraintStore, resonances[j]) constrDict[i] = 1 constrDict[j] = 1 constraint = NmrConstraint.DistanceConstraint( distConstraintList, weight=adcWeight, targetValue=75, upperLimit=175, lowerLimit=5.0, error=94.5) item = NmrConstraint.DistanceConstraintItem( constraint, resonances=[fixedResonance0, fixedResonance1]) return (distConstraintList, resonances) def showConstraints(self): if self.distanceConstraintList: self.guiParent.browseConstraints( constraintList=self.distanceConstraintList) def showAntiConstraints(self): if self.antiDistConstraintList: self.guiParent.browseConstraints( constraintList=self.antiDistConstraintList) def showPeaks(self): self.guiParent.viewPeaks(peaks=self.noesyPeaks) def showResonances(self): pass #self.guiParent.viewResonances(resonances=self.resonances) def setupResonances(self): if self.noesyPeakList and self.noesy3dPeakList and self.tocsyPeakList and self.hsqcPeakList: disambiguateNoesyPeaks(self.noesyPeakList, self.noesy3dPeakList, self.tocsyPeakList, self.hsqcPeakList) (self.origResonances, self.noesyPeaks, null) = getCloudsResonanceList(self.guiParent.argumentServer, hsqcPeakList=self.hsqcPeakList, tocsy3dPeakList=self.tocsyPeakList, noesy2dPeakList=self.noesyPeakList) self.setButtonStates() def setButtonStates(self): if self.origResonances: self.label03a.set('Resonances found: %d' % (len(self.origResonances))) if self.noesyPeaks: self.label03b.set('NOESY peaks found: %d' % (len(self.noesyPeaks))) if self.noesyPeakList and self.tocsyPeakList and self.hsqcPeakList: self.setupButtons.buttons[0].enable() else: self.setupButtons.buttons[0].disable() if self.noesyPeaks: self.setupButtons.buttons[1].enable() else: self.setupButtons.buttons[1].disable() if self.origResonances: self.setupButtons.buttons[2].enable() else: self.setupButtons.buttons[2].disable() if self.noesyPeaks and self.origResonances: self.midgeButtons.buttons[0].enable() else: self.midgeButtons.buttons[0].disable() if self.distanceConstraintList: self.midgeButtons.buttons[1].enable() self.distConstrLabel.set( 'Distance constraints: %d' % len(self.distanceConstraintList.constraints)) else: self.distConstrLabel.set('Distance constraints:') self.midgeButtons.buttons[1].disable() if self.antiDistConstraintList: self.antiConstrLabel.set( 'Anti-distance constraints: %d' % len(self.antiDistConstraintList.constraints)) self.midgeButtons.buttons[2].enable() else: self.antiConstrLabel.set('Anti-distance constraints:') self.midgeButtons.buttons[2].disable() if (self.distanceConstraintList and self.antiDistConstraintList and (self.numClouds > 0) and self.filePrefix): self.mdButtons.buttons[0].enable() self.mdButtons.buttons[1].enable() else: self.mdButtons.buttons[0].disable() self.mdButtons.buttons[1].disable() def getNoesys(self): names = [] spectra = getSpectraByType(self.project, '2dNOESY') for spectrum in spectra: for peakList in spectrum.peakLists: name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict[name] = peakList if not self.noesyPeakList: self.noesyPeakList = peakList return names def setNoesy(self, index, name=None): if not name: name = self.noesyPulldown.getSelected() self.noesyPeakList = self.peakListDict[name] self.setButtonStates() def getTocsys(self): names = [] spectra = getSpectraByType(self.project, '3dTOCSY') for spectrum in spectra: for peakList in spectrum.peakLists: name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict[name] = peakList if not self.tocsyPeakList: self.tocsyPeakList = peakList return names def getNoesy3ds(self): names = [] spectra = getSpectraByType(self.project, '3dNOESY') for spectrum in spectra: for peakList in spectrum.peakLists: name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict[name] = peakList if not self.noesy3dPeakList: self.noesy3dPeakList = peakList return names def setTocsy(self, index, name=None): if not name: name = self.tocsyPulldown.getSelected() self.tocsyPeakList = self.peakListDict[name] self.setButtonStates() def setNoesy3d(self, index, name=None): if not name: name = self.noesy3dPulldown.getSelected() self.noesy3dPeakList = self.peakListDict[name] self.setButtonStates() def getHsqcs(self): names = [] spectra = getSpectraByType(self.project, 'HSQC') for spectrum in spectra: for peakList in spectrum.peakLists: name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict[name] = peakList if not self.hsqcPeakList: self.hsqcPeakList = peakList return names def setHsqc(self, index, name=None): if not name: name = self.hsqcPulldown.getSelected() self.hsqcPeakList = self.peakListDict[name] self.setButtonStates() def getMdInitTemp(self, coolingStep): self.mdInitTempEntry.set(coolingStep[1]) def getMdFinTemp(self, coolingStep): self.mdFinTempEntry.set(coolingStep[2]) def getMdCoolSteps(self, coolingStep): self.mdCoolStepsEntry.set(coolingStep[3]) def getMdSimSteps(self, coolingStep): self.mdSimStepsEntry.set(coolingStep[4]) def getMdTau(self, coolingStep): self.mdTauEntry.set(coolingStep[5]) def getMdRepScale(self, coolingStep): self.mdRepScaleEntry.set(coolingStep[6]) def setMdInitTemp(self, event): value = self.mdInitTempEntry.get() if value is not None: self.coolingStep[1] = value self.updateCoolingScheme() def setMdFinTemp(self, event): value = self.mdFinTempEntry.get() if value is not None: self.coolingStep[2] = value self.updateCoolingScheme() def setMdCoolSteps(self, event): value = self.mdCoolStepsEntry.get() if value is not None: self.coolingStep[3] = value self.updateCoolingScheme() def setMdSimSteps(self, event): value = self.mdSimStepsEntry.get() if value is not None: self.coolingStep[4] = value self.updateCoolingScheme() def setMdTau(self, event): value = self.mdTauEntry.get() if value is not None: self.coolingStep[5] = value self.updateCoolingScheme() def setMdRepScale(self, event): value = self.mdRepScaleEntry.get() if value is not None: self.coolingStep[6] = value self.updateCoolingScheme() def selectCoolingStep(self, object, row, col): self.coolingStep = object def moveStepEarlier(self): if self.coolingStep: i = self.coolingStep[0] - 1 if i > 0: coolingStep = self.coolingScheme[i - 1] coolingStep[0] = i + 1 self.coolingStep[0] = i self.coolingScheme[i - 1] = self.coolingStep self.coolingScheme[i] = coolingStep self.updateCoolingScheme() self.coolingSchemeMatrix.hilightObject(self.coolingStep) def moveStepLater(self): if self.coolingStep: i = self.coolingStep[0] - 1 if i < len(self.coolingScheme) - 1: coolingStep = self.coolingScheme[i + 1] coolingStep[0] = i + 1 self.coolingStep[0] = i + 2 self.coolingScheme[i + 1] = self.coolingStep self.coolingScheme[i] = coolingStep self.updateCoolingScheme() self.coolingSchemeMatrix.hilightObject(self.coolingStep) def addCoolingStep(self): i = len(self.coolingScheme) + 1 datum = [i, 3000, 100, 10, 2500, 0.001, 1] self.coolingScheme.append(datum) self.updateCoolingScheme() def removeCoolingStep(self): if self.coolingStep: coolingScheme = [] i = 0 for coolingStep in self.coolingScheme: if coolingStep is not self.coolingStep: i += 1 coolingStep[0] = i coolingScheme.append(coolingStep) self.coolingScheme = coolingScheme self.updateCoolingScheme() def updateCoolingScheme(self): objectList = self.coolingScheme textMatrix = self.coolingScheme self.coolingSchemeMatrix.update(objectList=objectList, textMatrix=textMatrix) def updateMidgeParams(self): data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate, self.maxIntens ] self.midgeParamsMatrix.update(textMatrix=[ data, ]) def getSpecFreq(self, obj): self.specFreqEntry.set(self.specFreq) def getMaxIter(self, obj): self.maxIterEntry.set(self.maxIter) def getMixTime(self, obj): self.mixTimeEntry.set(self.mixTime) def getCorrTime(self, obj): self.corrTimeEntry.set(self.corrTime) def getLeakRate(self, obj): self.leakRateEntry.set(self.leakRate) def getMaxIntens(self, obj): self.maxIntensEntry.set(self.maxIntens) def setSpecFreq(self, event): value = self.specFreqEntry.get() if value is not None: self.specFreq = value self.updateMidgeParams() def setMaxIter(self, event): value = self.maxIterEntry.get() if value is not None: self.maxIter = value self.updateMidgeParams() def setMixTime(self, event): value = self.mixTimeEntry.get() if value is not None: self.mixTime = value self.updateMidgeParams() def setCorrTime(self, event): value = self.corrTimeEntry.get() if value is not None: self.corrTime = value self.updateMidgeParams() def setLeakRate(self, event): value = self.leakRateEntry.get() if value is not None: self.leakRate = value self.updateMidgeParams() def setMaxIntens(self, event): value = self.maxIntensEntry.get() if value is not None: self.maxIntens = value self.updateMidgeParams() def destroy(self): BasePopup.destroy(self)
class CreateShiftListPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'CreateShiftList.html') def __init__(self, parent, project): self.project = project self.peakLists = [] BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Create shift list from peak lists', modal=False, transient=True) def body(self, master): # # Peaklist setup # self.peakListDict = {} for experiment in self.project.currentNmrProject.sortedExperiments(): for dataSource in experiment.sortedDataSources(): for peakList in dataSource.sortedPeakLists(): peakListLabel = "%s:%s:%d:%s" % ( experiment.name, dataSource.name, peakList.serial, peakList.name) self.peakListDict[peakListLabel] = peakList peakListLabels = self.peakListDict.keys() peakListLabels.sort() # # chemical shift list setup # self.shiftListDict = {} self.shiftListDict['None'] = None for shiftList in self.project.currentNmrProject.findAllMeasurementLists( className='ShiftList'): shiftListLabel = "%d:%s" % (shiftList.serial, shiftList.name) self.shiftListDict[shiftListLabel] = shiftList shiftListLabels = self.shiftListDict.keys() shiftListLabels.sort() row = 0 label = Label(master, text="Generation of chemical shift list") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) row += 1 label = Label(master, text="Peak lists:") label.grid(row=row, column=0, sticky=Tkinter.W) self.peakListBox = ScrolledListbox(master, width=50, height=5, selectmode=Tkinter.MULTIPLE, initial_list=peakListLabels) self.peakListBox.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(master, text="Use existing shift list:") label.grid(row=row, column=0, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=shiftListLabels) self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(master, text="Use multiple assignments:") label.grid(row=row, column=0, sticky=Tkinter.W) self.useAllContribs = CheckButton(master) self.useAllContribs.grid(row=row, column=1, sticky=Tkinter.W) # # Setup the default shift error per nucleus # self.defaultShiftError = {} for (nucl, text, defValue) in [('1H', 'proton', '0.002'), ('13C', 'carbon', '0.1'), ('15N', 'nitrogen', '0.1')]: row += 1 label = Label(master, text="Default %s shift error:" % text) label.grid(row=row, column=0, sticky=Tkinter.W) self.defaultShiftError[nucl] = Entry(master, text=defValue) self.defaultShiftError[nucl].grid(row=row, column=1, sticky=Tkinter.W) row += 1 texts = ['Create shift list'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, columnspan=2, column=0) def apply(self): selectedPeakLists = self.peakListBox.getSelectedItems() for peakListLabel in selectedPeakLists: self.peakLists.append(self.peakListDict[peakListLabel]) chemShiftList = self.shiftListDict[self.shiftListSelect.getSelected()] if not chemShiftList: chemShiftListName = askString("Enter chemical shift list name", "New chemical shift list name", '', self) else: chemShiftListName = chemShiftList.name useAllContribs = self.useAllContribs.isSelected() defaultShiftError = {} for nucl in self.defaultShiftError.keys(): defaultShiftError[nucl] = returnFloat( self.defaultShiftError[nucl].get()) listCreated = createChemShifts(self.peakLists, guiParent=self.parent, multiDialog=self.parent.multiDialog, shiftList=chemShiftList, useAllContribs=useAllContribs, defaultShiftError=defaultShiftError, shiftListName=chemShiftListName) if listCreated: showInfo( "Success", "Succesfully created a chemical shift list from peaklist(s)") return True
class RegionSelector(Frame): def __init__(self, parent, label='', world_region=None, view_region=None, orient=Tkinter.HORIZONTAL, allow_resize=True, width=20, callback=None, borderwidth=1, show_text=True, text_color='#000000', text_decimals=2, units_scroll=0.1, pages_scroll=1.0, menu_entries=None, menu_callback=None, min_thickness=None, *args, **kw): self.menu_entries = menu_entries self.myCallback = callback Frame.__init__(self, parent, *args, **kw) self.text_decimals = text_decimals self.label = Label(self, text=label, width=4) self.menu = PulldownMenu(self, callback=menu_callback, entries=menu_entries) self.entry = FloatEntry(self, width=6, returnCallback=self.adjustScrollbar) self.region_scrollbar = RegionScrollbar(self, world_region=world_region, view_region=view_region, orient=orient, allow_resize=allow_resize, width=width, callback=self.doCallback, borderwidth=borderwidth, show_text=show_text, text_color=text_color, text_decimals=text_decimals, units_scroll=units_scroll, pages_scroll=pages_scroll, min_thickness=min_thickness) self.gridAll() def gridAll(self): col = 0 if (self.menu_entries and len(self.menu_entries) > 1): self.menu.grid(row=0, column=col, sticky=Tkinter.EW) col = col + 1 else: self.menu.grid_forget() self.label.grid(row=0, column=col, sticky=Tkinter.EW) col = col + 1 self.entry.grid(row=0, column=col, sticky=Tkinter.EW) self.grid_columnconfigure(col, weight=0) col = col + 1 self.region_scrollbar.grid(row=0, column=col, sticky=Tkinter.NSEW) self.grid_columnconfigure(col, weight=1) col = col + 1 self.grid_columnconfigure(col, weight=0) def setMinThickness(self, min_thickness): self.region_scrollbar.setMinThickness(min_thickness) def setMenuEntries(self, menu_entries): self.menu_entries = menu_entries self.menu.replace(menu_entries) self.gridAll() def getMenuEntry(self): return self.menu.getSelected() def adjustScrollbar(self, *event): try: x = float(self.entry.get()) except: showError('Entry error', 'Need to enter float in scrollbar box') self.setEntry() return (v0, v1) = self.region_scrollbar.view_region d = 0.5 * (v1 - v0) self.region_scrollbar.setViewRegion(x - d, x + d, do_callback=True) def doCallback(self, view_region): if (self.myCallback): self.myCallback(view_region) #print 'doCallback', view_region self.setEntry(view_region) def setEntry(self, view_region=None): if (not view_region): view_region = self.region_scrollbar.view_region (v0, v1) = view_region x = 0.5 * (v0 + v1) s = formatDecimals(x, decimals=self.text_decimals) self.entry.set(s) def __getattr__(self, name): # dispatch everything not defined by RegionSelector to scrollbar widget try: return getattr(self.__dict__['region_scrollbar'], name) except: raise AttributeError, "RegionSelector instance has no attribute '%s'" % name
class SelectionListPopup(TemporaryBasePopup): def __init__(self, parent, selectionList, title = 'Select', text = 'Select', topText = None, dismissText = None, selected = None, selectionDict = None, urlFile = None, dismissButton = True, modal = False): self.selectionList = selectionList self.selectionDict = selectionDict self.text = text self.dismissButton = dismissButton if dismissButton: if dismissText: self.dismissText = dismissText else: self.dismissText = 'dismiss' self.topText = topText self.isSelected = None if not selected: self.selectedIndex = 0 else: self.selectedIndex = self.selectionList.index(selected) if urlFile: self.help_url = joinPath(getHelpUrlDir(),urlFile + '.html') else: self.help_url = None TemporaryBasePopup.__init__(self,parent = parent, title = title, modal = modal, transient=True) def body(self, master): # # Popup window # row = 0 if self.topText: label = Label(master, text= self.topText) label.grid(row=row, column=0, columnspan = 2, sticky=Tkinter.EW) row = row + 1 label = Label(master, text= self.text) label.grid(row=row, column=0, sticky=Tkinter.EW) self.menu = PulldownMenu(master, entries = self.selectionList, selected_index = self.selectedIndex) self.menu.grid(row=row, column=1, sticky=Tkinter.E, ipadx = 20) row = row + 1 texts = [ 'OK' ] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here if self.dismissButton: buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text = self.dismissText, help_url=self.help_url) else: buttons = createHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan = 3) def apply(self): self.isSelected = self.menu.getSelected() if self.selectionDict: self.selection = self.selectionDict[self.isSelected] else: self.selection = self.isSelected return True
class EditSymmetryPopup(BasePopup): def __init__(self, parent, project): self.parent = parent self.ccpnProject = project self.hProject = project.currentHaddockProject self.molPartner = None self.molecules = [] self.symmetrySet = None self.symmetryOp = None self.symmetryCode = None self.waiting = False BasePopup.__init__(self, parent=parent, title='Symmetry Operations') self.font = 'Helvetica 12' self.setFont() def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) frame = LabelFrame(guiFrame, text='Options') frame.grid(row=0,column=0,sticky='ew') frame.grid_columnconfigure(5, weight=1) # Choose type of symmetry set to define or change (if allready present in the model) self.molLabel = Label(frame, text='Symmetry Operator:') self.molLabel.grid(row=0,column=2,sticky='w') self.symmCodePulldown = PulldownMenu(frame, callback=self.setSymmCode, entries=['NCS','C2','C3','C5'], do_initial_callback=False) self.symmCodePulldown.grid(row=0,column=3,sticky='w') frame = LabelFrame(guiFrame, text='Symmetry Operations') frame.grid(row=1,column=0,sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) self.molSysPulldown = PulldownMenu(self, callback=self.setMolSystem, do_initial_callback=False) self.chainSelect = MultiWidget(self, CheckButton, callback=self.setChains, minRows=0, useImages=False) self.segStartEntry = IntEntry(self, returnCallback=self.setSegStart, width=6) self.segLengthEntry = IntEntry(self, returnCallback=self.setSegLength, width=6) headings = ['#','Symmetry\noperator','Mol System','Chains','Start\nresidue','Segment\nlength'] editWidgets = [None, None, self.molSysPulldown, self.chainSelect, self.segStartEntry, self.segLengthEntry] editGetCallbacks = [None, None, self.getMolSystem, self.getChains, self.getSegStart, self.getSegLength] editSetCallbacks = [None, self.setSymmCode, self.setMolSystem, self.setChains, self.setSegStart, self.setSegLength] self.symmetryMatrix = ScrolledMatrix(frame,headingList=headings, callback=self.selectSymmetry, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.symmetryMatrix.grid(row=0,column=0,sticky='nsew') texts = ['Add Symmetry Set','Remove Symmetry Set'] commands = [self.addSymmetrySet,self.removeSymmetrySet] self.buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, expands=True) self.buttonList.grid(row=2,column=0,sticky='ew') self.updateMolPartners() self.notify(self.registerNotify) #Temporary report of parameters print self.molSystem print self.molecules print self.symmetrySet print self.symmetryOp print self.symmetryCode def getMolSystem(self, partner): """Select molecular system from list of molsystems stored in the project""" names = []; index = -1 molSystem = partner.molSystem molSystems = self.ccpnProject.sortedMolSystems() if molSystems: names = [ms.code for ms in molSystems] if molSystem not in molSystems: molSystem = molSystems[0] index = molSystems.index(molSystem) self.molSysPulldown.setup(names, index) def getChains(self, partner): names = [] values = [] molSystem = partner.molSystem if molSystem: for chain in molSystem.sortedChains(): names.append(chain.code) if not partner.chains: values.append(True) elif partner.findFirstChain(chain=chain): values.append(True) else: values.append(False) self.chainSelect.set(values=values,options=names) else: showWarning('Warning','Set Mol System or ensemble first',parent=self) self.symmetryMatrix.keyPressEscape() def getSegLength(self, symmetryOp): if symmetryOp and symmetryOp.segmentLength: self.segLengthEntry.set(symmetryOp.segmentLength) def getSegStart(self): pass def setMolSystem(self, partner, name=None): """Get all molsystems as stored in the project as list""" index = self.molSysPulldown.getSelectedIndex() molSystems = self.ccpnProject.sortedMolSystems() if molSystems: molSystem = molSystems[index] self.molPartner.molSystem = molSystem chains = molSystem.sortedChains() if (not self.molPartner.chains) and chains: setPartnerChains(self.molPartner,chains) self.updateAllAfter() def setChains(self, obj): """Get the list of chains for the selected molsystem""" if self.molPartner and self.molPartner.molSystem: if obj is not None: chains = self.molPartner.molSystem.sortedChains() values = self.chainSelect.get() chains = [chains[i] for i in range(len(values)) if values[i]] setPartnerChains(self.molPartner,chains) self.symmetryMatrix.keyPressEscape() self.updateAllAfter() def setSegLength(self, event): value = self.segLengthEntry.get() or 1 self.symmetryOp.segmentLength = value def setSegStart(self): pass def setSymmCode(self, index, name=None): self.symmetryCode = self.symmCodePulldown.getSelected() def selectSymmetry(self, obj, row, col): self.symmetryOp = obj self.updateMolSysPulldown() def notify(self, notifyFunc): for func in ('__init__', 'delete', 'setSymmetryCode','setSegmentLength'): notifyFunc(self.updateAllAfter, 'molsim.Symmetry.Symmetry', func) for func in ('__init__', 'delete','setfirstSeqId'): notifyFunc(self.updateAllAfter, 'molsim.Symmetry.Segment', func) def addSymmetrySet(self): if not self.ccpnProject.molSystems: showWarning('Warning','No molecular systems present in CCPN project',parent=self) return molSystem = self.ccpnProject.findFirstMolSystem() partner = self.hProject.newHaddockPartner(code=molSystem.code, molSystem=molSystem) setPartnerChains(partner, molSystem.chains) self.updateAllAfter() def removeSymmetrySet(self): pass def updateAllAfter(self, obj=None): if self.waiting: return else: self.waiting = True self.after_idle(self.updateSymmetries, self.updateMolPartners) def updateMolPartners(self): textMatrix = [] objectList = [] for partner in self.hProject.sortedHaddockPartners(): datum = [partner.code, self.symmetryCode, partner.molSystem.code, ','.join([c.chain.code for c in partner.chains]), partner.autoHistidinePstate and 'Yes' or 'No', partner.isDna and 'Yes' or 'No'] objectList.append(partner) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.updateMolSysPulldown() def updateMolSysPulldown(self): names = [] index = -1 partners = self.hProject.sortedHaddockPartners() if partners: if self.molPartner not in partners: self.molPartner = partners[0] names = ['Partner %s' % p.code for p in partners] index = partners.index(self.molPartner) else: self.molPartner = None self.molSysPulldown.setup(names, index) def updateSymmetries(self): textMatrix = []; objectList = [] if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: chains = []; segments = [] length = symmetryOp.segmentLength for segment in symmetryOp.sortedSegments(): code = segment.chainCode chain = self.molSystem.findFirstChain(code=code) if chain: chains.append(code) seqId = segment.firstSeqId residue1 = chain.findFirstResidue(seqId=seqId) residue2 = chain.findFirstResidue(seqId=seqId+length-1) segments.append('%s:%d-%d' % (code,residue1.seqCode,residue2.seqCode)) datum = [symmetryOp.serial, symmetryOp.symmetryCode, length, '\n'.join(chains), '\n'.join(segments)] objectList.append(symmetryOp) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self)
class AtomSelectPopup(TemporaryBasePopup): def __init__(self, parent, matchName, chemAtomList, chemAtomDict, propagateList, ccpCode, shifts, matchType='Resonance', matchInfoPopup=None, selectedIndex=4, title='Select resonance atom match', helpUrl='AtomSelect.html', headerLines=None, modal=False): self.help_url = joinPath(getHelpUrlDir(), helpUrl) # Constructor doesn't do much except call body # The parent is self.parent (parent of the popup) self.chemAtomOrSets = None self.propagate = None self.matchName = matchName self.matchType = matchType self.matchInfoPopup = matchInfoPopup self.chemAtomList = chemAtomList self.chemAtomDict = chemAtomDict self.propagateList = propagateList self.ccpCode = ccpCode self.shifts = shifts self.guiParent = parent self.headerLines = headerLines self.selectedIndex = selectedIndex # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__(self, parent=parent, title=title, modal=modal, transient=True) def showAllAtoms(self): self.chemAtomList = self.chemAtomDict.keys() self.chemAtomList.sort() self.menu.replace(self.chemAtomList) def body(self, master): # # Popup window # row = 0 if self.headerLines: for headerLine in self.headerLines: label = Label(master, text=headerLine) label.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) row += 1 label = Label(master, text="Residue type '%s'" % self.ccpCode) label.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) row = row + 1 matchNameString = "[%s]" % self.matchName if self.matchInfoPopup: label = Label(master, text="%s:" % self.matchType) label.grid(row=row, column=0, sticky=Tkinter.E) button = Tkinter.Button( master, text=matchNameString, command=lambda: self.matchInfoPopup(self, self.matchName), fg='blue') button.grid(row=row, column=1, columnspan=2) else: label = Label(master, text="%s:" % self.matchType) label.grid(row=row, column=0, sticky=Tkinter.E) label = Label(master, text=matchNameString, fg='blue') label.grid(row=row, column=1, columnspan=2) if self.shifts: row = row + 1 label = Label(master, text="(shifts: %s ppm)" % self.shifts) label.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW) row = row + 1 label = Label(master, text="Pick atom:") label.grid(row=row, column=0, sticky=Tkinter.E) self.menu = PulldownMenu(master, entries=self.chemAtomList) self.menu.grid(row=row, column=1, columnspan=2, ipadx=20) row = row + 1 label = Label(master, text="Propagate\nmapping to:") label.grid(row=row, column=0, sticky=Tkinter.E) self.propagateMenu = PulldownMenu(master, entries=self.propagateList, selected_index=self.selectedIndex) self.propagateMenu.grid(row=row, column=1, columnspan=2) row = row + 1 texts = ['OK', 'Show all atoms'] commands = [ self.ok, self.showAllAtoms ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Do not link', dismiss_cmd=self.doNotLink, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3) def apply(self): selectionText = self.menu.getSelected() if selectionText == '<None>': return False self.chemAtomOrSets = self.chemAtomDict[selectionText] self.propagate = self.propagateMenu.getSelectedIndex() return True def doNotLink(self): self.propagate = self.propagateMenu.getSelectedIndex() self.close()
class MidgePopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.project = parent.getProject() self.waiting = 0 self.specFreq = 800.13 self.maxIter = 15 self.mixTime = 60 self.corrTime = 11.5 self.leakRate = 2.0 self.ratioHD = 0.9 self.peakListDict = {} self.peakListDict3d = {} self.noesyPeakList = None self.noesy3dPeakList = None self.carbonLabel = 0 self.nitrogenLabel = 1 self.noesyPeakList1 = None self.noesyPeakList2 = None self.noesyPeakList3 = None self.noesyPeakList3d = None self.resonances = None self.noesyPeaks = None self.distanceConstraintList = None self.antiDistConstraintList = None self.adcAtomTypes = None self.structure = None BasePopup.__init__(self, parent, title="Relaxation Matrix Optimisation", **kw) def body(self, guiFrame): self.specFreqEntry = IntEntry(self, text=self.specFreq, width=8, returnCallback=self.setSpecFreq) self.maxIterEntry = IntEntry(self, text=self.maxIter, width=8, returnCallback=self.setMaxIter) self.mixTimeEntry = FloatEntry(self, text=self.mixTime, width=8, returnCallback=self.setMixTime) self.corrTimeEntry = FloatEntry(self, text=self.corrTime, width=8, returnCallback=self.setCorrTime) self.leakRateEntry = FloatEntry(self, text=self.leakRate, width=8, returnCallback=self.setLeakRate) guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) row = 0 labelFrame0 = LabelFrame(guiFrame, text='Input data') labelFrame0.grid(row=row, column=0, sticky=Tkinter.NSEW) labelFrame0.grid_columnconfigure(3, weight=1) label = Label(labelFrame0, text='Assigned NOESY spectrum') label.grid(row=0, column=0, sticky=Tkinter.NW) self.noesyPulldown = PulldownMenu(labelFrame0, entries=self.getNoesys(), callback=self.setNoesy, selected_index=0, do_initial_callback=0) self.noesyPulldown.grid(row=0, column=1, sticky=Tkinter.NW) label = Label(labelFrame0, text='H/D ratio: ') label.grid(row=0, column=2, sticky=Tkinter.NW) self.ratioHDEntry = FloatEntry(labelFrame0, text=self.ratioHD, width=6) self.ratioHDEntry.grid(row=0, column=3, sticky=Tkinter.NW) label = Label(labelFrame0, text='NOESY spectrum 1:') label.grid(row=1, column=0, sticky=Tkinter.NW) self.tmix1Pulldown = PulldownMenu(labelFrame0, entries=self.getNoesys(), callback=self.setNoesy1, selected_index=-0, do_initial_callback=0) self.tmix1Pulldown.grid(row=1, column=1, sticky=Tkinter.NW) label = Label(labelFrame0, text='Tmix (ms): ') label.grid(row=1, column=2, sticky=Tkinter.NW) self.tmix1Entry = FloatEntry(labelFrame0, text=60, width=6) self.tmix1Entry.grid(row=1, column=3, sticky=Tkinter.NW) label = Label(labelFrame0, text='NOESY spectrum 2:') label.grid(row=2, column=0, sticky=Tkinter.NW) self.tmix2Pulldown = PulldownMenu(labelFrame0, entries=self.getNoesys(), callback=self.setNoesy2, selected_index=0, do_initial_callback=0) self.tmix2Pulldown.grid(row=2, column=1, sticky=Tkinter.NW) label = Label(labelFrame0, text='Tmix (ms): ') label.grid(row=2, column=2, sticky=Tkinter.NW) self.tmix2Entry = FloatEntry(labelFrame0, text=120, width=6) self.tmix2Entry.grid(row=2, column=3, sticky=Tkinter.NW) label = Label(labelFrame0, text='NOESY spectrum 3:') label.grid(row=3, column=0, sticky=Tkinter.NW) self.tmix3Pulldown = PulldownMenu(labelFrame0, entries=self.getNoesys(), callback=self.setNoesy3, selected_index=0, do_initial_callback=0) self.tmix3Pulldown.grid(row=3, column=1, sticky=Tkinter.NW) label = Label(labelFrame0, text='Tmix (ms): ') label.grid(row=3, column=2, sticky=Tkinter.NW) self.tmix3Entry = FloatEntry(labelFrame0, text=200, width=6) self.tmix3Entry.grid(row=3, column=3, sticky=Tkinter.NW) label = Label(labelFrame0, text='3D NOESY:') label.grid(row=4, column=0, sticky=Tkinter.NW) self.noesy3dPulldown = PulldownMenu(labelFrame0, entries=self.getNoesys3d(), callback=self.setNoesy3d, selected_index=0, do_initial_callback=0) self.noesy3dPulldown.grid(row=4, column=1, sticky=Tkinter.NW) label10 = Label(labelFrame0, text='Num peaks:') label10.grid(row=5, column=0, sticky=Tkinter.NW) self.numPeaksLabel = Label(labelFrame0, text='0') self.numPeaksLabel.grid(row=5, column=1, sticky=Tkinter.NW) label11 = Label(labelFrame0, text='Num resonances:') label11.grid(row=5, column=2, sticky=Tkinter.NW) self.numResonancesLabel = Label(labelFrame0, text='0') self.numResonancesLabel.grid(row=5, column=3, sticky=Tkinter.NW) row += 1 labelFrame1 = LabelFrame(guiFrame, text='Parameters') labelFrame1.grid(row=row, column=0, sticky=Tkinter.NSEW) labelFrame1.grid_columnconfigure(3, weight=1) label = Label(labelFrame1, text='15N labelled sample:') label.grid(row=0, column=0, sticky=Tkinter.NW) self.nitrogenSelect = CheckButton(labelFrame1, callback=self.setNitrogenLabel) self.nitrogenSelect.grid(row=0, column=1, sticky=Tkinter.W) self.nitrogenSelect.set(1) label = Label(labelFrame1, text='13C labelled sample:') label.grid(row=0, column=2, sticky=Tkinter.NW) self.carbonSelect = CheckButton(labelFrame1, callback=self.setCarbonLabel) self.carbonSelect.grid(row=0, column=3, sticky=Tkinter.W) self.carbonSelect.set(0) labelFrame1.grid_rowconfigure(1, weight=1) data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate ] colHeadings = [ 'Spectrometer\nfrequency', 'Max\niterations', 'Mixing\ntime (ms)', 'Correl.\ntime (ns)', 'Leak\nrate' ] editWidgets = [ self.specFreqEntry, self.maxIterEntry, self.mixTimeEntry, self.corrTimeEntry, self.leakRateEntry, ] editGetCallbacks = [ self.getSpecFreq, self.getMaxIter, self.getMixTime, self.getCorrTime, self.getLeakRate, ] editSetCallbacks = [ self.setSpecFreq, self.setMaxIter, self.setMixTime, self.setCorrTime, self.setLeakRate, ] self.midgeParamsMatrix = ScrolledMatrix( labelFrame1, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, maxRows=1, initialCols=5, headingList=colHeadings, callback=None, objectList=[ 'None', ], textMatrix=[ data, ]) self.midgeParamsMatrix.grid(row=1, column=0, columnspan=4, sticky=Tkinter.NSEW) label10 = Label(labelFrame1, text='Benchmark structure') label10.grid(row=2, column=0, sticky=Tkinter.NW) self.structurePulldown = PulldownMenu(labelFrame1, entries=self.getStructures(), callback=self.setStructure, selected_index=0, do_initial_callback=0) self.structurePulldown.grid(row=2, column=1, sticky=Tkinter.NW) label11 = Label(labelFrame1, text='ADC atom types:') label11.grid(row=2, column=2, sticky=Tkinter.NW) self.adcAtomsPulldown = PulldownMenu(labelFrame1, entries=self.getAdcAtomTypes(), callback=self.setAdcAtomTypes, selected_index=0, do_initial_callback=0) self.adcAtomsPulldown.grid(row=2, column=3, sticky=Tkinter.NW) row += 1 labelFrame2 = LabelFrame(guiFrame, text='Output') labelFrame2.grid(row=row, column=0, sticky=Tkinter.NSEW) labelFrame2.grid_columnconfigure(3, weight=1) label20 = Label(labelFrame2, text='Distance constraints:') label20.grid(row=0, column=0, sticky=Tkinter.NW) self.distConstrLabel = Label(labelFrame2, text='0') self.distConstrLabel.grid(row=0, column=1, sticky=Tkinter.NW) label21 = Label(labelFrame2, text='Anti-distance constraints:') label21.grid(row=0, column=2, sticky=Tkinter.NW) self.antiConstrLabel = Label(labelFrame2, text='0') self.antiConstrLabel.grid(row=0, column=3, sticky=Tkinter.NW) texts = [ 'Calculate distances', 'Show distance\nconstraints', 'Show anti-distance\nconstraints' ] commands = [ self.calculateDistances, self.showConstraints, self.showAntiConstraints ] self.midgeButtons = ButtonList(labelFrame2, expands=1, texts=texts, commands=commands) self.midgeButtons.grid(row=1, column=0, columnspan=4, sticky=Tkinter.NSEW) row += 1 self.bottomButtons = createDismissHelpButtonList(guiFrame, expands=0, help_url=None) self.bottomButtons.grid(row=row, column=0, columnspan=4, sticky=Tkinter.EW) self.getPeaks() self.getResonances() self.update() self.geometry('600x400') def setCarbonLabel(self, boolean): self.carbonLabel = boolean def setNitrogenLabel(self, boolean): self.nitrogenLabel = boolean def update(self): if self.resonances and ( (self.noesyPeaks and self.noesyPeakList1 and self.noesyPeakList2 and self.noesyPeakList3) or self.noesyPeakList3d): self.midgeButtons.buttons[0].enable() else: self.midgeButtons.buttons[0].disable() if self.distanceConstraintList: self.distConstrLabel.set( str(len(self.distanceConstraintList.constraints))) self.midgeButtons.buttons[1].enable() else: self.distConstrLabel.set('') self.midgeButtons.buttons[1].disable() if self.antiDistConstraintList: self.antiConstrLabel.set( str(len(self.antiDistConstraintList.constraints))) self.midgeButtons.buttons[2].enable() else: self.antiConstrLabel.set('') self.midgeButtons.buttons[2].disable() if self.resonances: self.numResonancesLabel.set(str(len(self.resonances))) else: self.numResonancesLabel.set('') if self.noesyPeaks: self.numPeaksLabel.set(str(len(self.noesyPeaks))) else: self.numPeaksLabel.set('') def getStructures(self): names = [ '<None>', ] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): names.append('%s:%d' % (molSystem.name, structure.ensembleId)) return names def setStructure(self, index, name=None): if index < 1: self.structure = None else: structures = [] for molSystem in self.project.molSystems: for structure in molSystem.structureEnsembles: structures.append(structure) self.structure = structures[index - 1] def getAdcAtomTypes(self): return ['<None>', 'HN', 'HN HA', 'HN HA HB'] def setAdcAtomTypes(self, index, name=None): if name is None: name = self.adcAtomsPulldown.getSelected() if name == '<None>': name = None self.adcAtomTypes = name def getResonances(self): resonanceDict = {} if self.noesyPeaks: for peak in self.noesyPeaks: for peakDim in peak.peakDims: for contrib in peakDim.peakDimContribs: resonanceDict[contrib.resonance] = 1 # TBD: Set resonance.name for typing self.resonances = resonanceDict.keys() def getPeaks(self): if self.noesyPeakList: self.noesyPeaks = self.noesyPeakList.sortedPeaks() def calculateDistances(self): resonances = list(self.resonances) resDict = {} for resonance in resonances: resDict[resonance.serial] = resonance ratioHD = self.ratioHDEntry.get() or self.ratioHD tmix1 = self.tmix1Entry.get() or 60 tmix2 = self.tmix2Entry.get() or 120 tmix3 = self.tmix3Entry.get() or 200 data = [(tmix1, self.noesyPeakList1), (tmix2, self.noesyPeakList2), (tmix3, self.noesyPeakList3)] data.sort() mixingTimes = [x[0] for x in data] peakLists = [x[1] for x in data] # get a clean, symmetric and normalised NOE matrix noeMatrix = getNoeMatrixFromPeaks(self.noesyPeaks, resonances, peakLists, mixingTimes, ratioHD=ratioHD, analysis=self.guiParent) # optimiseRelaxation will remove unconstrained resonances self.distanceConstraintList, resonances = optimiseRelaxation( resonances, noeMatrix, self.mixTime, self.specFreq, self.corrTime, self.leakRate, self.carbonLabel, self.nitrogenLabel, maxIter=self.maxIter) #constrainSpinSystems(self.distanceConstraintList) # for testing calculate distances from structure overrides any resonances: uses assigned ones #(self.distanceConstraintList, self.resonances) = self.cheatForTesting() #self.antiDistConstraintList = self.distanceConstraintList protonNumbs = {'CH3': 3, 'Haro': 2, 'HN': 1, 'H': 1} PI = 3.1415926535897931 GH = 2.6752e4 HB = 1.05459e-27 CONST = GH * GH * GH * GH * HB * HB tc = 1.0e-9 * self.corrTime wh = 2.0 * PI * self.specFreq * 1.0e6 j0 = CONST * tc j1 = CONST * tc / (1.0 + wh * wh * tc * tc) j2 = CONST * tc / (1.0 + 4.0 * wh * wh * tc * tc) #jself = 6.0*j2 + 3.0*j1 + j0 jcross = 6.0 * j2 - j0 if self.distanceConstraintList and self.noesyPeakList: constraintHead = self.distanceConstraintList.nmrConstraintStore if self.adcAtomTypes: adcDict = { 'HN': ['H'], 'HN HA': ['H', 'HA', 'HA1', 'HA2'], 'HN HA HB': ['H', 'HA', 'HA1', 'HA2', 'HB', 'HB2', 'HB3'] } allowedAtomTypes = adcDict[self.adcAtomTypes] print "Making ADCs" self.antiDistConstraintList = makeNoeAdcs( resonances[:], self.noesyPeakList.dataSource, constraintHead, allowedAtomTypes=allowedAtomTypes) print "Done ADCs" if self.structure: N = len(self.resonances) sigmas = [[] for i in range(N)] for i in range(N): sigmas[i] = [0.0 for j in range(N)] for constraint in self.distanceConstraintList.constraints: item = constraint.findFirstItem() resonances = list(item.resonances) ri = resDict[resonances[0].resonanceSerial] rj = resDict[resonances[1].resonanceSerial] i = self.resonances.index(ri) j = self.resonances.index(rj) atomSets1 = list(ri.resonanceSet.atomSets) atomSets2 = list(rj.resonanceSet.atomSets) if atomSets1 == atomSets2: ass = list(atomSets1) atomSets1 = [ ass[0], ] atomSets2 = [ ass[-1], ] distance = getAtomSetsDistance(atomSets1, atomSets2, self.structure) r = distance * 1e-8 nhs = protonNumbs[rj.name] sigma = 0.1 * jcross * nhs / (r**6) sigmas[i][j] = sigma constraint.setOrigData(distance) self.update() def showConstraints(self): if self.distanceConstraintList: self.guiParent.browseConstraints( constraintList=self.distanceConstraintList) def showAntiConstraints(self): if self.antiDistConstraintList: self.guiParent.browseConstraints( constraintList=self.antiDistConstraintList) def getNoesys3d(self): peakLists = getThroughSpacePeakLists(self.project) names = [ '<None>', ] for peakList in peakLists: spectrum = peakList.dataSource if spectrum.numDim != 3: continue name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict3d[name] = peakList if not self.noesyPeakList: self.noesyPeakList = peakList return names def getNoesys(self): peakLists = getThroughSpacePeakLists(self.project) names = [ '<None>', ] for peakList in peakLists: spectrum = peakList.dataSource name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name, peakList.serial) names.append(name) self.peakListDict[name] = peakList if not self.noesyPeakList: self.noesyPeakList = peakList return names def setNoesy(self, index, name=None): if not name: name = self.noesyPulldown.getSelected() if name == '<None>': self.noesyPeakList = None else: self.noesyPeakList = self.peakListDict[name] self.getPeaks() self.getResonances() self.update() def setNoesy1(self, index, name=None): if not name: name = self.tmix1Pulldown.getSelected() if name != '<None>': self.noesyPeakList1 = self.peakListDict[name] else: self.noesyPeakList1 = None self.update() def setNoesy2(self, index, name=None): if not name: name = self.tmix2Pulldown.getSelected() if name != '<None>': self.noesyPeakList2 = self.peakListDict[name] else: self.noesyPeakList2 = None self.update() def setNoesy3(self, index, name=None): if not name: name = self.tmix3Pulldown.getSelected() if name != '<None>': self.noesyPeakList3 = self.peakListDict[name] else: self.noesyPeakList3 = None self.update() def setNoesy3d(self, index, name=None): if not name: name = self.noesy3dPulldown.getSelected() if name != '<None>': self.noesyPeakList3d = self.peakListDict3d[name] self.noesyPeaks = self.noesyPeakList3d.sortedPeaks() else: self.noesyPeakList3d = None self.noesyPeaks = [] self.getResonances() self.update() def updateMidgeParams(self): data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate ] self.midgeParamsMatrix.update(textMatrix=[ data, ]) def getSpecFreq(self, obj): self.specFreqEntry.set(self.specFreq) def getMaxIter(self, obj): self.maxIterEntry.set(self.maxIter) def getMixTime(self, obj): self.mixTimeEntry.set(self.mixTime) def getCorrTime(self, obj): self.corrTimeEntry.set(self.corrTime) def getLeakRate(self, obj): self.leakRateEntry.set(self.leakRate) def setSpecFreq(self, event): value = self.specFreqEntry.get() if value is not None: self.specFreq = value self.updateMidgeParams() def setMaxIter(self, event): value = self.maxIterEntry.get() if value is not None: self.maxIter = value self.updateMidgeParams() def setMixTime(self, event): value = self.mixTimeEntry.get() if value is not None: self.mixTime = value self.updateMidgeParams() def setCorrTime(self, event): value = self.corrTimeEntry.get() if value is not None: self.corrTime = value self.updateMidgeParams() def setLeakRate(self, event): value = self.leakRateEntry.get() if value is not None: self.leakRate = value self.updateMidgeParams() def destroy(self): BasePopup.destroy(self)
class EditSymmetryPopup(BasePopup): def __init__(self, parent, project): self.parent = parent self.project = project self.singleMolecule = True self.molSystem = None self.molecules = [] self.symmetrySet = None self.symmetryOp = None self.waiting = False BasePopup.__init__(self, parent=parent, title='Symmetry Operations') def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) frame = LabelFrame(guiFrame, text='Options') frame.grid(row=0, column=0, sticky='ew') frame.grid_columnconfigure(5, weight=1) label = Label(frame, text='MolSystem:') label.grid(row=0, column=0, sticky='w') self.molSystemPulldown = PulldownMenu(frame, callback=self.selectMolSystem) self.molSystemPulldown.grid(row=0, column=1, sticky='w') self.molLabel = Label(frame, text='Molecule:') self.molLabel.grid(row=0, column=2, sticky='w') self.moleculePulldown = PulldownMenu(frame, callback=self.selectMolecule) self.moleculePulldown.grid(row=0, column=3, sticky='w') label = Label(frame, text='Same Molecule Symmetry:') label.grid(row=0, column=4, sticky='w') self.molSelect = CheckButton(frame, callback=self.toggleSingleMolecule) self.molSelect.grid(row=0, column=5, sticky='w') self.molSelect.set(self.singleMolecule) frame = LabelFrame(guiFrame, text='Symmetry Operations') frame.grid(row=1, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) self.symmCodePulldown = PulldownMenu(self, callback=self.setSymmCode, do_initial_callback=False) self.segLengthEntry = IntEntry(self, returnCallback=self.setSegLength, width=6) self.setChainMulti = MultiWidget(self, CheckButton, callback=self.setChains, minRows=0, useImages=False) self.setSegmentMulti = MultiWidget(self, IntEntry, callback=self.setSegments, minRows=0, useImages=False) editWidgets = [ None, self.symmCodePulldown, self.segLengthEntry, self.setChainMulti, self.setSegmentMulti ] editGetCallbacks = [ None, self.getSymmCode, self.getSegLength, self.getChains, self.getSegments ] editSetCallbacks = [ None, self.setSymmCode, self.setSegLength, self.setChains, self.setSegments ] headings = [ '#', 'Symmetry\nType', 'Segment\nLength', 'Chains', 'Segment\nPositions' ] self.symmetryMatrix = ScrolledMatrix(frame, headingList=headings, callback=self.selectSymmetry, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.symmetryMatrix.grid(row=0, column=0, sticky='nsew') texts = ['Add Symmetry Op', 'Remove Symmetrey Op'] commands = [self.addSymmOp, self.removeSymmOp] buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, expands=True) buttonList.grid(row=2, column=0, sticky='ew') self.updateMolSystems() self.updateMolecules() self.updateSymmetriesAfter() self.notify(self.registerNotify) def open(self): self.updateMolSystems() self.updateMolecules() self.updateSymmetriesAfter() BasePopup.open(self) def notify(self, notifyFunc): for func in ('__init__', 'delete', 'setSymmetryCode', 'setSegmentLength'): notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Symmetry', func) for func in ('__init__', 'delete', 'setfirstSeqId'): notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Segment', func) def getSymmCode(self, symmetryOp): """Get allowed symmetry operators from the model""" symmetryOpCodes = symmetryOp.parent.metaclass.container.getElement( 'SymmetryOpCode').enumeration index = 0 if symmetryOp.symmetryCode in symmetryOpCodes: index = symmetryOpCodes.index(symmetryOp.symmetryCode) self.symmCodePulldown.setup(symmetryOpCodes, index) def getSegLength(self, symmetryOp): if symmetryOp and symmetryOp.segmentLength: self.segLengthEntry.set(symmetryOp.segmentLength) def getChains(self, symmetryOp): chains = [] for chain in self.molSystem.chains: if chain.residues: if chain.molecule in self.molecules: chains.append(chain.code) chains.sort() values = [] for chain in chains: if symmetryOp.findFirstSegment(chainCode=chain): values.append(True) else: values.append(False) self.setChainMulti.set(values=values, options=chains) def getSegments(self, symmetryOp): values = [] names = [] if symmetryOp: for segment in symmetryOp.sortedSegments(): names.append(segment.chainCode) values.append(segment.firstSeqId) n = len(values) self.setSegmentMulti.maxRows = n self.setSegmentMulti.minRows = n self.setSegmentMulti.set(values=values, options=names) def setSymmCode(self, index, name=None): """Set the symmetry code as NCS,C2,C3,C4,C5,C6""" if self.symmetryOp: symmCode = self.symmCodePulldown.getSelected() self.symmetryOp.symmetryCode = symmCode def setSegLength(self, event): value = self.segLengthEntry.get() or 1 self.symmetryOp.segmentLength = value def setChains(self, obj): if self.symmetryOp and obj: codes = self.setChainMulti.options segment = self.symmetryOp.findFirstSegment() values = self.setChainMulti.get() if segment: seqId0 = segment.firstSeqId else: seqId0 = 1 for i in range(len(values)): segment = self.symmetryOp.findFirstSegment(chainCode=codes[i]) if segment and not values[i]: segment.delete() elif values[i] and not segment: chain = self.molSystem.findFirstChain(code=codes[i]) residue = chain.findFirstResidue(seqid=seqId0) if residue: seqId = seqId0 else: residue = chain.sortedResidues()[0] seqId = residue.seqId residue2 = chain.findFirstResidue( seqid=seqId + self.symmetryOp.segmentLength) if not residue2: residue2 = chain.sortedResidues()[-1] self.symmetryOp.segmentLength = (residue2.seqId - seqId) + 1 segment = self.symmetryOp.newSegment(chainCode=codes[i], firstSeqId=seqId) self.symmetryMatrix.keyPressEscape() def setSegments(self, obj): if self.symmetryOp and obj: segments = self.symmetryOp.sortedSegments() values = self.setSegmentMulti.get() for i in range(len(values)): seqCode = values[i] chain = self.molSystem.findFirstChain( code=segments[i].chainCode) residue = chain.findFirstResidue(seqCode=seqCode) if residue: seqId = residue.seqId if segments[i].firstSeqId != seqId: segments[i].delete() segments[i] = self.symmetryOp.newSegment( chainCode=chain.code, firstSeqId=seqId) self.symmetryMatrix.keyPressEscape() def selectSymmetry(self, obj, row, col): self.symmetryOp = obj def addSymmOp(self): if self.molSystem: if not self.symmetrySet: self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet( ) if not self.symmetrySet: objGen = self.project.newMolSystemSymmetrySet self.symmetrySet = objGen(symmetrySetId=1, molSystem=self.molSystem) segLen = len(self.molSystem.findFirstChain().residues) symmetry = self.symmetrySet.newSymmetry(segmentLength=segLen) def removeSymmOp(self): if self.symmetryOp: self.symmetryOp.delete() def toggleSingleMolecule(self, boolean): self.singleMolecule = not boolean self.updateMolSystems() self.updateMolecules() def setMolecules(self, molecules): self.molecules = molecules if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: for segment in symmetryOp.segments: chain = self.molSystem.findFirstChain( code=segment.chainCode) if chain and (chain.molecule not in molecules): segment.delete() def selectMolecule(self, index, name): self.setMolecules(self.getMolecules()[index]) self.updateSymmetries() def getMolecules(self): counts = {} moleculesList = [] for chain in self.molSystem.chains: molecule = chain.molecule counts[molecule] = counts.get(molecule, 0) + 1 molecules = counts.keys() if self.singleMolecule: for molecule in counts: if counts[molecule] > 1: moleculesList.append([ molecule, ]) elif molecules: molecules = counts.keys() n = len(molecules) moleculesList.append([ molecules[0], ]) if n > 1: moleculesList.append([ molecules[1], ]) moleculesList.append([molecules[0], molecules[1]]) if n > 2: moleculesList.append([ molecules[2], ]) moleculesList.append([molecules[1], molecules[2]]) moleculesList.append( [molecules[0], molecules[1], molecules[2]]) if n > 3: moleculesList.append([ molecules[3], ]) moleculesList.append([molecules[0], molecules[3]]) moleculesList.append([molecules[1], molecules[3]]) moleculesList.append([molecules[2], molecules[3]]) moleculesList.append( [molecules[0], molecules[1], molecules[3]]) moleculesList.append( [molecules[0], molecules[2], molecules[3]]) moleculesList.append( [molecules[1], molecules[2], molecules[3]]) moleculesList.append( [molecules[0], molecules[1], molecules[2], molecules[3]]) return moleculesList def updateMolecules(self): names = [] index = -1 moleculesList = self.getMolecules() if moleculesList: if self.molecules not in moleculesList: self.setMolecules(moleculesList[0]) self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet( ) index = moleculesList.index(self.molecules) names = [] for molecules in moleculesList: names.append(','.join([mol.name for mol in molecules])) else: self.molecules = [] self.moleculePulldown.setup(names, index) def selectMolSystem(self, index, name): self.molSystem = self.getMolSystems()[index] self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet() self.updateSymmetries() def getMolSystems(self): molSystems = [] for molSystem in self.project.sortedMolSystems(): n = len(molSystem.chains) if self.singleMolecule and (n > 1): molSystems.append(molSystem) elif n > 0: molSystems.append(molSystem) return molSystems def updateMolSystems(self): names = [] index = -1 molSystems = self.getMolSystems() if molSystems: if self.molSystem not in molSystems: self.molSystem = molSystems[0] index = molSystems.index(self.molSystem) names = [ms.code for ms in molSystems] else: self.molSystem = None self.molSystemPulldown.setup(names, index) def updateSymmetriesAfter(self, obj=None): if self.waiting: return else: self.waiting = True self.after_idle(self.updateSymmetries) def updateSymmetries(self): textMatrix = [] objectList = [] if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: chains = [] segments = [] length = symmetryOp.segmentLength for segment in symmetryOp.sortedSegments(): code = segment.chainCode chain = self.molSystem.findFirstChain(code=code) if chain: chains.append(code) seqId = segment.firstSeqId residue1 = chain.findFirstResidue(seqId=seqId) residue2 = chain.findFirstResidue(seqId=seqId + length - 1) segments.append( '%s:%d-%d' % (code, residue1.seqCode, residue2.seqCode)) datum = [ symmetryOp.serial, symmetryOp.symmetryCode, length, '\n'.join(chains), '\n'.join(segments) ] objectList.append(symmetryOp) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self)
class LinkResonancesPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'LinkResonances.html') def __init__(self, parent, formatNamesList, formatNamesDict, title='Link resonances setup'): self.guiParent = parent self.formatNamesList = formatNamesList self.formatNamesDict = formatNamesDict self.status = False TemporaryBasePopup.__init__(self, parent=parent, title=title, modal=False, transient=False) def body(self, master): row = 0 label = Label(master, text='File format reference:') label.grid(row=row, column=0, sticky=Tkinter.E) self.menu = PulldownMenu(master, entries=self.formatNamesList) self.menu.grid(row=row, column=1, sticky=Tkinter.E, ipadx=20) row = row + 1 label = Label(master, text='Try to link unrecognized atom names') label.grid(row=row, column=0, sticky=Tkinter.E) self.linkRes = CheckButton(master, selected=True) self.linkRes.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Try IUPAC names (as backup)') label.grid(row=row, column=0, sticky=Tkinter.E) self.iupacNames = CheckButton(master) self.iupacNames.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Use ambiguous name information') label.grid(row=row, column=0, sticky=Tkinter.E) self.useAmb = CheckButton(master) self.useAmb.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Complete stereospecific assignment') label.grid(row=row, column=0, sticky=Tkinter.E) self.allStereo = CheckButton(master) self.allStereo.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Force shift merges') label.grid(row=row, column=0, sticky=Tkinter.E) self.shiftMerge = CheckButton(master) self.shiftMerge.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Status other atom for all single prochiral atoms') label.grid(row=row, column=0, sticky=Tkinter.E) self.allSingleProchiral = PulldownMenu( master, entries=['Unknown', 'Same information', 'Always ignore']) self.allSingleProchiral.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label( master, text='Status other atom for all possibly equivalent single atoms') label.grid(row=row, column=0, sticky=Tkinter.E) self.allSinglePossEquiv = PulldownMenu( master, entries=['Unknown', 'Always equivalent', 'Always ignore']) self.allSinglePossEquiv.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label( master, text= 'Automatically connect ambiguous resonances to stereospecific ones' ) label.grid(row=row, column=0, sticky=Tkinter.E) self.connStereo = CheckButton(master) self.connStereo.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Use minimal number of popups') label.grid(row=row, column=0, sticky=Tkinter.E) self.minimalPopups = CheckButton(master) self.minimalPopups.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label(master, text='Verbose output') label.grid(row=row, column=0, sticky=Tkinter.E) self.verbose = CheckButton(master, selected=True) self.verbose.grid(row=row, column=1, sticky=Tkinter.W) row = row + 1 label = Label( master, text= 'Warning: it is recommended you save your project first,\nin case linkResonances is interrupted (this might corrupt the data).', fg='red') label.grid(row=row, column=0, columnspan=2, ipady=15, sticky=Tkinter.EW) row = row + 1 texts = ['Link resonances to atoms'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3) def apply(self): self.assignFormat = self.formatNamesDict[self.menu.getSelected()] self.globalStereoAssign = self.allStereo.isSelected() self.useIupacMatching = self.iupacNames.isSelected() self.useLinkResonancePopup = self.linkRes.isSelected() self.minimalPrompts = self.minimalPopups.isSelected() self.verbose = self.verbose.isSelected() self.forceShiftMerge = self.shiftMerge.isSelected() self.useAmbiguity = self.useAmb.isSelected() self.autoConnectStereo = self.connStereo.isSelected() self.setSingleProchiral = self.allSingleProchiral.getSelected() self.setSinglePossEquiv = self.allSinglePossEquiv.getSelected() self.status = True return True
class GroupChemShiftsPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'GroupChemShifts.html') def __init__(self, parent, project): # # Info for writing file... # self.groupText = {} # # Set up molSystem information # self.project = project self.molSysList = list(project.sortedMolSystems()) self.molSystems = None self.molSysLabelList = [] self.molSysLabelDict = {} self.molSysRelationDict = {} molSysLabel = 'All molSystems' if self.setChainLabels(molSysLabel, self.molSysList): self.molSysLabelList.append(molSysLabel) self.molSysLabelDict[molSysLabel] = self.molSysList for molSys in self.molSysList: molSysLabel = '%s' % molSys.code if self.setChainLabels(molSysLabel, [molSys]): self.molSysLabelList.append(molSysLabel) self.molSysLabelDict[molSysLabel] = [molSys] if not self.molSysLabelList: showWarning('Warning', 'No chemical shift lists available! Exiting...') return # # Some initializing... # self.chains = None self.shiftList = None self.shiftListLabel = None self.results = None # modal = true means that it won't continue unless this one returns value BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Group chemical shift values', modal=False, transient=True) def setChainLabels(self, molSysLabel, molSysList): # # Set up chain information # chainLabelList = [] chainLabelDict = {} chainLabelShiftListDict = {} self.molSysRelationDict[molSysLabel] = [ chainLabelList, chainLabelDict, chainLabelShiftListDict ] chains = [] for molSys in molSysList: chains.extend(list(molSys.sortedChains())) chainLabel = 'All chains' if self.setShiftListLabels(chainLabel, chains, self.molSysRelationDict[molSysLabel][2]): self.molSysRelationDict[molSysLabel][0].append(chainLabel) self.molSysRelationDict[molSysLabel][1][chainLabel] = chains for chain in chains: chainLabel = "'%s' (mol. '%s')" % (chain.code, chain.molecule.name) if self.setShiftListLabels( chainLabel, [chain], self.molSysRelationDict[molSysLabel][2]): self.molSysRelationDict[molSysLabel][0].append(chainLabel) self.molSysRelationDict[molSysLabel][1][chainLabel] = [chain] return self.molSysRelationDict[molSysLabel][0] def setShiftListLabels(self, chainLabel, chains, chainLabelShiftListDict): # # Set up chemical shift list information (slooooww so done at start) # shiftLists = [] shiftListCount = {} resonanceTracker = [] shiftListLabels = [] shiftListLabelsDict = {} atomCount = 0 for chain in chains: for residue in chain.residues: for atom in residue.atoms: atomCount += 1 if atom.atomSet: for resonanceSet in atom.atomSet.resonanceSets: for resonance in resonanceSet.resonances: if resonance in resonanceTracker: continue resonanceTracker.append(resonance) for shift in resonance.shifts: if shift.parentList not in shiftLists: shiftLists.append(shift.parentList) shiftListCount[shift.parentList] = 0 shiftListCount[shift.parentList] += 1 for shiftList in shiftLists: percentage = (shiftListCount[shift.parentList] * 100.0) / atomCount shiftListLabel = "%d:%s (%.1f%%)" % (shiftList.serial, shiftList.name, percentage) shiftListLabels.append(shiftListLabel) shiftListLabelsDict[shiftListLabel] = shiftList chainLabelShiftListDict[chainLabel] = [ shiftListLabels, shiftListLabelsDict ] return shiftListLabels def body(self, master): # # Setup header # row = 0 self.columnSpan = 3 label = Label( master, text= 'Select molecular system, chains and chemical shift list to be analyzed:' ) label.grid(row=row, column=0, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 self.molSysSelect = PulldownMenu(master, entries=self.molSysLabelList, callback=self.setupChains) self.molSysSelect.grid(row=row, column=0, sticky=Tkinter.W) self.chainSelect = PulldownMenu(master, entries=self.chainLabelList, callback=self.setupShiftList) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=self.shiftListLabels, callback=self.setupPercentageFrame, do_initial_callback=False) self.shiftListSelect.grid(row=row, column=2, sticky=Tkinter.W) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 master.grid_rowconfigure(row, weight=1) for i in range(self.columnSpan): master.grid_columnconfigure(i, weight=1) self.percentageFrame = ScrolledFrame(master, height=180, doExtraConfig=False) self.percentageFrame.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.NSEW) self.percentageFrameRow = row self.percentageFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 master.grid_rowconfigure(row, weight=1) self.resultsFrame = ScrolledFrame(master, height=180, doExtraConfig=False) self.resultsFrame.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.NSEW) self.resultsFrameRow = row self.resultsFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 texts = ['Recalculate', 'Write to file'] commands = [ self.recalc, self.writeFile ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) self.shiftListSelect.callback(0, self.shiftListLabels[0]) def setupChains(self, listIndex, molSysLabel): molSystems = self.molSysLabelDict[molSysLabel] if self.molSystems == molSystems: return self.molSystems = molSystems self.chainLabelList = self.molSysRelationDict[molSysLabel][0] self.chainLabelDict = self.molSysRelationDict[molSysLabel][1] self.chainLabelShiftListDict = self.molSysRelationDict[molSysLabel][2] if hasattr(self, 'chainSelect'): self.chains = None self.chainSelect.callback(0, self.chainLabelList[0]) def setupShiftList(self, listIndex, chainLabel): chains = self.chainLabelDict[chainLabel] if self.chains == chains: return self.chains = chains # # Reset the pulldown menu # if hasattr(self, 'chainSelect'): self.chainSelect.replace(self.chainLabelList) # # Set up chemical shift lists # self.shiftListLabels = self.chainLabelShiftListDict[chainLabel][0] self.shiftListLabelsDict = self.chainLabelShiftListDict[chainLabel][1] if hasattr(self, 'percentageFrame'): self.shiftList = None self.shiftListLabel = None self.setupPercentageFrame(0, self.shiftListLabels[0]) def setupPercentageFrame(self, listIndex, shiftListLabel): if self.shiftListLabel == shiftListLabel: return self.shiftList = self.shiftListLabelsDict[shiftListLabel] self.shiftListLabel = shiftListLabel # # Reset chemical shift groups... # self.shiftGroupsList = [] for i in range(1, 10): shiftGroupLabel = 'Group_%s' % i self.shiftGroupsList.append(shiftGroupLabel) # # Reset the pulldown menu # if hasattr(self, 'shiftListSelect'): if hasattr(self.shiftListSelect, 'entries') and tuple(self.shiftListLabels) != tuple( self.shiftListSelect.entries): # HACK # otherwise can get infinite recursion but even with above could # if no self.shiftListLabels because of "None" entry in PulldownMenu self.shiftListSelect.replace(self.shiftListLabels) self.shiftListSelect.setSelected(shiftListLabel) # # Reset frame... # self.percentageFrame.destroy() self.percentageFrame = ScrolledFrame(self.percentageFrameMaster, height=180, doExtraConfig=False) self.percentageFrame.grid(row=self.percentageFrameRow, columnspan=self.columnSpan, sticky=Tkinter.NSEW) # # Recalculate results # self.results = makeChemShiftSelections(self.parent, self.chains, self.shiftList) resultKeys = self.results.keys() resultKeys.sort() # # Set up the information # frameRow = 0 frame = self.percentageFrame.frame self.shiftGroupObjects = {} for resultKey in resultKeys: allAtoms = self.results[resultKey][0] shiftAtoms = self.results[resultKey][1] percentage = shiftAtoms * 100.0 / allAtoms label = Label(frame, text=resultKey) label.grid(row=frameRow, column=0, sticky=Tkinter.W) label = Label(frame, text="%.1f%%" % percentage) label.grid(row=frameRow, column=1, sticky=Tkinter.W) label = Label(frame, text="(%d/%d)" % (shiftAtoms, allAtoms)) label.grid(row=frameRow, column=2, sticky=Tkinter.W) self.shiftGroupObjects[resultKey] = PulldownMenu( frame, entries=self.shiftGroupsList) self.shiftGroupObjects[resultKey].grid(row=frameRow, column=3, sticky=Tkinter.E) frameRow += 1 return True def recalc(self): groups = {} groupsInfo = {} for resultKey in self.shiftGroupObjects: group = self.shiftGroupObjects[resultKey].getSelected() if not groups.has_key(group): groups[group] = [] groupsInfo[group] = [0, 0] (allAtoms, shiftAtoms) = self.results[resultKey] groupsInfo[group][0] += allAtoms groupsInfo[group][1] += shiftAtoms groups[group].append(resultKey) # # Reset frame... # self.resultsFrame.destroy() self.resultsFrame = ScrolledFrame(self.resultsFrameMaster, height=180, doExtraConfig=False) self.resultsFrame.grid(row=self.resultsFrameRow, columnspan=self.columnSpan, sticky=Tkinter.NSEW) # # Set info in lower frame # frameRow = 0 frame = self.resultsFrame.frame groupKeys = groups.keys() groupKeys.sort() self.groupText = {} for group in groupKeys: percentage = groupsInfo[group][1] * 100.0 / groupsInfo[group][0] label = Label(frame, text=group) label.grid(row=frameRow, column=0, sticky=Tkinter.W) label = Label(frame, text=groups[group][0]) label.grid(row=frameRow, column=1, sticky=Tkinter.W) label = Label(frame, text="%.1f%%" % percentage) label.grid(row=frameRow, column=2, sticky=Tkinter.W) label = Label(frame, text="(%d/%d)" % (groupsInfo[group][1], groupsInfo[group][0])) label.grid(row=frameRow, column=3, sticky=Tkinter.W) self.groupText[group] = "%-10s %-20s %8.1f%% (%d/%d)%s" % ( group, groups[group][0], percentage, groupsInfo[group][1], groupsInfo[group][0], newline) frameRow += 1 for otherResultKey in groups[group][1:]: label = Label(frame, text=otherResultKey) label.grid(row=frameRow, column=2, sticky=Tkinter.W) self.groupText[group] += "%-10s %-20s%s" % ('', otherResultKey, newline) frameRow += 1 return True def writeFile(self): filePopup = FormatFilePopup(self, component='text') if filePopup.fileSelected: groupKeys = self.groupText.keys() groupKeys.sort() fout = open(filePopup.file, 'w') fout.write("Project: %s" % self.project.name + newline) fout.write("Molsystems: %s" % self.molSysSelect.getSelected() + newline) fout.write("Chains: %s" % self.chainSelect.getSelected() + newline) fout.write("Shiftlist: %s" % self.shiftListSelect.getSelected() + newline * 2) for group in groupKeys: fout.write(self.groupText[group]) print "Wrote file %s..." % filePopup.file def apply(self): return True
class TableExportPopup(BasePopup): def __init__(self, parent, headings, entries, title='', file='', *args, **kw): headings = [heading.replace('\n', ' ') for heading in headings] if (headings[0].lower() == 'number'): self.addNumber = False else: self.addNumber = True headings.insert(0, 'Number') if (not title): title = 'Export data' self.exportSelection = parent.tableExportSelection self.headings = headings self.entries = entries self.file = file kw['title'] = title kw['transient'] = True kw['modal'] = True BasePopup.__init__(self, parent=parent, *args, **kw) def body(self, master): master.grid_columnconfigure(2, weight=1) row = 0 label = Label(master, text='Data to export:') label.grid(row=row, column=0, columnspan=3, sticky=Tkinter.W) self.check_buttons = {} i = 0 for heading in self.headings: row = row + 1 isSelected = self.exportSelection.get(row, True) self.check_buttons[i] = c = CheckButton( master, selected=isSelected, callback=self.toggleCheckButton) c.grid(row=row, column=1) label = Label(master, text=heading) label.grid(row=row, column=2, sticky=Tkinter.W) i += 1 row = row + 1 button = Button(master, text='File:', command=self.findFile) button.grid(row=row, column=0, sticky=Tkinter.W) self.file_entry = Entry(master, text=self.file, width=30) self.file_entry.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW) row = row + 1 label = Label(master, text='Format:') label.grid(row=row, column=0, sticky=Tkinter.W) self.format_menu = PulldownMenu(master, entries=exportFormats) self.format_menu.grid(row=row, column=1, columnspan=2, sticky=Tkinter.W) row = row + 1 master.grid_rowconfigure(row, weight=1) texts = ['Save'] commands = [self.ok] buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel') buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) def toggleCheckButton(self, isSelected): for i in self.check_buttons.keys(): self.exportSelection[i] = self.check_buttons[i].get() def apply(self): file = self.file_entry.get() format = self.format_menu.getSelected() join = exportJoin[format] n = 0 headings = [] for heading in self.headings: if self.check_buttons[n].get(): headings.append(n) n += 1 if (not headings): showError('Nothing selected', 'No data selected to export.', parent=self) return False try: fp = open(file, 'w') except IOError, e: showError('File error', str(e)) return False for n in headings: if (n != headings[0]): fp.write(join) fp.write(self.headings[n].encode('utf-8')) fp.write('\n') m = 0 for data in self.entries: if data: for n in headings: if (n != headings[0]): fp.write(join) if (self.addNumber): if (n == 0): x = m + 1 else: x = data[n - 1] else: x = data[n] if (type(x) == type(float(1))): if (x == 0): t = '0' elif ((abs(x) > 10000) or (abs(x) < 0.001)): t = '%6.5e' % x else: t = '%6.5f' % x else: t = str(x) fp.write(t) fp.write('\n') m = m + 1 fp.close() return True