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 __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 __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)
class ImportFormatComponentPopup(GenericFormatPopup): help_url = joinPath(getHelpUrlDir(),'ImportFormatComponent.html') def setImportExportFlag(self): self.importExportFlag = 'import' self.titleText = "Project '%s': " % self.project.name + '%s %s %s' % (self.format,self.component,self.importExportFlag)
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 TextOutputPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'TextOutput.html') def __init__(self, parent, title='Text output'): BasePopup.__init__(self, parent=parent, title=title, modal=False, transient=False) def body(self, master): self.text = ScrolledText(master) self.text.pack(side=Tkinter.TOP, expand=Tkinter.YES, fill=Tkinter.BOTH) texts = ['Save text'] commands = [self.saveText] buttons = createHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.pack() def saveText(self): fileSelectPopup = FileSelectPopup( self, file_types=[ FileType('Text', ['*.txt', '*.out', '*.text']), FileType('All', ['*']) ], title='Select text output save file') fileName = fileSelectPopup.getFile() if fileName: writeFile = 1 if os.path.exists(fileName): if not showYesNo('Overwrite file', 'Overwrite existing file %s?' % fileName): writeFile = 0 if writeFile: fout = open(fileName, 'w') fout.write(self.text.text_area.getText()) fout.close() def apply(self): return True
class ChemCompSelectionPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ChemCompSelection.html') def __init__(self, parent, project, **keywds): self.project = project self.keywds = keywds origCode = self.keywds['origCode'] del self.keywds['origCode'] TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % project.name + "ChemComp selection for code '%s'" % origCode, modal=False, transient=False, width=200) def body(self, master): self.frame = ChemCompFrame(master, self.project, **self.keywds) self.frame.pack(side=Tkinter.TOP, expand=Tkinter.YES, fill=Tkinter.BOTH) texts = ['OK'] commands = [self.ok] buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel', help_url=self.help_url) buttons.pack() def apply(self): if self.frame.getSelectedChemComp(): return True else: showInfo( 'No selection', 'Please select a chemCompVar from the bottom half of the window, or press Cancel to quit.' ) return False
def __init__(self, parent, valueList, valueInfo, title = 'Entry list', topText = 'Enter values', dismissText = None, urlFile = None, dismissButton = True, conversionFunc = None, modal = False): self.valueList = valueList self.valueInfo = valueInfo self.values = [] self.dismissButton = dismissButton self.conversionFunc = conversionFunc if dismissButton: if dismissText: self.dismissText = dismissText else: self.dismissText = 'dismiss' self.topText = topText 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)
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 DataDimRefSelectByPeakDimPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'DataDimRefSelectByPeakDim.html') def __init__(self, parent, dataSource, peaks, order=None): self.dataSource = dataSource self.numDim = len(self.dataSource.dataDims) self.peaks = peaks self.dataDimRefs = [] self.order = order[self.numDim] TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % dataSource.root.name + "DataDimRef selection for PeakDims", modal=False, transient=True) def body(self, master): # # Initialize # # # Get chem shift range # peakChemShiftRange = [] if not self.peaks: return elif hasattr(self.peaks[0], 'ppm'): peakUnit = 'ppm' elif hasattr(self.peaks[0], 'point'): peakUnit = 'point' else: return for peak in self.peaks: peakInfo = getattr(peak, peakUnit) for dim in range(0, len(peakInfo)): if len(peakChemShiftRange) < dim + 1: peakChemShiftRange.append([999999, -999999]) if peakChemShiftRange[dim][0] > peakInfo[dim]: peakChemShiftRange[dim][0] = peakInfo[dim] if peakChemShiftRange[dim][1] < peakInfo[dim]: peakChemShiftRange[dim][1] = peakInfo[dim] # # Make datadimref lists # dataDimRefList = [] self.dataDimRefDict = {} dataDimRefSelection = [] for i in self.order: dataDim = self.dataSource.sortedDataDims()[i] if dataDim.dim == 1: addInfo = " (acqu)" else: addInfo = "" for dataDimRef in dataDim.dataDimRefs: # Note: key for dataDimRef is expDimRef! isotopeString = string.join(dataDimRef.expDimRef.isotopeCodes, dirsep) selectionString = "Dim %d, nucl %s, refValue %s%s" % ( dataDim.dim, isotopeString, dataDimRef.refValue, addInfo) # In principle this could go wrong if one expDim has two expDimRefs with same isotopelist # (but what would be the use? Is this a good constraint?) dataDimRefList.append(selectionString) self.dataDimRefDict[selectionString] = dataDimRef dataDimRefSelection.append(dataDimRefList[-1]) # # Add on a None dimension if necessary # if self.numDim < len(peakChemShiftRange): dataDimRefSelection.append('None') dataDimRefList.append('None') self.dataDimRefDict['None'] = None # # Popup info # # # Header labels # row = 0 label = Label(master, text="Peak dim") label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text="Chem. shift range") label.grid(row=row, column=1, sticky=Tkinter.EW) # TODO: add in peak dim column headers if known (for nmrView for example) label = Label(master, text="DataDimRef selection") label.grid(row=row, column=2, sticky=Tkinter.EW) # # Selection per peakDim # self.dataDimRefMenu = [] for peakDim in range(0, len(peakChemShiftRange)): row = row + 1 label = Label(master, text=str(peakDim)) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text="%.3f - %.3f %s" % (peakChemShiftRange[peakDim][0], peakChemShiftRange[peakDim][1], peakUnit)) label.grid(row=row, column=1, sticky=Tkinter.EW) if peakDim < len(dataDimRefList): selectedIndex = dataDimRefList.index( dataDimRefSelection[peakDim]) else: selectedIndex = len(dataDimRefList) - 1 self.dataDimRefMenu.append( PulldownMenu(master, entries=dataDimRefList, selected_index=selectedIndex)) self.dataDimRefMenu[-1].grid(row=row, column=2, sticky=Tkinter.E, ipadx=20) 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, columnspan=3) def apply(self): for peakDim in range(0, len(self.dataDimRefMenu)): dataDimRef = self.dataDimRefDict[ self.dataDimRefMenu[peakDim].getSelected()] if dataDimRef and self.dataDimRefs.count(dataDimRef) > 0: self.dataDimRefs = [] return False self.dataDimRefs.append(dataDimRef) if (len(self.dataDimRefs) - self.dataDimRefs.count(None)) != self.numDim: self.dataDimRefs = [] return False return True
class ChainExportPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ChainExport.html') def __init__(self, parent, ccpChainLabelDict, ccpChainSeqIDCodes, requireChainCode): # Constructor doesn't do much except call body # The parent is self.parent (parent of the popup) self.chain = None self.ccpChainLabelDict = ccpChainLabelDict self.ccpChainSeqIDCodes = ccpChainSeqIDCodes self.requireChainCode = requireChainCode self.exportChainCode = {} self.exportFirstSeqCode = {} project = self.ccpChainLabelDict.values()[0].root # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Export chains', modal=False, transient=True) def body(self, master): # # Setup header # row = 0 label = Label(master, text="Data model", fg='blue') label.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) label = Label(master, text="Export") label.grid(row=row, column=3, columnspan=2, sticky=Tkinter.EW) row += 1 label = Label(master, text="Sequence ID (code)", fg='blue') label.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW) row += 1 label = Label(master, text="Ccp chain code", fg='blue') label.grid(row=row, column=0, sticky=Tkinter.W) label = Label(master, text="start", fg='blue') label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text="end", fg='blue') label.grid(row=row, column=2, sticky=Tkinter.EW) column = 3 columnspan = 2 if self.requireChainCode: label = Label(master, text=self.requireChainCode) label.grid(row=row, column=column, sticky=Tkinter.W) column += 1 columnspan -= 1 label = Label(master, text="Sequence code start") label.grid(row=row, column=column, columnspan=columnspan, sticky=Tkinter.W) # # Setup list of ccp chains labels # ccpChainLabels = self.ccpChainLabelDict.keys() ccpChainLabels.sort() # # Currently only linking start in ccp chain (ONLY ONE!) to start in chain read in from file # Assuming sequential order thereafter. # for ccpChainLabel in ccpChainLabels: row = row + 1 chain = self.ccpChainLabelDict[ccpChainLabel] ccpCodeLow = "%d (%d)" % ( self.ccpChainSeqIDCodes[ccpChainLabel][0][0], self.ccpChainSeqIDCodes[ccpChainLabel][1][0]) ccpCodeHigh = "%d (%d)" % ( self.ccpChainSeqIDCodes[ccpChainLabel][0][-1], self.ccpChainSeqIDCodes[ccpChainLabel][1][-1]) label = Label(master, text=ccpChainLabel, fg='blue') label.grid(row=row, column=0, sticky=Tkinter.W) label = Label(master, text=ccpCodeLow, fg='blue') label.grid(row=row, column=1, sticky=Tkinter.W) label = Label(master, text=ccpCodeHigh, fg='blue') label.grid(row=row, column=2, sticky=Tkinter.W) column = 3 columnspan = 2 suggestedFirstSeqCode = str( self.ccpChainSeqIDCodes[ccpChainLabel][1][0]) if self.requireChainCode: if self.requireChainCode == 'molecule name': chainCodeText = chain.molecule.name width = 20 else: chainCodeText = chain.code width = 4 self.exportChainCode[chain] = Entry(master, text=chainCodeText, width=width) self.exportChainCode[chain].grid(row=row, column=column, sticky=Tkinter.W) column += 1 columnspan -= 1 suggestedFirstSeqCode = '1' self.exportFirstSeqCode[chain] = Entry(master, text=suggestedFirstSeqCode, width=4) self.exportFirstSeqCode[chain].grid(row=row, column=column, columnspan=columnspan, sticky=Tkinter.W) 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, columnspan=4) def apply(self): self.chainDict = {} exportSeqCodeRanges = {} for ccpChainLabel in self.ccpChainLabelDict.keys(): chain = self.ccpChainLabelDict[ccpChainLabel] # # Get the first seq code for export (always necessary) # exportFirstSeqCode = self.exportFirstSeqCode[chain].get() # # Check if integer # if str(returnInt(exportFirstSeqCode)) == exportFirstSeqCode: exportFirstSeqCode = returnInt(exportFirstSeqCode) else: showError("Error", "Sequence codes have to be integers!", self) return False # # If single chain export or chain already used, make sure doesn't fall within range other seqCodes # if self.requireChainCode: exportChainCode = self.exportChainCode[chain].get() else: exportChainCode = None # # Set ranges # seqLength = len(self.ccpChainSeqIDCodes[ccpChainLabel][0]) if not exportSeqCodeRanges.has_key(exportChainCode): exportSeqCodeRanges[exportChainCode] = [[ exportFirstSeqCode, exportFirstSeqCode + seqLength - 1 ]] checkChainCodes = 0 else: # # Check chain seqcodes # for (lowSeqID, highSeqID) in exportSeqCodeRanges[exportChainCode]: if highSeqID >= exportFirstSeqCode >= lowSeqID: # # Illegal! For same chain anyway... # showError( "Error", "Overlapping sequence code numbers within the same export chain - try changing them.", self) return False exportSeqCodeRanges[exportChainCode].append( [exportFirstSeqCode, exportFirstSeqCode + seqLength - 1]) self.chainDict[chain] = [exportChainCode, exportFirstSeqCode] return True
class AutoAssignProjectInfoPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'AutoAssignProjectInfo.html') def __init__(self, parent, project, autoAssignProjectFile): self.project = project self.guiParent = parent self.autoAssignProjectFile = autoAssignProjectFile self.validSelection = False self.peakLists = [] for nmrExp in self.project.currentNmrProject.sortedExperiments(): for ds in nmrExp.sortedDataSources(): for pl in ds.sortedPeakLists(): self.peakLists.append(pl) if not self.peakLists: raise ('No peak lists available!') (self.peakNameList, self.peakNameDict) = createSelection(self.peakLists) self.peakNameList.insert(0, 'None') self.peakNameDict['None'] = None BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Write AutoAssign project file', modal=True, transient=True) def body(self, master): self.geometry('600x400') columnspan = 5 row = 0 label = Label(master, text="AutoAssign project file setup window.") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.W) # # Set up the spectra # row += 1 label = Label(master, text="Spectrum type") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) label = Label(master, text="CCPN peak list") label.grid(row=row, column=2, columnspan=2, sticky=Tkinter.W) label = Label(master, text="Phase") # TODO What's this? label.grid(row=row, column=4, sticky=Tkinter.W) self.spectrumSelectWidget = {} self.spectrumPhaseWidget = {} for i in range(len(self.autoAssignProjectFile.defaultSpectra)): row += 1 specType = self.autoAssignProjectFile.defaultSpectra[i][0] if i == 0: labelText = "%s (root)" % specType else: labelText = "%s" % specType label = Label(master, text=labelText) label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) self.spectrumSelectWidget[specType] = PulldownMenu( master, entries=self.peakNameList) self.spectrumSelectWidget[specType].grid(row=row, column=2, columnspan=2, sticky=Tkinter.W) self.spectrumPhaseWidget[specType] = Entry(master, text="", width=4) self.spectrumPhaseWidget[specType].grid(row=row, column=4, sticky=Tkinter.W) # # 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 the tolerances # row += 1 label = Label(master, text="Atom tolerances") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) toleranceAtoms = self.autoAssignProjectFile.toleranceAtoms toleranceDefault = self.autoAssignProjectFile.toleranceDefault self.toleranceWidget = {} for i in range(0, len(toleranceAtoms), 2): row += 1 for j in range(2): curPos = i + j if curPos == len(toleranceAtoms): break toleranceAtom = toleranceAtoms[curPos] label = Label(master, text=toleranceAtom) label.grid(row=row, column=2 * j, sticky=Tkinter.E) self.toleranceWidget[toleranceAtom] = Entry( master, text=str(toleranceDefault[curPos]), width=6) self.toleranceWidget[toleranceAtom].grid(row=row, column=1 + 2 * j, sticky=Tkinter.W) # # 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 label = Label( master, text="Will save the peak files in the project file directory.", fg='red') label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) 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, help_url=self.help_url) buttons.grid(row=row, columnspan=columnspan, column=0) def apply(self): rootSpecType = self.autoAssignProjectFile.defaultSpectra[0][0] rootPeakList = self.peakNameDict[ self.spectrumSelectWidget[rootSpecType].getSelected()] if not rootPeakList: showError("No root spectrum", "Can't continue: need a root spectrum...") return False # # Organize peak/spectrum info # self.peakListInfo = [] for i in range(0, len(self.autoAssignProjectFile.defaultSpectra)): specType = self.autoAssignProjectFile.defaultSpectra[i][0] peakList = self.peakNameDict[ self.spectrumSelectWidget[specType].getSelected()] phase = self.spectrumPhaseWidget[specType].get() if peakList: self.peakListInfo.append((specType, peakList, phase)) # # Organize tolerance info # self.tolerances = {} toleranceAtoms = self.autoAssignProjectFile.toleranceAtoms toleranceDefault = self.autoAssignProjectFile.toleranceDefault for i in range(len(toleranceAtoms)): toleranceAtom = toleranceAtoms[i] value = returnFloat(self.toleranceWidget[toleranceAtom].get()) if not value: value = toleranceDefault[i] self.tolerances[toleranceAtom] = value self.validSelection = True return True
def setUrlFile(self, urlFile): if urlFile: self.help_url = joinPath(getHelpUrlDir(), urlFile + '.html') else: self.help_url = None
class WriteMappingPopup(BasePopup): help_url = joinPath(getHelpUrlDir(),'WriteMapping.html') def __init__(self, parent, project): self.project = project self.selectedFormats = [] self.defaultText = 'Select file' self.formats = allFormatsDict.keys() self.formats.sort() BasePopup.__init__(self, parent=parent, title= "Project '%s': " % project.name + 'Write ccpNmr mapping file', modal=False, transient=True) def body(self, master): row = 0 label = Label(master, text= "CcpNmr resonance -> atom mapping file writer.") label.grid(row=row, column=0, columnspan = 2, sticky=Tkinter.W) row += 1 label = Label(master, text= "File formats:") label.grid(row=row, column=0, sticky=Tkinter.W) self.formatListBox = ScrolledListbox(master, width = 50, height = 5, selectmode = Tkinter.MULTIPLE, initial_list = self.formats) self.formatListBox.grid(row=row, column=1, sticky=Tkinter.EW) # Default is all formats selected... self.formatListBox.setSelectedItems(self.formatListBox.getItems()) row += 1 label = Label(master, text= "Mapping output 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 mapping' ] 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 selectFile(self): fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: fileName = 'ccpNmr.map' popup = FormatFilePopup(self, file = fileName, component = 'mapping', format = ccpNmr_kw) if popup.fileSelected: self.fileButton.config(text = popup.file) popup.destroy() def apply(self): self.selectedFormats = self.formatListBox.getSelectedItems() fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: return False fileCreated = writeMappingFile(self.project,fileName,originalFormats = self.selectedFormats) if fileCreated: showInfo("Success","Succesfully wrote mapping file") else: showError("Not written","Error writing file %s. File not written" % fileName) return False return True
class SequenceLinkPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'SequenceLink.html') def __init__(self, parent, project, createMoleculeDict): self.project = project self.localCreateMoleculeDict = createMoleculeDict self.createMoleculeDict = createMoleculeDict self.resetInfo() TemporaryBasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Import original sequence', modal=False, transient=True) def body(self, master): self.frameMaster = master # # Setup header # row = 0 label = Label(master, text="Original import") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) label = Label(master, text="Data model", fg='blue') label.grid(row=row, column=1, columnspan=3, sticky=Tkinter.EW) row += 1 label = Label(master, text="Sequence") label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text="Molecular type", fg='blue') label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text="Molecule name", fg='blue') label.grid(row=row, column=2, sticky=Tkinter.EW) label = Label(master, text="Number of chains", fg='blue') label.grid(row=row, column=3, sticky=Tkinter.EW) row = self.setupWidgets(row=row) def makeNewInfo(self): newCreateMoleculeDict = {} # # Then get infor from self.localCreateMoleculeDict # self.localCreateMoleculeDict = newCreateMoleculeDict def setupWidgets(self, row=None): if row: self.widgetStartRow = row else: row = self.widgetStartRow # # Clear previous stuff... # if hasattr(self, 'origSeqButton'): for molName in self.origSeqButton.keys(): row = self.molNameRow[molName] self.origSeqButton[molName].grid_forget() self.molType[molName].grid_forget() self.molNameEntry[molName].grid_forget() self.numChains[molName].grid_forget() self.warningCode[molName].grid_forget() self.buttons.grid_forget() # # Setup new widget dicts and lists # self.molNameEntry = {} self.origSeqButton = {} self.molType = {} self.numChains = {} self.warningCode = {} self.molNameRow = {} # # Create the specific information... # for molName in self.molNames: row = row + 1 self.molNameRow[molName] = row self.origSeqButton[molName] = Tkinter.Button( self.frameMaster, text=self.origSeqLabel[molName], command=lambda molName=molName: self. popupSequenceChemCompSelect(molName)) self.origSeqButton[molName].grid(row=row, column=0, sticky=Tkinter.EW) self.molType[molName] = Label(self.frameMaster, text=self.currentMolType[molName], fg='blue') self.molType[molName].grid(row=row, column=1, sticky=Tkinter.EW) self.molNameEntry[molName] = Tkinter.Button( self.frameMaster, text=molName, command=lambda molName=molName: self.changeMolName(molName)) self.molNameEntry[molName].grid(row=row, column=2, sticky=Tkinter.EW) self.numChains[molName] = Entry(self.frameMaster, text=str( self.ccpNumChains[molName]), width=2) self.numChains[molName].grid(row=row, column=3) self.warningCode[molName] = Tkinter.StringVar() self.warningCode[molName] = Label( self.frameMaster, textvariable=self.warningCode[molName], fg='red') self.warningCode[molName].grid(row=row, column=4, sticky=Tkinter.N) self.updateWarnings() row = row + 1 texts = ['OK', 'Reset to original'] commands = [ self.ok, self.resetOriginal ] # This calls 'ok' in BasePopup, this then calls 'apply' in here self.buttons = createDismissHelpButtonList(self.frameMaster, texts=texts, commands=commands, dismiss_text='Cancel', help_url=self.help_url) self.buttons.grid(row=row, column=0, columnspan=5) return row def popupSequenceChemCompSelect(self, molName): popup = SequenceChemCompSelect(self, self.project, molName, self.createMoleculeDict, self.localCreateMoleculeDict) if popup and popup.hasChanged: self.localCreateMoleculeDict = popup.localCreateMoleculeDict self.resetInfo() self.setupWidgets() def changeMolName(self, molName): newMolName = askString('Enter molecule name', 'New name for molecule', molName, self) if newMolName and newMolName != molName: if newMolName in self.molNames: showError("Molecule name present", "This molecule name is already present!") elif self.project.findFirstMolecule(name=newMolName): # TODO TODO: allow user to select an existing molecule?!?! showError( "Molecule exists", "A molecule with this name already exists in the data model." ) else: moleculeInfo = self.localCreateMoleculeDict[molName] self.localCreateMoleculeDict[newMolName] = moleculeInfo del self.localCreateMoleculeDict[molName] # # Clean out text... # for molName in self.molNames: self.warningCode[molName].set("") self.resetInfo() self.setupWidgets() def updateWarnings(self): for molName in self.molNames: # # Just use the first one as reference! # (origSequence, origSequenceList) = self.localCreateMoleculeDict[molName][1][0] texts = {} for seqIndex in range(0, len(origSequenceList)): (seqElement, chemComp, chemCompVar) = origSequenceList[seqIndex] text = None if not chemComp: text = 'chemComp(s) missing' elif not chemCompVar: text = 'chemCompVar(s) missing' if text: if not texts.has_key(text): texts[text] = 0 texts[text] += 1 text = "" if texts: textSorted = texts.keys() textSorted.sort() for textItem in textSorted: text += "Warning: %d %s in sequence.\n" % (texts[textItem], textItem) self.warningCode[molName].set(text) def resetOriginal(self): self.localCreateMoleculeDict = self.createMoleculeDict self.resetInfo() self.setupWidgets() def resetInfo(self): self.origSeqLabel = {} self.origSeqDict = {} self.currentMolType = {} self.ccpNumChains = {} self.molNames = self.localCreateMoleculeDict.keys() self.molNames.sort() for molName in self.molNames: molecule = self.localCreateMoleculeDict[molName][0] sequences = self.localCreateMoleculeDict[molName][1] self.ccpNumChains[molName] = len(sequences) # # Just use the first one as reference! # (origSequence, origSequenceList) = sequences[0] self.origSeqDict[molName] = {} # # Set the text to appear # seqTexts = [] if len(origSequenceList) > 9: seqIndexes = [0, 1, 2, '...', -3, -2, -1] else: seqIndexes = range(0, len(origSequenceList)) for seqIndex in seqIndexes: if type(seqIndex) == type(''): seqTexts.append(seqIndex) else: ccHead = origSequenceList[seqIndex][1] if not ccHead: seqEl = origSequenceList[seqIndex][0] if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: seqText = seqEl.code3Letter else: seqText = seqEl.code1Letter else: seqText = ccHead.ccpCode seqTexts.append(seqText) self.origSeqLabel[molName] = string.join(seqTexts, '-') self.origSeqDict[molName][ self.origSeqLabel[molName]] = origSequence # # Check for allowed molTypes # molTypes = [] for seqIndex in range(0, len(origSequenceList)): (seqElement, chemComp, chemCompVar) = origSequenceList[seqIndex] if chemComp: if chemComp.molType not in molTypes: molTypes.append(chemComp.molType) if not molTypes or len(molTypes) > 1: molType = 'other' else: molType = molTypes[0] self.currentMolType[molName] = molType def apply(self): returnStatus = True self.createMoleculeDict = self.localCreateMoleculeDict # # Have to check the number of chains and check if any info available... # self.molNames = self.createMoleculeDict.keys() self.molNames.sort() for molName in self.molNames: molecule = self.createMoleculeDict[molName][0] sequences = self.createMoleculeDict[molName][1] # # Remove altogether if there's no info.. # if not sequences or not sequences[0] or not sequences[0][1]: del self.createMoleculeDict[molName] continue # # Check number of chains # numChains = returnInt(self.numChains[molName].get(), default=None) if numChains != None: numSequences = len(sequences) if numChains == 0: for sequence in sequences: sequence[0] = None elif numChains > numSequences: (sequence, sequenceList) = sequences[0] for i in range(numSequences, numChains): self.createMoleculeDict[molName][1].append( (sequence, sequenceList[:])) elif numChains < numSequences: for i in range(numSequences, numChains, -1): self.createMoleculeDict[molName][1].pop(i - 1) return returnStatus
class SequenceChemCompSelect(BasePopup): help_url = joinPath(getHelpUrlDir(), 'SequenceChemCompSelect.html') def __init__(self, parent, project, molName, createMoleculeDict, localCreateMoleculeDict): self.molName = molName self.project = project self.createMoleculeDict = createMoleculeDict self.localCreateMoleculeDict = localCreateMoleculeDict self.hasChanged = False self.molecule = self.localCreateMoleculeDict[self.molName][0] self.deleteText = 'Delete' self.okText = 'OK' self.startText = 'Insert at start' self.endText = 'Append to end' self.newMoleculeList = [] for molName in self.localCreateMoleculeDict.keys(): if molName != self.molName and not self.localCreateMoleculeDict[ molName][0]: self.newMoleculeList.append(molName) # modal = true means that it won't continue unless this one returns value BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Set chemComps for sequence', modal=True, transient=True) def body(self, master): self.geometry('700x500') # # Setup header # row = 0 label = Label(master, text='Original', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Modify ChemCompVar', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text='Status', width=20) label.grid(row=row, column=2, sticky=Tkinter.EW) label = Label(master, text='', width=5) label.grid(row=row, column=3, sticky=Tkinter.EW) row += 1 label = Label(master, text='code', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='ccpCode (molType): linking, descriptor', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Tkinter.Button(master, text='Add new molecule', command=self.addNewMolecule) label.grid(row=row, column=2) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(4): master.grid_columnconfigure(i, weight=1) self.sequenceFrame = ScrolledFrame(master, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=row, column=0, columnspan=4, sticky=Tkinter.NSEW) self.sequenceFrameRow = row self.sequenceFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 texts = ['Change', 'Change and quit'] commands = [ self.updateMolDict, self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) self.setupSequenceFrame() def setupSequenceFrame(self, resetFrame=False, resetStatus=True): frameRow = 0 x = y = 0 if resetFrame: self.sequenceFrame = ScrolledFrame(self.sequenceFrameMaster, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=self.sequenceFrameRow, column=0, columnspan=4, sticky=Tkinter.NSEW) frame = self.sequenceFrame.frame # # Just use the first one as reference! # sequences = self.localCreateMoleculeDict[self.molName][1] (self.origSequence, self.origSequenceList) = sequences[0] if len(sequences) > 1: multipleSequences = True else: multipleSequences = False # # Set info... # label = Label(frame, text='', width=10) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) label = Label(frame, text='', width=35) label.grid(row=frameRow, column=1, sticky=Tkinter.EW) label = Label(frame, text='', width=20) label.grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 self.ccvButtons = [] if resetStatus or resetFrame: self.statusList = [] self.moveStatus = {} # # Set up a list of status entries # statusEntries = [self.okText, self.deleteText] for newMolName in self.newMoleculeList: for appendCode in [self.startText, self.endText]: statusEntries.append('%s of %s' % (appendCode, newMolName)) self.moveStatus[statusEntries[-1]] = (newMolName, appendCode) # # Start creating all the objects... # for seqIndex in range(0, len(self.origSequenceList)): (seqEl, ccHead, ccVar) = self.origSequenceList[seqIndex] # # Set the original sequence code info... # seqCode = seqEl.seqCode if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: seqText = seqEl.code3Letter else: seqText = seqEl.code1Letter label = Label(frame, text="%s-%d" % (seqText, seqCode)) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) # # Set the chemCompVar info # keywds = {} if ccHead: textCode = "%s (%s)" % (ccHead.ccpCode, ccHead.molType) if ccVar: textCode += ": %s,%s" % (ccVar.linking, ccVar.descriptor) else: textCode = 'Select chemCompVar for %s' % textCode keywds['fg'] = 'red' else: textCode = 'Select chemCompVar' keywds['fg'] = 'red' self.ccvButtons.append( Tkinter.Button(frame, text=textCode, command=lambda seqIndex=seqIndex: self. selectChemCompVar(seqIndex), **keywds)) self.ccvButtons[-1].grid(row=frameRow, column=1, sticky=Tkinter.EW) # # Set the selector... # if resetStatus or resetFrame: self.statusList.append( PulldownMenu(frame, entries=statusEntries, label_color='red')) self.statusList[-1].grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 return True def addNewMolecule(self): molFormat = 'newMolecule_%d' if not hasattr(self, 'molNames'): self.molNames = self.localCreateMoleculeDict.keys() for i in range(0, 10): newMolName = molFormat % (i + 1) if newMolName not in self.molNames and not self.project.findFirstMolecule( name=newMolName): break self.molNames.append(newMolName) for statusPullDown in self.statusList: for appendCode in [self.startText, self.endText]: entryText = '%s of %s' % (appendCode, newMolName) statusPullDown.append(entryText) self.moveStatus[entryText] = (newMolName, appendCode) def updateMolDict(self): hasChanged = False actualSeqIndex = 0 seqLength = len(self.origSequenceList) origSequenceList = self.origSequenceList[:] for seqIndex in range(0, seqLength): (seqEl, ccHead, ccVar) = origSequenceList[seqIndex] newStatus = self.statusList[seqIndex].getSelected() if newStatus != self.okText: hasChanged = True if self.localCreateMoleculeDict == self.createMoleculeDict: self.copyCreateMoleculeDict() self.origSequenceList.pop(actualSeqIndex) if newStatus != self.deleteText: (moveToMoleculeName, appendCode) = self.moveStatus[newStatus] if not self.localCreateMoleculeDict.has_key( moveToMoleculeName): self.localCreateMoleculeDict[moveToMoleculeName] = [ None, [(None, [])] ] sequences = self.localCreateMoleculeDict[ moveToMoleculeName][1] for (tempSequence, tempSequenceList) in sequences: if appendCode == self.startText: tempSequenceList.insert(0, (seqEl, ccHead, ccVar)) elif appendCode == self.endText: tempSequenceList.append((seqEl, ccHead, ccVar)) else: actualSeqIndex += 1 # # Check if changed and do some resets if so... # if hasChanged: self.hasChanged = True # # Reset the linking if appropriate # for molName in self.localCreateMoleculeDict.keys(): if not self.localCreateMoleculeDict[molName][0]: sequences = self.localCreateMoleculeDict[molName][1] for (origSequence, origSequenceList) in sequences: molTypes = [] for (seqEl, ccHead, ccVar) in origSequenceList: if ccHead: if ccHead.molType not in molTypes: molTypes.append(ccHead.molType) if len(molTypes) == 1 and molTypes[0] != 'other': seqLength = len(origSequenceList) for seqIndex in range(0, seqLength): (seqEl, ccHead, ccVar) = origSequenceList[seqIndex] if ccVar: if seqIndex == 0: linking = 'start' elif seqIndex == seqLength - 1: linking = 'end' else: linking = 'middle' if ccVar.linking != linking: ccVar = ccHead.chemComp.findFirstChemCompVar( descriptor=ccVar.descriptor, linking=linking) if ccVar: origSequenceList[seqIndex] = ( seqEl, ccHead, ccVar) self.setupSequenceFrame(resetFrame=True) def selectChemCompVar(self, seqIndex): hasChanged = False (seqEl, ccHead, ccVar) = self.origSequenceList[seqIndex] keywds = {} if ccHead: keywds['molTypeEntries'] = [ccHead.molType] # TODO HAS TO CHANGE!! keywds['selectedChemCompHeads'] = [ccHead] if ccVar: keywds['selectLinking'] = ccVar.linking if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: keywds['origCode'] = seqEl.code3Letter else: keywds['origCode'] = seqEl.code1Letter popup = ChemCompSelectionPopup(self, self.project, chemCompEntries=['ChemCompVar'], **keywds) self.wait_window(popup) if popup.frame.getSelectedChemComp(): newChemCompVar = popup.frame.getSelectedChemComp() if not ccVar or ccVar != newChemCompVar: if self.localCreateMoleculeDict == self.createMoleculeDict: self.copyCreateMoleculeDict() self.origSequenceList[seqIndex] = ( seqEl, newChemCompVar.chemComp.chemCompHead, newChemCompVar) hasChanged = True if hasChanged: self.setupSequenceFrame(resetStatus=False) self.hasChanged = hasChanged def copyCreateMoleculeDict(self): self.localCreateMoleculeDict = {} for molName in self.createMoleculeDict.keys(): self.localCreateMoleculeDict[molName] = [ self.createMoleculeDict[molName][0], [] ] for (sequence, sequenceList) in self.createMoleculeDict[molName][1]: self.localCreateMoleculeDict[molName][1].append( (sequence, sequenceList[:])) sequences = self.localCreateMoleculeDict[self.molName][1] (self.origSequence, self.origSequenceList) = sequences[0] def apply(self): self.updateMolDict() return True
class ProcFilePopup(BasePopup): help_url = joinPath(getHelpUrlDir(),'ProcFile.html') def __init__(self, parent, acqProcPars, format): self.rawData = acqProcPars.experiment.rawData self.freqData = acqProcPars.freqDataDims[format][0].dataSource self.expDimRefs = acqProcPars.expDimRefs self.format = format self.updateAcqProcPars = acqProcPars.parameterUpdate self.updateAcqProcParsWidget = acqProcPars.updateFromWidget self.getDataDimRefs = acqProcPars.getDataDimRefs self.formatObjectDict = parent.formatObjectDict self.guiParent = parent self.project = self.rawData.root # # Dict for setup # # TODO: really need two datasources for nmrPipe... one fid, one processed!?!? # for writeFormatName in acqProcPars.writeFormats: setattr(self,writeFormatName,writeFormatName) value = 0 self.fileSetup = {} self.writeSetup = {} # # nmrPipe definitions # self.fileSetup[self.nmrPipe] = [ ['Conversion script file\n (outputs to...)', lambda: self.rawData.findFirstApplicationData(application = self.nmrPipe,keyword = 'conversion script'), lambda x = value: self.setApplData(self.rawData,self.nmrPipe,'conversion script',x), ['autoconv.com'], 'conversion script'], [' nmrPipe FIDs\n(inputs to...)', lambda: self.rawData.findFirstApplicationData(application = self.nmrPipe,keyword = 'FID'), lambda x = value: self.setApplData(self.rawData,self.nmrPipe,'FID',x), ['auto.fid','auto%03d.fid'], 'FID'], ['Processing script file\n (outputs to...)', lambda: self.freqData.findFirstApplicationData(application = self.nmrPipe,keyword = 'processing script'), lambda x = value: self.setApplData(self.freqData,self.nmrPipe,'processing script',x), ['autoproc.com'], 'processing script'], ['Processed data', lambda: self.getDataSourceFileName(self.freqData), lambda x = value: self.doDataStoreFileName(self.freqData,x), ['auto.ft','auto%03d.ft'], 'processed data'] ] # TODO: can add execute nmrPipe program buttons... see dataNavigator self.writeSetup[self.nmrPipe] = [ ['Write conversion file', lambda : self.writeFile(self.nmrPipe,['conversion'])], ['Write processing file', lambda : self.writeFile(self.nmrPipe,['processing'])], ['Write all', lambda : self.writeFile(self.nmrPipe,['conversion','processing'])] ] # # azara definitions # self.fileSetup[self.azara] = [ ['Processing parameters file\n (inputs to...)', lambda: self.rawData.findFirstApplicationData(application = self.azara,keyword = 'processing parameters'), lambda x = value: self.setApplData(self.rawData,self.azara,'processing parameters',x), ['autoproc.par'], 'processing parameters'], ['Processing script file\n (outputs to both...)', lambda: self.freqData.findFirstApplicationData(application = self.azara,keyword = 'processing script'), lambda x = value: self.setApplData(self.freqData,self.azara,'processing script',x), ['autoproc.scr'], 'processing script'], ['Processed data', lambda: self.getDataSourceFileName(self.freqData), lambda x = value: self.doDataStoreFileName(self.freqData,x), ['spectrum.ft'], 'spectrum'], ['Processed data parameter file\n', lambda: self.freqData.findFirstApplicationData(application = self.azara,keyword = 'spectrum parameters'), lambda x = value: self.setApplData(self.freqData,self.azara,'spectrum parameters',x), ['spectrum.par'], 'spectrum parameters'] ] # TODO: can add execute process program buttons... see dataNavigator self.writeSetup[self.azara] = [ ['Write processing parameters file', lambda : self.writeFile(self.azara,['processingPars'])], ['Write processing script file', lambda : self.writeFile(self.azara,['processingScript'])], ['Write all', lambda : self.writeFile(self.azara,['processingPars','processingScript'])] ] BasePopup.__init__(self,parent = parent, title = "Project '%s': " % self.project.name + '%s processing write' % format, modal = False, transient=False) def body(self, master): self.buttons = [] # # Popup window # row = 0 label = Label(master, text= "Experiment '%s'" % self.rawData.experiment.name, fg = 'blue') label.grid(row=row, column=0, columnspan = 2, sticky=Tkinter.EW) # # File name buttons # for buttonIndex in range(0,len(self.fileSetup[self.format])): row = row + 1 (textLabel,getter,setter,defaults,popupTitle) = self.fileSetup[self.format][buttonIndex] getFuncOrValue = getter() if not getFuncOrValue: if len(defaults) > 1 and len(self.expDimRefs) > 2: fileName = defaults[1] else: fileName = defaults[0] else: if type(getFuncOrValue) == type(""): fileName = getFuncOrValue else: fileName = getFuncOrValue.value label = Label(master, text= textLabel) label.grid(row=row, column=0, sticky=Tkinter.E) self.buttons.append(Tkinter.Button(master, text = fileName, command = (lambda x = buttonIndex: self.selectFile(self.format,x)))) self.buttons[-1].grid(row=row, column=1, sticky=Tkinter.W) # # Buttons to write conversion and/or processing files... # for buttonIndex in range(0,len(self.writeSetup[self.format])): row = row + 1 (text,command) = self.writeSetup[self.format][buttonIndex] button = Tkinter.Button(master, text = text, command = command) button.grid(row=row, column=0, columnspan = 2, 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, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan = 3) def setApplData(self,dataSource,format,keyword,value): applData = dataSource.findFirstApplicationData(application = format, keyword = keyword) if applData: applData.value = value else: createAppData(dataSource,application = format, keyword = keyword, value = value) def selectFile(self,format,buttonIndex): fileName = self.buttons[buttonIndex].__getitem__('text') popupTitle = 'Select ' + self.format + ' ' + self.fileSetup[format][buttonIndex][4] + ' file' popup = FormatFilePopup(self, file = fileName, component = 'processing', title = popupTitle, format = self.format) # TODO: some testing on file name? Is it correct (ie has % code in for fid/ft bits?) if popup.file: self.fileSetup[format][buttonIndex][2](popup.file) self.buttons[buttonIndex].config(text = popup.file) popup.destroy() def doDataStoreFileName(self,masterClass,file): (dataUrlPath, localPath) = os.path.split(file) setDataSourceDataStore(masterClass,dataUrlPath,localPath) def getDataSourceFileName(self,dataStore): return getDataSourceFileName(dataStore) def writeFile(self,format,tasks): self.updateAcqProcParsWidget() self.updateAcqProcPars() # # Get or set up format classes # if self.formatObjectDict[self.format]: formatObject = self.formatObjectDict[self.format] else: formatLabel = allFormatsDict[self.format] formatModule = __import__('ccpnmr.format.converters.%sFormat' % formatLabel,{},{},['%sFormat' % formatLabel]) formatClass = getattr(formatModule,'%sFormat' % formatLabel) formatObject = formatClass(self.project,self.guiParent,verbose = 1) self.formatObjectDict[self.format] = formatObject # Bit cumbersome... is there a better way to define writeFile, ... ? dataDimRefs = self.getDataDimRefs(format) for task in tasks: parFile = None addKeywds = {'dataDimRefs': dataDimRefs} if format == self.nmrPipe: if task == 'conversion': function = 'writeProcPars' self.fileName = self.buttons[0].__getitem__('text') outputFile = self.buttons[1].__getitem__('text') addKeywds['outputFile'] = outputFile elif task == 'processing': function = 'writeProcScript' self.fileName = self.buttons[2].__getitem__('text') inputFile = self.buttons[1].__getitem__('text') outputFile = self.buttons[3].__getitem__('text') addKeywds['outputFile'] = outputFile addKeywds['inputFile'] = inputFile if format == self.azara: if task == 'processingPars': function = 'writeProcPars' self.fileName = self.buttons[0].__getitem__('text') elif task == 'processingScript': function = 'writeProcScript' self.fileName = self.buttons[1].__getitem__('text') inputFile = self.buttons[0].__getitem__('text') outputFile = self.buttons[2].__getitem__('text') parFile = self.buttons[3].__getitem__('text') addKeywds['outputFile'] = outputFile addKeywds['inputFile'] = inputFile addKeywds['parFile'] = parFile # Write for each task in list exportFunc = getattr(formatObject,function) if exportFunc(self.fileName, **addKeywds): showInfo("Success","Successfully exported file:\n%s." % self.fileName,self) else: showError("Error","Error while exporting file:\n%s." % self.fileName,self) def apply(self): return True
class ExperimentCreatePopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ExperimentCreate.html') def __init__(self, parent, project, numDim=None, topText=None, expName=''): self.parent = parent self.project = project self.numDim = numDim self.topText = topText self.skip = 1 self.expName = expName setCurrentStore(project, 'ChemElementStore') TemporaryBasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Create Experiment', modal=False, transient=True) def body(self, parent): row = 0 columnspan = 3 if self.numDim != None: columnspan += 1 if self.topText: label = Label(parent, text=self.topText) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row = row + 1 if self.expName: expNameText = " for experiment '%s'" % self.expName else: expNameText = '' label = Label( parent, text= 'Select a reference experiment%s from the list below, then press Create' % expNameText) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row = row + 1 colHeadings = self.getHeadings() parent.grid_rowconfigure(row, weight=1, minsize=300) parent.grid_columnconfigure(0, weight=1, minsize=100) self.table = ScrolledMatrix(parent, headingList=colHeadings, callback=None) self.table.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.NSEW) row = row + 1 texts = ['Create'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here if self.numDim != None: texts.append('Show all experiments') commands.append(self.showAll) buttons = createDismissHelpButtonList(parent, texts=texts, commands=commands, dismiss_text='Skip', help_url=self.help_url) buttons.grid(row=row, column=0) self.update() def update(self): textMatrix = [] objectList = [] for nep in self.project.sortedNmrExpPrototypes(): #print "%d: %s (%s) %s" % (nep.serial, nep.name, nep.category, nep.synonym) for re in nep.refExperiments: """ #print " %s:" % re.name, atomDimList = [] for refExpDim in re.refExpDims: for refExpDimRef in refExpDim.refExpDimRefs: expMeasurement = refExpDimRef.expMeasurement atoms = [] addText = "" for atomSite in expMeasurement.atomSites: atoms.append(atomSite.isotopeCode[-1]) if expMeasurement.measurementType != "Shift": addText = "(%s)" % expMeasurement.measurementType atomDimList.append("%s%s" % (string.join(atoms,''),addText)) string.join(atomDimList,'-'), """ valueList = [ nep.synonym, re.name, len(re.refExpDims), nep.name, nep.category ] objectList.append(re) textMatrix.append(valueList) self.table.update(textMatrix=textMatrix, objectList=objectList) if self.numDim != None: filterClass = FilterMatrix(self.table.parent, self.table, searchString=str(self.numDim), column=2) filterClass.apply() def showAll(self): self.numDim = None self.update() def getHeadings(self): colHeadings = [ 'Common pathway name', 'Experiment', 'Dimensions', 'Pathway name', 'Category' ] return colHeadings def apply(self): self.refExperiment = self.table.currentObject names = [ exp.name for exp in self.project.currentNmrProject.sortedExperiments() ] while 1: self.name = askString('Give the name of the experiment', 'Experiment name:', initial_value=self.expName, parent=self.parent) if (self.name in names): showError('Repeated experiment name', 'Name already used - choose another.') else: break self.skip = 0 return True
class ChainLinkPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ChainLink.html') def __init__(self, parent, ccpChainLabelDict, ccpChainSeqIdCodes, formatChains, formatChainList, formatChainDict, defaultFormatChain): # Constructor doesn't do much except call body # The parent is self.parent (parent of the popup) self.chain = None self.formatChains = formatChains self.ccpChainLabelDict = ccpChainLabelDict self.ccpChainSeqIdCodes = ccpChainSeqIdCodes self.formatChainList = formatChainList self.formatChainDict = formatChainDict self.localFormatChainDict = {} self.defaultFormatChain = defaultFormatChain self.ccpChainSeqIdDict = {} self.ccpChainSeqCodeDict = {} project = self.ccpChainLabelDict.values()[0].root # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Link chains', modal=False, transient=True) def body(self, master): # # Setup header # row = 0 label = Label(master, text="Data model", fg='blue') label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) label = Label(master, text="Information from external file") label.grid(row=row, column=2, columnspan=2, sticky=Tkinter.EW) row += 1 label = Label(master, text="Ccp chain code", fg='blue') label.grid(row=row, column=0, sticky=Tkinter.W) label = Label(master, text="Sequence Id (code) start", fg='blue') label.grid(row=row, column=1, sticky=Tkinter.W) label = Label(master, text="Format chain code") label.grid(row=row, column=2, sticky=Tkinter.W) label = Label(master, text="Sequence code start") label.grid(row=row, column=3, sticky=Tkinter.W) # # Setup list of ccp chains and selection menus for other chains # self.formatChainMenu = {} self.ccpCodeLow = {} self.formatChainCodeLow = {} self.formatRemoveCode = {} self.formatRemoveLabel = {} ccpChainLabels = self.ccpChainLabelDict.keys() ccpChainLabels.sort() ccpChainSeqIdLabels = {} for ccpChainLabel in ccpChainLabels: ccpChainSeqIdLabels[ccpChainLabel] = [] self.ccpChainSeqIdDict[ccpChainLabel] = {} self.ccpChainSeqCodeDict[ccpChainLabel] = {} # # Make a dict to list codes with Ids for ccp # for i in range(0, len(self.ccpChainSeqIdCodes[ccpChainLabel][0])): seqId = self.ccpChainSeqIdCodes[ccpChainLabel][0][i] (seqCode, seqInsertCode) = self.ccpChainSeqIdCodes[ccpChainLabel][1][i] label = "%s (%s)" % (seqId, seqCode + string.strip(seqInsertCode)) ccpChainSeqIdLabels[ccpChainLabel].append(label) self.ccpChainSeqIdDict[ccpChainLabel][label] = seqId self.ccpChainSeqCodeDict[ccpChainLabel][label] = seqCode # # Currently only linking start in ccp chain (ONLY ONE!) to start in chain read in from file # Assuming sequential order thereafter. # for ccpChainLabel in ccpChainLabels: row = row + 1 label = Label(master, text=ccpChainLabel, fg='blue') label.grid(row=row, column=0, sticky=Tkinter.W) self.ccpCodeLow[ccpChainLabel] = ScrolledListbox( master, initial_list=ccpChainSeqIdLabels[ccpChainLabel], width=4, height=4, xscroll=False) self.ccpCodeLow[ccpChainLabel].grid(row=row, column=1, sticky=Tkinter.EW) self.formatChainMenu[ccpChainLabel] = PulldownMenu( master, entries=self.formatChainList, selected_index=self.formatChainList.index( self.defaultFormatChain)) self.formatChainMenu[ccpChainLabel].grid(row=row, column=2, sticky=Tkinter.EW) self.formatChainCodeLow[ccpChainLabel] = ScrolledListbox( master, initial_list=[], width=4, height=4, xscroll=False) self.formatChainCodeLow[ccpChainLabel].grid(row=row, column=3, sticky=Tkinter.EW) self.formatRemoveLabel[ccpChainLabel] = Label(master, text="", fg='red') self.formatRemoveCode[ccpChainLabel] = Tkinter.Button( master, text="Remove", command=(lambda x=ccpChainLabel, row=row: self.removeSeqCode( x, row))) self.formatRemoveLabel[ccpChainLabel].grid(row=row, column=4, sticky=Tkinter.N) self.formatRemoveLabel[ccpChainLabel].grid_forget() self.formatRemoveCode[ccpChainLabel].grid(row=row, column=4, sticky=Tkinter.S) self.formatChainMenu[ccpChainLabel].callback = ( lambda x=-1, y=self.defaultFormatChain, z=ccpChainLabel, row= row: self.updateSeqCodes(x, y, z, row)) 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, columnspan=5) def removeSeqCode(self, ccpChainLabel, row): selection = self.formatChainMenu[ccpChainLabel].getSelected() if selection != 'Do not link': chainDictKey = (ccpChainLabel, selection) (formatChainCode, seqCodesList) = self.localFormatChainDict[chainDictKey] selectedItems = self.formatChainCodeLow[ ccpChainLabel].getSelectedItems() for selectedItem in selectedItems: seqCodeKey = getSeqAndInsertCode(selectedItem) try: seqCodeIndex = seqCodesList.index(seqCodeKey) seqCodesList.pop(seqCodeIndex) except: pass self.updateSeqCodes(-1, selection, ccpChainLabel, row) def updateSeqCodes(self, formatChainIndex, formatChainText, ccpChainLabel, row): if formatChainText == 'Do not link': self.formatChainCodeLow[ccpChainLabel].setItems([]) else: chainDictKey = (ccpChainLabel, formatChainText) if not self.localFormatChainDict.has_key(chainDictKey): (formatChainCode, seqCodesList) = self.formatChainDict[formatChainText] self.localFormatChainDict[chainDictKey] = (formatChainCode, seqCodesList[:]) (formatChainCode, seqCodesList) = self.localFormatChainDict[chainDictKey] self.formatChainCodeLow[ccpChainLabel].clear() seqCodeJumps = 0 oldSeqCode = seqCodesList[0][0] - 1 oldSeqInsertCode = seqCodesList[0][1] for (seqCode, seqInsertCode) in seqCodesList: self.formatChainCodeLow[ccpChainLabel].append( str(seqCode) + seqInsertCode) if oldSeqInsertCode == seqInsertCode and oldSeqCode + 1 != seqCode: seqCodeJumps = 1 oldSeqInsertCode = seqInsertCode oldSeqCode = seqCode self.formatChainCodeLow[ccpChainLabel].setSelectedItems( [str(seqCodesList[0][0]) + seqCodesList[0][1]]) # # Try to match on sequence code... # foundMatch = 0 (formatFirstSeqCode, formatSeqInsertCode) = seqCodesList[0] matchKey = (str(formatFirstSeqCode), formatSeqInsertCode) if matchKey in self.ccpChainSeqIdCodes[ccpChainLabel][1]: matchKey = str(formatFirstSeqCode) + string.strip( formatSeqInsertCode) for label in self.ccpChainSeqCodeDict[ccpChainLabel].keys(): if self.ccpChainSeqCodeDict[ccpChainLabel][ label] == matchKey: self.ccpCodeLow[ccpChainLabel].setSelectedItems( [label]) foundMatch = 1 break if not foundMatch: # # Try to match on sequence id... # This could all be more intelligent but leave for now. # if str(formatFirstSeqCode ) in self.ccpChainSeqIdCodes[ccpChainLabel][0]: for label in self.ccpChainSeqIdDict[ccpChainLabel].keys(): if self.ccpChainSeqIdDict[ccpChainLabel][label] == str( formatFirstSeqCode): self.ccpCodeLow[ccpChainLabel].setSelectedItems( [label]) foundMatch = 1 break # # Set 'remove' if seqInsertCodes present, and print warning # multipleSeqInsertCodes = 0 for chainDictKey in self.localFormatChainDict.keys(): (tempFormatChainCode, tempSeqCodesList) = self.localFormatChainDict[chainDictKey] if formatSeqInsertCode != tempSeqCodesList[0][1]: multipleSeqInsertCodes += 1 # # Set user warning messages... # text = "" if multipleSeqInsertCodes: text += "Warning: insertion codes present" if seqCodeJumps: text += "Warning: jumps in seqCode - assumed sequential" self.formatRemoveLabel[ccpChainLabel].grid_forget() if text: self.formatRemoveLabel[ccpChainLabel].set(text) self.formatRemoveLabel[ccpChainLabel].grid(row=row, column=4, sticky=Tkinter.N) def apply(self): self.chainDict = {} for ccpChainLabel in self.ccpChainLabelDict.keys(): chain = self.ccpChainLabelDict[ccpChainLabel] selection = self.formatChainMenu[ccpChainLabel].getSelected() if selection != 'Do not link': chainDictKey = (ccpChainLabel, selection) (formatChainCode, seqCodesList) = self.localFormatChainDict[chainDictKey] selectedItems = self.ccpCodeLow[ ccpChainLabel].getSelectedItems() if not selectedItems: showError( "No sequence ID selected", "Please select a sequence ID on the left side for chain %s!" % ccpChainLabel) return False ccpCodeLow = returnInt( self.ccpChainSeqIdDict[ccpChainLabel][selectedItems[0]]) (formatChainSeqCodeLow, seqInsertCode) = getSeqAndInsertCode( self.formatChainCodeLow[ccpChainLabel].getSelectedItems() [0]) exportSeqCodesList = seqCodesList[:] for (tempSeqCode, tempSeqInsertCode) in seqCodesList: if tempSeqCode == formatChainSeqCodeLow and tempSeqInsertCode == seqInsertCode: break else: exportSeqCodesList.pop(0) self.chainDict[chain] = [ formatChainCode, ccpCodeLow, exportSeqCodesList ] return True
class ChemCompInfoPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ChemCompInfo.html') def __init__(self, parent, formula, bondNumber, chemCompInfo): self.formula = formula self.bondNumber = bondNumber self.chemCompInfo = chemCompInfo self.updated = 0 self.nonEntryAttributes = { 'molType': (PulldownMenu, ['protein', 'DNA', 'RNA', 'carbohydrate', 'other']), 'hasStdChirality': (CheckButton, None) } TemporaryBasePopup.__init__(self, parent=parent, title='ChemComp creation', modal=False, transient=True) def body(self, master): # # Popup window # self.widgets = [] row = 0 label = Label(master, text="ChemComp formula '%s'" % self.formula) label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) row = row + 1 label = Label(master, text="Number of bonds: %d" % self.bondNumber) label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) # # Show relevant attributes... # for chemCompAttrInfo in self.chemCompInfo: row = row + 1 attrName = chemCompAttrInfo[0] label = Label(master, text=attrName) label.grid(row=row, column=0, sticky=Tkinter.EW) if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] == PulldownMenu: self.widgets.append( PulldownMenu(master, entries=widgetInfo[1], selected_index=widgetInfo[1].index( chemCompAttrInfo[1]))) elif widgetInfo[0] == CheckButton: self.widgets.append( CheckButton(master, selected=widgetInfo[1])) else: text = chemCompAttrInfo[1] if not text: text = '' self.widgets.append(Entry(master, text=text)) self.widgets[-1].grid(row=row, column=1, 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, columnspan=2) def apply(self): self.updated = 1 for widgetNum in range(0, len(self.chemCompInfo)): chemCompAttrInfo = self.chemCompInfo[widgetNum] attrName = chemCompAttrInfo[0] if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] in [PulldownMenu, CheckButton]: value = self.widgets[widgetNum].getSelected() else: value = self.widgets[widgetNum].get() if value == '': value = None self.chemCompInfo[widgetNum] = (attrName, value) return True
class ProchiralStatusPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ProchiralStatus.html') def __init__(self, parent, chainList, chainAtomSetsDict): self.chainList = chainList self.chainAtomSetsDict = chainAtomSetsDict self.resParentDict = {} self.resParentList = [] self.resParentChainLabelDict = {} self.resParentChainLabelList = {} self.chainResonancesDict = {} for resParent in self.chainAtomSetsDict.keys(): if isinstance(resParent, NmrConstraint.NmrConstraintStore): strucGens = resParent.structureGenerations strucGenSerials = [str(sg.serial) for sg in strucGens] strucGenLabel = string.join(strucGenSerials, ',') resParentLabel = "Constraint set %d (strucGens %s)" % ( resParent.serial, strucGenSerials) else: resParentLabel = "Nmr project %s" % resParent.name self.resParentDict[resParentLabel] = resParent self.resParentList.append(resParentLabel) self.chainResonancesDict[resParent] = {} self.resParentChainLabelDict[resParent] = {} self.resParentChainLabelList[resParent] = [] for chain in self.chainList: self.project = chain.root if self.chainAtomSetsDict[resParent].has_key( chain) and self.chainAtomSetsDict[resParent][chain]: chainLabel = "Molecular system '%s':Chain '%s' (molecule '%s')" % ( chain.molSystem.code, chain.code, chain.molecule.name) self.resParentChainLabelList[resParent].append(chainLabel) self.resParentChainLabelDict[resParent][chainLabel] = chain self.chainResonancesDict[resParent][chain] = [] # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % self.project.name + 'Set status prochiral atoms/resonances', modal=False, transient=True) def body(self, master): # # Setup header # row = 0 label = Label(master, text='Select the resonance list:') label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Select the chain:') label.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 self.resParentSelect = PulldownMenu(master, entries=self.resParentList, callback=self.setupResParentList, do_initial_callback=False) self.resParentSelect.grid(row=row, column=0, sticky=Tkinter.EW) self.chainSelect = PulldownMenu(master, entries=[], callback=self.setupProchiralList, do_initial_callback=False) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=2, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(2): master.grid_columnconfigure(i, weight=1) self.prochiralListFrame = ScrolledFrame(master, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=row, column=0, columnspan=2, sticky=Tkinter.NSEW) self.prochiralListFrameRow = row self.prochiralListFrameMaster = master row = row + 1 texts = ['Set all', 'Set chain'] commands = [ self.ok, self.setStereo ] # 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, columnspan=2, sticky=Tkinter.EW) self.resParentSelect.callback(0, self.resParentList[0]) def setupResParentList(self, listIndex, resParentLabel): resParent = self.resParentDict[resParentLabel] self.resParent = resParent self.chainSelect.setup(self.resParentChainLabelList[self.resParent], 0) self.chainSelect.callback( 0, self.resParentChainLabelList[self.resParent][0]) def setupProchiralList(self, listIndex, chainLabel): chain = self.resParentChainLabelDict[self.resParent][chainLabel] self.chain = chain self.prochiralListFrame.destroy() self.prochiralListFrame = ScrolledFrame(self.prochiralListFrameMaster, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=self.prochiralListFrameRow, column=0, columnspan=2, sticky=Tkinter.NSEW) # # TODO: also handle case one resonance, two atomSets!?!? # frameRow = 0 x = y = 0 frame = self.prochiralListFrame.frame self.resonanceObjects = {} self.resonanceLabelDict = {} # # Reuse previous settings... # if len(self.chainResonancesDict[self.resParent][chain]) == len( self.chainAtomSetsDict[self.resParent][chain]): usePreviousSettings = True else: usePreviousSettings = False for i in range(0, len(self.chainAtomSetsDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] isStereo = False hasResonances = False isValidCase = False resonances = [] if usePreviousSettings and self.chainResonancesDict[ self.resParent][chain][i]: resonances = self.chainResonancesDict[ self.resParent][chain][i][3] isStereo = self.chainResonancesDict[ self.resParent][chain][i][0] hasResonances = True isValidCase = True else: for atomSet in atomSetGroup: resonanceSets = atomSet.sortedResonanceSets() if resonanceSets: hasResonances = True for resonanceSet in resonanceSets: for resonance in resonanceSet.sortedResonances(): if resonance not in resonances: resonances.append(resonance) if len(resonanceSets) == 1: isValidCase = True if len(resonanceSet.atomSets) == 1: isStereo = True else: # Case only one resonance but stereo assigned resonances.append(0) if len(resonances) == 1: # Case only one resonance, not stereo assigned resonances.append(None) # # Set up only for valid cases # if hasResonances and isValidCase: if not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append( [isStereo, False, False, resonances]) residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode rowspan = 2 checkButton = CheckButton( frame, selected=isStereo, callback=lambda status=isStereo, fr=frameRow, item=i, setup =False: self.toggleResonances(status, fr, item, setup)) checkButton.grid(row=frameRow, rowspan=rowspan, column=0, sticky=Tkinter.EW) label = Label(frame, text=ccpCode, width=5) label.grid(row=frameRow, rowspan=rowspan, column=1, sticky=Tkinter.E) label = Label(frame, text=str(seqCode), width=5) label.grid(row=frameRow, rowspan=rowspan, column=2, sticky=Tkinter.W) # # Set up the atom names # for j in range(0, len(atomSetGroup)): atomSet = atomSetGroup[j] label = Label(frame, text=atomSet.name) label.grid(row=frameRow + j, column=3, sticky=Tkinter.E, ipadx=4) # # Set up the resonances # self.resonanceObjects[frameRow] = { True: [[], []], False: [[], []] } resonanceLabelList = [] for resonance in resonances: if not resonance: resonanceLabel = 'unknown' else: if hasattr(resonance, 'shifts') and resonance.shifts: shiftLabel = " (shifts: " for shift in resonance.sortedShifts(): shiftLabel += "%.2f, " % shift.value shiftLabel = shiftLabel[:-2] + ")" else: shiftLabel = "" resonanceLabel = "'%d.%s'%s" % ( seqCode, resonance.name, shiftLabel) self.resonanceLabelDict[resonanceLabel] = resonance resonanceLabelList.append(resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow, column=4, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(separator) separator = CrossLine(frame, height=20, width=30, canvas_bg=frame['bg'], color='dimgray') self.resonanceObjects[frameRow][False][0].append(separator) resonanceList = PulldownMenu( frame, entries=resonanceLabelList, callback=lambda selInd=x, selItem=y, fr=frameRow, item=i: self.setProchiralLabels(selInd, selItem, fr, item), do_initial_callback=False, label_color='red') resonanceList.grid(row=frameRow, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(resonanceList) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[0], fg='dimgray') self.resonanceObjects[frameRow][False][0].append( resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + 1, column=4) self.resonanceObjects[frameRow][True][1].append(separator) self.resonanceObjects[frameRow][False][1].append(None) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='red') resonanceLabel.grid(row=frameRow + 1, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][1].append(resonanceLabel) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='dimgray') self.resonanceObjects[frameRow][False][1].append( resonanceLabel) if not isStereo: checkButton.callback(isStereo, setup=True) separator = Separator(frame, height=1) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + rowspan, columnspan=6, sticky=Tkinter.EW) frameRow += rowspan + 1 elif not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append(None) return True def setProchiralLabels(self, selInd, selItem, fr, item): resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][False][0][1].set(resonanceLabel) selInd = not selInd resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][True][1][1].set(resonanceLabel) self.resonanceObjects[fr][False][1][1].set(resonanceLabel) self.chainResonancesDict[self.resParent][ self.chain][item][2] = not self.chainResonancesDict[ self.resParent][self.chain][item][2] self.chainResonancesDict[self.resParent][self.chain][item][3].reverse() def toggleResonances(self, status, frameRow, item, setup): if not setup: self.chainResonancesDict[self.resParent][ self.chain][item][0] = status self.chainResonancesDict[self.resParent][ self.chain][item][1] = not self.chainResonancesDict[ self.resParent][self.chain][item][1] for i in range(0, len(self.resonanceObjects[frameRow])): # # Remove other widgets from grid # rpds = self.resonanceObjects[frameRow][not status][i] for rpd in rpds: if rpd: rpd.grid_forget() # # Set current widgets # rpds = self.resonanceObjects[frameRow][status][i] for j in range(0, len(rpds)): rpd = rpds[j] if rpd: keywds = {} if j == 1: keywds['sticky'] = Tkinter.W if j == 0: if not status: keywds['rowspan'] = 2 rpd.grid(row=frameRow + i, column=4 + j, **keywds) def setStereo(self, chain=None): if not chain: chain = self.chain if self.chainResonancesDict[self.resParent][chain]: for i in range( 0, len(self.chainResonancesDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] (stereoStatus, stereoStatusChanged, resChanged, resonances ) = self.chainResonancesDict[self.resParent][chain][i] if stereoStatusChanged or (stereoStatus and resChanged): residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode atomText = "%s/%s" % (atomSetGroup[0].name, atomSetGroup[1].name) if stereoStatusChanged: if stereoStatus: stereoText = "non-stereospecific to stereospecific." else: stereoText = "stereospecific to non-stereospecific." print " Warning: Changed '%s.%d' prochiral resonances for atoms %s from %s" % ( ccpCode, seqCode, atomText, stereoText) self.chainResonancesDict[ self.resParent][chain][i][1] = False self.chainResonancesDict[ self.resParent][chain][i][2] = False if stereoStatus: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[0]: resonanceSet.removeAtomSet(atomSetGroup[1]) if resonances[1]: if not resonances[0]: # Remove right atom set if only one resonance... resonanceSet.removeAtomSet(atomSetGroup[0]) else: # Only create a new resonance set if two resonances present! resonanceSet.removeResonance(resonances[1]) if isinstance( self.resParent, NmrConstraint.NmrConstraintStore): newResonanceSet = self.resParent.newFixedResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: newResonanceSet = self.resParent.newResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: if resonances[0]: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[1]: atomSetGroup[1].findFirstResonanceSet( ).delete() resonanceSet.addResonance(resonances[1]) resonanceSet.addAtomSet(atomSetGroup[1]) elif resonances[1]: resonanceSet = atomSetGroup[1].resonanceSets[0] resonanceSet.addAtomSet(atomSetGroup[0]) elif stereoStatus and resChanged: print " Warning: Changed resonance assignment for '%s.%d' stereospecifically assigned atoms %s." % ( ccpCode, seqCode, atomText) self.chainResonancesDict[ self.resParent][chain][i][2] = False resonanceSets = [] for i in range(0, 2): if atomSetGroup[i].resonanceSets: resonanceSets.append( atomSetGroup[i].findFirstResonanceSet()) else: resonanceSets.append(None) for i in range(0, 2): resonanceSet = resonanceSets[i] if resonanceSet: resonanceSet.addAtomSet(atomSetGroup[not i]) resonanceSet.removeAtomSet(atomSetGroup[i]) def apply(self): for chain in self.chainList: self.setStereo(chain=chain) return True
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 ChemCompAtomBondInfoPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(),'ChemCompAtomBondInfo.html') def __init__(self, parent, chemCompInfo, chemCompAtoms, chemCompBonds): self.chemCompInfo = chemCompInfo self.chemCompAtoms = chemCompAtoms self.chemCompBonds = chemCompBonds self.obligatoryAtoms = [] for molTypeTuple in standardBackboneAtoms.keys(): if self.chemCompInfo[0][1] in molTypeTuple: for atomName in standardBackboneAtoms[molTypeTuple]: if atomName not in self.obligatoryAtoms: self.obligatoryAtoms.append(atomName) self.nonEntryAttributes = { 'chirality': (PulldownMenu,['R','S','unknown']), 'waterExchangeable': (CheckButton,False) } TemporaryBasePopup.__init__(self, parent=parent, title='ChemComp atom and bond creation', modal=False, transient=True) def body(self, master): # # Popup window # self.columnspan = len(self.chemCompAtoms[0]) row = 0 label = Label(master, text= "Molecule type '%s', ccp code '%s'" % (self.chemCompInfo[0][1],self.chemCompInfo[1][1])) label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Warning message if necessary! # if self.obligatoryAtoms: row += 1 label = Label(master, text= "Warning: have to define atoms: %s!" % string.join(self.obligatoryAtoms,', '), fg = 'red') label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Show top information... # row = row + 1 colNum = 0 self.frameWidth = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(master, text = attrName, width = len(attrName) + 2) label.grid(row=row, column=colNum, sticky=Tkinter.EW) self.frameWidth += len(attrName) + 2 colNum += 1 # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # Separate frame for info (have to be able to scroll) # row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row,weight = 1) for i in range(self.columnspan): master.grid_columnconfigure(i,weight = 1) self.atomFrame = ScrolledFrame(master, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) self.atomFrameRow = row self.atomFrameMaster = master # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # End bit... # row = row + 1 texts = [ 'OK', 'Update' ] commands = [ self.ok, self.update ] # 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, columnspan = self.columnspan) self.setupAtomFrame() def setupAtomFrame(self,resetFrame = False, resetStatus = True): frameRow = 0 self.atomWidgets = [] if resetFrame: self.atomFrame = ScrolledFrame(self.atomFrameMaster, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=self.atomFrameRow, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) frame = self.atomFrame.frame # # Make fake info at top for col length... # colNum = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(frame, text = '', width = len(attrName) + 2) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) colNum += 1 # # Now atom info... # for chemCompAtom in self.chemCompAtoms: frameRow += 1 colNum = 0 self.atomWidgets.append([]) for chemCompAtomInfo in chemCompAtom: attrName = chemCompAtomInfo[0] if attrName == 'bondedAtoms': bondedAtomText = "" for otherAtom in chemCompAtomInfo[1]: bondedAtomText += otherAtom[0][1] + ',' label = Label(frame, text = bondedAtomText[:-1]) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) else: if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] == PulldownMenu: self.atomWidgets[-1].append(PulldownMenu(frame, entries = widgetInfo[1], selected_index = widgetInfo[1].index(chemCompAtomInfo[1]))) elif widgetInfo[0] == CheckButton: self.atomWidgets[-1].append(CheckButton(frame, selected = chemCompAtomInfo[1])) else: text = chemCompAtomInfo[1] if not text: text = '' self.atomWidgets[-1].append(Entry(frame, text = text, width = 5)) self.atomWidgets[-1][-1].grid(row=frameRow, column=colNum) colNum += 1 def update(self): self.apply(checkAtoms = False) self.setupAtomFrame() def apply(self, checkAtoms = True): atomNames = [] duplicateNames = [] if checkAtoms: obligatoryAtoms = self.obligatoryAtoms[:] for atomNum in range(0,len(self.chemCompAtoms)): chemCompAtom = self.chemCompAtoms[atomNum] widgets = self.atomWidgets[atomNum] for widgetNum in range(0,len(widgets)): attrName = chemCompAtom[widgetNum][0] if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] in [PulldownMenu,CheckButton]: value = widgets[widgetNum].getSelected() if widgetInfo[0] == CheckButton: if value: value = True else: value = False else: value = widgets[widgetNum].get() if value == '': value = None chemCompAtom[widgetNum] = (attrName,value) if attrName == 'name': if value in atomNames: if value not in duplicateNames: duplicateNames.append(value) else: atomNames.append(value) if checkAtoms: if value in obligatoryAtoms: obligatoryAtoms.pop(obligatoryAtoms.index(value)) if duplicateNames: showWarning(self,"Duplicate atom names: %s - names have to be unique!" % string.join(duplicateNames,', ')) return False if checkAtoms and obligatoryAtoms: showWarning(self,"Obligatory atoms: %s still missing - please rename accordingly." % string.join(obligatoryAtoms,', ')) return False return True
class WindowFunctionSelect(BasePopup): help_url = joinPath(getHelpUrlDir(), 'WindowFunctionSelect.html') def __init__(self, parent, format, dim, getValue): # # General setup # self.maxArgs = 4 self.nmrPipe = 'nmrPipe' self.azara = 'azara' self.format = format self.freqDataDim = parent.freqDataDims[format][dim] self.expDimRef = parent.expDimRefs[dim] # # Window function settings (different per program) # self.windowFunctions = {} specWidth = self.freqDataDim.spectralWidthOrig # TODO: these for azara still have to change a bit... self.windowFunctions[self.azara] = [ ['sine', 'sinebell', [['Angle (deg)', 0, 'deg']]], ['sine^2', 'sinebell2', [['Angle (deg)', 0, 'deg']]], ['exponential (fixed)', 'decay', [['End value', 0.5, 'end']]], [ 'exponential', 'decay_sw', [['Line broadening (Hz)', 10, 'lb'], ['Spectral width (Hz)', specWidth, 'sw']] ], [ 'gaussian (fixed)', 'gaussian', [['Total points fraction for max', 0.25, 'frac'], ['End value', 1, 'end']] ], [ 'gaussian', 'gaussian_sw', [['Line broadening (Hz)', 10, 'lb'], ['Sharpening factor', 0.7, 'shrp'], ['Spectral width (Hz)', specWidth, 'sw']] ], [ 'inverse cosine', 'inv_cosine', [['Frequency (Hz)', 0, 'freq'], ['Spectral width (Hz)', specWidth, 'sw']] ] ] self.windowFunctions[self.nmrPipe] = [ [ 'sine', 'SP', [['Start sine at (pi)', 0, 'off'], ['End sine at (pi)', 1, 'end'], ['Sine to power', 1, 'pow']] ], ['exponential', 'EM', [['Line broadening (Hz)', 10, 'lb']]], [ 'lorentz-gauss', 'GM', [['Inverse exp width (Hz)', 0, 'g1'], ['Gaussian width (Hz)', 0, 'g2'], ['Center (0-1)', 0, 'g3']] ], [ 'gaussian', 'GMB', [['Exponential term', 0, 'lb'], ['Gaussian term', 0, 'gb']] ], [ 'trapezoid', 'TM', [['Ramp length left', 0, 't1'], ['Ramp length right', 0, 't2']] ], [ 'triangle', 'TRI', [['Point loc of apex', 0, 'loc'], ['Left edge height', 0, 'lHi'], ['Right edge height', 0, 'rHi']] ] ] # # Make list of names for pulldown menu # self.windowFuncList = [] for (winFunc, winFuncAppl, winFuncArgs) in self.windowFunctions[format]: self.windowFuncList.append(winFunc) # # Get the right window function from appldata (if there) # self.windowFunctionKeyword = 'windowFunction' self.winFuncIndex = self.getWindowFunctionIndex() # # Set defaults depending on nucleus type if no window function set # if self.winFuncIndex == -1: if format == self.nmrPipe: self.winFuncIndex = 0 if self.expDimRef.isotopeCodes[0] == '1H': # use SP '-off 0.3333 -pow 2.0' self.windowFunctions[self.nmrPipe][ self.winFuncIndex][2][0][1] = 0.3333 self.windowFunctions[self.nmrPipe][ self.winFuncIndex][2][2][1] = 2.0 else: # for non-H, use SP '-off 0.5 -pow 2.0' self.windowFunctions[self.nmrPipe][ self.winFuncIndex][2][0][1] = 0.5 self.windowFunctions[self.nmrPipe][ self.winFuncIndex][2][2][1] = 2.0 elif format == self.azara: self.winFuncIndex = 1 if self.expDimRef.isotopeCodes[0] == '1H': # use sinebell2 60 self.windowFunctions[self.azara][ self.winFuncIndex][2][0][1] = 60 else: # for non-H, use sinebell2 90 self.windowFunctions[self.azara][ self.winFuncIndex][2][0][1] = 90 # Get actual values for arguments from appldata if they exists! self.updateWindowFunctions() # Also using this to return the current window function 'string value' if not getValue: # modal = true means that it won't continue unless this one returns value BasePopup.__init__( self, parent=parent, title='Select window function', modal=False, transient=True, ) def body(self, master): # Master is the owner widget (not self.parent) - parent of the widget here # # Popup window # self.entries = [] self.labels = [] value = 0 row = 0 label = Label(master, text="Window function:") label.grid(row=row, column=0, sticky=Tkinter.EW) self.menuRow = row self.menu = PulldownMenu(master, entries=self.windowFuncList, selected_index=self.winFuncIndex) self.menu.grid(row=row, column=1, sticky=Tkinter.W, ipadx=20) self.menulabel = Label( master, text="(" + self.windowFunctions[self.format][self.winFuncIndex][1] + ")") self.menulabel.grid(row=row, column=2, sticky=Tkinter.E) # # Setup arguments - make room for four # for argIndex in range(0, self.maxArgs): row = row + 1 try: argRef = self.windowFunctions[self.format][ self.winFuncIndex][2][argIndex] argName = argRef[0] argValue = argRef[1] except: argName = None argValue = None self.labels.append(Label(master, text="%s" % argName)) self.labels[-1].grid(row=row, column=0, sticky=Tkinter.EW) self.entries.append(Entry(master, text=str(argValue))) self.entries[-1].grid(row=row, column=1, columnspan=2, sticky=Tkinter.W) if not argName: self.labels[-1].grid_forget() self.entries[-1].grid_forget() # # Add callback to menu after setup # self.menu.callback = self.updateWindow 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, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3) def getApplDataAndReturnString(self): keyword = self.windowFunctionKeyword returnString = self.windowFunctions[self.format][self.winFuncIndex][0] winFuncName = self.windowFunctions[self.format][self.winFuncIndex][1] for (argName, argValue, argShort ) in self.windowFunctions[self.format][self.winFuncIndex][2]: applData = self.freqDataDim.findFirstApplicationData( application=self.format, keyword=keyword + winFuncName + argShort) returnString += ' ' + argShort if not applData: returnString += ' ' + str(argValue) else: returnString += ' ' + str(applData.value) return returnString def updateWindowFunctions(self): keyword = self.windowFunctionKeyword winFuncName = self.windowFunctions[self.format][self.winFuncIndex][1] # # Update windowfunction parameters # for i in range( 0, len(self.windowFunctions[self.format][self.winFuncIndex][2])): (argName, argValue, argShort ) = self.windowFunctions[self.format][self.winFuncIndex][2][i] applData = self.freqDataDim.findFirstApplicationData( application=self.format, keyword=keyword + winFuncName + argShort) if applData: self.windowFunctions[self.format][ self.winFuncIndex][2][i][1] = str(applData.value) def setApplData(self): keyword = self.windowFunctionKeyword winFuncName = self.windowFunctions[self.format][self.winFuncIndex][1] # # Set windowfunction # applData = self.freqDataDim.findFirstApplicationData( application=self.format, keyword=keyword) if not applData: applData = createAppData(self.freqDataDim, application=self.format, keyword=keyword, value=winFuncName) else: applData.value = winFuncName # # Set windowfunction parameters # for (argName, argValue, argShort ) in self.windowFunctions[self.format][self.winFuncIndex][2]: applData = self.freqDataDim.findFirstApplicationData( application=self.format, keyword=keyword + winFuncName + argShort) if not applData: applData = createAppData(self.freqDataDim, application=self.format, keyword=keyword + winFuncName + argShort, value=str(argValue)) else: applData.value = str(argValue) def getWindowFunctionIndex(self): keyword = self.windowFunctionKeyword applData = self.freqDataDim.findFirstApplicationData( application=self.format, keyword=keyword) if applData: origWinFuncAppl = applData.value for i in range(0, len(self.windowFunctions[self.format])): (winFunc, winFuncAppl, winFuncArgs) = self.windowFunctions[self.format][i] if winFuncAppl == origWinFuncAppl: return i return -1 def updateWindow(self, *args): # # First do a value update of the current stuff? # # # Reset arguments # row = self.menuRow self.winFuncIndex = self.menu.getSelectedIndex() self.menulabel.set( "(" + self.windowFunctions[self.format][self.winFuncIndex][1] + ")") for argIndex in range(0, self.maxArgs): row = row + 1 try: argRef = self.windowFunctions[self.format][ self.winFuncIndex][2][argIndex] argName = argRef[0] argValue = argRef[1] except: argName = None argValue = None self.labels[argIndex].set(argName) self.labels[argIndex].grid(row=row, column=0, sticky=Tkinter.W) self.entries[argIndex].set(str(argValue)) self.entries[argIndex].grid(row=row, column=1, columnspan=2, sticky=Tkinter.W) if not argName: self.entries[argIndex].grid_forget() self.labels[argIndex].grid_forget() def setWindowFunctionsValues(self): self.winFuncIndex for argIndex in range( 0, len(self.windowFunctions[self.format][self.winFuncIndex][2])): argValue = returnFloat(self.entries[argIndex].get()) self.windowFunctions[self.format][ self.winFuncIndex][2][argIndex][1] = argValue def apply(self): self.winFuncIndex = self.menu.getSelectedIndex() self.setWindowFunctionsValues() self.setApplData() return True
class ProcParToExpDimPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ProcParToExpDim.html') def __init__(self, parent, experiment, fPars, linkDict=None): self.experiment = experiment self.fPars = fPars self.linkDict = linkDict TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % experiment.root.name + "Experiment dim selection for procPar reading", modal=False, transient=True) def body(self, master): # # Initialize # # # Make expDimRef lists # expDimRefList = [] self.expDimRefDict = {} expDimRefSelection = {} for expDim in self.experiment.sortedExpDims(): if expDim.dim == 1: addInfo = " (acqu)" else: addInfo = "" for expDimRef in expDim.expDimRefs: isotopeString = string.join(expDimRef.isotopeCodes, dirsep) selectionString = "Dim %d, nucl %s %s" % ( expDim.dim, isotopeString, addInfo) expDimRefList.append(selectionString) self.expDimRefDict[selectionString] = expDimRef expDimRefSelection[expDimRef] = len(expDimRefList) - 1 # # Popup info # # # Header labels # columnspan = 4 row = 0 if self.fPars.has_key('inputFile'): text = "Processing file %s" % (self.fPars['inputFile']) else: text = "Processing experiment %s" % (self.experiment.name) label = Label(master, text=text) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 label = Label(master, text="NumPoints") label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text="SW") label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text="Isotope") label.grid(row=row, column=2, sticky=Tkinter.EW) label = Label(master, text="ExpDimRef selection") label.grid(row=row, column=3, sticky=Tkinter.EW) # # Selection per dimension from the procpar file # self.expDimRefMenu = [] for dim in range(0, len(self.fPars['nucleus'])): row = row + 1 label = Label(master, text=str(self.fPars['numPoints'][dim])) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text="%.1f" % self.fPars['spectralWidth'][dim]) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text=self.fPars['nucleus'][dim]) label.grid(row=row, column=2, sticky=Tkinter.EW) expDimRef = self.linkDict[dim] selectedIndex = expDimRefSelection[expDimRef] self.expDimRefMenu.append( PulldownMenu(master, entries=expDimRefList, selected_index=selectedIndex)) self.expDimRefMenu[-1].grid(row=row, column=3, sticky=Tkinter.E, ipadx=20) 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, columnspan=columnspan) def apply(self): self.expDimRefs = [] expDims = [] for dim in range(0, len(self.expDimRefMenu)): expDimRef = self.expDimRefDict[ self.expDimRefMenu[dim].getSelected()] if self.expDimRefs.count(expDimRef) > 0 or expDims.count( expDimRef.expDim) > 0: self.expDimRefs = [] expDims = [] return False elif expDimRef: self.expDimRefs.append(expDimRef) expDims.append(expDimRef.expDim) if len(self.expDimRefs) != self.experiment.numDim: self.expDimRefs = [] return False return True
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 ResonanceGroupPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'ResonanceGroup.html') def __init__(self, parent, resonanceNameList, resonanceLineDict, ccpCode, title='Group resonances'): self.resNameGroups = None self.resonanceNameList = resonanceNameList self.resonanceLineDict = resonanceLineDict self.checkButtons = [] self.ccpCode = ccpCode BasePopup.__init__(self, parent=parent, title=title, modal=True, transient=True) def body(self, master): master.grid_columnconfigure(0, weight=1) master.grid_columnconfigure(1, weight=1) self.geometry('600x400') # # Popup window # row = 0 label = Label(master, text="Residue type '%s'" % self.ccpCode) label.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 label = Label( master, text= "Please select resonances that belong together (remaining ones are also grouped)" ) label.grid(row=row, column=0, sticky=Tkinter.EW) for resName in self.resonanceNameList: row = row + 1 label = Label(master, text="Resonance '%s'" % resName) label.grid(row=row, column=0, sticky=Tkinter.EW) self.checkButtons.append(CheckButton(master)) self.checkButtons[-1].grid(row=row, column=1, 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) for i in range(row): master.grid_rowconfigure(i, weight=1) def apply(self): self.resNameGroups = [] self.resNameGroups.append([]) self.resNameGroups.append([]) for i in range(0, len(self.checkButtons)): checkButton = self.checkButtons[i] if checkButton.isSelected(): groupIndex = 0 else: groupIndex = 1 self.resNameGroups[groupIndex].append(self.resonanceLineDict[i]) 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