示例#1
0
    def __init__(self,
                 parent,
                 label,
                 entry='',
                 separator=': ',
                 label_width=20,
                 entry_width=60,
                 label_anchor=Tkinter.E,
                 show='',
                 returnCallback=None,
                 tipText=None,
                 *args,
                 **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_columnconfigure(1, weight=1)

        self.separator = separator

        text = label + separator
        self.label = Label(self,
                           text=text,
                           width=label_width,
                           anchor=label_anchor)
        self.label.grid(row=0, column=0, sticky=Tkinter.EW)

        self.entry = Entry(self,
                           show=show,
                           width=entry_width,
                           returnCallback=returnCallback,
                           tipText=tipText)
        self.entry.insert(0, entry)
        self.entry.grid(row=0, column=1, sticky=Tkinter.EW)
示例#2
0
    def body(self, master):

        master.grid_columnconfigure(1, weight=1)

        row = 0
        label = Label(master, text='Axis unit name: ', grid=(row, 0))
        tipText = 'Short textual name for the unit, e.g. "KPa" or "ms"'
        self.nameEntry = Entry(master,
                               width=10,
                               grid=(row, 1),
                               tipText=tipText)

        row += 1
        label = Label(master, text='Unit is backwards: ', grid=(row, 0))
        tipText = 'Whether the axis values decrease left to right & bottom to top. For example "ppm" does, but most units do not'
        self.backwardsMenu = BooleanPulldownMenu(master,
                                                 grid=(row, 1),
                                                 tipText=tipText)

        row += 1
        tipTexts = [
            'Make a new unit specification using the stated options and close this popup'
        ]
        texts = ['Create']
        commands = [self.ok]
        buttons = UtilityButtonList(master,
                                    texts=texts,
                                    commands=commands,
                                    closeText='Cancel',
                                    helpUrl=self.help_url,
                                    grid=(row, 0),
                                    gridSpan=(1, 2),
                                    tipTexts=tipTexts)

        master.grid_rowconfigure(row, weight=1)
示例#3
0
    def body(self, master):

        self.geometry('600x130')
        master.grid_columnconfigure(1, weight=1)
        for n in range(5):
            master.grid_rowconfigure(n, weight=1)

        row = 0
        label = Label(master, text='Spectrum: ')
        label.grid(row=row, column=0, sticky='e')
        tipText = 'The spectrum for which the contour file is being added'
        self.expt_spectrum = PulldownList(master,
                                          callback=self.updateContourDir,
                                          tipText=tipText)
        self.expt_spectrum.grid(row=row, column=1, sticky='w')

        row = row + 1
        tipText = 'The location of the directory where contour files are stored on disk'
        label = Label(master, text='Contour dir: ')
        label.grid(row=row, column=0, sticky='e')
        self.dir_label = Label(master, text='', tipText=tipText)
        self.dir_label.grid(row=row, column=1, sticky='w')

        row = row + 1
        label = Label(
            master,
            text=
            '(file will be copied into Contour dir if it is not already in there)'
        )
        label.grid(row=row, column=1, sticky='w')

        row = row + 1
        tipText = 'Browse for a file store contour data'
        button = Button(master,
                        text='File name: ',
                        command=self.selectFile,
                        tipText=tipText)
        button.grid(row=row, column=0, sticky='e')
        tipText = 'Enter the name of the file to store contour data'
        self.file_entry = Entry(master, tipText=tipText)
        self.file_entry.grid(row=row, column=1, sticky='ew')

        row = row + 1
        texts = ['Add File']
        commands = [self.addFile]
        tipTexts = [
            'Use the selected contour file in the current project, copying it to the contour directory if required',
        ]
        self.buttons = UtilityButtonList(master,
                                         texts=texts,
                                         doClone=False,
                                         tipTexts=tipTexts,
                                         commands=commands,
                                         helpUrl=self.help_url)
        self.buttons.grid(row=row, column=0, columnspan=2, sticky='ew')

        self.curateNotifiers(self.registerNotify)
        self.updateSpectrum()
示例#4
0
    def addLabelEntry(self,
                      n,
                      label='',
                      entry='',
                      show='',
                      frozen=False,
                      doGrid=True):

        text = label + self.separator
        l = Tkinter.Label(self,
                          text=text,
                          width=self.label_width,
                          anchor=self.label_anchor)
        self.labels[n:n] = [l]

        e = Entry(self,
                  text=entry,
                  show=show,
                  width=self.entry_width,
                  returnCallback=lambda n=n: self.returnCallback(n))
        if (frozen):
            e.config(bg='gray', state=Tkinter.DISABLED)
            e.bind('<Button>', lambda event, e=e: e.focus())
        else:
            e.config(bg='white')
        self.entries[n:n] = [e]

        if (doGrid):
            self.gridAll()
示例#5
0
    def __init__(self,
                 parent,
                 width=70,
                 height=20,
                 xscroll=False,
                 yscroll=True,
                 *args,
                 **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_columnconfigure(1, weight=1)

        row = 0
        texts = ('back', 'forward', 'load')
        commands = (self.prevUrl, self.nextUrl, self.loadUrl)
        self.buttons = ButtonList(self, texts=texts, commands=commands)
        self.buttons.grid(row=row, column=0)
        self.url_entry = Entry(self, returnCallback=self.loadUrl)
        self.url_entry.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW)
        row = row + 1

        frame = Frame(self)
        frame.grid(row=row, column=0, columnspan=3, sticky=Tkinter.W)
        self.createFindFrame(frame)
        row = row + 1

        self.grid_rowconfigure(row, weight=1)
        self.help_text = ScrolledHtml(self,
                                      width=width,
                                      height=height,
                                      xscroll=xscroll,
                                      yscroll=yscroll,
                                      startUrlCallback=self.startOpenUrl,
                                      endUrlCallback=self.endOpenUrl,
                                      enterLinkCallback=self.setLinkLabel,
                                      leaveLinkCallback=self.setLinkLabel)
        self.help_text.grid(row=row,
                            column=0,
                            columnspan=3,
                            sticky=Tkinter.NSEW)
        row = row + 1

        self.link_label = Label(self)
        self.link_label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W)
        button = memops.gui.Util.createDismissButton(self,
                                                     dismiss_cmd=self.close)
        button.grid(row=row, column=2)

        self.urls = []
        self.current = -1
        self.updateUrlList = True

        self.setButtonState()
示例#6
0
  def body(self, guiParent):
    
    guiParent.grid_columnconfigure(0, weight=1)

    row = 0
    guiParent.grid_rowconfigure(row, weight=1)
    inputFrame = LabelFrame(guiParent, text='Inputs:')
    inputFrame.grid(row=row, column=0, sticky=Tkinter.NSEW)
 
    label = Label(inputFrame, text='NOESY:')
    label.grid(row=0, column=0, sticky=Tkinter.NW)
    
    self.hNoesyPulldown = PulldownMenu(inputFrame,callback=self.setHNoesy)
    self.hNoesyPulldown.grid(row=0, column=1, sticky=Tkinter.NW)

    label = Label(inputFrame, text='15N NOESY:')
    label.grid(row=1, column=0, sticky=Tkinter.NW)
    
    self.nNoesyPulldown = PulldownMenu(inputFrame,callback=self.setNNoesy)
    self.nNoesyPulldown.grid(row=1, column=1, sticky=Tkinter.NW)
    
    label = Label(inputFrame, text='13C NOESY:')
    label.grid(row=2, column=0, sticky=Tkinter.NW)
 
    self.cNoesyPulldown = PulldownMenu(inputFrame,callback=self.setCNoesy)
    self.cNoesyPulldown.grid(row=2, column=1, sticky=Tkinter.NW)
    
    label = Label(inputFrame, text='Shift List:')
    label.grid(row=3, column=0, sticky=Tkinter.NW)
 
    self.shiftListPulldown = PulldownMenu(inputFrame,callback=self.setShiftList)
    self.shiftListPulldown.grid(row=3, column=1, sticky=Tkinter.NW)
    
    label = Label(inputFrame, text='2d BACUS executable:')
    label.grid(row=4, column=0, sticky=Tkinter.NW)
    
    self.executableEntry = Entry(inputFrame, text='/home/tjs23/clouds/justin/SpiBacusMidge/bacus/bacus_tjs.exe')
    self.executableEntry.grid(row=4, column=1, sticky=Tkinter.NW)

    self.executableButton = Button(inputFrame, text='Choose file', command=self.chooseExecutable)
    self.executableButton.grid(row=5, column=1, sticky=Tkinter.EW)
    
    row += 1
    outputFrame = LabelFrame(guiParent, text='Output:')
    outputFrame.grid(row=row, column=0, sticky=Tkinter.NSEW)
 
    row += 1
    texts    = ['Run BACUS 2d','Run BACUS 3d']
    commands = [self.runBacus,self.runBacus3d]
    self.bottomButtons = createDismissHelpButtonList(guiParent,texts=texts,commands=commands,expands=0,help_url=None)
    self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW)
    
    self.update()    
示例#7
0
  def body(self, guiParent):

    guiParent.grid_columnconfigure(1,weight=1)
    row = 0

    file_types = [  FileType('Python', ['*.py']), FileType('All', ['*']) ]
    self.file_select = FileSelect(guiParent, file_types=file_types,
                                  single_callback=self.chooseFile,
                                  double_callback=self.chooseFile)
    self.file_select.grid(row=row, column=0, columnspan=2, sticky='nsew')
    
    row = row + 1
    headingList=('Function',)
    self.scrolledMatrix = ScrolledMatrix(guiParent, initialRows=4,
                            headingList=headingList, callback=self.selectFunction)
    self.scrolledMatrix.grid(row=row, column=0, columnspan=2, sticky='nsew')
    guiParent.grid_rowconfigure(row,weight=1)

    row = row + 1
    self.moduleLabel1 = Label(guiParent, text='Module: ')
    self.moduleLabel1.grid(row=row, column=0, sticky='nw')
    self.moduleLabel2 = Label(guiParent, text=' ')
    self.moduleLabel2.grid(row=row, column=1, sticky='nw')

    row = row + 1
    self.functionLabel1 = Label(guiParent, text='Function: ')
    self.functionLabel1.grid(row=row, column=0, sticky='nw')
    self.functionLabel2 = Label(guiParent, text=' ')
    self.functionLabel2.grid(row=row, column=1, sticky='nw')

    row = row + 1
    self.nameLabel = Label(guiParent, text='Name: ')
    self.nameLabel.grid(row=row, column=0, sticky='nw')
    self.nameEntry = Entry(guiParent, text=' ', width=40)
    self.nameEntry.grid(row=row, column=1, sticky='nw')

    row = row + 1
    texts = [ 'Load Macro' ]
    commands = [ self.loadMacro ]
    buttons = UtilityButtonList(guiParent, texts=texts,
                                commands=commands, helpUrl=self.help_url)
    buttons.grid(row=row, column=0, columnspan=2, sticky='ew')
    
    self.loadButton = buttons.buttons[0]
    self.loadButton.disable()
    
    self.path     = None
    self.module   = None
    self.function = None
示例#8
0
    def body(self, master):

        master.grid_columnconfigure(2, weight=1)

        row = 0
        label = Label(master, text='Data to export:')
        label.grid(row=row, column=0, columnspan=3, sticky=Tkinter.W)

        self.check_buttons = {}
        i = 0
        for heading in self.headings:
            row = row + 1
            isSelected = self.exportSelection.get(row, True)
            self.check_buttons[i] = c = CheckButton(
                master, selected=isSelected, callback=self.toggleCheckButton)
            c.grid(row=row, column=1)
            label = Label(master, text=heading)
            label.grid(row=row, column=2, sticky=Tkinter.W)
            i += 1

        row = row + 1
        button = Button(master, text='File:', command=self.findFile)
        button.grid(row=row, column=0, sticky=Tkinter.W)
        self.file_entry = Entry(master, text=self.file, width=30)
        self.file_entry.grid(row=row,
                             column=1,
                             columnspan=2,
                             sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text='Format:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.format_menu = PulldownMenu(master, entries=exportFormats)
        self.format_menu.grid(row=row,
                              column=1,
                              columnspan=2,
                              sticky=Tkinter.W)

        row = row + 1
        master.grid_rowconfigure(row, weight=1)
        texts = ['Save']
        commands = [self.ok]
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              dismiss_text='Cancel')
        buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW)
示例#9
0
    def __init__(self,
                 parent,
                 values,
                 initial_index=0,
                 orient=Tkinter.HORIZONTAL,
                 scale_length=200,
                 entry_width=5,
                 entry_format='%2.1f',
                 set_callback=None,
                 *args,
                 **kw):

        assert len(values) > 0

        self.entry_format = entry_format
        self.values = tuple(values)
        self.set_callback = set_callback

        apply(Frame.__init__, (self, parent) + args, kw)

        if (orient == Tkinter.HORIZONTAL):
            self.grid_columnconfigure(1, weight=1)
            sticky = Tkinter.EW
            row = 0
            col = 1
        else:
            self.grid_rowconfigure(1, weight=1)
            sticky = Tkinter.NS
            row = 1
            col = 0

        self.entry = Entry(self, width=entry_width)
        self.entry.grid(row=0, column=0, sticky=sticky)
        self.entry.bind('<KeyPress>', self.keyPress)

        self.scale = Tkinter.Scale(self,
                                   orient=orient,
                                   length=scale_length,
                                   from_=0,
                                   to=len(values) - 1,
                                   label='',
                                   showvalue=0,
                                   command=self.setCallback)
        self.scale.grid(row=row, column=col, sticky=sticky)

        self.set(initial_index)
示例#10
0
    def body(self, guiFrame):

        self.geometry('600x250+600+250')

        analysisProfile = self.analysisProfile
        userName = analysisProfile.userName
        userOrganisation = analysisProfile.userOrganisation
        userEmail = analysisProfile.userEmail

        guiFrame.grid_rowconfigure(0, weight=1)
        guiFrame.grid_columnconfigure(1, weight=1)

        explainText = 'To keep track of our users and which versions are being used\n' \
                          'we would like you to register your details with us.\n' \
                    'Collating the number of users is important for grant applications.\n' \
                    'Please do not use accents in any of the information\n' \
                    'because Python does not handle it gracefully.'
        row = 0
        label = Label(guiFrame,
                      text=explainText,
                      grid=(row, 0),
                      gridSpan=(1, 2),
                      sticky='ew')
        row += 1

        licenseAgreeText = 'I agree to abide by the rules of the CCPN licensing agreement.'

        self.agreeButton = CheckButton(guiFrame,
                                       licenseAgreeText,
                                       tipText=licenseAgreeText)
        self.agreeButton.grid(row=row, column=1, columnspan=1, sticky='nsew')

        row += 1

        self.entryWidgets = []
        for (text, value) in (('Name', userName),
                              ('Organisation', userOrganisation), ('Email',
                                                                   userEmail)):
            label = Label(guiFrame, text=text + ':', grid=(row, 0))
            entry = Entry(guiFrame,
                          text=value or '',
                          grid=(row, 1),
                          sticky='ew',
                          tipText='Your ' + text)
            self.entryWidgets.append(entry)
            row += 1

        texts = ['Register Now', 'Read License', 'Register Later']
        tipTexts = ['Register now', 'Read License', 'Register later']
        commands = [self.register, self.openLicense, self.close]
        buttons = UtilityButtonList(guiFrame,
                                    helpUrl=self.help_url,
                                    grid=(row, 0),
                                    gridSpan=(1, 2),
                                    commands=commands,
                                    texts=texts,
                                    tipTexts=tipTexts)
        self.buttons = buttons
示例#11
0
  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)
示例#12
0
class LabeledEntry(Frame):
    def __init__(self,
                 parent,
                 label,
                 entry='',
                 separator=': ',
                 label_width=20,
                 entry_width=60,
                 label_anchor=Tkinter.E,
                 show='',
                 returnCallback=None,
                 tipText=None,
                 *args,
                 **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_columnconfigure(1, weight=1)

        self.separator = separator

        text = label + separator
        self.label = Label(self,
                           text=text,
                           width=label_width,
                           anchor=label_anchor)
        self.label.grid(row=0, column=0, sticky=Tkinter.EW)

        self.entry = Entry(self,
                           show=show,
                           width=entry_width,
                           returnCallback=returnCallback,
                           tipText=tipText)
        self.entry.insert(0, entry)
        self.entry.grid(row=0, column=1, sticky=Tkinter.EW)

    def getLabel(self):

        text = self.label.get()
        n = text.find(self.separator)
        if (n >= 0):
            text = text[:n]

        return text

    def setLabel(self, text=''):

        text = text + self.separator
        self.label.set(text)

    def getEntry(self):

        return self.entry.get()

    def setEntry(self, text=''):

        self.entry.set(text)
示例#13
0
    def body(self, frame):

        label = Label(frame, text=self.prompt)

        if self.hide:
            entry = Entry(frame, text=self.initVal, bg='white', show='*')
        else:
            entry = Entry(frame, text=self.initVal, bg='white')

        label.grid(row=0, column=0, sticky=Tkinter.W)
        entry.grid(row=1, column=0, sticky=Tkinter.W)

        entry.focus_set()  # for the keypresses
        return entry
示例#14
0
    def __init__(self, guiParent, dataText, dataObjects, dataValues, helpText,
                 selectionText, **kw):

        Frame.__init__(self, guiParent, **kw)

        label = Label(self, text=dataText + ':', grid=(0, 0))
        self.selectionList = PulldownList(self,
                                          objects=dataObjects,
                                          texts=dataValues,
                                          grid=(0, 1))
        label = Label(self, text=helpText, grid=(1, 0), gridSpan=(1, 2))
        label = Label(self, text=selectionText + ':', grid=(2, 0))
        self.selectionEntry = Entry(self, grid=(2, 1))
示例#15
0
    def body(self, master):

        #
        # Popup window
        #

        row = 0

        label = Label(master, text=self.topText)
        label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW)

        row = row + 1

        self.valueWidgets = []

        for i in range(0, len(self.valueList)):

            value = self.valueList[i]
            labelText = self.valueInfo[i]

            label = Label(master, text=labelText)
            label.grid(row=row, column=0, sticky=Tkinter.EW)

            self.valueWidgets.append(Entry(master, text=str(value)))
            self.valueWidgets[-1].grid(row=row,
                                       column=1,
                                       sticky=Tkinter.E,
                                       ipadx=20)

            row = row + 1

        texts = ['OK']
        commands = [
            self.ok
        ]  # This calls 'ok' in BasePopup, this then calls 'apply' in here

        if self.dismissButton:
            buttons = createDismissHelpButtonList(
                master,
                texts=texts,
                commands=commands,
                dismiss_text=self.dismissText,
                help_url=self.help_url)
        else:
            buttons = createHelpButtonList(master,
                                           texts=texts,
                                           commands=commands,
                                           help_url=self.help_url)

        buttons.grid(row=row, column=0, columnspan=3)
示例#16
0
    def body(self, master):

        master.grid_columnconfigure(1, weight=1)

        row = 0
        label = Label(master, text='Panel name: ', grid=(row, 0))
        tipText = 'Short text name for the new axis panel, e.g. "N2"'
        self.name_entry = Entry(master,
                                width=15,
                                grid=(row, 1),
                                tipText=tipText)

        row += 1
        label = Label(master, text='Axis type:', grid=(row, 0))
        tipText = 'The type of axis (isotope, time, sampled etc.) represented by panel type'
        self.types_list = PulldownList(master, grid=(row, 1), tipText=tipText)

        row += 1
        tipTexts = [
            'Create a new panel type object with the selected options & close the popup'
        ]
        texts = ['Create']
        commands = [self.ok]
        buttons = UtilityButtonList(master,
                                    texts=texts,
                                    commands=commands,
                                    doClone=False,
                                    closeText='Cancel',
                                    helpUrl=self.help_url,
                                    grid=(row, 0),
                                    gridSpan=(1, 2),
                                    tipTexts=tipTexts)

        master.grid_rowconfigure(row, weight=1)

        self.administerNotifiers(self.registerNotify)
        self.update()
示例#17
0
    def createFindFrame(self, master):

        frame = Frame(master)
        frame.grid(row=0, column=0, sticky=Tkinter.W)

        arrow = ToggleArrow(frame, callback=self.toggleFindFrame)
        arrow.grid(row=0, column=0)
        button = Button(frame, text='find:', command=self.findPhrase)
        button.grid(row=0, column=1)
        self.find_entry = Entry(frame,
                                width=20,
                                returnCallback=self.findPhrase)
        self.find_entry.grid(row=0, column=2)

        self.find_frame = frame = Frame(master)

        entries = ('search forwards', 'search backwards')
        self.direction_buttons = PulldownMenu(frame, entries=entries)
        self.direction_buttons.grid(row=0, column=0, sticky=Tkinter.W, padx=5)

        self.forwards_entries = entries = ('wrap search', 'stop at end')
        self.backwards_entries = ('wrap search', 'stop at beginning')
        self.wrap_buttons = PulldownMenu(frame, entries=entries)
        self.wrap_buttons.grid(row=0, column=1, sticky=Tkinter.W, padx=5)

        self.direction_buttons.callback = self.setWrapText

        entries = ('case insensitive', 'case sensitive')
        self.case_buttons = PulldownMenu(frame, entries=entries)
        self.case_buttons.grid(row=0, column=2, sticky=Tkinter.W, padx=5)

        entries = ('literal search', 'regex search')
        self.pattern_buttons = PulldownMenu(frame, entries=entries)
        self.pattern_buttons.grid(row=0, column=3, sticky=Tkinter.W, padx=5)

        self.countVar = Tkinter.IntVar()
示例#18
0
class CreatePanelTypePopup(BasePopup):
    def __init__(self, parent, *args, **kw):

        self.axisType = None

        BasePopup.__init__(self,
                           parent=parent,
                           title='Create panel type',
                           modal=True,
                           **kw)

    def body(self, master):

        master.grid_columnconfigure(1, weight=1)

        row = 0
        label = Label(master, text='Panel name: ', grid=(row, 0))
        tipText = 'Short text name for the new axis panel, e.g. "N2"'
        self.name_entry = Entry(master,
                                width=15,
                                grid=(row, 1),
                                tipText=tipText)

        row += 1
        label = Label(master, text='Axis type:', grid=(row, 0))
        tipText = 'The type of axis (isotope, time, sampled etc.) represented by panel type'
        self.types_list = PulldownList(master, grid=(row, 1), tipText=tipText)

        row += 1
        tipTexts = [
            'Create a new panel type object with the selected options & close the popup'
        ]
        texts = ['Create']
        commands = [self.ok]
        buttons = UtilityButtonList(master,
                                    texts=texts,
                                    commands=commands,
                                    doClone=False,
                                    closeText='Cancel',
                                    helpUrl=self.help_url,
                                    grid=(row, 0),
                                    gridSpan=(1, 2),
                                    tipTexts=tipTexts)

        master.grid_rowconfigure(row, weight=1)

        self.administerNotifiers(self.registerNotify)
        self.update()

    def administerNotifiers(self, notifyFunc):

        for func in ('__init__', 'delete', 'setName'):
            notifyFunc(self.update, 'ccpnmr.Analysis.AxisType', func)

    def destroy(self):

        self.administerNotifiers(self.unregisterNotify)

        BasePopup.destroy(self)

    def update(self, *extra):

        axisType = self.axisType
        axisTypes = self.parent.getAxisTypes()
        names = [x.name for x in axisTypes]
        if axisTypes:
            if axisType not in axisTypes:
                self.axisType = axisType = axisTypes[0]
            index = axisTypes.index(axisType)
        else:
            index = 0
            self.axisType = None

        self.types_list.setup(names, axisTypes, index)

    def apply(self):

        name = self.name_entry.get()
        if not name:
            showError('No name', 'Need to enter name', parent=self)
            return False

        names = [
            panelType.name for panelType in self.analysisProject.panelTypes
        ]
        if name in names:
            showError('Repeated name', 'Name already used', parent=self)
            return False

        axisType = self.types_list.getObject()

        if not axisType:
            showError('No axis type', 'Need to create axis type', parent=self)
            return False

        self.analysisProject.newPanelType(name=name, axisType=axisType)

        return True
示例#19
0
class CingFrame(NmrSimRunFrame):

  def __init__(self, parent, application, *args, **kw):

    project = application.project
    simStore = project.findFirstNmrSimStore(application=APP_NAME) or \
               project.newNmrSimStore(application=APP_NAME, name=APP_NAME)

    self.application = application
    self.residue = None
    self.structure = None
    self.serverCredentials = None
    self.iCingBaseUrl = DEFAULT_URL
    self.resultsUrl = None
    self.chain = None
    self.nmrProject = application.nmrProject
    self.serverDone = False

    NmrSimRunFrame.__init__(self, parent, project, simStore, *args, **kw)

    # # # # # # New Structure Frame # # # # #

    self.structureFrame.grid_forget()

    tab = self.tabbedFrame.frames[0]

    frame = Frame(tab, grid=(1,0))
    frame.expandGrid(2,1)

    div = LabelDivider(frame, text='Structures', grid=(0,0), gridSpan=(1,2))

    label = Label(frame, text='Ensemble: ', grid=(1,0))
    self.structurePulldown = PulldownList(frame, callback=self.changeStructure, grid=(1,1))

    headingList = ['Model','Use']
    editWidgets      = [None,None]
    editGetCallbacks = [None,self.toggleModel]
    editSetCallbacks = [None,None,]
    self.modelTable = ScrolledMatrix(frame, grid=(2,0), gridSpan=(1,2),
                                     callback=self.selectStructModel,
                                     editWidgets=editWidgets,
                                     editGetCallbacks=editGetCallbacks,
                                     editSetCallbacks=editSetCallbacks,
                                     headingList=headingList)

    texts = ['Activate Selected','Inactivate Selected']
    commands = [self.activateModels, self.disableModels]
    buttons = ButtonList(frame, texts=texts, commands=commands, grid=(3,0), gridSpan=(1,2))


    # # # # # # Submission frame # # # # # #

    tab = self.tabbedFrame.frames[1]
    tab.expandGrid(1,0)

    frame = LabelFrame(tab, text='Server Job Submission', grid=(0,0))
    frame.expandGrid(None,2)

    srow = 0
    label = Label(frame, text='iCing URL:', grid=(srow, 0))
    urls = [DEFAULT_URL,]
    self.iCingBaseUrlPulldown = PulldownList(frame, texts=urls, objects=urls, index=0, grid=(srow,1))


    srow +=1
    label = Label(frame, text='Results File:', grid=(srow, 0))
    self.resultFileEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50)
    self.setZipFileName()
    button = Button(frame, text='Choose File', bd=1, sticky='ew',
                    command=self.chooseZipFile, grid=(srow, 2))

    srow +=1
    label = Label(frame, text='Results URL:', grid=(srow, 0))
    self.resultUrlEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50)
    button = Button(frame, text='View Results HTML', bd=1, sticky='ew',
                    command=self.viewHtmlResults, grid=(srow, 2))

    srow +=1
    texts    = ['Submit Project!', 'Check Run Status',
                'Purge Server Result', 'Download Results']
    commands = [self.runCingServer, self.checkStatus,
                self.purgeCingServer, self.downloadResults]

    self.buttonBar = ButtonList(frame, texts=texts, commands=commands,
                                grid=(srow, 0), gridSpan=(1,3))

    for button in self.buttonBar.buttons[:1]:
      button.config(bg=CING_BLUE)

    # # # # # # Residue frame # # # # # #

    frame = LabelFrame(tab, text='Residue Options', grid=(1,0))
    frame.expandGrid(1,1)

    label = Label(frame, text='Chain: ')
    label.grid(row=0,column=0,sticky='w')
    self.chainPulldown = PulldownList(frame, callback=self.changeChain)
    self.chainPulldown.grid(row=0,column=1,sticky='w')

    headingList = ['#','Residue','Linking','Decriptor','Use?']
    editWidgets      = [None,None,None,None,None]
    editGetCallbacks = [None,None,None,None,self.toggleResidue]
    editSetCallbacks = [None,None,None,None,None,]
    self.residueMatrix = ScrolledMatrix(frame,
                                        headingList=headingList,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        callback=self.selectResidue)
    self.residueMatrix.grid(row=1, column=0, columnspan=2, sticky = 'nsew')

    texts = ['Activate Selected','Inactivate Selected']
    commands = [self.activateResidues, self.deactivateResidues]
    self.resButtons = ButtonList(frame, texts=texts, commands=commands,)
    self.resButtons.grid(row=2, column=0, columnspan=2, sticky='ew')

    """
    # # # # # # Validate frame # # # # # #

    frame = LabelFrame(tab, text='Validation Options', grid=(2,0))
    frame.expandGrid(None,2)

    srow = 0
    self.selectCheckAssign = CheckButton(frame)
    self.selectCheckAssign.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckAssign.set(True)
    label = Label(frame, text='Assignments and shifts')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckResraint = CheckButton(frame)
    self.selectCheckResraint.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckResraint.set(True)
    label = Label(frame, text='Restraints')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckQueen = CheckButton(frame)
    self.selectCheckQueen.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckQueen.set(False)
    label = Label(frame, text='QUEEN')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckScript = CheckButton(frame)
    self.selectCheckScript.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckScript.set(False)
    label = Label(frame, text='User Python script\n(overriding option)')
    label.grid(row=srow,column=1,sticky='nw')

    self.validScriptEntry = Entry(frame, bd=1, text='')
    self.validScriptEntry.grid(row=srow,column=2,sticky='ew')

    scriptButton = Button(frame, bd=1,
                          command=self.chooseValidScript,
                          text='Browse')
    scriptButton.grid(row=srow,column=3,sticky='ew')
    """

    # # # # # # # # # #

    self.update(simStore)

    self.administerNotifiers(application.registerNotify)

  def downloadResults(self):

    if not self.run:
      msg = 'No current iCing run'
      showWarning('Failure', msg, parent=self)
      return

    credentials = self.serverCredentials
    if not credentials:
      msg = 'No current iCing server job'
      showWarning('Failure', msg, parent=self)
      return

    fileName = self.resultFileEntry.get()
    if not fileName:
      msg = 'No save file specified'
      showWarning('Failure', msg, parent=self)
      return

    if os.path.exists(fileName):
      msg = 'File %s already exists. Overwite?' % fileName
      if not showOkCancel('Query', msg, parent=self):
        return

    url = self.iCingBaseUrl
    iCingUrl = self.getServerUrl(url)
    logText = iCingRobot.iCingFetch(credentials, url, iCingUrl, fileName)
    print logText

    msg = 'Results saved to file %s\n' % fileName
    msg += 'Purge results from iCing server?'
    if showYesNo('Query',msg, parent=self):
      self.purgeCingServer()


  def getServerUrl(self, baseUrl):

    iCingUrl = os.path.join(baseUrl, 'icing/serv/iCingServlet')
    return iCingUrl

  def viewHtmlResults(self):

    resultsUrl = self.resultsUrl
    if not resultsUrl:
      msg = 'No current iCing results URL'
      showWarning('Failure', msg, parent=self)
      return

    webBrowser = WebBrowser(self.application, popup=self.application)
    webBrowser.open(self.resultsUrl)


  def runCingServer(self):

    if not self.project:
      return

    run = self.run
    if not run:
      msg = 'No CING run setup'
      showWarning('Failure', msg, parent=self)
      return

    structure = self.structure
    if not structure:
      msg = 'No structure ensemble selected'
      showWarning('Failure', msg, parent=self)
      return

    ensembleText = getModelsString(run)
    if not ensembleText:
      msg = 'No structural models selected from ensemble'
      showWarning('Failure', msg, parent=self)
      return

    residueText = getResiduesString(structure)
    if not residueText:
      msg = 'No active residues selected in structure'
      showWarning('Failure', msg, parent=self)
      return

    url = self.iCingBaseUrlPulldown.getObject()
    url.strip()
    if not url:
      msg = 'No iCing server URL specified'
      showWarning('Failure', msg, parent=self)
      self.iCingBaseUrl = None
      return

    msg = 'Submit job now? You will be informed when the job is done.'
    if not showOkCancel('Confirm', msg, parent=self):
      return

    self.iCingBaseUrl = url
    iCingUrl = self.getServerUrl(url)
    self.serverCredentials, results, tarFileName = iCingRobot.iCingSetup(self.project, userId='ccpnAp', url=iCingUrl)

    if not results:
      # Message already issued on failure
      self.serverCredentials = None
      self.resultsUrl = None
      self.update()
      return

    else:
      credentials = self.serverCredentials
      os.unlink(tarFileName)

    entryId = iCingRobot.iCingProjectName(credentials, iCingUrl).get(iCingRobot.RESPONSE_RESULT)
    baseUrl, htmlUrl, logUrl, zipUrl = iCingRobot.getResultUrls(credentials, entryId, url)

    self.resultsUrl = htmlUrl

    # Save server data in this run for persistence

    setRunParameter(run, iCingRobot.FORM_USER_ID, self.serverCredentials[0][1])
    setRunParameter(run, iCingRobot.FORM_ACCESS_KEY, self.serverCredentials[1][1])
    setRunParameter(run, ICING_BASE_URL, url)
    setRunParameter(run, HTML_RESULTS_URL, htmlUrl)
    self.update()

    run.inputStructures = structure.sortedModels()

    # select residues from the structure's chain
    #iCingRobot.iCingResidueSelection(credentials, iCingUrl, residueText)

    # Select models from ensemble
    #iCingRobot.iCingEnsembleSelection(credentials, iCingUrl, ensembleText)

    # Start the actual run
    self.serverDone = False
    iCingRobot.iCingRun(credentials, iCingUrl)

    # Fetch server progress occasionally, report when done
    # this function will call itself again and again
    self.after(CHECK_INTERVAL, self.timedCheckStatus)

    self.update()

  def timedCheckStatus(self):

    if not self.serverCredentials:
      return

    if self.serverDone:
      return

    status = iCingRobot.iCingStatus(self.serverCredentials, self.getServerUrl(self.iCingBaseUrl))

    if not status:
      #something broke, already warned
      return

    result = status.get(iCingRobot.RESPONSE_RESULT)
    if result == iCingRobot.RESPONSE_DONE:
      self.serverDone = True
      msg = 'CING run is complete!'
      showInfo('Completion', msg, parent=self)
      return

    self.after(CHECK_INTERVAL, self.timedCheckStatus)

  def checkStatus(self):

    if not self.serverCredentials:
      return

    status = iCingRobot.iCingStatus(self.serverCredentials, self.getServerUrl(self.iCingBaseUrl))

    if not status:
      #something broke, already warned
      return

    result = status.get(iCingRobot.RESPONSE_RESULT)
    if result == iCingRobot.RESPONSE_DONE:
      msg = 'CING run is complete!'
      showInfo('Completion', msg, parent=self)
      self.serverDone = True
      return

    else:
      msg = 'CING job is not done.'
      showInfo('Processing', msg, parent=self)
      self.serverDone = False
      return


  def purgeCingServer(self):

    if not self.project:
      return

    if not self.run:
      msg = 'No CING run setup'
      showWarning('Failure', msg, parent=self)
      return

    if not self.serverCredentials:
      msg = 'No current iCing server job'
      showWarning('Failure', msg, parent=self)
      return

    url = self.iCingBaseUrl
    results = iCingRobot.iCingPurge(self.serverCredentials, self.getServerUrl(url))

    if results:
      showInfo('Info','iCing server results cleared')
      self.serverCredentials = None
      self.iCingBaseUrl = None
      self.serverDone = False
      deleteRunParameter(self.run, iCingRobot.FORM_USER_ID)
      deleteRunParameter(self.run, iCingRobot.FORM_ACCESS_KEY)
      deleteRunParameter(self.run, HTML_RESULTS_URL)
    else:
      showInfo('Info','Purge failed')

    self.update()

  def chooseZipFile(self):

    fileTypes = [  FileType('Zip', ['*.zip']), ]
    popup = FileSelectPopup(self, file_types=fileTypes, file=self.resultFileEntry.get(),
                            title='Results zip file location', dismiss_text='Cancel',
                            selected_file_must_exist=False)

    fileName = popup.getFile()

    if fileName:
      self.resultFileEntry.set(fileName)
    popup.destroy()

  def setZipFileName(self):

    zipFile = '%s_CING_report.zip' % self.project.name
    self.resultFileEntry.set(zipFile)

  def selectStructModel(self, model, row, col):

    self.model = model

  def selectResidue(self, residue, row, col):

    self.residue = residue

  def deactivateResidues(self):

    for residue in self.residueMatrix.currentObjects:
      residue.useInCing = False

    self.updateResidues()

  def activateResidues(self):

    for residue in self.residueMatrix.currentObjects:
      residue.useInCing = True

    self.updateResidues()

  def activateModels(self):

    if self.run:
      for model in self.modelTable.currentObjects:
        if model not in self.run.inputStructures:
          self.run.addInputStructure(model)

      self.updateModels()

  def disableModels(self):

    if self.run:
      for model in self.modelTable.currentObjects:
        if model in self.run.inputStructures:
          self.run.removeInputStructure(model)

      self.updateModels()

  def toggleModel(self, *opt):

    if self.model and self.run:
      if self.model in self.run.inputStructures:
        self.run.removeInputStructure(self.model)
      else:
        self.run.addInputStructure(self.model)

      self.updateModels()

  def toggleResidue(self, *opt):

    if self.residue:
      self.residue.useInCing = not self.residue.useInCing
      self.updateResidues()


  def updateResidues(self):

    if self.residue and (self.residue.topObject is not self.structure):
      self.residue = None

    textMatrix = []
    objectList = []
    colorMatrix = []

    if self.chain:
      chainCode = self.chain.code

      for residue in self.chain.sortedResidues():
        msResidue = residue.residue

        if not hasattr(residue, 'useInCing'):
          residue.useInCing = True

        if residue.useInCing:
          colors = [None, None, None, None, CING_BLUE]
          use = 'Yes'

        else:
          colors = [None, None, None, None, None]
          use = 'No'

        datum = [residue.seqCode,
                 msResidue.ccpCode,
                 msResidue.linking,
                 msResidue.descriptor,
                 use,]

        textMatrix.append(datum)
        objectList.append(residue)
        colorMatrix.append(colors)

    self.residueMatrix.update(objectList=objectList,
                              textMatrix=textMatrix,
                              colorMatrix=colorMatrix)


  def updateChains(self):

    index = 0
    names = []
    chains = []
    chain = self.chain

    if self.structure:
      chains = self.structure.sortedCoordChains()
      names = [chain.code for chain in chains]

      if chains:
        if chain not in chains:
          chain = chains[0]
          index = chains.index(chain)

        self.changeChain(chain)

    self.chainPulldown.setup(names, chains, index)


  def updateStructures(self):

    index = 0
    names = []
    structures = []
    structure = self.structure

    if self.run:
      model = self.run.findFirstInputStructure()
      if model:
        structure = model.structureEnsemble

      structures0 = [(s.ensembleId, s) for s in self.project.structureEnsembles]
      structures0.sort()

      for eId, structure in structures0:
        name = '%s:%s' % (structure.molSystem.code, eId)
        structures.append(structure)
        names.append(name)

    if structures:
      if structure not in structures:
        structure = structures[-1]

      index = structures.index(structure)

    self.changeStructure(structure)

    self.structurePulldown.setup(names, structures, index)


  def updateModels(self):

    textMatrix = []
    objectList = []
    colorMatrix = []

    if self.structure and self.run:
      used = self.run.inputStructures

      for model in self.structure.sortedModels():


        if model in used:
          colors = [None, CING_BLUE]
          use = 'Yes'

        else:
          colors = [None, None]
          use = 'No'

        datum = [model.serial,use]

        textMatrix.append(datum)
        objectList.append(model)
        colorMatrix.append(colors)

    self.modelTable.update(objectList=objectList,
                           textMatrix=textMatrix,
                           colorMatrix=colorMatrix)


  def changeStructure(self, structure):

    if self.project and (self.structure is not structure):
      self.project.currentEstructureEnsemble = structure
      self.structure = structure

      if self.run:
        self.run.inputStructures = structure.sortedModels()

      self.updateModels()
      self.updateChains()


  def changeChain(self, chain):

    if self.project and (self.chain is not chain):
      self.chain = chain
      self.updateResidues()

  def chooseValidScript(self):

    # Prepend default Cyana file extension below
    fileTypes = [  FileType('Python', ['*.py']), ]
    popup = FileSelectPopup(self, file_types = fileTypes,
                            title='Python file', dismiss_text='Cancel',
                            selected_file_must_exist = True)

    fileName = popup.getFile()
    self.validScriptEntry.set(fileName)
    popup.destroy()

  def updateAll(self, project=None):

    if project:
      self.project = project
      self.nmrProject = project.currentNmrProject
      simStore = project.findFirstNmrSimStore(application='CING') or \
                 project.newNmrSimStore(application='CING', name='CING')
    else:
      simStore = None

    if not self.project:
      return

    self.setZipFileName()
    if not self.project.currentNmrProject:
      name = self.project.name
      self.nmrProject = self.project.newNmrProject(name=name)
    else:
      self.nmrProject = self.project.currentNmrProject

    self.update(simStore)

  def update(self, simStore=None):

    NmrSimRunFrame.update(self, simStore)

    run = self.run
    urls = [DEFAULT_URL,]
    index = 0

    if run:
      userId = getRunParameter(run, iCingRobot.FORM_USER_ID)
      accessKey = getRunParameter(run, iCingRobot.FORM_ACCESS_KEY)
      if userId and accessKey:
        self.serverCredentials = [(iCingRobot.FORM_USER_ID, userId),
                                  (iCingRobot.FORM_ACCESS_KEY, accessKey)]

      url = getRunParameter(run, ICING_BASE_URL)
      if url:
        htmlUrl = getRunParameter(run, HTML_RESULTS_URL)
        self.iCingBaseUrl = url
        self.resultsUrl = htmlUrl # May be None

      self.resultUrlEntry.set(self.resultsUrl)

      if self.iCingBaseUrl and self.iCingBaseUrl not in urls:
        index = len(urls)
        urls.append(self.iCingBaseUrl)

    self.iCingBaseUrlPulldown.setup(urls, urls, index)

    self.updateButtons()
    self.updateStructures()
    self.updateModels()
    self.updateChains()

  def updateButtons(self, event=None):

    buttons = self.buttonBar.buttons
    if self.project and self.run:
      buttons[0].enable()

      if self.resultsUrl and self.serverCredentials:
        buttons[1].enable()
        buttons[2].enable()
        buttons[3].enable()

      else:
        buttons[1].disable()
        buttons[2].disable()
        buttons[3].disable()

    else:
      buttons[0].disable()
      buttons[1].disable()
      buttons[2].disable()
      buttons[3].disable()
示例#20
0
class NewWindowPopup(BasePopup):
    """
  **Create New Windows to Display Spectra**
  
  This tool is used to make new windows for the graphical display of spectra,
  which will usually be as contours. It is notable that some spectrum windows
  will be made automatically when spectra are loaded if there is no existing
  appropriate window to display a spectrum. However, making new spectrum windows
  allows the user to specialise different windows for different tasks and gives
  complete freedom as to which types of axis go in which direction. For example
  the user may wish to make a new window so that a spectrum can be viewed from
  an orthogonal, rotated aspect.

  A new spectrum window is made by first considering whether it is similar to
  any existing windows. If so, then the user selects the appropriate template
  window to base the new one upon. The user then chooses a name for the window
  via the "New window name" field, although the name may be changed after the
  window is created. Usually the user does not need to consider the "Strips"
  section, but if required the new window can be created with starting strips
  and orthogonal sub-divisions (although these are not permanent). After setting
  the required axes and spectrum visibility, as described below, the user clicks
  on [Create Window!] to actually make the new spectrum display window.

  **Axes**

  The number and type of axes for the new window are chosen using the pulldown
  menus in the "Axes" section. The idea is that the user chooses which NMR
  isotopes should appear on the X, Y, & Z axes. Naturally, X and Y axes must
  always be set to something, to represent the plane of the screen, but the Z
  axes are optional. If not required, a Z axis may be set to "None" to indicate
  that it will not be used. Up to four Z axes may be specified, labelled as
  "z1", "z2" etc., and these represent extra dimensions orthogonal to the plane
  of the  screen, which are often conceptualised as depth axes.
  
  It should be noted that the Y axis type may be set to "value", which refers to
  a spectrum intensity axis, rather than an NMR isotope axis. Setting the Y axis
  to "value" and only having the X axis set to an isotope is used to create
  windows that can show 1D spectra. Such value axes can also be used for 2D and
  higher dimensionality spectra, to show the data as an intensity graph (a
  "slice") rather than as contours.

  **Spectra**

  The lower "Viewed Spectra" section lists all of the spectra within the project
  that may be shown by a window with the selected axes. All spectra with
  isotopes in their data dimensions that match the isotope types of the window
  axes can potentially be displayed. This system also allows for displayed 
  spectra to have fewer dimensions than the axes has windows, as long as at
  least the X and Y axes are present. For example a 2D H-N spectrum can be
  shown in a 3D H-N-H window, but not a 3D H-H-N.

  For spectra that have more than one data dimension of the same isotope, then
  which data dimension goes with which window axis is not always known to
  Analysis. Where there is ambiguity, this system will simply map the spectrum
  data dimensions in order to the next matching window axis. If this mapping
  turns out to be wrong, then it may be changed at any time via the main
  _Windows settings; toggling the "Dim. Mapping" of the "Spectrum & Peak List
  Mappings" tab.
  
  For the spectra listed in the lower table, which may be placed in the new
  window, the user has control over whether the spectra actually will appear.
  Firstly the user can change the "Visible?" column, either via a double-click
  or by using the appropriate lower buttons. By default spectra are set as not
  being visible in new windows, and the user toggles the ones that should be
  seen to "Yes". This basic spectrum visibility can readily be changed by the
  toggle buttons that appear in the "toolbar" at the top of the spectrum
  display, so the "Visible?" setting here is only about what initially appears. 

  The "In Toolbar?" setting of a spectrum is a way of allowing the user to state
  that a spectrum should never appear in the window, and not even allow it to be
  toggled on later via the toolbar at the top of the windows. This is a way of
  reducing clutter, and allows certain windows to be used for particular subsets
  of spectra. For example the user may wish to put the spectra for a temperature
  series in one window, but not in other windows used for resonance assignment
  where they would get in the way. The "In Toolbar" setting can be changed
  after a window has been made, but only via the main Windows_ settings popup.

  .. _Windows: EditWindowPopup.html

  """
    def __init__(self, parent, *args, **kw):

        self.visibleSpectra = parent.visibleSpectra
        self.toolbarSpectra = parent.toolbarSpectra
        self.waiting = False
        self.window = None

        BasePopup.__init__(self,
                           parent=parent,
                           title='Window : New Window',
                           **kw)

    def body(self, guiFrame):

        guiFrame.grid_columnconfigure(2, weight=1)

        row = 0
        label = Label(guiFrame, text='Template window: ', grid=(row, 0))
        tipText = 'Selects which window to use as the basis for making a new spectrum window; sets the axis types accordingly'
        self.window_list = PulldownList(guiFrame,
                                        grid=(row, 1),
                                        callback=self.setAxisTypes,
                                        tipText=tipText)
        frame = LabelFrame(guiFrame,
                           text='Strips',
                           grid=(row, 2),
                           gridSpan=(2, 1))
        buttons = UtilityButtonList(guiFrame,
                                    doClone=False,
                                    helpUrl=self.help_url,
                                    grid=(row, 3))

        row += 1
        label = Label(guiFrame, text='New window name: ', grid=(row, 0))
        tipText = 'A short name to identify the spectrum window, which will appear in the graphical interface'
        self.nameEntry = Entry(guiFrame,
                               width=16,
                               grid=(row, 1),
                               tipText=tipText)

        row += 1

        label = Label(frame, text='Columns: ', grid=(0, 0))
        tipText = 'The number of vertical strips/dividers to initially make in the spectrum window'
        self.cols_menu = PulldownList(frame,
                                      objects=STRIP_NUMS,
                                      grid=(0, 1),
                                      texts=[str(x) for x in STRIP_NUMS],
                                      tipText=tipText)

        label = Label(frame, text='Rows: ', grid=(0, 2))
        tipText = 'The number of horizontal strips/dividers to initially make in the spectrum window'
        self.rows_menu = PulldownList(frame,
                                      objects=STRIP_NUMS,
                                      grid=(0, 3),
                                      texts=[str(x) for x in STRIP_NUMS],
                                      tipText=tipText)
        row += 1
        div = LabelDivider(guiFrame,
                           text='Axes',
                           grid=(row, 0),
                           gridSpan=(1, 4))

        row += 1
        self.axis_lists = {}
        frame = Frame(guiFrame, grid=(row, 0), gridSpan=(1, 4))

        col = 0
        self.axisTypes = {}
        self.axisTypesIncludeNone = {}
        for label in AXIS_LABELS:
            self.axisTypes[label] = None
            w = Label(frame, text=' ' + label)
            w.grid(row=0, column=col, sticky='w')
            col += 1

            if label in ('x', 'y'):
                includeNone = False
                tipText = 'Sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label
            else:
                includeNone = True
                tipText = 'Where required, sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label
            self.axisTypesIncludeNone[label] = includeNone

            getAxisTypes = lambda label=label: self.getAxisTypes(label)
            callback = lambda axisType, label=label: self.changedAxisType(
                label, axisType)
            self.axis_lists[label] = PulldownList(frame,
                                                  callback=callback,
                                                  tipText=tipText)
            self.axis_lists[label].grid(row=0, column=col, sticky='w')
            col += 1

        frame.grid_columnconfigure(col, weight=1)

        row += 1
        div = LabelDivider(guiFrame,
                           text='Viewed Spectra',
                           grid=(row, 0),
                           gridSpan=(1, 4))

        row += 1
        guiFrame.grid_rowconfigure(row, weight=1)

        editWidgets = [None, None, None, None]
        editGetCallbacks = [None, self.toggleVisible, self.toggleToolbar, None]
        editSetCallbacks = [None, None, None, None]
        tipTexts = [
            'The "experiment:spectrum" name for the spectrum that may be viewed in the new window, given the axis selections',
            'Sets whether the spectrum contours will be visible in the new window',
            'Sets whether the spectrum appears at all in the window; if not in the toolbar it cannot be displayed',
            'The number of peak lists the spectrum contains'
        ]
        headingList = ['Spectrum', 'Visible?', 'In Toolbar?', 'Peak Lists']

        self.scrolledMatrix = ScrolledMatrix(guiFrame,
                                             headingList=headingList,
                                             editWidgets=editWidgets,
                                             editGetCallbacks=editGetCallbacks,
                                             editSetCallbacks=editSetCallbacks,
                                             multiSelect=True,
                                             grid=(row, 0),
                                             gridSpan=(1, 4),
                                             tipTexts=tipTexts)

        row += 1
        tipTexts = [
            'Creates a new spectrum window with the specified parameters',
            'Sets the contours of the selected spectra to be visible when the new window is made',
            'Sets the contours of the selected spectra to not be displayed when the new window is made',
            'Sets the selected spectra as absent from the window toolbar, and thus not displayable at all'
        ]
        texts = [
            'Create Window!', 'Selected\nVisible', 'Selected\nNot Visible',
            'Selected\nNot In Toolbar'
        ]
        commands = [
            self.ok, self.setSelectedDisplay, self.setSelectedHide,
            self.setSelectedAbsent
        ]
        buttonList = ButtonList(guiFrame,
                                texts=texts,
                                grid=(row, 0),
                                commands=commands,
                                gridSpan=(1, 4),
                                tipTexts=tipTexts)
        buttonList.buttons[0].config(bg='#B0FFB0')

        self.updateAxisTypes()
        self.updateWindow()
        self.updateWindowName()

        self.administerNotifiers(self.registerNotify)
        self.updateAfter()

    def administerNotifiers(self, notifyFunc):

        self.registerNotify(self.updateWindowName,
                            'ccpnmr.Analysis.SpectrumWindow', '__init__')

        for clazz in ('ccp.nmr.Nmr.Experiment', 'ccp.nmr.Nmr.DataSource'):
            for func in ('__init__', 'delete', 'setName'):
                notifyFunc(self.updateAfter, clazz, func)

        for func in ('__init__', 'delete'):
            notifyFunc(self.updateAfter, 'ccp.nmr.Nmr.PeakList', func)

        for func in ('__init__', 'delete', 'setName', 'addSpectrumWindowGroup',
                     'removeSpectrumWindowGroup', 'setSpectrumWindowGroups'):
            notifyFunc(self.updateWindow, 'ccpnmr.Analysis.SpectrumWindow',
                       func)

        for func in ('addSpectrumWindow', 'removeSpectrumWindow',
                     'setSpectrumWindows'):
            notifyFunc(self.updateWindow,
                       'ccpnmr.Analysis.SpectrumWindowGroup', func)

        for func in ('__init__', 'delete', 'setName'):
            notifyFunc(self.updateAxisTypes, 'ccpnmr.Analysis.AxisType', func)


# Set visible contours, on commit, according to selection
#   Get hold of spectrumWindowView ASAP

    def destroy(self):

        self.administerNotifiers(self.unregisterNotify)

        BasePopup.destroy(self)

    def getSpectra(self):

        spectrumIsotopes = {}

        spectra = []
        for experiment in self.nmrProject.sortedExperiments():
            name = experiment.name

            for spectrum in experiment.sortedDataSources():
                spectrumIsotopes[spectrum] = []
                spectra.append(['%s:%s' % (name, spectrum.name), spectrum])

                for dataDim in spectrum.dataDims:
                    dimTypes = []

                    if dataDim.className != 'SampledDataDim':
                        for dataDimRef in dataDim.dataDimRefs:
                            expDimRef = dataDimRef.expDimRef
                            isotopes = set()

                            for isotopeCode in expDimRef.isotopeCodes:
                                isotopes.add(isotopeCode)

                            dimTypes.append(
                                (expDimRef.measurementType.lower(), isotopes))
                    else:
                        dimTypes.append('sampled')

                    spectrumIsotopes[spectrum].append(dimTypes)

        axisIsotopes = {}
        for label in AXIS_LABELS:
            if label not in ('x', 'y'):
                if self.axis_lists[label].getSelectedIndex() == 0:
                    continue

            axisType = self.axis_lists[label].getObject()
            axisIsotopes[label] = (axisType.measurementType.lower(),
                                   set(axisType.isotopeCodes))

        spectraSel = []
        axes = axisIsotopes.keys()
        axes.sort()
        for name, spectrum in spectra:
            dimIsotopes = spectrumIsotopes[spectrum]

            for label in axes:
                mType, selected = axisIsotopes[label]
                if label == 'y' and mType == 'none':
                    continue  # value axis

                for i, dimTypes in enumerate(dimIsotopes):
                    for dimType in dimTypes:
                        if dimType == 'sampled':
                            if label != 'z1':
                                continue
                            axisType = self.axis_lists[label].getObject()
                            if axisType.name != 'sampled':
                                continue
                            dimIsotopes.pop(i)
                            break
                        else:
                            measurementType, isotopes = dimType
                            if (mType == measurementType) and (selected <=
                                                               isotopes):
                                dimIsotopes.pop(i)
                                break
                    else:
                        continue
                    break

                else:
                    if label in ('x', 'y'):
                        break

            else:

                if not dimIsotopes:
                    spectraSel.append([name, spectrum])

        return spectraSel

    def setSelectedAbsent(self):

        for spectrum in self.scrolledMatrix.currentObjects:
            self.visibleSpectra[spectrum] = False
            self.toolbarSpectra[spectrum] = False

        self.updateAfter()

    def setSelectedDisplay(self):

        for spectrum in self.scrolledMatrix.currentObjects:
            self.visibleSpectra[spectrum] = True
            self.toolbarSpectra[spectrum] = True

        self.updateAfter()

    def setSelectedHide(self):

        for spectrum in self.scrolledMatrix.currentObjects:
            self.visibleSpectra[spectrum] = False
            self.toolbarSpectra[spectrum] = True

        self.updateAfter()

    def toggleToolbar(self, spectrum):

        boolean = not self.toolbarSpectra.get(spectrum, True)
        self.toolbarSpectra[spectrum] = boolean

        if boolean is False:
            self.visibleSpectra[spectrum] = False

        self.updateAfter()

    def toggleVisible(self, spectrum):

        boolean = not self.visibleSpectra.get(spectrum, False)
        self.visibleSpectra[spectrum] = boolean

        if boolean:
            if not self.toolbarSpectra.get(spectrum, True):
                self.toolbarSpectra[spectrum] = True

        self.updateAfter()

    def updateAfter(self, object=None):

        if self.waiting:
            return

        else:
            self.waiting = True
            self.after_idle(self.update)

    def update(self):

        for spectrum in self.visibleSpectra.keys():
            if spectrum.isDeleted:
                del self.visibleSpectra[spectrum]

        textMatrix = []
        objectList = []
        colorMatrix = []

        for name, spectrum in self.getSpectra():
            colours = [None, None, None, None]

            if self.visibleSpectra.get(spectrum):
                colours[0] = '#60F060'
                isVisible = 'Yes'
                self.visibleSpectra[
                    spectrum] = True  # do not need this but play safe in case above if changed
            else:
                isVisible = 'No'
                self.visibleSpectra[spectrum] = False

            if self.toolbarSpectra.get(spectrum, True):
                inToolbar = 'Yes'
                self.toolbarSpectra[spectrum] = True
            else:
                colours[0] = '#600000'
                inToolbar = 'No'
                self.toolbarSpectra[spectrum] = False

            datum = [
                name, isVisible, inToolbar,
                ','.join(['%d' % pl.serial for pl in spectrum.peakLists])
            ]

            textMatrix.append(datum)
            objectList.append(spectrum)
            colorMatrix.append(colours)

        self.scrolledMatrix.update(objectList=objectList,
                                   textMatrix=textMatrix,
                                   colorMatrix=colorMatrix)

        self.waiting = False

    def updateAxisTypes(self, *extra):

        for label in AXIS_LABELS:
            names = []
            objects = []
            includeNone = self.axisTypesIncludeNone[label]

            if includeNone:
                names.append('None')
                objects.append(None)
            axisType = self.axisTypes[label]
            axisTypes = self.getAxisTypes(label)
            objects.extend(axisTypes)

            if axisTypes:
                if axisType not in objects:
                    axisType = objects[0]
                index = objects.index(axisType)
                names.extend([x.name for x in axisTypes])

            else:
                index = 0

            self.axis_lists[label].setup(names, objects, index)
            self.changedAxisType(label, axisType)

    def changedAxisType(self, label, axisType):

        if axisType is not self.axisTypes[label]:
            self.axisTypes[label] = axisType

        self.updateAfter()

    def updateWindow(self, *extra):

        window = self.window
        windows = self.parent.getWindows()
        if windows:
            if window not in windows:
                window = windows[0]
            index = windows.index(window)
            names = [x.name for x in windows]
        else:
            index = 0
            names = []

        self.window_list.setup(names, windows, index)
        self.setAxisTypes(window)

    def updateWindowName(self, *extra):

        self.nameEntry.set(WindowBasic.defaultWindowName(self.project))

    def getAxisTypes(self, label):

        axisTypes = self.parent.getAxisTypes()

        if label == 'z1':
            axisTypes = [
                axisType for axisType in axisTypes
                if axisType.name == 'sampled' or not axisType.isSampled
            ]
        else:
            axisTypes = [
                axisType for axisType in axisTypes if not axisType.isSampled
            ]

        if label != 'y':
            axisTypes = [
                at for at in axisTypes
                if at.name != WindowBasic.VALUE_AXIS_NAME
            ]

        return axisTypes

    def setAxisTypes(self, window):

        project = self.project
        if not project:
            return

        if window is self.window:
            return

        self.window = window
        if window:
            windowPanes = window.sortedSpectrumWindowPanes()
            if windowPanes:
                # might be empty because notifier called before windowPanes set up
                windowPane = windowPanes[0]

                for label in AXIS_LABELS:
                    axisPanel = windowPane.findFirstAxisPanel(label=label)

                    if axisPanel and axisPanel.panelType \
                        and axisPanel.panelType.axisType:
                        self.axis_lists[label].setSelected(
                            axisPanel.panelType.axisType)

                    elif label not in ('x', 'y'):
                        self.axis_lists[label].setIndex(0)

            self.updateAfter()

    def apply(self):

        project = self.project
        if not project:
            return False

        name = self.nameEntry.get().strip()
        if not name:
            showError('No name', 'Need to enter name', parent=self)
            return False

        names = [
            window.name for window in self.analysisProject.spectrumWindows
        ]

        if (name in names):
            showError('Repeated name', 'Name already used', parent=self)
            return False

        axisTypes = []
        for label in AXIS_LABELS:
            if label not in ('x', 'y'):
                if self.axis_lists[label].getSelectedIndex() == 0:
                    continue

            axisType = self.axis_lists[label].getObject()
            axisTypes.append(axisType)

        ncols = self.cols_menu.getObject()
        nrows = self.rows_menu.getObject()

        window = WindowBasic.createSpectrumWindow(project,
                                                  name, [
                                                      axisTypes,
                                                  ],
                                                  ncols=ncols,
                                                  nrows=nrows)

        return True
示例#21
0
  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
示例#22
0
class AnnealingSettingsTab(object):
    '''This class describes the tab in the GUI where the user
       can change setting that govern the monte carlo / annleaing
       procedure. This also includes which information from the ccpn
       analysis project is used and which information is
       ignored. This includes:
           * present sequential assignments
           * tentative assignments
           * amino acid type information
           * whether to include untyped spin systems
           * assignments to peak dimensions
       ALso the chain can be selected here.
       Furthermore the user can set the temperature
       regime of the annealing, the amount of times the procedure
       is repeated to obtain statistics. The fraction of peaks
       that is left out in each run to diversify the results,
       the treshhold score for amino acid typing and the treshhold
       collabelling for a peak to be expected.
    '''

    def __init__(self, parent, frame):
        '''Init. args: parent: the guiElement that this
                               tab is part of.
                       frame:  the frame this part of the
                               GUI lives in.
        '''

        self.guiParent = parent
        self.frame = frame
        self.project = parent.project
        self.nmrProject = parent.nmrProject

        self.minIsoFrac = 0.1
        self.leavePeaksOutFraction = 0.0
        self.minTypeScore = 1.0
        self.chain = None
        self.amountOfRepeats = 10
        self.amountOfSteps = 10000
        self.acceptanceConstantList = [0.0, 0.01, 0.015, 0.022,
                                       0.033, 0.050, 0.075, 0.113,
                                       0.170, 0.256, 0.384, 0.576,
                                       0.864, 1.297, 1.946, 2.919,
                                       4.378, 6.568, 9.852, 14.77,
                                       22.16, 33.25]
        self.energyDataSets = [[]]
        self.residues = []
        self.body()

    def body(self):
        '''describes the body of this tab. It bascically consists
           of some field to fill out for the user at the top and
           a ScrolledGraph that shows the progess of the annealing
           procedure a the bottom.
        '''

        frame = self.frame

        # frame.expandGrid(13,0)
        frame.expandGrid(15, 1)
        row = 0

        text = 'Calculate Assignment Suggestions'
        command = self.runCalculations
        self.startButton = Button(frame, command=command, text=text)
        self.startButton.grid(row=row, column=0, sticky='nsew', columnspan=2)

        row += 1

        Label(frame, text='Amount of runs: ', grid=(row, 0))
        tipText = 'The amount of times the whole optimization procedure is performed, each result is safed'
        self.repeatEntry = IntEntry(frame, grid=(row, 1), width=7, text=10,
                                    returnCallback=self.updateRepeatEntry,
                                    tipText=tipText, sticky='nsew')
        self.repeatEntry.bind('<Leave>', self.updateRepeatEntry, '+')

        row += 1

        Label(frame, text='Temperature regime: ', grid=(row, 0))
        tipText = 'This list of numbers govern the temperature steps during the annealing, every number represents 1/(kb*t), where kb is the Boltzmann constant and t the temperature of one step.'
        self.tempEntry = Entry(frame, text=map(str, self.acceptanceConstantList), width=64,
                               grid=(row, 1), isArray=True, returnCallback=self.updateAcceptanceConstantList,
                               tipText=tipText, sticky='nsew')

        row += 1

        Label(frame, text='Amount of attempts per temperature:', grid=(row, 0))
        tipText = 'The amount of attempts to switch the position of two spinsystems in the sequence are performed for each temperature point'
        self.NAStepEntry = IntEntry(frame, grid=(row, 1), width=7, text=10000,
                                    returnCallback=self.updateStepEntry,
                                    tipText=tipText, sticky='nsew')
        self.NAStepEntry.bind('<Leave>', self.updateStepEntry, '+')

        row += 1

        Label(frame, text='Fraction of peaks to leave out:', grid=(row, 0))
        tipText = 'In each run a fraction of the peaks can be left out of the optimization, thereby increasing the variability in the outcome and reducing false negatives. In each run this will be different randomly chosen sub-set of all peaks. 0.1 (10%) can be a good value.'
        self.leaveOutPeaksEntry = FloatEntry(frame, grid=(row, 1), width=7, text=0.0,
                                             returnCallback=self.updateLeavePeaksOutEntry,
                                             tipText=tipText, sticky='nsew')
        self.leaveOutPeaksEntry.bind(
            '<Leave>', self.updateLeavePeaksOutEntry, '+')

        row += 1

        Label(frame, text='Minmal amino acid typing score:', grid=(row, 0))
        tipText = 'If automatic amino acid typing is selected, a cut-off value has to set. Every amino acid type that scores higher than the cut-off is taken as a possible type. This is the same score as can be found under resonance --> spin systems --> predict type. Value should be between 0 and 100'
        self.minTypeScoreEntry = FloatEntry(frame, grid=(row, 1), width=7, text=1.0,
                                            returnCallback=self.updateMinTypeScoreEntry,
                                            tipText=tipText, sticky='nsew')
        self.minTypeScoreEntry.bind(
            '<Leave>', self.updateMinTypeScoreEntry, '+')

        row += 1

        Label(frame, text='Minimal colabelling fraction:', grid=(row, 0))
        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minLabelEntry = FloatEntry(frame, grid=(row, 1), width=7, text=0.1,
                                        returnCallback=self.updateMinLabelEntry,
                                        tipText=tipText, sticky='nsew')
        self.minLabelEntry.bind('<Leave>', self.updateMinLabelEntry, '+')

        row += 1

        Label(frame, text='Use sequential assignments:', grid=(row, 0))
        tipText = 'When this option is select the present sequential assignments will be kept in place'
        self.useAssignmentsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use tentative assignments:', grid=(row, 0))
        tipText = 'If a spin system has tentative assignments this can be used to narrow down the amount of possible sequential assignments.'
        self.useTentativeCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use amino acid types:', grid=(row, 0))
        tipText = 'Use amino acid types of the spin systems. If this option is not checked the spin systems are re-typed, only resonance names and frequencies are used'
        self.useTypeCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Include untyped spin systems:', grid=(row, 0))
        tipText = 'Also include spin system that have no type information. Amino acid typing will be done on the fly.'
        self.useAlsoUntypedSpinSystemsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use dimensional assignments:', grid=(row, 0))
        tipText = 'If one or more dimensions of a peak is already assigned, assume that this assignment is the only option. If not the check the program will consider all possibilities for the assignment of the dimension.'
        self.useDimensionalAssignmentsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Chain:', grid=(row, 0))
        self.molPulldown = PulldownList(
            frame, callback=self.changeMolecule, grid=(row, 1))
        self.updateChains()

        row += 1

        Label(frame, text='Residue ranges: ', grid=(row, 0))
        tipText = 'Which residues should be included. Example: "10-35, 62-100, 130".'
        self.residueRangeEntry = Entry(frame, text=None, width=64,
                                       grid=(row, 1), isArray=True, returnCallback=self.updateResidueRanges,
                                       tipText=tipText, sticky='nsew')
        self.updateResidueRanges(fromChain=True)

        row += 1

        self.energyPlot = ScrolledGraph(frame, symbolSize=2, width=600,
                                        height=200, title='Annealing',
                                        xLabel='temperature step', yLabel='energy')
        self.energyPlot.grid(row=row, column=0, columnspan=2, sticky='nsew')

    def runCalculations(self):
        '''Run all calculations. Also triggers the disabling of
           some buttons and fields.
        '''

        self.startButton.disable()
        self.disableIllegalButtonsAfterPrecalculations()
        self.guiParent.connector.runAllCalculations()
        self.startButton.configure(text='More runs')
        self.startButton.enable()

    def disableIllegalButtonsAfterPrecalculations(self):
        '''Disable buttons and field the user can not alter
           any longer after the model is set up and the
           'pre-calculations' have finished.
           This is done because this part of the calculation
           should only be run once. All settings that would
           be changed after this point will not have any influence.
        '''

        illegalButtons = [self.minTypeScoreEntry, self.minLabelEntry,
                          self.useAlsoUntypedSpinSystemsCheck, self.useAssignmentsCheck,
                          self.useTypeCheck, self.useDimensionalAssignmentsCheck,
                          self.useTentativeCheck]

        for illegalButton in illegalButtons:
            illegalButton.configure(state='disabled')

        self.molPulldown.disable()

    def getChainName(self, chain):
        '''Get the name for a chain.
               args: chain: ccpn analysis
                            chain object
               returns: chain name
        '''

        return '%s:%s (%s)' % (chain.molSystem.code, chain.code, chain.molecule.molType)

    def getChains(self):
        '''Get all chains present in the project.
               returns: list of ccpn analysis chain objects
        '''
        chains = []
        if self.project:
            for molSystem in self.project.sortedMolSystems():
                for chain in molSystem.sortedChains():
                    if chain.residues:
                        chains.append(chain)

        return chains

    def updateChains(self, *opt):
        '''Updates the list of chains if a new one is added
           to or deleted from the project. Updates the
           pull down list where a chain can be selected.
        '''

        index = 0
        texts = []
        chains = self.getChains()
        chain = self.chain

        if chains:
            if chain not in chains:
                chain = chains[0]

            texts = [self.getChainName(c) for c in chains]
            index = chains.index(chain)

        else:
            chain = None

        self.molPulldown.setup(texts, chains, index)

        if chain is not self.chain:
            self.chain = chain

    def changeMolecule(self, chain):
        '''Select a molecular chain.'''

        if chain is not self.chain:
            self.chain = chain
            self.updateResidueRanges(fromChain=True)

    def updateStepEntry(self, event=None):
        '''Update the value and entry that sets the amount of
           steps per temperature point.
        '''

        value = self.NAStepEntry.get()
        if value == self.amountOfSteps:
            return
        if value < 1:
            self.NAStepEntry.set(1)
            self.amountOfSteps = 1
        else:
            self.amountOfSteps = value
            self.NAStepEntry.set(value)

    def updateRepeatEntry(self, event=None):
        '''Update the value and entry of that sets
           the amount of times the whole annealing
           procedure is repeated in order
           to obtain statistics.
        '''

        value = self.repeatEntry.get()

        if value == self.amountOfRepeats:
            return
        if value < 1:
            self.repeatEntry.set(1)
            self.amountOfRepeats = 1
        else:
            self.amountOfRepeats = value
            self.repeatEntry.set(value)

    def updateMinTypeScoreEntry(self, event=None):
        '''Updates the value and the entry for the
           treshhold value for amino acid typing.
        '''

        value = self.minTypeScoreEntry.get()

        if value == self.minTypeScore:
            return
        if value < 0:
            self.minTypeScoreEntry.set(0.0)
            self.minTypeScore = 0.0
        elif value > 100:
            self.minTypeScoreEntry.set(100.0)
            self.minTypeScore = 100.0
        else:
            self.minTypeScoreEntry.set(value)
            self.minTypeScore = value

    def updateMinLabelEntry(self, event=None):
        '''Updates the minimum colabelling fraction
           for which a peak is expected to be present
           in the spectra.
        '''

        value = self.minLabelEntry.get()

        if value == self.minIsoFrac:
            return
        if value < 0:
            self.minIsoFrac = 0.0
            self.minLabelEntry.set(0.0)
        elif value > 1:
            self.minIsoFrac = 1.0
            self.minLabelEntry.set(1.0)
        else:
            self.minIsoFrac = value
            self.minLabelEntry.set(value)

    def updateLeavePeaksOutEntry(self, event=None):
        '''Updates the value and entry of the fraction
           of peaks that should be left out in each
           run in order to diversify the results.
        '''

        value = self.leaveOutPeaksEntry.get()

        if value == self.leavePeaksOutFraction:
            return
        if value < 0:
            self.leavePeaksOutFraction = 0.0
            self.leaveOutPeaksEntry.set(0.0)
        elif value > 1:
            self.leavePeaksOutFraction = 1.0
            self.leaveOutPeaksEntry.set(1.0)
        else:
            self.leavePeaksOutFraction = value
            self.leaveOutPeaksEntry.set(value)

    def updateAcceptanceConstantList(self, event=None):
        '''Updates the list with constants that are used
           during the monte carlo procedure to decide whether
           a changed is accepted or not.
        '''

        acList = self.tempEntry.get()
        newList = []

        for constant in acList:

            try:

                number = float(constant)
                newList.append(number)

            except ValueError:

                string = constant + \
                    ' in temperature constants is not a number.'

                showWarning('Not A Number', string, parent=self.guiParent)

                return False

        self.acceptanceConstantList = newList

        return True

    def updateResidueRanges(self, event=None, fromChain=False):

        self.residues = set()

        subRanges = self.residueRangeEntry.get()
        if not subRanges or fromChain:
            self.residues = set(self.chain.residues)
            residues = self.chain.sortedResidues()
            text = '{}-{}'.format(residues[0].seqCode, residues[-1].seqCode)
            self.residueRangeEntry.set(text=text)
            return

        for subRange in subRanges:
            indeces = subRange.split('-')
            start = int(indeces[0])
            stop = int(indeces[-1]) + 1
            for seqCode in range(start, stop):
                residue = self.chain.findFirstResidue(seqCode=seqCode)
                if not residue:
                    showWarning('Residue out of range.',
                                'There is no residue at position {}'.format(seqCode),
                                parent=self.guiParent)
                    self.residues = set()
                    return
                self.residues.add(residue)

    def addEnergyPoint(self, energy, time):
        '''Adds a point to the graph that shows the progress
           of the annealling procedure.
               args: energy: the y-value
                     time:   the x-value
        '''

        point = (time, energy * -1)

        # This means one run has finished
        if len(self.energyDataSets[-1]) / (len(self.acceptanceConstantList) + 1):

            self.energyDataSets.append([point])

        else:

            self.energyDataSets[-1].append(point)

        colors = colorSeries
        Ncolors = len(colors)
        NdataSets = len(self.energyDataSets)
        colorList = (NdataSets / Ncolors) * colors + \
            colors[:NdataSets % Ncolors]
        self.energyPlot.update(dataSets=self.energyDataSets,
                               dataColors=colorList)

        # Forcing the graph to draw, eventhough calculations
        # are still running. Only do this with high numbers of
        # steps, otherwise drawing takes longer than annealling.
        if self.amountOfSteps >= 100000:

            self.energyPlot.draw()
示例#23
0
  def body(self, guiFrame):

    self.geometry("500x500")

    self.nameEntry  = Entry(self, text='', returnCallback=self.setName,    width=12)
    self.detailsEntry = Entry(self, text='', returnCallback=self.setDetails, width=16)
    self.valueEntry = FloatEntry(self, text='', returnCallback=self.setValue, width=10)
    self.errorEntry = FloatEntry(self, text='', returnCallback=self.setError, width=8)
    
    self.conditionNamesPulldown = PulldownList(self, callback=self.setConditionName,
                                               texts=self.getConditionNames())
    self.unitPulldown = PulldownList(self, callback=self.setUnit,
                                     texts=self.getUnits())
    self.experimentPulldown = PulldownList(self, callback=self.setExperiment)

    guiFrame.grid_columnconfigure(0, weight=1)

    row = 0
    frame = Frame(guiFrame, grid=(row, 0))
    frame.expandGrid(None,0)
    div = LabelDivider(frame, text='Current Series', grid=(0, 0))
    utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0,1))

    row += 1
    frame0 = Frame(guiFrame, grid=(row, 0))
    frame0.expandGrid(0,0)
    tipTexts = ['The serial number of the experiment series, but left blank if the series as actually a pseudo-nD experiment (with a sampled non-frequency axis)',
                'The name of the experiment series, which may be a single pseudo-nD experiment',
                'The number of separate experiments (and hence spectra) present in the series',
                'The kind of quantity that varies for different experiments/planes within the NMR series, e.g. delay time, temperature, ligand concentration etc.',
                'The number of separate points, each with a separate experiment/plane and parameter value, in the series']
    headingList      = ['#','Name','Experiments','Parameter\nVaried','Num\nPoints']
    editWidgets      = [None, self.nameEntry, None, self.conditionNamesPulldown, None]
    editGetCallbacks = [None, self.getName,   None, self.getConditionName, None]
    editSetCallbacks = [None, self.setName,   None, self.setConditionName, None]
    self.seriesMatrix = ScrolledMatrix(frame0, tipTexts=tipTexts,
                                       editSetCallbacks=editSetCallbacks,
                                       editGetCallbacks=editGetCallbacks,
                                       editWidgets=editWidgets,
                                       headingList=headingList,
                                       callback=self.selectExpSeries,
                                       deleteFunc=self.deleteExpSeries,
                                       grid=(0,0), gridSpan=(None, 3))

    tipTexts = ['Make a new, blank NMR series specification in the CCPN project',
                'Delete the selected NMR series from the project, although any component experiments remain. Note you cannot delete pseudo-nD series; delete the actual experiment instead',
                'Colour the spectrum contours for each experiment in the selected series (not pseudo-nD) using a specified scheme']
    texts    = ['Add Series','Delete Series',
                'Auto Colour Spectra']
    commands = [self.addExpSeries,self.deleteExpSeries,
                self.autoColorSpectra]
                
    self.seriesButtons = ButtonList(frame0, texts=texts, commands=commands,
                                    grid=(1,0), tipTexts=tipTexts)

    label = Label(frame0, text='Scheme:', grid=(1,1))
    
    tipText = 'Selects which colour scheme to apply to the contours of (separate) experiments within an NMR series'
    self.colorSchemePulldown = PulldownList(frame0, grid=(1,2), tipText=tipText)

    row += 1
    div = LabelDivider(guiFrame, text='Experimental Parameters & Conditions', grid=(row, 0))

    row += 1
    guiFrame.grid_rowconfigure(row, weight=1)
    frame1 = Frame(guiFrame, grid=(row, 0))
    frame1.expandGrid(0,0)
    tipTexts = ['The kind of experimental parameter that is being used to define the NMR series',
                'The experiment that corresponds to the specified parameter value; can be edited from an arbitrary initial experiment',
                'The numeric value of the parameter (condition) that relates to the experiment or point in the NMR series',
                'The estimated error in value of the condition',
                'The measurement unit in which the value of the condition is represented']
    headingList      = ['Parameter','Experiment','Value','Error','Unit']
    editWidgets      = [None,self.experimentPulldown,self.valueEntry,self.errorEntry, self.unitPulldown]
    editGetCallbacks = [None,self.getExperiment,     self.getValue,  self.getError,   self.getUnit]
    editSetCallbacks = [None,self.setExperiment,     self.setValue,  self.setError,   self.setUnit]
    self.conditionPointsMatrix = ScrolledMatrix(frame1, grid=(0,0), tipTexts=tipTexts,
                                                editSetCallbacks=editSetCallbacks,
                                                editGetCallbacks=editGetCallbacks,
                                                editWidgets=editWidgets,
                                                headingList=headingList,
                                                callback=self.selectConditionPoint,
                                                deleteFunc=self.deleteConditionPoint)
    
    self.conditionPointsMatrix.doEditMarkExtraRules = self.conditionTableShow 
    tipTexts = ['Add a new point to the NMR series with an associated parameter value and experiment',
                'Remove the selected point from the series, including any associated parameter value',
                'For appropriate kinds of NMR series, set or unset a point as representing the plane to use as a reference']
    texts    = ['Add Series Point','Delete Series Point','Set/Unset Ref Plane']
    commands = [self.addConditionPoint,self.deleteConditionPoint,self.setSampledReferencePlane]
    self.conditionPointsButtons = ButtonList(frame1, texts=texts, commands=commands,
                                             tipTexts=tipTexts, grid=(1,0))
    
    self.updateAfter()
    self.updateColorSchemes()

    self.administerNotifiers(self.registerNotify)
示例#24
0
    def body(self, guiFrame):

        self.specFreqEntry = IntEntry(self,
                                      text=self.specFreq,
                                      width=8,
                                      returnCallback=self.setSpecFreq)
        self.maxIterEntry = IntEntry(self,
                                     text=self.maxIter,
                                     width=8,
                                     returnCallback=self.setMaxIter)
        self.mixTimeEntry = FloatEntry(self,
                                       text=self.mixTime,
                                       width=8,
                                       returnCallback=self.setMixTime)
        self.corrTimeEntry = FloatEntry(self,
                                        text=self.corrTime,
                                        width=8,
                                        returnCallback=self.setCorrTime)
        self.leakRateEntry = FloatEntry(self,
                                        text=self.leakRate,
                                        width=8,
                                        returnCallback=self.setLeakRate)
        self.maxIntensEntry = IntEntry(self,
                                       text=self.maxIntens,
                                       width=8,
                                       returnCallback=self.setMaxIntens)

        self.mdInitTempEntry = FloatEntry(self,
                                          text='',
                                          returnCallback=self.setMdInitTemp)
        self.mdFinTempEntry = FloatEntry(self,
                                         text='',
                                         returnCallback=self.setMdFinTemp)
        self.mdCoolStepsEntry = IntEntry(self,
                                         text='',
                                         returnCallback=self.setMdCoolSteps)
        self.mdSimStepsEntry = IntEntry(self,
                                        text='',
                                        returnCallback=self.setMdSimSteps)
        self.mdTauEntry = FloatEntry(self,
                                     text='',
                                     returnCallback=self.setMdTau)
        self.mdRepScaleEntry = FloatEntry(self,
                                          text='',
                                          returnCallback=self.setMdRepScale)

        guiFrame.grid_columnconfigure(0, weight=1)

        row = 0
        frame0 = LabelFrame(guiFrame, text='Setup peak lists')
        frame0.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame0.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame0.grid_columnconfigure(1, weight=1)

        f0row = 0
        label00 = Label(frame0, text='1H-1H NOESY spectrum')
        label00.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.noesyPulldown = PulldownMenu(frame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.noesyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label01 = Label(frame0, text='15N HSQC spectrum')
        label01.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.hsqcPulldown = PulldownMenu(frame0,
                                         entries=self.getHsqcs(),
                                         callback=self.setHsqc,
                                         selected_index=0,
                                         do_initial_callback=0)
        self.hsqcPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label02 = Label(frame0, text='15N HSQC TOCSY spectrum')
        label02.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.tocsyPulldown = PulldownMenu(frame0,
                                          entries=self.getTocsys(),
                                          callback=self.setTocsy,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.tocsyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label02 = Label(frame0, text='15N HSQC NOESY spectrum')
        label02.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.noesy3dPulldown = PulldownMenu(frame0,
                                            entries=self.getNoesy3ds(),
                                            callback=self.setNoesy3d,
                                            selected_index=0,
                                            do_initial_callback=0)
        self.noesy3dPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        texts = ['Setup resonances & peaks', 'Show Peaks', 'Show resonances']
        commands = [self.setupResonances, self.showPeaks, self.showResonances]
        self.setupButtons = ButtonList(frame0,
                                       expands=1,
                                       texts=texts,
                                       commands=commands)
        self.setupButtons.grid(row=f0row,
                               column=0,
                               columnspan=2,
                               sticky=Tkinter.NSEW)

        f0row += 1
        self.label03a = Label(frame0, text='Resonances found: 0')
        self.label03a.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.label03b = Label(frame0, text='NOESY peaks found: 0')
        self.label03b.grid(row=f0row, column=1, sticky=Tkinter.NW)

        row += 1
        frame1 = LabelFrame(guiFrame, text='Calculate distance constraints')
        frame1.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame1.grid_columnconfigure(3, weight=1)

        f1row = 0
        frame1.grid_rowconfigure(f1row, weight=1)
        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate, self.maxIntens
        ]
        colHeadings = [
            'Spectrometer\nfrequency', 'Max\niterations', 'Mixing\ntime (ms)',
            'Correl.\ntime (ns)', 'Leak\nrate', 'Max\nintensity'
        ]
        editWidgets = [
            self.specFreqEntry,
            self.maxIterEntry,
            self.mixTimeEntry,
            self.corrTimeEntry,
            self.leakRateEntry,
            self.maxIntensEntry,
        ]
        editGetCallbacks = [
            self.getSpecFreq,
            self.getMaxIter,
            self.getMixTime,
            self.getCorrTime,
            self.getLeakRate,
            self.getMaxIntens,
        ]
        editSetCallbacks = [
            self.setSpecFreq,
            self.setMaxIter,
            self.setMixTime,
            self.setCorrTime,
            self.setLeakRate,
            self.setMaxIntens,
        ]
        self.midgeParamsMatrix = ScrolledMatrix(
            frame1,
            editSetCallbacks=editSetCallbacks,
            editGetCallbacks=editGetCallbacks,
            editWidgets=editWidgets,
            maxRows=1,
            initialCols=5,
            headingList=colHeadings,
            callback=None,
            objectList=[
                'None',
            ],
            textMatrix=[
                data,
            ])
        self.midgeParamsMatrix.grid(row=f1row,
                                    column=0,
                                    columnspan=4,
                                    sticky=Tkinter.NSEW)

        f1row += 1
        label10 = Label(frame1, text='Benchmark structure')
        label10.grid(row=f1row, column=0, sticky=Tkinter.NW)
        self.structurePulldown = PulldownMenu(frame1,
                                              entries=self.getStructures(),
                                              callback=self.setStructure,
                                              selected_index=0,
                                              do_initial_callback=0)
        self.structurePulldown.grid(row=f1row, column=1, sticky=Tkinter.NW)

        label11 = Label(frame1, text='ADC atom types:')
        label11.grid(row=f1row, column=2, sticky=Tkinter.NW)
        self.adcAtomsPulldown = PulldownMenu(frame1,
                                             entries=self.getAdcAtomTypes(),
                                             callback=self.setAdcAtomTypes,
                                             selected_index=0,
                                             do_initial_callback=0)
        self.adcAtomsPulldown.grid(row=f1row, column=3, sticky=Tkinter.NW)

        f1row += 1
        texts = [
            'Calculate distances', 'Show distance\nconstraints',
            'Show anti-distance\nconstraints'
        ]
        commands = [
            self.calculateDistances, self.showConstraints,
            self.showAntiConstraints
        ]
        self.midgeButtons = ButtonList(frame1,
                                       expands=1,
                                       texts=texts,
                                       commands=commands)
        self.midgeButtons.grid(row=f1row,
                               column=0,
                               columnspan=4,
                               sticky=Tkinter.NSEW)

        f1row += 1
        self.distConstrLabel = Label(frame1, text='Distance constraints:')
        self.distConstrLabel.grid(row=f1row,
                                  column=0,
                                  columnspan=2,
                                  sticky=Tkinter.NW)
        self.antiConstrLabel = Label(frame1, text='Anti-distance constraints:')
        self.antiConstrLabel.grid(row=f1row,
                                  column=2,
                                  columnspan=2,
                                  sticky=Tkinter.NW)

        row += 1
        guiFrame.grid_rowconfigure(row, weight=1)
        frame2 = LabelFrame(guiFrame, text='Proton cloud molecular dynamics')
        frame2.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame2.grid_columnconfigure(1, weight=1)

        f2row = 0
        frame2.grid_rowconfigure(f2row, weight=1)
        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate
        ]
        colHeadings = [
            'Step', 'Initial temp.', 'Final temp.', 'Cooling steps',
            'MD steps', 'MD tau', 'Rep. scale'
        ]
        editWidgets = [
            None, self.mdInitTempEntry, self.mdFinTempEntry,
            self.mdCoolStepsEntry, self.mdSimStepsEntry, self.mdTauEntry,
            self.mdRepScaleEntry
        ]
        editGetCallbacks = [
            None, self.getMdInitTemp, self.getMdFinTemp, self.getMdCoolSteps,
            self.getMdSimSteps, self.getMdTau, self.getMdRepScale
        ]
        editSetCallbacks = [
            None, self.setMdInitTemp, self.setMdFinTemp, self.setMdCoolSteps,
            self.setMdSimSteps, self.setMdTau, self.setMdRepScale
        ]
        self.coolingSchemeMatrix = ScrolledMatrix(
            frame2,
            editSetCallbacks=editSetCallbacks,
            editGetCallbacks=editGetCallbacks,
            editWidgets=editWidgets,
            maxRows=9,
            initialRows=12,
            headingList=colHeadings,
            callback=self.selectCoolingStep,
            objectList=self.coolingScheme,
            textMatrix=self.coolingScheme)
        self.coolingSchemeMatrix.grid(row=f2row,
                                      column=0,
                                      columnspan=4,
                                      sticky=Tkinter.NSEW)

        f2row += 1
        texts = ['Move earlier', 'Move later', 'Add step', 'Remove step']
        commands = [
            self.moveStepEarlier, self.moveStepLater, self.addCoolingStep,
            self.removeCoolingStep
        ]
        self.coolingSchemeButtons = ButtonList(frame2,
                                               expands=1,
                                               commands=commands,
                                               texts=texts)
        self.coolingSchemeButtons.grid(row=f2row,
                                       column=0,
                                       columnspan=4,
                                       sticky=Tkinter.EW)

        f2row += 1
        label20 = Label(frame2, text='Number of clouds:')
        label20.grid(row=f2row, column=0, sticky=Tkinter.NW)
        self.numCloudsEntry = FloatEntry(frame2,
                                         text=100,
                                         returnCallback=self.setNumClouds,
                                         width=10)
        self.numCloudsEntry.grid(row=f2row, column=1, sticky=Tkinter.NW)
        label21 = Label(frame2, text='Cloud file prefix:')
        label21.grid(row=f2row, column=2, sticky=Tkinter.NW)
        self.filePrefixEntry = Entry(frame2,
                                     text='cloud_',
                                     returnCallback=self.setFilePrefix,
                                     width=10)
        self.filePrefixEntry.grid(row=f2row, column=3, sticky=Tkinter.NW)

        f2row += 1
        texts = ['Start molecular dynamics', 'Show dynamics progress']
        commands = [self.startMd, self.showMdProgress]
        self.mdButtons = ButtonList(frame2,
                                    expands=1,
                                    commands=commands,
                                    texts=texts)
        self.mdButtons.grid(row=f2row,
                            column=0,
                            columnspan=4,
                            sticky=Tkinter.NSEW)

        row += 1
        self.bottomButtons = createDismissHelpButtonList(guiFrame,
                                                         expands=0,
                                                         help_url=None)
        self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW)

        self.setButtonStates()
示例#25
0
    def body(self):
        '''describes the body of this tab. It bascically consists
           of some field to fill out for the user at the top and
           a ScrolledGraph that shows the progess of the annealing
           procedure a the bottom.
        '''

        frame = self.frame

        # frame.expandGrid(13,0)
        frame.expandGrid(15, 1)
        row = 0

        text = 'Calculate Assignment Suggestions'
        command = self.runCalculations
        self.startButton = Button(frame, command=command, text=text)
        self.startButton.grid(row=row, column=0, sticky='nsew', columnspan=2)

        row += 1

        Label(frame, text='Amount of runs: ', grid=(row, 0))
        tipText = 'The amount of times the whole optimization procedure is performed, each result is safed'
        self.repeatEntry = IntEntry(frame, grid=(row, 1), width=7, text=10,
                                    returnCallback=self.updateRepeatEntry,
                                    tipText=tipText, sticky='nsew')
        self.repeatEntry.bind('<Leave>', self.updateRepeatEntry, '+')

        row += 1

        Label(frame, text='Temperature regime: ', grid=(row, 0))
        tipText = 'This list of numbers govern the temperature steps during the annealing, every number represents 1/(kb*t), where kb is the Boltzmann constant and t the temperature of one step.'
        self.tempEntry = Entry(frame, text=map(str, self.acceptanceConstantList), width=64,
                               grid=(row, 1), isArray=True, returnCallback=self.updateAcceptanceConstantList,
                               tipText=tipText, sticky='nsew')

        row += 1

        Label(frame, text='Amount of attempts per temperature:', grid=(row, 0))
        tipText = 'The amount of attempts to switch the position of two spinsystems in the sequence are performed for each temperature point'
        self.NAStepEntry = IntEntry(frame, grid=(row, 1), width=7, text=10000,
                                    returnCallback=self.updateStepEntry,
                                    tipText=tipText, sticky='nsew')
        self.NAStepEntry.bind('<Leave>', self.updateStepEntry, '+')

        row += 1

        Label(frame, text='Fraction of peaks to leave out:', grid=(row, 0))
        tipText = 'In each run a fraction of the peaks can be left out of the optimization, thereby increasing the variability in the outcome and reducing false negatives. In each run this will be different randomly chosen sub-set of all peaks. 0.1 (10%) can be a good value.'
        self.leaveOutPeaksEntry = FloatEntry(frame, grid=(row, 1), width=7, text=0.0,
                                             returnCallback=self.updateLeavePeaksOutEntry,
                                             tipText=tipText, sticky='nsew')
        self.leaveOutPeaksEntry.bind(
            '<Leave>', self.updateLeavePeaksOutEntry, '+')

        row += 1

        Label(frame, text='Minmal amino acid typing score:', grid=(row, 0))
        tipText = 'If automatic amino acid typing is selected, a cut-off value has to set. Every amino acid type that scores higher than the cut-off is taken as a possible type. This is the same score as can be found under resonance --> spin systems --> predict type. Value should be between 0 and 100'
        self.minTypeScoreEntry = FloatEntry(frame, grid=(row, 1), width=7, text=1.0,
                                            returnCallback=self.updateMinTypeScoreEntry,
                                            tipText=tipText, sticky='nsew')
        self.minTypeScoreEntry.bind(
            '<Leave>', self.updateMinTypeScoreEntry, '+')

        row += 1

        Label(frame, text='Minimal colabelling fraction:', grid=(row, 0))
        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minLabelEntry = FloatEntry(frame, grid=(row, 1), width=7, text=0.1,
                                        returnCallback=self.updateMinLabelEntry,
                                        tipText=tipText, sticky='nsew')
        self.minLabelEntry.bind('<Leave>', self.updateMinLabelEntry, '+')

        row += 1

        Label(frame, text='Use sequential assignments:', grid=(row, 0))
        tipText = 'When this option is select the present sequential assignments will be kept in place'
        self.useAssignmentsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use tentative assignments:', grid=(row, 0))
        tipText = 'If a spin system has tentative assignments this can be used to narrow down the amount of possible sequential assignments.'
        self.useTentativeCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use amino acid types:', grid=(row, 0))
        tipText = 'Use amino acid types of the spin systems. If this option is not checked the spin systems are re-typed, only resonance names and frequencies are used'
        self.useTypeCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Include untyped spin systems:', grid=(row, 0))
        tipText = 'Also include spin system that have no type information. Amino acid typing will be done on the fly.'
        self.useAlsoUntypedSpinSystemsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Use dimensional assignments:', grid=(row, 0))
        tipText = 'If one or more dimensions of a peak is already assigned, assume that this assignment is the only option. If not the check the program will consider all possibilities for the assignment of the dimension.'
        self.useDimensionalAssignmentsCheck = CheckButton(
            frame, selected=True, tipText=tipText, grid=(row, 1))

        row += 1

        Label(frame, text='Chain:', grid=(row, 0))
        self.molPulldown = PulldownList(
            frame, callback=self.changeMolecule, grid=(row, 1))
        self.updateChains()

        row += 1

        Label(frame, text='Residue ranges: ', grid=(row, 0))
        tipText = 'Which residues should be included. Example: "10-35, 62-100, 130".'
        self.residueRangeEntry = Entry(frame, text=None, width=64,
                                       grid=(row, 1), isArray=True, returnCallback=self.updateResidueRanges,
                                       tipText=tipText, sticky='nsew')
        self.updateResidueRanges(fromChain=True)

        row += 1

        self.energyPlot = ScrolledGraph(frame, symbolSize=2, width=600,
                                        height=200, title='Annealing',
                                        xLabel='temperature step', yLabel='energy')
        self.energyPlot.grid(row=row, column=0, columnspan=2, sticky='nsew')
示例#26
0
  def __init__(self, parent, application, *args, **kw):

    project = application.project
    simStore = project.findFirstNmrSimStore(application=APP_NAME) or \
               project.newNmrSimStore(application=APP_NAME, name=APP_NAME)

    self.application = application
    self.residue = None
    self.structure = None
    self.serverCredentials = None
    self.iCingBaseUrl = DEFAULT_URL
    self.resultsUrl = None
    self.chain = None
    self.nmrProject = application.nmrProject
    self.serverDone = False

    NmrSimRunFrame.__init__(self, parent, project, simStore, *args, **kw)

    # # # # # # New Structure Frame # # # # #

    self.structureFrame.grid_forget()

    tab = self.tabbedFrame.frames[0]

    frame = Frame(tab, grid=(1,0))
    frame.expandGrid(2,1)

    div = LabelDivider(frame, text='Structures', grid=(0,0), gridSpan=(1,2))

    label = Label(frame, text='Ensemble: ', grid=(1,0))
    self.structurePulldown = PulldownList(frame, callback=self.changeStructure, grid=(1,1))

    headingList = ['Model','Use']
    editWidgets      = [None,None]
    editGetCallbacks = [None,self.toggleModel]
    editSetCallbacks = [None,None,]
    self.modelTable = ScrolledMatrix(frame, grid=(2,0), gridSpan=(1,2),
                                     callback=self.selectStructModel,
                                     editWidgets=editWidgets,
                                     editGetCallbacks=editGetCallbacks,
                                     editSetCallbacks=editSetCallbacks,
                                     headingList=headingList)

    texts = ['Activate Selected','Inactivate Selected']
    commands = [self.activateModels, self.disableModels]
    buttons = ButtonList(frame, texts=texts, commands=commands, grid=(3,0), gridSpan=(1,2))


    # # # # # # Submission frame # # # # # #

    tab = self.tabbedFrame.frames[1]
    tab.expandGrid(1,0)

    frame = LabelFrame(tab, text='Server Job Submission', grid=(0,0))
    frame.expandGrid(None,2)

    srow = 0
    label = Label(frame, text='iCing URL:', grid=(srow, 0))
    urls = [DEFAULT_URL,]
    self.iCingBaseUrlPulldown = PulldownList(frame, texts=urls, objects=urls, index=0, grid=(srow,1))


    srow +=1
    label = Label(frame, text='Results File:', grid=(srow, 0))
    self.resultFileEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50)
    self.setZipFileName()
    button = Button(frame, text='Choose File', bd=1, sticky='ew',
                    command=self.chooseZipFile, grid=(srow, 2))

    srow +=1
    label = Label(frame, text='Results URL:', grid=(srow, 0))
    self.resultUrlEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50)
    button = Button(frame, text='View Results HTML', bd=1, sticky='ew',
                    command=self.viewHtmlResults, grid=(srow, 2))

    srow +=1
    texts    = ['Submit Project!', 'Check Run Status',
                'Purge Server Result', 'Download Results']
    commands = [self.runCingServer, self.checkStatus,
                self.purgeCingServer, self.downloadResults]

    self.buttonBar = ButtonList(frame, texts=texts, commands=commands,
                                grid=(srow, 0), gridSpan=(1,3))

    for button in self.buttonBar.buttons[:1]:
      button.config(bg=CING_BLUE)

    # # # # # # Residue frame # # # # # #

    frame = LabelFrame(tab, text='Residue Options', grid=(1,0))
    frame.expandGrid(1,1)

    label = Label(frame, text='Chain: ')
    label.grid(row=0,column=0,sticky='w')
    self.chainPulldown = PulldownList(frame, callback=self.changeChain)
    self.chainPulldown.grid(row=0,column=1,sticky='w')

    headingList = ['#','Residue','Linking','Decriptor','Use?']
    editWidgets      = [None,None,None,None,None]
    editGetCallbacks = [None,None,None,None,self.toggleResidue]
    editSetCallbacks = [None,None,None,None,None,]
    self.residueMatrix = ScrolledMatrix(frame,
                                        headingList=headingList,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        callback=self.selectResidue)
    self.residueMatrix.grid(row=1, column=0, columnspan=2, sticky = 'nsew')

    texts = ['Activate Selected','Inactivate Selected']
    commands = [self.activateResidues, self.deactivateResidues]
    self.resButtons = ButtonList(frame, texts=texts, commands=commands,)
    self.resButtons.grid(row=2, column=0, columnspan=2, sticky='ew')

    """
    # # # # # # Validate frame # # # # # #

    frame = LabelFrame(tab, text='Validation Options', grid=(2,0))
    frame.expandGrid(None,2)

    srow = 0
    self.selectCheckAssign = CheckButton(frame)
    self.selectCheckAssign.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckAssign.set(True)
    label = Label(frame, text='Assignments and shifts')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckResraint = CheckButton(frame)
    self.selectCheckResraint.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckResraint.set(True)
    label = Label(frame, text='Restraints')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckQueen = CheckButton(frame)
    self.selectCheckQueen.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckQueen.set(False)
    label = Label(frame, text='QUEEN')
    label.grid(row=srow,column=1,sticky='nw')

    srow += 1
    self.selectCheckScript = CheckButton(frame)
    self.selectCheckScript.grid(row=srow, column=0,sticky='nw' )
    self.selectCheckScript.set(False)
    label = Label(frame, text='User Python script\n(overriding option)')
    label.grid(row=srow,column=1,sticky='nw')

    self.validScriptEntry = Entry(frame, bd=1, text='')
    self.validScriptEntry.grid(row=srow,column=2,sticky='ew')

    scriptButton = Button(frame, bd=1,
                          command=self.chooseValidScript,
                          text='Browse')
    scriptButton.grid(row=srow,column=3,sticky='ew')
    """

    # # # # # # # # # #

    self.update(simStore)

    self.administerNotifiers(application.registerNotify)
示例#27
0
class HelpFrame(Frame):
    def __init__(self,
                 parent,
                 width=70,
                 height=20,
                 xscroll=False,
                 yscroll=True,
                 *args,
                 **kw):

        apply(Frame.__init__, (self, parent) + args, kw)

        self.grid_columnconfigure(1, weight=1)

        row = 0
        texts = ('back', 'forward', 'load')
        commands = (self.prevUrl, self.nextUrl, self.loadUrl)
        self.buttons = ButtonList(self, texts=texts, commands=commands)
        self.buttons.grid(row=row, column=0)
        self.url_entry = Entry(self, returnCallback=self.loadUrl)
        self.url_entry.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW)
        row = row + 1

        frame = Frame(self)
        frame.grid(row=row, column=0, columnspan=3, sticky=Tkinter.W)
        self.createFindFrame(frame)
        row = row + 1

        self.grid_rowconfigure(row, weight=1)
        self.help_text = ScrolledHtml(self,
                                      width=width,
                                      height=height,
                                      xscroll=xscroll,
                                      yscroll=yscroll,
                                      startUrlCallback=self.startOpenUrl,
                                      endUrlCallback=self.endOpenUrl,
                                      enterLinkCallback=self.setLinkLabel,
                                      leaveLinkCallback=self.setLinkLabel)
        self.help_text.grid(row=row,
                            column=0,
                            columnspan=3,
                            sticky=Tkinter.NSEW)
        row = row + 1

        self.link_label = Label(self)
        self.link_label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W)
        button = memops.gui.Util.createDismissButton(self,
                                                     dismiss_cmd=self.close)
        button.grid(row=row, column=2)

        self.urls = []
        self.current = -1
        self.updateUrlList = True

        self.setButtonState()

    def close(self):

        if (self.popup):
            if (self.popup.modal):
                self.popup.do_grab()

        popup = self.parent
        while (not hasattr(popup, 'top')):
            popup = popup.parent
        popup.close()

    def createFindFrame(self, master):

        frame = Frame(master)
        frame.grid(row=0, column=0, sticky=Tkinter.W)

        arrow = ToggleArrow(frame, callback=self.toggleFindFrame)
        arrow.grid(row=0, column=0)
        button = Button(frame, text='find:', command=self.findPhrase)
        button.grid(row=0, column=1)
        self.find_entry = Entry(frame,
                                width=20,
                                returnCallback=self.findPhrase)
        self.find_entry.grid(row=0, column=2)

        self.find_frame = frame = Frame(master)

        entries = ('search forwards', 'search backwards')
        self.direction_buttons = PulldownMenu(frame, entries=entries)
        self.direction_buttons.grid(row=0, column=0, sticky=Tkinter.W, padx=5)

        self.forwards_entries = entries = ('wrap search', 'stop at end')
        self.backwards_entries = ('wrap search', 'stop at beginning')
        self.wrap_buttons = PulldownMenu(frame, entries=entries)
        self.wrap_buttons.grid(row=0, column=1, sticky=Tkinter.W, padx=5)

        self.direction_buttons.callback = self.setWrapText

        entries = ('case insensitive', 'case sensitive')
        self.case_buttons = PulldownMenu(frame, entries=entries)
        self.case_buttons.grid(row=0, column=2, sticky=Tkinter.W, padx=5)

        entries = ('literal search', 'regex search')
        self.pattern_buttons = PulldownMenu(frame, entries=entries)
        self.pattern_buttons.grid(row=0, column=3, sticky=Tkinter.W, padx=5)

        self.countVar = Tkinter.IntVar()

    def setWrapText(self, entry_ind, entry):

        if (entry_ind == 0):
            entries = self.forwards_entries
        else:
            entries = self.backwards_entries

        self.wrap_buttons.replace(
            entries, selected_index=self.wrap_buttons.getSelectedIndex())

    def findPhrase(self, *extra):

        phrase = self.find_entry.get()
        if (not phrase):
            showError('No find phrase', 'Enter phrase in entry box.')
            return

        if (self.direction_buttons.getSelectedIndex() == 0):
            forwards = 1
            backwards = 0
        else:
            forwards = 0
            backwards = 1

        if (self.case_buttons.getSelectedIndex() == 0):
            nocase = 1
        else:
            nocase = 0

        if (self.pattern_buttons.getSelectedIndex() == 0):
            exact = 1
            regexp = 0
        else:
            exact = 0
            regexp = 1

        start = self.help_text.tag_nextrange(Tkinter.SEL, '1.0')
        if (start):
            start = start[0]
            if (forwards):
                start = '%s+1c' % start
            else:
                start = '%s-1c' % start
        else:
            start = Tkinter.CURRENT

        if (self.wrap_buttons.getSelectedIndex() == 0):
            match = self.help_text.search(phrase,
                                          start,
                                          count=self.countVar,
                                          forwards=forwards,
                                          backwards=backwards,
                                          nocase=nocase,
                                          exact=exact,
                                          regexp=regexp)
        elif (forwards):
            match = self.help_text.search(phrase,
                                          start,
                                          count=self.countVar,
                                          forwards=forwards,
                                          backwards=backwards,
                                          nocase=nocase,
                                          exact=exact,
                                          regexp=regexp,
                                          stopindex=Tkinter.END)
        else:
            match = self.help_text.search(phrase,
                                          start,
                                          count=self.countVar,
                                          forwards=forwards,
                                          backwards=backwards,
                                          nocase=nocase,
                                          exact=exact,
                                          regexp=regexp,
                                          stopindex='1.0')

        if (match):
            self.help_text.see(match)
            self.help_text.setSelection(
                match, '%s+%dc' % (match, self.countVar.get()))
            self.help_text.tag_config(Tkinter.SEL, background='gray70')
        else:
            showInfo('No match', 'No match found for phrase.')

    def toggleFindFrame(self, isClosed):

        if (isClosed):
            self.find_frame.grid_forget()
        else:
            self.find_frame.grid(row=1, column=0, sticky=Tkinter.W)

    def setButtonState(self):

        n = len(self.urls)

        if ((n >= 2) and (self.current > 0)):
            state = Tkinter.NORMAL
        else:
            state = Tkinter.DISABLED
        self.buttons.buttons[0].config(state=state)

        if ((n >= 2) and (self.current < (n - 1))):
            state = Tkinter.NORMAL
        else:
            state = Tkinter.DISABLED
        self.buttons.buttons[1].config(state=state)

    def setLinkLabel(self, url=''):

        self.link_label.set(url)

    def loadUrl(self, *extra):

        url = self.url_entry.get()
        if (url):
            if (url.find(':') == -1):
                if (url[:2] != '//'):
                    url = '//' + url
                url = 'http:' + url
            self.showUrl(url, forceLoad=True)

    def newUrl(self, url):

        self.current = self.current + 1
        self.urls[self.current:] = [[url, 0.0]]
        self.setButtonState()
        #print 'newUrl', self.current, self.urls

    def prevUrl(self):

        if (self.current > 0):  # True if called via button
            (url, offset) = self.urls[self.current - 1]
            self.updateUrlList = False
            self.showUrl(url, offset=offset, allowModifyPath=False)
            self.updateUrlList = True
            self.current = self.current - 1
            self.setButtonState()
        #print 'prevUrl', self.current, self.urls

    def nextUrl(self):

        if (self.current < (len(self.urls) - 1)):  # True if called via button
            (url, offset) = self.urls[self.current + 1]
            self.updateUrlList = False
            self.showUrl(url, offset=offset, allowModifyPath=False)
            self.updateUrlList = True
            self.current = self.current + 1
            self.setButtonState()
        #print 'nextUrl', self.current, self.urls

    def showText(self, message, popup=None):

        self.popup = popup
        if (popup):
            self.parent.modal = popup.modal
        self.help_text.setState(Tkinter.NORMAL)  # so that can add text
        self.help_text.clear()  # clear existing text
        self.help_text.append(message)
        self.help_text.setState(Tkinter.DISABLED)  # make text read-only
        self.open()

    def startOpenUrl(self, yview):

        if (self.urls):
            self.urls[self.current][1] = yview[0]

    def endOpenUrl(self, url):

        #print 'endOpenUrl', url, self.updateUrlList
        self.url_entry.set(url)
        if (self.updateUrlList):
            self.newUrl(url)
        self.setLinkLabel()
        self.open()

    def showUrl(self,
                url,
                offset=None,
                forceLoad=False,
                allowModifyPath=True,
                popup=None):

        self.popup = popup
        if (popup):
            self.parent.modal = popup.modal
        self.help_text.openUrl(url,
                               forceLoad=forceLoad,
                               allowModifyPath=allowModifyPath)
        if (offset is not None):
            self.help_text.yview(Tkinter.MOVETO, str(offset))
示例#28
0
文件: gui.py 项目: VuisterLab/cing
class CingGui(BasePopup):

    def __init__(self, parent, options, *args, **kw):


        # Fill in below variable once run generates some results
        self.haveResults = None
        # store the options
        self.options = options

        BasePopup.__init__(self, parent=parent, title='CING Setup', **kw)

#    self.setGeometry(850, 750, 50, 50)

        self.project = None

#    self.tk_strictMotif( True)

        self.updateGui()
    # end def __init__

    def body(self, guiFrame):

        row = 0
        col =0
#    frame = Frame( guiFrame )
#    frame.grid(row=row, column=col, sticky='news')
        self.menuBar = Menu( guiFrame)
        self.menuBar.grid( row=row, column=col, sticky='ew')

        #----------------------------------------------------------------------------------
        # Project frame
        #----------------------------------------------------------------------------------

#    guiFrame.grid_columnconfigure(row, weight=1)
#    frame = LabelFrame(guiFrame, text='Project', font=medFont)
        row = +1
        col =0
        frame = LabelFrame(guiFrame, text='Project', **labelFrameAttributes )
        print '>', frame.keys()
        frame.grid(row=row, column=col, sticky='nsew' )
        frame.grid_columnconfigure(2, weight=1)
#    frame.grid_rowconfigure(0, weight=1)

        srow = 0
        self.projectOptions = ['old','new from PDB','new from CCPN','new from CYANA']
        self.projOptionsSelect = RadioButtons(frame, selected_index=0, entries=self.projectOptions, direction='vertical',
                                              select_callback=self.updateGui
                                             )
        self.projOptionsSelect.grid(row=srow,column=0,rowspan=len(self.projectOptions),columnspan=2, sticky='w')

        if self.options.name: 
            text = self.options.name
        else: 
            text=''
        # end if
        self.projEntry = Entry(frame, bd=1, text=text, returnCallback=self.updateGui)
        self.projEntry.grid(row=srow,column=2,columnspan=2,sticky='ew')
#    self.projEntry.bind('<Key>', self.updateGui)
        self.projEntry.bind('<Leave>', self.updateGui)

        projButton = Button(frame, bd=1,command=self.chooseOldProjectFile, text='browse')
        projButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.pdbEntry = Entry(frame, bd=1, text='')
        self.pdbEntry.grid(row=srow,column=2,sticky='ew')
        self.pdbEntry.bind('<Leave>', self.updateGui)

        pdbButton = Button(frame, bd=1,command=self.choosePdbFile, text='browse')
        pdbButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.ccpnEntry = Entry(frame, bd=1, text='')
        self.ccpnEntry.grid(row=srow,column=2,sticky='ew')
        self.ccpnEntry.bind('<Leave>', self.updateGui)

        ccpnButton = Button(frame, bd=1,command=self.chooseCcpnFile, text='browse')
        ccpnButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.cyanaEntry = Entry(frame, bd=1, text='')
        self.cyanaEntry.grid(row=srow,column=2,sticky='ew')
        self.cyanaEntry.bind('<Leave>', self.updateGui)

        cyanaButton = Button(frame, bd=1,command=self.chooseCyanaFile, text='browse')
        cyanaButton.grid(row=srow,column=3,sticky='ew')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        label = Label(frame, text='Project name:')
        label.grid(row=srow,column=0,sticky='nw')
        self.nameEntry = Entry(frame, bd=1, text='')
        self.nameEntry.grid(row=srow,column=2,sticky='w')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        self.openProjectButton = Button(frame, command=self.openProject, text='Open Project', **actionButtonAttributes )
        self.openProjectButton.grid(row=srow,column=0, columnspan=4, sticky='ew')


        #----------------------------------------------------------------------------------
        # status
        #----------------------------------------------------------------------------------
#    guiFrame.grid_columnconfigure(1, weight=0)
        srow = 0
        frame = LabelFrame(guiFrame, text='Status', **labelFrameAttributes)
        frame.grid( row=srow, column=1, sticky='wnes')
        self.projectStatus = Text(frame, height=11, width=70, borderwidth=0, relief='flat')
        self.projectStatus.grid(row=0, column=0, sticky='wen')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        self.closeProjectButton = Button(frame, command=self.closeProject, text='Close Project', **actionButtonAttributes)
        self.closeProjectButton.grid(row=srow,column=0, columnspan=4, sticky='ew')

        #----------------------------------------------------------------------------------
        # Validate frame
        #----------------------------------------------------------------------------------

        row +=1
        col=0
        frame = LabelFrame(guiFrame, text='Validate', **labelFrameAttributes)
#    frame = LabelFrame(guiFrame, text='Validate', font=medFont)
        frame.grid(row=row, column=col, sticky='nsew')
#    frame.grid_columnconfigure(2, weight=1)
        frame.grid_rowconfigure(0, weight=1)

        srow = 0
#    label = Label(frame, text='validation')
#    label.grid(row=srow,column=0,sticky='nw')
#
#    self.selectDoValidation = CheckButton(frame)
#    self.selectDoValidation.grid(row=srow, column=1,sticky='nw' )
#    self.selectDoValidation.set(True)
#
#    srow += 1
#    label = Label(frame, text='')
#    label.grid(row=srow,column=0,sticky='nw')
#
#    srow += 1
        label = Label(frame, text='checks')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectCheckAssign = CheckButton(frame)
        self.selectCheckAssign.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckAssign.set(True)
        label = Label(frame, text='assignments and shifts')
        label.grid(row=srow,column=2,sticky='nw')


#    srow += 1
#    self.selectCheckQueen = CheckButton(frame)
#    self.selectCheckQueen.grid(row=srow, column=4,sticky='nw' )
#    self.selectCheckQueen.set(False)
#    label = Label(frame, text='QUEEN')
#    label.grid(row=srow,column=5,sticky='nw')
#
#    queenButton = Button(frame, bd=1,command=None, text='setup')
#    queenButton.grid(row=srow,column=6,sticky='ew')


        srow += 1
        self.selectCheckResraint = CheckButton(frame)
        self.selectCheckResraint.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckResraint.set(True)
        label = Label(frame, text='restraints')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectCheckStructure = CheckButton(frame)
        self.selectCheckStructure.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckStructure.set(True)
        label = Label(frame, text='structural')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectMakeHtml = CheckButton(frame)
        self.selectMakeHtml.grid(row=srow, column=1,sticky='nw' )
        self.selectMakeHtml.set(True)
        label = Label(frame, text='generate HTML')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectCheckScript = CheckButton(frame)
        self.selectCheckScript.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckScript.set(False)
        label = Label(frame, text='user script')
        label.grid(row=srow,column=0,sticky='nw')

        self.validScriptEntry = Entry(frame, bd=1, text='')
        self.validScriptEntry.grid(row=srow,column=2,columnspan=3, sticky='ew')

        scriptButton = Button(frame, bd=1,command=self.chooseValidScript, text='browse')
        scriptButton.grid(row=srow,column=5,sticky='ew')

        srow += 1
        label = Label(frame, text='ranges')
        label.grid(row=srow,column=0,sticky='nw')
        self.rangesEntry = Entry( frame, text='' )
        self.rangesEntry.grid( row=srow, column=2, columnspan=3, sticky='ew')

#    self.validScriptEntry = Entry(frame, bd=1, text='')
#    self.validScriptEntry.grid(row=srow,column=3,sticky='ew')
#
#    scriptButton = Button(frame, bd=1,command=self.chooseValidScript, text='browse')
#    scriptButton.grid(row=srow,column=4,sticky='ew')


        srow += 1
        texts    = ['Run Validation','View Results','Setup QUEEN']
        commands = [self.runCing, None, None]
        buttonBar = ButtonList(frame, texts=texts, commands=commands,expands=True)
        buttonBar.grid(row=srow, column=0, columnspan=6, sticky='ew')
        for button in buttonBar.buttons:
            button.config(**actionButtonAttributes)
        # end for
        self.runButton = buttonBar.buttons[0]
        self.viewResultButton = buttonBar.buttons[1]
        self.queenButton = buttonBar.buttons[2]

        #----------------------------------------------------------------------------------
        # Miscellaneous frame
        #----------------------------------------------------------------------------------

        row +=0
        col=1
#    frame = LabelFrame(guiFrame, text='Miscellaneous', font=medFont)
        frame = LabelFrame(guiFrame, text='Miscellaneous', **labelFrameAttributes)
        frame.grid(row=row, column=col, sticky='news')
        frame.grid_columnconfigure(2, weight=1)
        frame.grid_columnconfigure(4, weight=1,minsize=30)
        frame.grid_rowconfigure(0, weight=1)

        # Exports

        srow = 0
        label = Label(frame, text='export to')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectExportXeasy = CheckButton(frame)
        self.selectExportXeasy.grid(row=srow, column=1,sticky='nw' )
        self.selectExportXeasy.set(True)
        label = Label(frame, text='Xeasy, Sparky, TALOS, ...')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportCcpn = CheckButton(frame)
        self.selectExportCcpn.grid(row=srow, column=1,sticky='nw' )
        self.selectExportCcpn.set(True)
        label = Label(frame, text='CCPN')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportQueen = CheckButton(frame)
        self.selectExportQueen.grid(row=srow, column=1,sticky='nw' )
        self.selectExportQueen.set(True)
        label = Label(frame, text='QUEEN')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportRefine = CheckButton(frame)
        self.selectExportRefine.grid(row=srow, column=1,sticky='nw' )
        self.selectExportRefine.set(True)
        label = Label(frame, text='refine')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        # User script

        srow += 1
        label = Label(frame, text='user script')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectMiscScript = CheckButton(frame)
        self.selectMiscScript.grid(row=srow, column=1,sticky='nw' )
        self.selectMiscScript.set(False)

        self.miscScriptEntry = Entry(frame, bd=1, text='')
        self.miscScriptEntry.grid(row=srow,column=3,sticky='ew')

        script2Button = Button(frame, bd=1,command=self.chooseMiscScript, text='browse')
        script2Button.grid(row=srow,column=4,sticky='ew')

        srow += 1
        texts    = ['Export','Run Script']
        commands = [None, None]
        buttonBar = ButtonList(frame, texts=texts, commands=commands,expands=True)
        buttonBar.grid(row=srow, column=0, columnspan=5, sticky='ew')
        for button in buttonBar.buttons:
            button.config(**actionButtonAttributes)
        # end for
        self.exportButton = buttonBar.buttons[0]
        self.scriptButton = buttonBar.buttons[1]

        #----------------------------------------------------------------------------------
        # Textarea
        #----------------------------------------------------------------------------------
        row +=1
        guiFrame.grid_rowconfigure(row, weight=1)
        self.outputTextBox = ScrolledText(guiFrame)
        self.outputTextBox.grid(row=row, column=0, columnspan=2, sticky='nsew')

        self.redirectConsole()

        #----------------------------------------------------------------------------------
        # Buttons
        #----------------------------------------------------------------------------------
        row +=1
        col=0
        texts    = ['Quit', 'Help']
        commands = [self.close, None]
        self.buttonBar = ButtonList(guiFrame, texts=texts, commands=commands,expands=True)
        self.buttonBar.grid(row=row, column=col, columnspan=2, sticky='ew')

#    self.openProjectButton = self.buttonBar.buttons[0]
#    self.closeProjectButton = self.buttonBar.buttons[1]
#    self.runButton = self.buttonBar.buttons[0]
#    self.viewResultButton = self.buttonBar.buttons[1]

        for button in self.buttonBar.buttons:
            button.config(**actionButtonAttributes)
        # end for
    # end def body


    def getGuiOptions(self):

        projectName = self.projEntry.get()

        index = self.projOptionsSelect.getIndex()

        if index > 0:
            makeNewProject = True
            projectImport  = None

            if index > 1:
                i = index-2
                format = ['PDB','CCPN','CYANA'][i]
                file   = [self.pdbEntry, self.ccpnEntry, self.cyanaEntry][i].get()

                if not file:
                    showWarning('Failure','No %s file selected' % format)
                    return
                # end if

                projectImport  = (format, file)
            # end if

        else:
            # Chould also check that any old project file exists

            makeNewProject = False
            projectImport  = None
        # end if

        doValidation = self.selectDoValidation.get()
        checks = []

        if doValidation:
            if self.selectCheckAssign.get():
                checks.append('assignments')
            # end if

            if self.selectCheckResraint.get():
                checks.append('restraints')
            # end if

            if self.selectCheckStructure.get():
                checks.append('structural')
            # end if

            if self.selectMakeHtml.get():
                checks.append('HTML')
            # end if

            if self.selectCheckScript.get():
                script = self.validScriptEntry.get()

                if script:
                    checks.append( ('script',script) )
                # end if
            # end if

            if self.selectCheckQueen.get():
                checks.append('queen')
            # end if
        # end if

        exports = []

        if self.selectExportXeasy.get():
            exports.append('Xeasy')
        # end if

        if self.selectExportCcpn.get():
            exports.append('CCPN')
        # end if

        if self.selectExportQueen.get():
            exports.append('QUEEN')
        # end if

        if self.selectExportRefine.get():
            exports.append('refine')
        # end if

        miscScript = None

        if self.selectMiscScript.get():
            script = self.miscScriptEntry.get()

            if script:
                miscScript = script
            # end if
        # end if

        return projectName, makeNewProject, projectImport, doValidation, checks, exports, miscScript
    # end def getGuiOptions


    def runCing(self):

        options = self.getGuiOptions()

        if options:

            projectName, makeNewProject, projectImport, doValidation, checks, exports, miscScript = options

            print 'Project name:', projectName
            print 'Make new project?', makeNewProject
            print 'Import source:', projectImport
            print 'Do vailidation?', doValidation
            print 'Validation checks:', ','.join(checks)
            print 'Export to:', ','.join(exports)
            print 'User script:', miscScript
        # end if
    # end def runCing

        # else there was already an error message

    def chooseOldProjectFile(self):

        fileTypes = [  FileType('CING', ['project.xml']),
                       FileType('All',  ['*'])
                    ]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'Select CING project file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
#    dirName  = popup.getDirectory()

        if len(fileName) > 0:
                # Put text into entry,name widgets
            dummy,name = cing.Project.rootPath(fileName)
            self.projEntry.configure(state='normal')
            self.projEntry.set(fileName)

            self.nameEntry.configure(state='normal')
            self.nameEntry.set(name)
            self.nameEntry.configure(state='disabled')
            # choose the correct radiobutton
            self.projOptionsSelect.setIndex(0)
            self.updateGui()
        # end if
        #nd if

        popup.destroy()
    # end def chooseOldProjectFile

    def choosePdbFile(self):

        fileTypes = [ FileType('PDB', ['*.pdb']),  FileType('All', ['*'])]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'PDB file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
        if len(fileName)>0:
            # Put text into entry widget
            self.pdbEntry.configure(state='normal')
            self.pdbEntry.set(fileName)
            # Put text into name widget
            _dir,name,dummy = nTpath( fileName )
            self.nameEntry.configure(state='normal')
            self.nameEntry.set(name)
            # choose the correct radiobutton
            self.projOptionsSelect.setIndex(1)
            self.updateGui()
        #end if

        popup.destroy()
    # end def choosePdbFile


    def chooseCcpnFile(self):

        fileTypes = [  FileType('XML', ['*.xml']), FileType('All', ['*'])]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'CCPN project XML file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
        if len(fileName)>0:
            self.pdbEntry.configure(state='normal')
            self.pdbEntry.set(fileName)
            self.projOptionsSelect.setIndex(1)

            _dir,name,dummy = nTpath( fileName )
            self.nameEntry.set(name)
        #end if
        self.ccpnEntry.set(fileName)
        self.projOptionsSelect.setIndex(2)

        popup.destroy()
    # end def chooseCcpnFile


    def chooseCyanaFile(self):

        # Prepend default Cyana file extension below
        fileTypes = [  FileType('All', ['*']), ]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'CYANA fproject file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
        self.cyanaEntry.set(fileName)
        self.projOptionsSelect.setIndex(3)

        popup.destroy()
    # end def chooseCyanaFile

    def chooseValidScript(self):

        # Prepend default Cyana file extension below
        fileTypes = [  FileType('All', ['*']), ]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'Script file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
        self.validScriptEntry.set(fileName)
        popup.destroy()
    # end def chooseValidScript

    def chooseMiscScript(self):

        # Prepend default Cyana file extension below
        fileTypes = [  FileType('All', ['*']), ]
        popup = FileSelectPopup(self, file_types = fileTypes,
                                title = 'Script file', dismiss_text = 'Cancel',
                                selected_file_must_exist = True)

        fileName = popup.getFile()
        self.miscScriptEntry.set(fileName)
        popup.destroy()
    # end def chooseMiscScript

    def openProject(self ):
        projOption = self.projOptionsSelect.get()
        if projOption == self.projectOptions[0]: 
            self.openOldProject()
        elif projOption == self.projectOptions[1]: 
            self.initPdb()
        # end if

        if self.project: 
            self.project.gui = self
        # end if
        self.updateGui()
    #end def

    def openOldProject(self ):
        fName = self.projEntry.get()
        if not os.path.exists( fName ):
            nTerror('Error: file "%s" does not exist\n', fName)
        #end if

        if self.project: 
            self.closeProject()
        # end if
        self.project = cing.Project.open( name=fName, status='old', verbose=False )
    #end def

    def initPdb(self ):
        fName = self.pdbEntry.get()
        if not os.path.exists( fName ):
            nTerror('Error: file "%s" does not exist\n', fName)
        #end if
        self.project = cing.Project.open( self.nameEntry.get(), status='new' )
        self.project.initPDB( pdbFile=fName, convention = 'PDB' )
    #end def

    def closeProject(self):
        if self.project: 
            self.project.close()
        # end if
        self.project = None
        self.updateGui()
    #end def

    def updateGui(self, event=None):

        projOption = self.projOptionsSelect.get()
        buttons = self.buttonBar.buttons

        # Disable entries
        for e in [self.projEntry, self.pdbEntry, self.ccpnEntry, self.cyanaEntry, self.nameEntry]:
            e.configure(state='disabled')
        #end for

        if projOption == self.projectOptions[0]:
            # Enable entries
            self.projEntry.configure(state='normal')

            if (len(self.projEntry.get()) > 0):
                self.openProjectButton.enable()
                self.runButton.enable()
            else:
                self.openProjectButton.disable()
                self.runButton.disable()
            #end if

        elif projOption == self.projectOptions[1]:
            # Enable entries
            self.pdbEntry.configure(state='normal')
            self.nameEntry.configure(state='normal')

            if (len(self.pdbEntry.get()) > 0 and len(self.nameEntry.get())  > 0):
                buttons[0].enable()
                buttons[1].enable()
            else:
                buttons[0].disable()
                buttons[1].disable()
            #end if
        #end if

        elif projOption == self.projectOptions[2]:
            # Enable entries
            self.ccpnEntry.configure(state='normal')
            self.nameEntry.configure(state='normal')

            if (len(self.ccpnEntry.get()) > 0 and len(self.nameEntry.get())  > 0):
                buttons[0].enable()
                buttons[1].enable()
            else:
                buttons[0].disable()
                buttons[1].disable()
            #end if
        #end if

        elif projOption == self.projectOptions[3]:
            # Enable entries
            self.cyanaEntry.configure(state='normal')
            self.nameEntry.configure(state='normal')

            if (len(self.cyanaEntry.get()) > 0 and len(self.nameEntry.get())  > 0):
                buttons[0].enable()
                buttons[1].enable()
            else:
                buttons[0].disable()
                buttons[1].disable()
            #end if
        #end if

        self.projectStatus.clear()
        if not self.project:
            self.projectStatus.setText('No open project')
            self.closeProjectButton.setText('Close Project')
            self.closeProjectButton.disable()
        else:
            self.projectStatus.setText(self.project.format())
            self.closeProjectButton.enable()
            self.closeProjectButton.setText(sprintf('Close Project "%s"', self.project.name))
        #end if
    #end def

    def redirectConsole(self):

        #pipe = TextPipe(self.inputTextBox.text_area)
        #sys.stdin = pipe

        pipe = TextPipe(self.outputTextBox.text_area)
        sys.stdout = pipe
        nTmessage.stream = pipe
    # end def redirectConsole
#    sys.stderr = pipe

    def resetConsole(self):
        #sys.stdin   = stdin
        nTmessage.stream = stdout
        sys.stdout  = stdout
        sys.stderr  = stderr
    # end def resetConsole

    def open(self):

        self.redirectConsole()
        BasePopup.open(self)
    # end def open

    def close(self):

        geometry = self.getGeometry()
        self.resetConsole()
        BasePopup.close(self)

        print 'close:',geometry
        sys.exit(0) # remove later
    # end def close

    def destroy(self):

        geometry = self.getGeometry()
        self.resetConsole()
        BasePopup.destroy(self)

        print 'destroy:',geometry
        sys.exit(0) # remove later
示例#29
0
  def body(self, mainFrame):

    mainFrame.grid_columnconfigure(1, weight=1, minsize=100)
    mainFrame.config(borderwidth=5, relief='solid')

    row = 0
    label = Label(mainFrame, text="Frame (with sub-widgets):")
    label.grid(row=row, column=0, sticky=Tkinter.E)

    frame = Frame(mainFrame, relief='raised', border=2, background='#8080D0')
    # Frame expands East-West
    frame.grid(row=row, column=1, sticky=Tkinter.EW)
    # Last column expands => Widgets pusted to the West
    frame.grid_columnconfigure(3, weight=1)
    
    # Label is within the sub frame
    label = Label(frame, text='label ')
    label.grid(row=0, column=0, sticky=Tkinter.W)
    
    entry = Entry(frame, text='Entry', returnCallback=self.showWarning)
    entry.grid(row=0, column=1, sticky=Tkinter.W)
    
    self.check = CheckButton(frame, text='Checkbutton', selected=True, callback=self.updateObjects)
    self.check.grid(row=0, column=2, sticky=Tkinter.W)
    
    # stick a button to the East wall
    button = Button(frame, text='Button', command=self.pressButton)
    button.grid(row=0, column=3, sticky=Tkinter.E)
  
    row += 1
    label = Label(mainFrame, text="Text:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    self.textWindow = Text(mainFrame, text='Initial Text\n', width=60, height=5)
    self.textWindow.grid(row=row, column=1, sticky=Tkinter.NSEW)
    
    row += 1
    label = Label(mainFrame, text="CheckButtons:")
    label.grid(row=row, column=0, sticky=Tkinter.E)

    entries = ['Alpha','Beta','Gamma','Delta']
    selected = entries[2:]
    self.checkButtons = CheckButtons(mainFrame, entries, selected=selected,select_callback=self.changedCheckButtons)
    self.checkButtons.grid(row=row, column=1, sticky=Tkinter.W)
  
    row += 1
    label = Label(mainFrame, text="PartitionedSelector:")
    label.grid(row=row, column=0, sticky=Tkinter.E)

    labels   = ['Bool','Int','Float','String']
    objects  = [type(0),type(1),type(1.0),type('a')]
    selected = [type('a')]
    self.partitionedSelector= PartitionedSelector(mainFrame, labels=labels,
                                                  objects=objects,
                                                  colors = ['red','yellow','green','#000080'],
                                                  callback=self.toggleSelector,selected=selected)
    self.partitionedSelector.grid(row=row, column=1, sticky=Tkinter.EW)

    row += 1
    label = Label(mainFrame, text="PulldownMenu")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    
    entries = ['Frodo','Pipin','Merry','Sam','Bill','Gandalf','Strider','Gimli','Legolas']
    self.pulldownMenu = PulldownMenu(mainFrame, callback=self.selectPulldown,
                                     entries=entries, selected_index=2,
                                     do_initial_callback=False)
    self.pulldownMenu.grid(row=row, column=1, sticky=Tkinter.W)

    row += 1
    label = Label(mainFrame, text="RadioButtons in a\nScrolledFrame.frame:")
    label.grid(row=row, column=0, sticky=Tkinter.EW)
    
    frame = ScrolledFrame(mainFrame, yscroll = False, doExtraConfig = True, width=100)
    frame.grid(row=row, column=1, sticky=Tkinter.EW)
    frame.grid_columnconfigure(0, weight=1)

    self.radioButtons = RadioButtons(frame.frame, entries=entries,
                                     select_callback=self.checkRadioButtons,
                                     selected_index=1, relief='groove')
    self.radioButtons.grid(row=0, column=0, sticky=Tkinter.W)
    
    row += 1
    label = Label(mainFrame, text="LabelFrame with\nToggleLabels inside:")
    label.grid(row=row, column=0, sticky=Tkinter.E)

    labelFrame = LabelFrame(mainFrame, text='Frame Title')
    labelFrame.grid(row=row, column=1, sticky=Tkinter.NSEW)
    labelFrame.grid_rowconfigure(0, weight=1)
    labelFrame.grid_columnconfigure(3, weight=1)
    
        
    self.toggleLabel1 = ToggleLabel(labelFrame, text='ScrolledMatrix', callback=self.toggleFrame1)
    self.toggleLabel1.grid(row=0, column=0, sticky=Tkinter.W)
    self.toggleLabel1.arrowOn()

    self.toggleLabel2 = ToggleLabel(labelFrame, text='ScrolledGraph', callback=self.toggleFrame2)
    self.toggleLabel2.grid(row=0, column=1, sticky=Tkinter.W)

    self.toggleLabel3 = ToggleLabel(labelFrame, text='ScrolledCanvas', callback=self.toggleFrame3)
    self.toggleLabel3.grid(row=0, column=2, sticky=Tkinter.W)
    
    row += 1
    mainFrame.grid_rowconfigure(row, weight=1)

    label = Label(mainFrame, text="changing/shrinking frames:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    
    self.toggleRow = row
    self.toggleFrame = Frame(mainFrame)
    self.toggleFrame.grid(row=row, column=1, sticky=Tkinter.NSEW)
    self.toggleFrame.grid_rowconfigure(0, weight=1)
    self.toggleFrame.grid_columnconfigure(0, weight=1)
    
    # option 1
    
    self.intEntry = IntEntry(self, returnCallback = self.setNumber, width=8)
    
    self.multiWidget = MultiWidget(self, Entry, options=None, 
                                  values=None, callback=self.setKeywords,
                                  minRows=3, maxRows=5)

    editWidgets      = [None, None, self.intEntry,  self.multiWidget]
    editGetCallbacks = [None, None, self.getNumber, self.getKeywords]
    editSetCallbacks = [None, None, self.setNumber, self.setKeywords]
    
    headingList = ['Name','Color','Number','Keywords']
    self.scrolledMatrix = ScrolledMatrix(self.toggleFrame, headingList=headingList,
                                         editSetCallbacks=editSetCallbacks,
                                         editGetCallbacks=editGetCallbacks,
                                         editWidgets=editWidgets,
                                         callback=self.selectObject,
                                         multiSelect=False) 
                                         
    self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW)

    # option 2
    self.scrolledGraph = ScrolledGraph(self.toggleFrame, width=400,
                                       height=300, symbolSize=5,
                                       symbols=['square','circle'],
                                       dataColors=['#000080','#800000'],
                                       lineWidths=[0,1] )

    self.scrolledGraph.setZoom(1.3)

    dataSet1 = [[0,0],[1,1],[2,4],[3,9],[4,16],[5,25]]
    dataSet2 = [[0,0],[1,3],[2,6],[3,9],[4,12],[5,15]]
    self.scrolledGraph.update(dataSets=[dataSet1,dataSet2],
                              xLabel = 'X axis label',
                              yLabel = 'Y axis label',
                              title  = 'Main Title')
    self.scrolledGraph.draw()

    # option 3
    self.scrolledCanvas = ScrolledCanvas(self.toggleFrame,relief = 'groove', borderwidth = 2, resizeCallback=None)
    canvas = self.scrolledCanvas.canvas
    font   = 'Helvetica 10'
    box    = canvas.create_rectangle(10,10,150,200, outline='grey', fill='grey90')
    line   = canvas.create_line(0,0,200,200,fill='#800000', width=2)
    text   = canvas.create_text(120,50, text='Text', font=font, fill='black')
    circle = canvas.create_oval(30,30,50,50,outline='#008000',fill='#404040',width=3)
     
    row += 1
    label = Label(mainFrame, text="FloatEntry:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    self.floatEntry = FloatEntry(mainFrame, text=3.14159265, returnCallback=self.floatEntryReturn)
    self.floatEntry.grid(row=row, column=1, sticky=Tkinter.W)
    
     
    row += 1
    label = Label(mainFrame, text="Scale:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    self.scale = Scale(mainFrame, from_=10, to=90, value=50, orient=Tkinter.HORIZONTAL)
    self.scale.grid(row=row, column=1, sticky=Tkinter.W)

    row += 1
    label = Label(mainFrame, text="Value Ramp:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    self.valueRamp = ValueRamp(mainFrame, self.valueRampCallback, speed = 1.5, delay = 50)
    self.valueRamp.grid(row=row, column=1, sticky=Tkinter.W)
  

    row += 1
    label = Label(mainFrame, text="ButtonList:")
    label.grid(row=row, column=0, sticky=Tkinter.E)
    
    texts    = ['Select File','Close','Quit']
    commands = [self.selectFile, self.close, self.quit]
    bottomButtons = ButtonList(mainFrame, texts=texts, commands=commands, expands=True) 
    bottomButtons.grid(row=row, column=1, sticky=Tkinter.EW)
  
    self.protocol('WM_DELETE_WINDOW', self.quit)
示例#30
0
文件: gui.py 项目: VuisterLab/cing
    def body(self, guiFrame):

        row = 0
        col =0
#    frame = Frame( guiFrame )
#    frame.grid(row=row, column=col, sticky='news')
        self.menuBar = Menu( guiFrame)
        self.menuBar.grid( row=row, column=col, sticky='ew')

        #----------------------------------------------------------------------------------
        # Project frame
        #----------------------------------------------------------------------------------

#    guiFrame.grid_columnconfigure(row, weight=1)
#    frame = LabelFrame(guiFrame, text='Project', font=medFont)
        row = +1
        col =0
        frame = LabelFrame(guiFrame, text='Project', **labelFrameAttributes )
        print '>', frame.keys()
        frame.grid(row=row, column=col, sticky='nsew' )
        frame.grid_columnconfigure(2, weight=1)
#    frame.grid_rowconfigure(0, weight=1)

        srow = 0
        self.projectOptions = ['old','new from PDB','new from CCPN','new from CYANA']
        self.projOptionsSelect = RadioButtons(frame, selected_index=0, entries=self.projectOptions, direction='vertical',
                                              select_callback=self.updateGui
                                             )
        self.projOptionsSelect.grid(row=srow,column=0,rowspan=len(self.projectOptions),columnspan=2, sticky='w')

        if self.options.name: 
            text = self.options.name
        else: 
            text=''
        # end if
        self.projEntry = Entry(frame, bd=1, text=text, returnCallback=self.updateGui)
        self.projEntry.grid(row=srow,column=2,columnspan=2,sticky='ew')
#    self.projEntry.bind('<Key>', self.updateGui)
        self.projEntry.bind('<Leave>', self.updateGui)

        projButton = Button(frame, bd=1,command=self.chooseOldProjectFile, text='browse')
        projButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.pdbEntry = Entry(frame, bd=1, text='')
        self.pdbEntry.grid(row=srow,column=2,sticky='ew')
        self.pdbEntry.bind('<Leave>', self.updateGui)

        pdbButton = Button(frame, bd=1,command=self.choosePdbFile, text='browse')
        pdbButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.ccpnEntry = Entry(frame, bd=1, text='')
        self.ccpnEntry.grid(row=srow,column=2,sticky='ew')
        self.ccpnEntry.bind('<Leave>', self.updateGui)

        ccpnButton = Button(frame, bd=1,command=self.chooseCcpnFile, text='browse')
        ccpnButton.grid(row=srow,column=3,sticky='ew')

        srow += 1
        self.cyanaEntry = Entry(frame, bd=1, text='')
        self.cyanaEntry.grid(row=srow,column=2,sticky='ew')
        self.cyanaEntry.bind('<Leave>', self.updateGui)

        cyanaButton = Button(frame, bd=1,command=self.chooseCyanaFile, text='browse')
        cyanaButton.grid(row=srow,column=3,sticky='ew')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        label = Label(frame, text='Project name:')
        label.grid(row=srow,column=0,sticky='nw')
        self.nameEntry = Entry(frame, bd=1, text='')
        self.nameEntry.grid(row=srow,column=2,sticky='w')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        self.openProjectButton = Button(frame, command=self.openProject, text='Open Project', **actionButtonAttributes )
        self.openProjectButton.grid(row=srow,column=0, columnspan=4, sticky='ew')


        #----------------------------------------------------------------------------------
        # status
        #----------------------------------------------------------------------------------
#    guiFrame.grid_columnconfigure(1, weight=0)
        srow = 0
        frame = LabelFrame(guiFrame, text='Status', **labelFrameAttributes)
        frame.grid( row=srow, column=1, sticky='wnes')
        self.projectStatus = Text(frame, height=11, width=70, borderwidth=0, relief='flat')
        self.projectStatus.grid(row=0, column=0, sticky='wen')

        #Empty row
        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        srow += 1
        self.closeProjectButton = Button(frame, command=self.closeProject, text='Close Project', **actionButtonAttributes)
        self.closeProjectButton.grid(row=srow,column=0, columnspan=4, sticky='ew')

        #----------------------------------------------------------------------------------
        # Validate frame
        #----------------------------------------------------------------------------------

        row +=1
        col=0
        frame = LabelFrame(guiFrame, text='Validate', **labelFrameAttributes)
#    frame = LabelFrame(guiFrame, text='Validate', font=medFont)
        frame.grid(row=row, column=col, sticky='nsew')
#    frame.grid_columnconfigure(2, weight=1)
        frame.grid_rowconfigure(0, weight=1)

        srow = 0
#    label = Label(frame, text='validation')
#    label.grid(row=srow,column=0,sticky='nw')
#
#    self.selectDoValidation = CheckButton(frame)
#    self.selectDoValidation.grid(row=srow, column=1,sticky='nw' )
#    self.selectDoValidation.set(True)
#
#    srow += 1
#    label = Label(frame, text='')
#    label.grid(row=srow,column=0,sticky='nw')
#
#    srow += 1
        label = Label(frame, text='checks')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectCheckAssign = CheckButton(frame)
        self.selectCheckAssign.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckAssign.set(True)
        label = Label(frame, text='assignments and shifts')
        label.grid(row=srow,column=2,sticky='nw')


#    srow += 1
#    self.selectCheckQueen = CheckButton(frame)
#    self.selectCheckQueen.grid(row=srow, column=4,sticky='nw' )
#    self.selectCheckQueen.set(False)
#    label = Label(frame, text='QUEEN')
#    label.grid(row=srow,column=5,sticky='nw')
#
#    queenButton = Button(frame, bd=1,command=None, text='setup')
#    queenButton.grid(row=srow,column=6,sticky='ew')


        srow += 1
        self.selectCheckResraint = CheckButton(frame)
        self.selectCheckResraint.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckResraint.set(True)
        label = Label(frame, text='restraints')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectCheckStructure = CheckButton(frame)
        self.selectCheckStructure.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckStructure.set(True)
        label = Label(frame, text='structural')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectMakeHtml = CheckButton(frame)
        self.selectMakeHtml.grid(row=srow, column=1,sticky='nw' )
        self.selectMakeHtml.set(True)
        label = Label(frame, text='generate HTML')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectCheckScript = CheckButton(frame)
        self.selectCheckScript.grid(row=srow, column=1,sticky='nw' )
        self.selectCheckScript.set(False)
        label = Label(frame, text='user script')
        label.grid(row=srow,column=0,sticky='nw')

        self.validScriptEntry = Entry(frame, bd=1, text='')
        self.validScriptEntry.grid(row=srow,column=2,columnspan=3, sticky='ew')

        scriptButton = Button(frame, bd=1,command=self.chooseValidScript, text='browse')
        scriptButton.grid(row=srow,column=5,sticky='ew')

        srow += 1
        label = Label(frame, text='ranges')
        label.grid(row=srow,column=0,sticky='nw')
        self.rangesEntry = Entry( frame, text='' )
        self.rangesEntry.grid( row=srow, column=2, columnspan=3, sticky='ew')

#    self.validScriptEntry = Entry(frame, bd=1, text='')
#    self.validScriptEntry.grid(row=srow,column=3,sticky='ew')
#
#    scriptButton = Button(frame, bd=1,command=self.chooseValidScript, text='browse')
#    scriptButton.grid(row=srow,column=4,sticky='ew')


        srow += 1
        texts    = ['Run Validation','View Results','Setup QUEEN']
        commands = [self.runCing, None, None]
        buttonBar = ButtonList(frame, texts=texts, commands=commands,expands=True)
        buttonBar.grid(row=srow, column=0, columnspan=6, sticky='ew')
        for button in buttonBar.buttons:
            button.config(**actionButtonAttributes)
        # end for
        self.runButton = buttonBar.buttons[0]
        self.viewResultButton = buttonBar.buttons[1]
        self.queenButton = buttonBar.buttons[2]

        #----------------------------------------------------------------------------------
        # Miscellaneous frame
        #----------------------------------------------------------------------------------

        row +=0
        col=1
#    frame = LabelFrame(guiFrame, text='Miscellaneous', font=medFont)
        frame = LabelFrame(guiFrame, text='Miscellaneous', **labelFrameAttributes)
        frame.grid(row=row, column=col, sticky='news')
        frame.grid_columnconfigure(2, weight=1)
        frame.grid_columnconfigure(4, weight=1,minsize=30)
        frame.grid_rowconfigure(0, weight=1)

        # Exports

        srow = 0
        label = Label(frame, text='export to')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectExportXeasy = CheckButton(frame)
        self.selectExportXeasy.grid(row=srow, column=1,sticky='nw' )
        self.selectExportXeasy.set(True)
        label = Label(frame, text='Xeasy, Sparky, TALOS, ...')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportCcpn = CheckButton(frame)
        self.selectExportCcpn.grid(row=srow, column=1,sticky='nw' )
        self.selectExportCcpn.set(True)
        label = Label(frame, text='CCPN')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportQueen = CheckButton(frame)
        self.selectExportQueen.grid(row=srow, column=1,sticky='nw' )
        self.selectExportQueen.set(True)
        label = Label(frame, text='QUEEN')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        self.selectExportRefine = CheckButton(frame)
        self.selectExportRefine.grid(row=srow, column=1,sticky='nw' )
        self.selectExportRefine.set(True)
        label = Label(frame, text='refine')
        label.grid(row=srow,column=2,sticky='nw')

        srow += 1
        label = Label(frame, text='')
        label.grid(row=srow,column=0,sticky='nw')

        # User script

        srow += 1
        label = Label(frame, text='user script')
        label.grid(row=srow,column=0,sticky='nw')

        self.selectMiscScript = CheckButton(frame)
        self.selectMiscScript.grid(row=srow, column=1,sticky='nw' )
        self.selectMiscScript.set(False)

        self.miscScriptEntry = Entry(frame, bd=1, text='')
        self.miscScriptEntry.grid(row=srow,column=3,sticky='ew')

        script2Button = Button(frame, bd=1,command=self.chooseMiscScript, text='browse')
        script2Button.grid(row=srow,column=4,sticky='ew')

        srow += 1
        texts    = ['Export','Run Script']
        commands = [None, None]
        buttonBar = ButtonList(frame, texts=texts, commands=commands,expands=True)
        buttonBar.grid(row=srow, column=0, columnspan=5, sticky='ew')
        for button in buttonBar.buttons:
            button.config(**actionButtonAttributes)
        # end for
        self.exportButton = buttonBar.buttons[0]
        self.scriptButton = buttonBar.buttons[1]

        #----------------------------------------------------------------------------------
        # Textarea
        #----------------------------------------------------------------------------------
        row +=1
        guiFrame.grid_rowconfigure(row, weight=1)
        self.outputTextBox = ScrolledText(guiFrame)
        self.outputTextBox.grid(row=row, column=0, columnspan=2, sticky='nsew')

        self.redirectConsole()

        #----------------------------------------------------------------------------------
        # Buttons
        #----------------------------------------------------------------------------------
        row +=1
        col=0
        texts    = ['Quit', 'Help']
        commands = [self.close, None]
        self.buttonBar = ButtonList(guiFrame, texts=texts, commands=commands,expands=True)
        self.buttonBar.grid(row=row, column=col, columnspan=2, sticky='ew')

#    self.openProjectButton = self.buttonBar.buttons[0]
#    self.closeProjectButton = self.buttonBar.buttons[1]
#    self.runButton = self.buttonBar.buttons[0]
#    self.viewResultButton = self.buttonBar.buttons[1]

        for button in self.buttonBar.buttons:
            button.config(**actionButtonAttributes)
示例#31
0
    def body(self, guiFrame):

        guiFrame.grid_columnconfigure(2, weight=1)

        row = 0
        label = Label(guiFrame, text='Template window: ', grid=(row, 0))
        tipText = 'Selects which window to use as the basis for making a new spectrum window; sets the axis types accordingly'
        self.window_list = PulldownList(guiFrame,
                                        grid=(row, 1),
                                        callback=self.setAxisTypes,
                                        tipText=tipText)
        frame = LabelFrame(guiFrame,
                           text='Strips',
                           grid=(row, 2),
                           gridSpan=(2, 1))
        buttons = UtilityButtonList(guiFrame,
                                    doClone=False,
                                    helpUrl=self.help_url,
                                    grid=(row, 3))

        row += 1
        label = Label(guiFrame, text='New window name: ', grid=(row, 0))
        tipText = 'A short name to identify the spectrum window, which will appear in the graphical interface'
        self.nameEntry = Entry(guiFrame,
                               width=16,
                               grid=(row, 1),
                               tipText=tipText)

        row += 1

        label = Label(frame, text='Columns: ', grid=(0, 0))
        tipText = 'The number of vertical strips/dividers to initially make in the spectrum window'
        self.cols_menu = PulldownList(frame,
                                      objects=STRIP_NUMS,
                                      grid=(0, 1),
                                      texts=[str(x) for x in STRIP_NUMS],
                                      tipText=tipText)

        label = Label(frame, text='Rows: ', grid=(0, 2))
        tipText = 'The number of horizontal strips/dividers to initially make in the spectrum window'
        self.rows_menu = PulldownList(frame,
                                      objects=STRIP_NUMS,
                                      grid=(0, 3),
                                      texts=[str(x) for x in STRIP_NUMS],
                                      tipText=tipText)
        row += 1
        div = LabelDivider(guiFrame,
                           text='Axes',
                           grid=(row, 0),
                           gridSpan=(1, 4))

        row += 1
        self.axis_lists = {}
        frame = Frame(guiFrame, grid=(row, 0), gridSpan=(1, 4))

        col = 0
        self.axisTypes = {}
        self.axisTypesIncludeNone = {}
        for label in AXIS_LABELS:
            self.axisTypes[label] = None
            w = Label(frame, text=' ' + label)
            w.grid(row=0, column=col, sticky='w')
            col += 1

            if label in ('x', 'y'):
                includeNone = False
                tipText = 'Sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label
            else:
                includeNone = True
                tipText = 'Where required, sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label
            self.axisTypesIncludeNone[label] = includeNone

            getAxisTypes = lambda label=label: self.getAxisTypes(label)
            callback = lambda axisType, label=label: self.changedAxisType(
                label, axisType)
            self.axis_lists[label] = PulldownList(frame,
                                                  callback=callback,
                                                  tipText=tipText)
            self.axis_lists[label].grid(row=0, column=col, sticky='w')
            col += 1

        frame.grid_columnconfigure(col, weight=1)

        row += 1
        div = LabelDivider(guiFrame,
                           text='Viewed Spectra',
                           grid=(row, 0),
                           gridSpan=(1, 4))

        row += 1
        guiFrame.grid_rowconfigure(row, weight=1)

        editWidgets = [None, None, None, None]
        editGetCallbacks = [None, self.toggleVisible, self.toggleToolbar, None]
        editSetCallbacks = [None, None, None, None]
        tipTexts = [
            'The "experiment:spectrum" name for the spectrum that may be viewed in the new window, given the axis selections',
            'Sets whether the spectrum contours will be visible in the new window',
            'Sets whether the spectrum appears at all in the window; if not in the toolbar it cannot be displayed',
            'The number of peak lists the spectrum contains'
        ]
        headingList = ['Spectrum', 'Visible?', 'In Toolbar?', 'Peak Lists']

        self.scrolledMatrix = ScrolledMatrix(guiFrame,
                                             headingList=headingList,
                                             editWidgets=editWidgets,
                                             editGetCallbacks=editGetCallbacks,
                                             editSetCallbacks=editSetCallbacks,
                                             multiSelect=True,
                                             grid=(row, 0),
                                             gridSpan=(1, 4),
                                             tipTexts=tipTexts)

        row += 1
        tipTexts = [
            'Creates a new spectrum window with the specified parameters',
            'Sets the contours of the selected spectra to be visible when the new window is made',
            'Sets the contours of the selected spectra to not be displayed when the new window is made',
            'Sets the selected spectra as absent from the window toolbar, and thus not displayable at all'
        ]
        texts = [
            'Create Window!', 'Selected\nVisible', 'Selected\nNot Visible',
            'Selected\nNot In Toolbar'
        ]
        commands = [
            self.ok, self.setSelectedDisplay, self.setSelectedHide,
            self.setSelectedAbsent
        ]
        buttonList = ButtonList(guiFrame,
                                texts=texts,
                                grid=(row, 0),
                                commands=commands,
                                gridSpan=(1, 4),
                                tipTexts=tipTexts)
        buttonList.buttons[0].config(bg='#B0FFB0')

        self.updateAxisTypes()
        self.updateWindow()
        self.updateWindowName()

        self.administerNotifiers(self.registerNotify)
        self.updateAfter()
示例#32
0
class MeccanoPopup(BasePopup):

  def __init__(self, parent, project, *args, **kw):
  
    self.alignMedium = None
    self.chain = None
    self.constraint = None
    self.constraintSet = None
    self.molSystem = None
    self.project = project
    self.run = None
    self.shiftList = None
    self.tensor = None

    
    BasePopup.__init__(self, parent=parent, title='MECCANO', *args, **kw)

    self.curateNotifiers(self.registerNotify)

  def body(self, guiFrame):
  
    guiFrame.grid_columnconfigure(0, weight=1)
    guiFrame.grid_rowconfigure(0, weight=1)

    options = ['Parameters','Restraints','Alignment Media & Tensors','About Meccano']
    tabbedFrame = TabbedFrame(guiFrame, options=options)
    tabbedFrame.grid(row=0, column=0, sticky='nsew')
    
    frameA, frameB, frameC, frameD = tabbedFrame.frames
    frameA.grid_columnconfigure(1, weight=1)
    frameA.grid_rowconfigure(13, weight=1)
    frameB.grid_columnconfigure(1, weight=1)
    frameB.grid_rowconfigure(1, weight=1)
    frameC.grid_columnconfigure(0, weight=1)
    frameC.grid_rowconfigure(1, weight=1)
    frameD.grid_columnconfigure(0, weight=1)
    frameD.grid_rowconfigure(0, weight=1)
    
    texts = ['Run MECCANO!']
    commands = [self.runMeccano]
    bottomButtons = createDismissHelpButtonList(guiFrame, texts=texts,
                                                commands=commands, expands=True)
    bottomButtons.grid(row=1, column=0, sticky='ew')

    if not Meccano:
      bottomButtons.buttons[0].disable()
  
    # Parameters
        
    row = 0
    label = Label(frameA, text='Calculation Run:')
    label.grid(row=row,column=0,sticky='w')
    self.runPulldown = PulldownList(frameA, callback=self.selectRun)
    self.runPulldown.grid(row=row,column=1,sticky='w')
    
    row += 1    
    label = Label(frameA, text='Shift List (for CO):')
    label.grid(row=row,column=0,sticky='w')
    self.shiftListPulldown = PulldownList(frameA, callback=self.selectShiftList)
    self.shiftListPulldown.grid(row=row,column=1,sticky='w')
           
    row += 1    
    label = Label(frameA, text='Keep Copy of Used Shifts:')
    label.grid(row=row,column=0,sticky='w')
    self.toggleCopyShifts = CheckButton(frameA)
    self.toggleCopyShifts.grid(row=row,column=1,sticky='w')
    self.toggleCopyShifts.set(True)
        
    row += 1    
    label = Label(frameA, text='Molecular System:')
    label.grid(row=row,column=0,sticky='w')
    self.molSystemPulldown = PulldownList(frameA, callback=self.selectMolSystem)
    self.molSystemPulldown.grid(row=row,column=1,sticky='w')
        
    row += 1    
    label = Label(frameA, text='Chain:')
    label.grid(row=row,column=0,sticky='w')
    self.chainPulldown = PulldownList(frameA, callback=self.selectChain)
    self.chainPulldown.grid(row=row,column=1,sticky='w')
    self.chainPulldown.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='First Peptide Plane:')
    label.grid(row=row,column=0,sticky='w')
    self.firstResEntry = IntEntry(frameA, text=None, width=8)
    self.firstResEntry.grid(row=row,column=1,sticky='w')
    self.firstResEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Last Peptide Plane:')
    label.grid(row=row,column=0,sticky='w')
    self.lastResEntry = IntEntry(frameA, text=None, width=8)
    self.lastResEntry.grid(row=row,column=1,sticky='w')
    self.lastResEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Max Num Optimisation Steps:')
    label.grid(row=row,column=0,sticky='w')
    self.maxOptStepEntry = IntEntry(frameA, text=500, width=8)
    self.maxOptStepEntry.grid(row=row,column=1,sticky='w')
    self.maxOptStepEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Num Optimisation Peptide Planes:')
    label.grid(row=row,column=0,sticky='w')
    self.numOptPlaneEntry = IntEntry(frameA, text=2, width=8)
    self.numOptPlaneEntry.grid(row=row,column=1,sticky='w')
    self.numOptPlaneEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Min Num Optimisation Hits:')
    label.grid(row=row,column=0,sticky='w')
    self.numOptHitsEntry = IntEntry(frameA, text=5, width=8)
    self.numOptHitsEntry.grid(row=row,column=1,sticky='w')
    self.numOptHitsEntry.bind('<Leave>', self.updateRunParams) 

    row += 1    
    label = Label(frameA, text='File Name Prefix:')
    label.grid(row=row,column=0,sticky='w')
    self.pdbFileEntry = Entry(frameA, text='Meccano', width=8)
    self.pdbFileEntry.grid(row=row,column=1,sticky='w')
    self.pdbFileEntry.bind('<Leave>', self.updateRunParams) 
           
    row += 1    
    label = Label(frameA, text='Write Output File (.out):')
    label.grid(row=row,column=0,sticky='w')
    self.toggleWriteOutFile = CheckButton(frameA)
    self.toggleWriteOutFile.grid(row=row,column=1,sticky='w')
    self.toggleWriteOutFile.set(False)
    self.toggleWriteOutFile.bind('<Leave>', self.updateRunParams) 
           
    row += 1    
    label = Label(frameA, text='Write PDB File (.pdb):')
    label.grid(row=row,column=0,sticky='w')
    self.toggleWritePdbFile = CheckButton(frameA)
    self.toggleWritePdbFile.grid(row=row,column=1,sticky='w')
    self.toggleWritePdbFile.set(True)
    self.toggleWritePdbFile.bind('<Leave>', self.updateRunParams) 
    
    if not Meccano:
      row += 1    
      label = Label(frameA, text='The Meccano executable is not available (it needs to be compiled)', fg='red')
      label.grid(row=row,column=0,columnspan=2,sticky='w')

    # Restraints
    
    label = Label(frameB, text='Constraint Set:')
    label.grid(row=0,column=0,sticky='w')
    
    self.constraintSetPulldown = PulldownList(frameB, callback=self.selectConstraintSet)
    self.constraintSetPulldown.grid(row=0,column=1,sticky='w')
    
    self.alignMediumPulldown= PulldownList(self, callback=self.setAlignMedium)
    
    headingList = ['#','List Type','Use?','Alignment\nMedium','Num\nRestraints']
    editWidgets      = [None,None,None,self.alignMediumPulldown,None]
    editGetCallbacks = [None,None,self.toggleUseRestraints,self.getAlignMedium,None]
    editSetCallbacks = [None,None,None,self.setAlignMedium,None]
    self.restraintMatrix = ScrolledMatrix(frameB,
                                          headingList=headingList,
                                          editSetCallbacks=editSetCallbacks,
                                          editGetCallbacks=editGetCallbacks, 
                                          editWidgets=editWidgets,
                                          callback=None,
                                          multiSelect=True)
    self.restraintMatrix.grid(row=1,column=0,columnspan=2,sticky='nsew')
    
    
    # Alignment Media
    
    div = LabelDivider(frameC,text='Alignment Media')
    div.grid(row=0,column=0,sticky='ew')
    
    self.mediumNameEntry = Entry(self, returnCallback=self.setMediumName)
    self.mediumDetailsEntry = Entry(self, returnCallback=self.setMediumDetails)
    
    headingList = ['#','Name','Details','Static Tensor','Dynamic Tensor']
    editWidgets      = [None, self.mediumNameEntry, self.mediumDetailsEntry, None, None]
    editGetCallbacks = [None, self.getMediumName, self.getMediumDetails, None, None]
    editSetCallbacks = [None, self.setMediumName, self.setMediumDetails, None, None]
    self.mediaMatrix = ScrolledMatrix(frameC,
                                      headingList=headingList,
                                      editSetCallbacks=editSetCallbacks,
                                      editGetCallbacks=editGetCallbacks, 
                                      editWidgets=editWidgets,
                                      callback=self.selectAlignMedium,
                                      multiSelect=True)
                                 
    self.mediaMatrix.grid(row=1,column=0,sticky='nsew')
     
    
    texts = ['Add Alignment medium','Remove Alignment Medium']
    commands = [self.addAlignMedium,self.removeAlignMedium]
    buttonList = ButtonList(frameC, texts=texts, commands=commands, expands=True)
    buttonList.grid(row=2,column=0,sticky='nsew')
    
    self.editAxialEntry = FloatEntry(self, returnCallback=self.setAxial)
    self.editRhombicEntry = FloatEntry(self, returnCallback=self.setRhombic)
    self.editAlphaEulerEntry = FloatEntry(self, returnCallback=self.setEulerAlpha)
    self.editBetaEulerEntry = FloatEntry(self, returnCallback=self.setEulerBeta)
    self.editGammaEulerEntry = FloatEntry(self, returnCallback=self.setEulerGamma)
    
    
    div = LabelDivider(frameC,text='Alignment Tensors')
    div.grid(row=3,column=0,sticky='ew')
    
    headingList = ['Type', u'Axial (\u03B6)',u'Rhombic (\u03B7)',
                   u'Euler \u03B1',u'Euler \u03B2',u'Euler \u03B3']
    editWidgets      = [None,self.editAxialEntry,
                        self.editRhombicEntry,self.editAlphaEulerEntry,
                        self.editBetaEulerEntry,self.editGammaEulerEntry]
    editSetCallbacks = [None,self.setAxial,self.setRhombic,
                        self.setEulerAlpha,self.setEulerBeta,self.setEulerGamma]
    editGetCallbacks = [None,self.getAxial,self.getRhombic,
                        self.getEulerAlpha,self.getEulerBeta,self.getEulerGamma]
                   
    self.tensorMatrix = ScrolledMatrix(frameC, maxRows=2,
                                       headingList=headingList,
                                       editSetCallbacks=editSetCallbacks,
                                       editGetCallbacks=editGetCallbacks, 
                                       editWidgets=editWidgets,
                                       callback=self.selectTensor,
                                       multiSelect=True)
                                          
    self.tensorMatrix.grid(row=4,column=0,sticky='nsew')
    
    texts = ['Add Static Tensor','Add Dynamic Tensor','Remove Tensor']
    commands = [self.addStaticTensor,self.addDynamicTensor,self.removeTensor]
    buttonList = ButtonList(frameC,texts=texts, commands=commands, expands=True)
    buttonList.grid(row=5,column=0,sticky='ew')
       
    # About
    
    label = Label(frameD, text='About Meccano...')
    label.grid(row=0,column=0,sticky='w')
  
    #
  
    self.geometry('500x400')

    self.updateShiftLists()
    self.updateMolSystems()
    self.updateResidueRanges()
    self.updateConstraintSets()
    self.updateAlignMedia()
    self.updateRuns()
    
  def close(self):
  
    self.updateRunParams()
    
    BasePopup.close(self)
  
  def destroy(self):
  
    self.updateRunParams()
    self.curateNotifiers(self.unregisterNotify)
    
    BasePopup.destroy(self)
  
  def curateNotifiers(self, notifyFunc):
  
    for func in ('__init__', 'delete'):
      notifyFunc(self.updateConstraintSetsAfter, 'ccp.nmr.NmrConstraint.NmrConstraintStore', func)
    
    for func in ('__init__', 'delete','setName','setConditionState'):
      for clazz in ('ccp.nmr.NmrConstraint.CsaConstraintList',
                    'ccp.nmr.NmrConstraint.DihedralConstraintList',
                    'ccp.nmr.NmrConstraint.DistanceConstraintList',
                    'ccp.nmr.NmrConstraint.HBondConstraintList',
                    'ccp.nmr.NmrConstraint.JCouplingConstraintList',
                    'ccp.nmr.NmrConstraint.RdcConstraintList'):
        notifyFunc(self.updateConstraintListsAfter, clazz, func)
        
    for func in ('__init__', 'delete',):
      for clazz in ('ccp.nmr.NmrConstraint.CsaConstraint',
                    'ccp.nmr.NmrConstraint.DihedralConstraint',
                    'ccp.nmr.NmrConstraint.DistanceConstraint',
                    'ccp.nmr.NmrConstraint.HBondConstraint',
                    'ccp.nmr.NmrConstraint.JCouplingConstraint',
                    'ccp.nmr.NmrConstraint.RdcConstraint'):
        notifyFunc(self.updateConstraintsAfter, clazz, func)    
    
    for func in ('__init__', 'delete'):
      notifyFunc(self.updateShiftListsAfter,'ccp.nmr.Nmr.ShiftList', func)

    for func in ('__init__', 'delete'):
      notifyFunc(self.updateMolSystemsAfter,'ccp.molecule.MolSystem.MolSystem', func)

    for func in ('__init__', 'delete'):
      notifyFunc(self.updateChainsAfter,'ccp.molecule.MolSystem.Chain', func)

    for func in ('__init__', 'delete','setDynamicAlignment',
                 'setStaticAlignment','setName','setDetails'):
      notifyFunc(self.updateAlignMediaAfter,'ccp.nmr.NmrConstraint.ConditionState', func)

  def updateAlignMediaAfter(self, alignMedium):
  
     if alignMedium.nmrConstraintStore is self.constraintSet:
       self.after_idle(self.updateAlignMedia)
 
       if alignMedium is self.alignMedium:
         self.after_idle(self.updateTensors)

  def updateConstraintSetsAfter(self, constraintSet):
  
     self.after_idle(self.updateConstraintSets)

  def updateShiftListsAfter(self, shiftList):
  
     self.after_idle(self.updateShiftLists)

  def updateMolSystemsAfter(self, molSystem):
  
     self.after_idle(self.updateMolSystems)

  def updateChainsAfter(self, chain):
  
     self.after_idle(self.updateChains)
  
  def updateConstraintsAfter(self, constraint):
  
     if constraint.parent.parent is self.constraintSet:
       self.after_idle(self.updateConstraintLists)
  
  def updateConstraintListsAfter(self, constraintList):
  
     if constraintList.parent is self.constraintSet:
       self.after_idle(self.updateConstraintLists)
    
  def runMeccano(self):
    
    #
    #
    # Input checks first
    #
    #
  
    warning = ''
    if not self.molSystem:
      warning += 'No molecular system selected\n'
    
    if not self.chain:
      warning += 'No chain selected\n'
  
    if not self.constraintSet:
      warning += 'No selected constraint set\n'  
    else:
      constraintLists = [cl for cl in self.constraintSet.constraintLists if cl.useForMeccano]  
      if not constraintLists:
        warning += 'No constraint lists selected for use\n'   
 
    first, last = self.updateResidueRanges()
    if (last-first) < 2:
      warning += 'Too few peptide planes selected\n'         
  
    if warning:
      showWarning('Cannot run MECCANO','Encountered the following problems:\n' + warning)
      return
      
    if not self.run:
      self.run = self.makeSimRun()
      
    self.updateRunParams()
    
    if self.toggleCopyShifts.get() and self.shiftList:
      shiftList = self.run.findFirstOutputMeasurementList(className='ShiftList')
      
      if not shiftList:
        shiftList = self.project.currentNmrProject.newShiftList(name='Meccano Input')
        
      self.run.setOutputMeasurementLists([shiftList,])
    
      shiftDict = {}
      for shift in shiftList.shifts:
        shiftDict[shift.resonance] = shift
      
    
      for shift in self.shiftList.shifts:
        resonance = shift.resonance
        resonanceSet = resonance.resonanceSet
        
        if resonanceSet:
          atom = resonanceSet.findFirstAtomSet().findFirstAtom()
          
          if (atom.name == 'C') and (atom.residue.molResidue.molType == 'protein'):
            shift2 = shiftDict.get(resonance)
            if shift2:
              shift2.value = shift.value
              shift2.error = shift.error
              
            else:
              shiftList.newShift(resonance=resonance, value=shift.value, error=shift.error)  
    
    #
    #
    # Accumulate data from CCPN data model & GUI
    #
    #

    # Sequence

    residues = self.chain.sortedResidues()
    residueDict = {}
    
    seqData = []
    for residue in residues:
      molResidue = residue.molResidue
      
      code1Letter = molResidue.chemComp.code1Letter
      
      if not code1Letter:
        msg = 'Encountered non-standard residue type: %s'
        showWarning('Cannot run MECCANO', msg % residue.ccpCode)
        return
     
      seqCode = residue.seqCode
      seqData.append((seqCode, code1Letter))
      residueDict[seqCode] = residue.chemCompVar.chemComp.code3Letter

    # Media, RDCs & Dihedrals

    rdcLists = []
    dihedralLists = []

    for constraintList in constraintLists:
      if constraintList.className == 'RdcConsraintList':
        if constraintList.conditionState:
          rdcLists.append(constraintList)
      
      elif constraintList.className == 'DihedralConstraintList':
        dihedralLists.append(dihedralLists)
    
    f = PI_OVER_180  
    mediaData = []
    for constraintList in rdcLists:
      medium = constraintList.conditionState
      dynamicTensor = medium.dynamicAlignment
      staticTensor = medium.staticAlignment
    
      if not (dynamicTensor or staticTensor):
        continue
    
      if dynamicTensor:
        dynamicTensorData = ['Dynamic', dynamicTensor.aAxial, dynamicTensor.aRhombic,
                             f*dynamicTensor.alpha, f*dynamicTensor.beta, f*dynamicTensor.gamma]
   
      if staticTensor:
        staticTensorData = ['Static', staticTensor.aAxial, staticTensor.aRhombic,
                            f*staticTensor.alpha, f*staticTensor.beta, f*staticTensor.gamma]
      
      if not dynamicTensor:
        dynamicTensorData = staticTensorData
      
      elif not staticTensor:
        staticTensorData = dynamicTensorData
      
      rdcData = []
      for restraint in constraintList.constraints:
        items = list(restraint.items)
        
        if len(items) != 1:
          continue
          
        resonanceA, resonanceB = [fr.resonance for fr in items[0].resonances] 
        
        resonanceSetA = resonanceA.resonanceSet
        if not resonanceSetA:
          continue
        
        resonanceSetB = resonanceB.resonanceSet
        if not resonanceSetB:
          continue
        
        resNameA = getResonanceName(resonanceA)
        resNameB = getResonanceName(resonanceB)
          
        residueA = resonanceSetA.findFirstAtomSet().findFirstAtom().residue  
        residueB = resonanceSetB.findFirstAtomSet().findFirstAtom().residue  
        
        seqA = residueA.seqCode
        seqB = residueB.seqCode
        
        value = restraint.targetValue
        error = restraint.error
        
        if error is None:
          key = [resNameA,resNameB]
          key.sort()
          sigma = DEFAULT_ERRORS.get(tuple(key), 1.0)
        
        rdcData.append([seqA, resNameA, seqB, resNameB, value, error])
      
      mediaData.append((dynamicTensorData,staticTensorData,rdcData))
      
    oneTurn = 360.0
    dihedralDict = {}
    for constraintList in dihedralLists:
      for restraint in constraintList.constraints:
        items = list(restraint.items)
        
        if len(items) != 1:
          continue
        
        item = items[0]
        resonances = [fr.resonance for fr in item.resonances] 
        
        resonanceSets = [r.resonanceSet for r in resonances]
        
        if None in resonanceSets:
          continue
          
        atoms = [rs.findFirstAtomSet().findFirstAtom() for rs in resonanceSets]  
    
        atomNames = [a.name for a in atoms]
        
        if atomNames == PHI_ATOM_NAMES:
          isPhi = True
        elif atomNames == PSI_ATOM_NAMES:
          isPhi = False
        else:
          continue
    
        residue = atoms[2].residue
        
        if residue.chain is not self.chain:
          continue
        
        if isPhi:
          residuePrev = getLinkedResidue(residue, linkCode='prev')
          
          if not residuePrev:
            continue
            
          atomC0 = residuePrev.findFirstAtom(name='C')
          atomN  = residue.findFirstAtom(name='N')
          atomCa = residue.findFirstAtom(name='CA')
          atomC  = residue.findFirstAtom(name='C')
          atoms2 = [atomC0, atomN, atomCa, atomC]
          
        else:
          residueNext = getLinkedResidue(residue, linkCode='next')
          
          if not residueNext:
            continue
          
          atomN  = residue.findFirstAtom(name='N')
          atomCa = residue.findFirstAtom(name='CA')
          atomC  = residue.findFirstAtom(name='C')
          atomN2 = residueNext.findFirstAtom(name='N')
          atoms2 = [atomN, atomCa, atomC, atomN2]
          
        if atoms != atoms2:
          continue
        
        value = item.targetValue
        error = item.error
        
        if error is None:
          upper = item.upperLimit
          lower = item.lowerLimit
          
          if (upper is not None) and (lower is not None):
            dUpper = angleDifference(value, lower, oneTurn)
            dLower = angleDifference(upper, value, oneTurn)
            error  = max(dUpper, dLower)
            
          elif lower is not None:
            error = angleDifference(value, lower, oneTurn)
            
          elif upper is not None:
            error = angleDifference(upper, value, oneTurn)
            
          else:
            error = 30.0 # Arbitrary, but sensible for TALOS, DANGLE
        
        seqCode = residue.seqCode
        if not dihedralDict.has_key(seqCode):
          dihedralDict[seqCode] = [None, None, None, None] # Phi, Psi, PhiErr, PsiErr
        
        if isPhi:
          dihedralDict[seqCode][0] = value
          dihedralDict[seqCode][2] = error
        else:
          dihedralDict[seqCode][1] = value
          dihedralDict[seqCode][3] = error
          
          
    phipsiData = []
    seqCodes = dihedralDict.keys()
    seqCodes.sort()
    
    for seqCode in seqCodes:
      data = dihedralDict[seqCode]
      
      if None not in data:
        phi, psi, phiErr, psiErr = data
        phipsiData.append((seqCode, phi, psi, phiErr, psiErr))
        
    
    # User options
    
    firstPPlaneFrag = self.firstResEntry.get() or 1
    lastPPlaneFrag  = self.lastResEntry.get() or 1
    ppNbMin         = self.numOptPlaneEntry.get() or 1
    minValueBest    = self.numOptHitsEntry.get() or 2
    maxValueBest    = self.maxOptStepEntry.get() or 5

    strucData = Meccano.runFwd(firstPPlaneFrag, lastPPlaneFrag, ppNbMin,
                               minValueBest, maxValueBest, RAMACHANDRAN_DATABASE,
                               seqData, mediaData, phipsiData)
   
    if strucData:
      fileName = 'CcpnMeccanoPdb%f.pdb' % time.time()
      fileObj = open(fileName, 'w')
 
      ch = self.chain.pdbOneLetterCode.strip()
      if not ch:
        ch = self.chain.code[0].upper()
 
        i = 1
        for atomType, resNb, x, y, z in strucData:
          resType = residueDict.get(resNb, '???')
          line = PDB_FORMAT % ('ATOM',i,'%-3s' % atomType,'',resType,ch,resNb,'',x,y,z,1.0,1.0)
 
          i += 1

      fileObj.close()
      
      ensemble = getStructureFromFile(self.molSystem, fileName)
      
      
      if not self.toggleWritePdbFile.get():
        os.unlink(fileName)
         
      self.run.outputEnsemble = ensemble
      self.run = None
    
    self.updateRuns()

  def getMediumName(self, alignMedium):
  
    self.mediumNameEntry.set(alignMedium.name)
    
  def getMediumDetails(self, alignMedium):
  
    self.mediumDetailsEntry.set(alignMedium.details)
    
  def setMediumName(self, event): 

    value = self.mediumNameEntry.get()
    self.alignMedium.name = value or None
    
  def setMediumDetails(self, event): 

    value = self.mediumDetailsEntry.get()
    self.alignMedium.details = value or None
      
  def setAlignMedium(self, alignMedium):

    if self.constraintSet:
      self.constraintSet.conditionState = alignMedium
    
  def getAlignMedium(self, constraintList):

    media = self.getAlignmentMedia()
    names = [am.name for am in media]
    
    if constraintList.conditionState in media:
      index = media.index(constraintList.conditionState)
    else:
      index = 0
  
    self.alignMediumPulldown.setup(names, media, index)

  def toggleUseRestraints(self, constraintList):
 
    bool = constraintList.useForMeccano
    bool = not bool
 
    if bool and (not constraintList.conditionState) \
     and (constraintList.className == 'RdcConsraintList'):
      msg = 'Cannot use RDC restraint list for Meccano '
      msg += 'unless it is first associated with an amigment medium'
      showWarning('Warning', msg, parent=self)
    else:
      constraintList.useForMeccano = bool
      
    self.updateConstraintLists()
 
  def addStaticTensor(self):
  
    if self.alignMedium:
      tensor = Implementation.SymmTracelessMatrix(aAxial=0.0,aRhombic=0.0,
                                                  alpha=0.0,beta=0.0,
                                                  gamma=0.0)
      

      self.alignMedium.staticAlignment = tensor
 
      self.updateAlignMediaAfter(self.alignMedium)
 
  def addDynamicTensor(self):
  
    if self.alignMedium:
      tensor = Implementation.SymmTracelessMatrix(aAxial=0.0,aRhombic=0.0,
                                                  alpha=0.0,beta=0.0,
                                                  gamma=0.0)
      self.alignMedium.dynamicAlignment = tensor
      
      self.updateAlignMediaAfter(self.alignMedium)
  
  def removeTensor(self):
  
    if self.alignMedium and self.tensor:
      if self.tensor is self.alignMedium.dynamicAlignment:
        self.alignMedium.dynamicAlignment = None
        
      elif self.tensor is self.alignMedium.staticAlignment:
        self.alignMedium.staticAlignment = None
      
      self.updateAlignMediaAfter(self.alignMedium)
        
  def addAlignMedium(self):
  
    if self.constraintSet:
      medium = self.constraintSet.newConditionState()
      medium.name = 'Align Medium %d' % medium.serial   
  
  def removeAlignMedium(self):

    if self.alignMedium:
      self.alignMedium.delete()

  def updateTensor(self, aAxial=None, aRhombic=None, alpha=None, beta=None, gamma=None):
  
    aAxial   = aAxial   or self.tensor.aAxial
    aRhombic = aRhombic or self.tensor.aRhombic
    alpha    = alpha    or self.tensor.alpha
    beta     = beta     or self.tensor.beta
    gamma    = gamma    or self.tensor.gamma
    
    tensor = Implementation.SymmTracelessMatrix(aAxial=aAxial,
                                                aRhombic=aRhombic,
                                                alpha=alpha,beta=beta,
                                                gamma=gamma)
 
    if self.alignMedium:
      if self.tensor is self.alignMedium.dynamicAlignment:
        self.alignMedium.dynamicAlignment = tensor
        
      elif self.tensor is self.alignMedium.staticAlignment:
        self.alignMedium.staticAlignment = tensor
 
    self.tensor = tensor
 
  def setAxial(self, event): 
  
    value = self.editAxialEntry.get()
    self.updateTensor(aAxial=value)
    self.updateTensors()
    
  def setRhombic(self,  event): 
  
    value = self.editRhombicEntry.get()
    self.updateTensor(aRhombic=value)
    self.updateTensors()
   
  def setEulerAlpha(self,  event): 
  
    value = self.editAlphaEulerEntry.get()
    self.updateTensor(alpha=value)
    self.updateTensors()
    
  def setEulerBeta(self,  event): 
  
    value = self.editBetaEulerEntry.get()
    self.updateTensor(beta=value)
    self.updateTensors()
    
  def setEulerGamma(self,  event): 
  
    value = self.editGammaEulerEntry.get()
    self.updateTensor(gamma=value)
    self.updateTensors()

  def getAxial(self, tensor): 
  
    value = tensor.aAxial
    self.editAxialEntry.set(value)
     
  def getRhombic(self, tensor): 
  
    value = tensor.aRhombic
    self.editRhombicEntry.set(value)
     
  def getEulerAlpha(self, tensor): 
  
    value = tensor.alpha
    self.editAlphaEulerEntry.set(value)
     
  def getEulerBeta(self, tensor): 
  
    value = tensor.beta
    self.editBetaEulerEntry.set(value)
     
  def getEulerGamma(self, tensor): 
  
    value = tensor.gamma
    self.editGammaEulerEntry.set(value)
 
  def selectTensor(self, tensor, row, col):
  
    self.tensor = tensor
 
  def selectAlignMedium(self, alignMedium, row, col):
  
    self.alignMedium = alignMedium
    self.updateTensors()
 
  def getAlignmentMedia(self):
  
    if self.constraintSet:
      return self.constraintSet.sortedConditionStates()
    else:
      return []
 
  def updateAlignMedia(self):

    textMatrix = []
    objectList = []
    
    if self.constraintSet:
      objectList = self.getAlignmentMedia()
        
      for conditionState in objectList:
         
         staticTensor = None
         dyamicTensor = None
         tensor = conditionState.dynamicAlignment
         if tensor:
           vals = (tensor.aAxial, tensor.aRhombic, tensor.alpha, tensor.beta, tensor.gamma)
           dyamicTensor = u'\u03B6:%.3f \u03B7:%.3f \u03B1:%.3f \u03B2:%.3f \u03B3:%.3f ' % vals

         tensor = conditionState.staticAlignment
         if tensor:
           vals = (tensor.aAxial, tensor.aRhombic, tensor.alpha, tensor.beta, tensor.gamma)
           staticTensor = u'\u03B6:%.3f \u03B7:%.3f \u03B1:%.3f \u03B2:%.3f \u03B3:%.3f ' % vals
           
         datum = [conditionState.serial,
                  conditionState.name,
                  conditionState.details,
                  dyamicTensor,
                  staticTensor]
         textMatrix.append(datum)

         if dyamicTensor or staticTensor:
           if not self.alignMedium:
             self.alignMedium = conditionState
   
    self.mediaMatrix.update(textMatrix=textMatrix, objectList=objectList)
      
    if self.alignMedium:
      self.mediaMatrix.selectObject(self.alignMedium)
 
  def updateTensors(self):
    
    textMatrix = []
    objectList = []
    conditionState = self.alignMedium
    
    if conditionState:
    
      tensor = conditionState.dynamicAlignment
      if tensor:
        datum = ['Dynamic', tensor.aAxial, tensor.aRhombic,
                 tensor.alpha, tensor.beta, tensor.gamma]
        textMatrix.append(datum)
        objectList.append(tensor)
      
      tensor = conditionState.staticAlignment
      if tensor:
        datum = ['Static', tensor.aAxial, tensor.aRhombic,
                 tensor.alpha, tensor.beta, tensor.gamma]
        textMatrix.append(datum)
        objectList.append(tensor)

    self.tensorMatrix.update(textMatrix=textMatrix, objectList=objectList)  
 
  def getMolSystems(self):
  
    molSystems = []
    
    for molSystem in self.project.sortedMolSystems():
      if molSystem.chains:
        molSystems.append(molSystem)
        
    return molSystems    
     
     
  def updateMolSystems(self, *notifyObj):
  
    index = 0
    names = []
    
    molSystems = self.getMolSystems()
    molSystem = self.molSystem
    
    if molSystems:
      if molSystem not in molSystems:
        molSystem = molSystems[0]
      
      index = molSystems.index(molSystem)
      names = [ms.code for ms in molSystems] 
    
    else:
      self.molSystem = None
    
    if self.molSystem is not molSystem:
      if self.run:
        self.run.molSystem = molSystem
        
      self.molSystem = molSystem
      self.updateChains()
    
    self.molSystemPulldown.setup(texts=names, objects=molSystems, index=index)
    
  
  def selectMolSystem(self, molSystem):
  
    if self.molSystem is not molSystem:
      if self.run:
        self.run.molSystem = molSystem
        
      self.molSystem = molSystem
      self.updateChains()
     
     
  def updateChains(self, *notifyObj):
  
    index = 0
    names = []
    chains = []
    chain = self.chain
    
    if self.molSystem:
      chains = [c for c in self.molSystem.sortedChains() if c.residues]
    
    if chains: 
      if chain not in chains:
        chain = chains[0]
        
      index = chains.index(chain)
      names = [c.code for c in chains]
    
    if chain is not self.chain:
      self.chain = chain
      self.updateResidueRanges()
    
    self.chainPulldown.setup(texts=names, objects=chains, index=index)
     
  def selectChain(self, chain):
  
    if chain is not self.chain:
      self.chain = chain
      self.updateResidueRanges()

  def updateResidueRanges(self):
  
    first = self.firstResEntry.get()
    last = self.lastResEntry.get()
    
    if self.chain:
      residues = self.chain.sortedResidues()
      firstSeq = residues[0].seqCode
      lastSeq = residues[-2].seqCode
      
      if first < firstSeq:
        first = firstSeq
     
      if last == first:
        last = lastSeq
      
      elif last > lastSeq:
        last = lastSeq
        
      if first > last:
        last, first = first, last    
      
  
    self.firstResEntry.set(first)
    self.lastResEntry.set(last)
 
    return first, last

  def getConstraintSets(self):
  
    constraintSets = []
    nmrProject = self.project.currentNmrProject
    
    for constraintSet in nmrProject.sortedNmrConstraintStores():
      for constraintList in constraintSet.constraintLists:
        if constraintList.className not in ('ChemShiftConstraintList','somethingElse'):
          constraintSets.append(constraintSet)
          break
    
    return constraintSets
  
  def updateConstraintSets(self, *notifyObj):

    index = 0
    names = []
    constraintSets = self.getConstraintSets()
    constraintSet = self.constraintSet

    if constraintSets:
      if constraintSet not in constraintSets:
        constraintSet = constraintSets[0]
        
      index = constraintSets.index(constraintSet)
      names = ['%d' % cs.serial for cs in constraintSets]
    
    if constraintSet is not self.constraintSet:
      if self.run:
        self.run.inputConstraintStore = constraintSet
    
      self.constraintSet = constraintSet
      self.updateConstraintLists()    
    
    self.constraintSetPulldown.setup(texts=names, objects=constraintSets, index=index)

  def selectConstraintSet(self, constraintSet):
  
    if self.constraintSet is not constraintSet:
      if self.run:
        self.run.inputConstraintStore = constraintSet
        
      self.constraintSet = constraintSet
      self.updateConstraintLists() 
  
  def getConstraintLists(self):
  
    constraintLists = []
    if self.constraintSet:
      for constraintList in self.constraintSet.sortedConstraintLists():
        if constraintList.className not in ('ChemShiftConstraintList','somethingElse'):
          constraintLists.append(constraintList)
  
    return constraintLists
    
  def updateConstraintLists(self, *notifyObj):
  
    textMatrix = []
    objectList = self.getConstraintLists()
    
    for constraintList in objectList:
      if not hasattr(constraintList, 'useForMeccano'):
        if constraintList.conditionState \
         or (constraintList.className != 'RdcConstraintList'):
          bool = True
        else:
          bool = False  
      
        constraintList.useForMeccano = bool
    
      if constraintList.conditionState:
        alignMedium = constraintList.conditionState.name
      else:
        alignMedium = None
    
      datum = [constraintList.serial,
               constraintList.className[:-14],
               constraintList.useForMeccano and 'Yes' or 'No',
               alignMedium,
               len(constraintList.constraints)]
  
      textMatrix.append(datum)
  
    self.restraintMatrix.update(textMatrix=textMatrix, objectList=objectList)
  
  def selectConstraint(self, obj, row, column):
  
    if self.constraint is not obj:
      self.constraint = obj

  def getSimStore(self):
  
    simStore = self.project.findFirstNmrSimStore(name='meccano')
    if not simStore:
      simStore = self.project.newNmrSimStore(name='meccano')
    
    return simStore

  def getRuns(self):
  
    runs = [None, ]
    
    if self.molSystem and self.constraintSet:
      simStore = self.getSimStore()
      runs += simStore.sortedRuns()
    
    return runs
  
  def updateRuns(self, *notifyObj):
  
    index = 0
    names = ['<New>']
    runs = self.getRuns()
    run = self.run

    if runs:
      if run not in runs:
        run = runs[0]
    
      index = runs.index(run)
      names += [r.serial for r in runs if r]
    
    if run is not self.run:
      self.updateConstraintSets()
      self.updateMolSystems()
      self.updateShiftLists()
    
    self.runPulldown.setup(names, runs, index)
  
  def updateRunParams(self, event=None):
  
    if self.run and self.molSystem and self.constraintSet:
      simRun = self.run
      
      simRun.inputConstraintStore = self.constraintSet
      simRun.molSystem = self.molSystem
      
      if self.shiftList:
        simRun.setInputMeasurementLists([self.shiftList,])                 

      simRun.newRunParameter(code='FirstPepPlane',id=1, 
                             intValue=self.firstResEntry.get() or 0)
      simRun.newRunParameter(code='LastPepPlane' ,id=1, 
                             intValue=self.lastResEntry.get() or 0)
      simRun.newRunParameter(code='MaxOptSteps',  id=1, 
                             intValue=self.maxOptStepEntry.get() or 0)
      simRun.newRunParameter(code='NumOptPlanes', id=1, 
                             intValue=self.numOptPlaneEntry.get() or 0)
      simRun.newRunParameter(code='MinOptHits',   id=1, 
                             intValue=self.numOptHitsEntry.get() or 0)
  
  def makeSimRun(self, template=None):

    simStore = self.getSimStore()
   
    if template:
      molSystem = template.molSystem
      constraintSet = template.inputConstraintStore
      shiftList = template.findFirstInputMeasurementList(className='ShiftList')
      protocol = template.annealProtocol
    else:
      molSystem = self.molSystem
      constraintSet = self.constraintSet
      shiftList = self.shiftList
      protocol = self.annealProtocol
    
    simRun = simStore.newRun(annealProtocol=protocol,
                             molSystem=molSystem,
                             inputConstraintStore=protocol)
    
    if shiftList:
      simRun.addInputMeasurementList(shiftList)                 
    
    if template:
      for param in template.runParameters:
        simRun.newRunParameter(code=param.code,
                               id=param.id,
                               booleanValue=param.booleanValue,
                               floatValue=param.floatValue,
                               intValue=param.intValue,
                               textValue=param.textValue)
    else:
       if self.chain:
         chainCode = self.chain.code
       else:
         chaincode = 'A'
    
       simRun.newRunParameter(code='FirstPepPlane',id=1, 
                              intValue=self.firstResEntry.get() or 0)
       simRun.newRunParameter(code='LastPepPlane' ,id=1, 
                              intValue=self.lastResEntry.get() or 0)
       simRun.newRunParameter(code='MaxOptSteps',  id=1, 
                              intValue=self.maxOptStepEntry.get() or 0)
       simRun.newRunParameter(code='NumOptPlanes', id=1, 
                              intValue=self.numOptPlaneEntry.get() or 0)
       simRun.newRunParameter(code='MinOptHits',   id=1, 
                              intValue=self.numOptHitsEntry.get() or 0)
       simRun.newRunParameter(code='ChainCode',    id=1,
                              textValue=chainCode)

    return simRun
 
  def selectRun(self, simRun):
  
    if self.run is not simRun:
      if simRun:
        if simRun.outputEnsemble:
          msg  = 'Selected run has already been used to generate a structure.'
          msg += 'A new run will be setup based on the selection.'
          showWarning('Warning',msg)
          simRun = self.makeSimRun(template=simRun)
 
        molSystem = simRun.molSystem
        constraintSet = simRun.inputConstraintStore
        shiftList = simRun.findFirstInputMeasurementList(className='ShiftList')
 
        if molSystem and (self.molSystem is not molSystem):
          self.molSystem = molSystem
          self.updateMolSystems()
 
        if constraintSet and (self.constraintSet is not constraintSet):
          self.constraintSet = constraintSet
          self.updateConstraintSets()
    
        if shiftList and (self.shiftList is not shiftList): 
          self.shiftList = shiftList
          self.updateShiftLists()
        
        firstPepPlane = simRun.findFirstrunParameter(code='FirstPepPlane')
        lastPepPlane = simRun.findFirstrunParameter(code='LastPepPlane')
        maxOptSteps = simRun.findFirstrunParameter(code='MaxOptSteps')
        numOptPlanes = simRun.findFirstrunParameter(code='NumOptPlanes')
        minOptHits = simRun.findFirstrunParameter(code='MinOptHits')
        chainCode = simRun.findFirstrunParameter(code='ChainCode')

        
        if firstPepPlane is not None:
          self.firstResEntry.set(firstPepPlane.intValue or 0)
        
        if lastPepPlane is not None:
          self.lastResEntry.set(lastPepPlane.intValue or 0)
          
        if maxOptSteps is not None:
          self.maxOptStepEntry.set(maxOptSteps.intValue or 0)
            
        if numOptPlanes is not None:
          self.numOptPlaneEntry.set(numOptPlanes.intValue or 0)
          
        if minOptHits is not None:
          self.numOptHitsEntry.set(minOptHits.intValue or 0)
           
        if chainCode is not None:
          chainCode = chainCode.textValue or 'A'
          if self.molSystem:
            chain = self.molSystem.findFirsChain(code=chainCode)
 
            if chain:
              self.selectChain(chain) 
                 
      self.run = simRun

  def updateShiftLists(self, *notifyObj):
    
    index = 0
    names = []
    nmrProject = self.project.currentNmrProject
    
    shiftLists = nmrProject.findAllMeasurementLists(className='ShiftList')
    shiftLists = [(sl.serial, sl) for sl in shiftLists]
    shiftLists.sort()
    shiftLists = [x[1] for x in shiftLists]
    
    shiftList = self.shiftList

    if shiftLists:
      if shiftList not in shiftLists:
        shiftList = shiftLists[0]
    
      index = shiftLists.index(shiftList)
      names = ['%d'% sl.serial for sl in shiftLists]
    
    if shiftList is not self.shiftList:
      if self.run:
        self.run.setInputMeasurementLists([shiftList])
  
    self.shiftListPulldown.setup(texts=names, objects=shiftLists, index=index)

  def selectShiftList(self, shiftList):
  
    if shiftList is not self.shiftList:
      if self.run:
        self.run.setInputMeasurementLists([shiftList])
      
      self.shiftList = shiftList                   
示例#33
0
class CloudsPopup(BasePopup):
    def __init__(self, parent, *args, **kw):

        self.guiParent = parent
        self.project = parent.getProject()
        self.waiting = 0
        self.specFreq = 800.13
        self.maxIter = 50
        self.mixTime = 60
        self.corrTime = 11.5
        self.leakRate = 2.0
        self.peakListDict = {}
        self.noesyPeakList = None
        self.tocsyPeakList = None
        self.noesy3dPeakList = None
        self.hsqcPeakList = None
        self.maxIntens = 37000000

        self.resonances = None
        self.origResonances = None
        self.noesyPeaks = None
        self.distanceConstraintList = None
        self.antiDistConstraintList = None
        self.numClouds = 100
        self.filePrefix = 'cloud_'
        self.cloudsFiles = []
        self.adcAtomTypes = 'HN'
        self.structure = None

        # step num, initial temp, final temp, cooling steps, MD steps, MD tau, rep scale
        self.coolingScheme = []
        self.coolingScheme.append([1, 1, 1, 3, 500, 0.001, 0])
        self.coolingScheme.append([2, 80000, 4000, 19, 1000, 0.001, 0])
        self.coolingScheme.append([3, 4000, 1, 5, 500, 0.001, 0])
        self.coolingScheme.append([4, 15000, 1, 3, 1000, 0.001, 0])
        self.coolingScheme.append([5, 1, 1, 5, 500, 0.001, 0])
        self.coolingScheme.append([6, 8000, 1, 3, 1000, 0.001, 0])
        self.coolingScheme.append([7, 1, 1, 5, 500, 0.001, 0])
        self.coolingScheme.append([8, 3000, 25, 60, 2500, 0.001, 1])
        self.coolingScheme.append([9, 25, 25, 1, 7500, 0.001, 1])
        self.coolingScheme.append([10, 10, 10, 1, 7500, 0.001, 1])
        self.coolingScheme.append([11, 0.01, 0.01, 1, 7500, 0.0005, 1])

        self.coolingStep = None

        BasePopup.__init__(self,
                           parent,
                           title="Resonance Clouds Analysis",
                           **kw)

    def body(self, guiFrame):

        self.specFreqEntry = IntEntry(self,
                                      text=self.specFreq,
                                      width=8,
                                      returnCallback=self.setSpecFreq)
        self.maxIterEntry = IntEntry(self,
                                     text=self.maxIter,
                                     width=8,
                                     returnCallback=self.setMaxIter)
        self.mixTimeEntry = FloatEntry(self,
                                       text=self.mixTime,
                                       width=8,
                                       returnCallback=self.setMixTime)
        self.corrTimeEntry = FloatEntry(self,
                                        text=self.corrTime,
                                        width=8,
                                        returnCallback=self.setCorrTime)
        self.leakRateEntry = FloatEntry(self,
                                        text=self.leakRate,
                                        width=8,
                                        returnCallback=self.setLeakRate)
        self.maxIntensEntry = IntEntry(self,
                                       text=self.maxIntens,
                                       width=8,
                                       returnCallback=self.setMaxIntens)

        self.mdInitTempEntry = FloatEntry(self,
                                          text='',
                                          returnCallback=self.setMdInitTemp)
        self.mdFinTempEntry = FloatEntry(self,
                                         text='',
                                         returnCallback=self.setMdFinTemp)
        self.mdCoolStepsEntry = IntEntry(self,
                                         text='',
                                         returnCallback=self.setMdCoolSteps)
        self.mdSimStepsEntry = IntEntry(self,
                                        text='',
                                        returnCallback=self.setMdSimSteps)
        self.mdTauEntry = FloatEntry(self,
                                     text='',
                                     returnCallback=self.setMdTau)
        self.mdRepScaleEntry = FloatEntry(self,
                                          text='',
                                          returnCallback=self.setMdRepScale)

        guiFrame.grid_columnconfigure(0, weight=1)

        row = 0
        frame0 = LabelFrame(guiFrame, text='Setup peak lists')
        frame0.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame0.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame0.grid_columnconfigure(1, weight=1)

        f0row = 0
        label00 = Label(frame0, text='1H-1H NOESY spectrum')
        label00.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.noesyPulldown = PulldownMenu(frame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.noesyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label01 = Label(frame0, text='15N HSQC spectrum')
        label01.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.hsqcPulldown = PulldownMenu(frame0,
                                         entries=self.getHsqcs(),
                                         callback=self.setHsqc,
                                         selected_index=0,
                                         do_initial_callback=0)
        self.hsqcPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label02 = Label(frame0, text='15N HSQC TOCSY spectrum')
        label02.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.tocsyPulldown = PulldownMenu(frame0,
                                          entries=self.getTocsys(),
                                          callback=self.setTocsy,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.tocsyPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        label02 = Label(frame0, text='15N HSQC NOESY spectrum')
        label02.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.noesy3dPulldown = PulldownMenu(frame0,
                                            entries=self.getNoesy3ds(),
                                            callback=self.setNoesy3d,
                                            selected_index=0,
                                            do_initial_callback=0)
        self.noesy3dPulldown.grid(row=f0row, column=1, sticky=Tkinter.NW)

        f0row += 1
        texts = ['Setup resonances & peaks', 'Show Peaks', 'Show resonances']
        commands = [self.setupResonances, self.showPeaks, self.showResonances]
        self.setupButtons = ButtonList(frame0,
                                       expands=1,
                                       texts=texts,
                                       commands=commands)
        self.setupButtons.grid(row=f0row,
                               column=0,
                               columnspan=2,
                               sticky=Tkinter.NSEW)

        f0row += 1
        self.label03a = Label(frame0, text='Resonances found: 0')
        self.label03a.grid(row=f0row, column=0, sticky=Tkinter.NW)
        self.label03b = Label(frame0, text='NOESY peaks found: 0')
        self.label03b.grid(row=f0row, column=1, sticky=Tkinter.NW)

        row += 1
        frame1 = LabelFrame(guiFrame, text='Calculate distance constraints')
        frame1.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame1.grid_columnconfigure(3, weight=1)

        f1row = 0
        frame1.grid_rowconfigure(f1row, weight=1)
        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate, self.maxIntens
        ]
        colHeadings = [
            'Spectrometer\nfrequency', 'Max\niterations', 'Mixing\ntime (ms)',
            'Correl.\ntime (ns)', 'Leak\nrate', 'Max\nintensity'
        ]
        editWidgets = [
            self.specFreqEntry,
            self.maxIterEntry,
            self.mixTimeEntry,
            self.corrTimeEntry,
            self.leakRateEntry,
            self.maxIntensEntry,
        ]
        editGetCallbacks = [
            self.getSpecFreq,
            self.getMaxIter,
            self.getMixTime,
            self.getCorrTime,
            self.getLeakRate,
            self.getMaxIntens,
        ]
        editSetCallbacks = [
            self.setSpecFreq,
            self.setMaxIter,
            self.setMixTime,
            self.setCorrTime,
            self.setLeakRate,
            self.setMaxIntens,
        ]
        self.midgeParamsMatrix = ScrolledMatrix(
            frame1,
            editSetCallbacks=editSetCallbacks,
            editGetCallbacks=editGetCallbacks,
            editWidgets=editWidgets,
            maxRows=1,
            initialCols=5,
            headingList=colHeadings,
            callback=None,
            objectList=[
                'None',
            ],
            textMatrix=[
                data,
            ])
        self.midgeParamsMatrix.grid(row=f1row,
                                    column=0,
                                    columnspan=4,
                                    sticky=Tkinter.NSEW)

        f1row += 1
        label10 = Label(frame1, text='Benchmark structure')
        label10.grid(row=f1row, column=0, sticky=Tkinter.NW)
        self.structurePulldown = PulldownMenu(frame1,
                                              entries=self.getStructures(),
                                              callback=self.setStructure,
                                              selected_index=0,
                                              do_initial_callback=0)
        self.structurePulldown.grid(row=f1row, column=1, sticky=Tkinter.NW)

        label11 = Label(frame1, text='ADC atom types:')
        label11.grid(row=f1row, column=2, sticky=Tkinter.NW)
        self.adcAtomsPulldown = PulldownMenu(frame1,
                                             entries=self.getAdcAtomTypes(),
                                             callback=self.setAdcAtomTypes,
                                             selected_index=0,
                                             do_initial_callback=0)
        self.adcAtomsPulldown.grid(row=f1row, column=3, sticky=Tkinter.NW)

        f1row += 1
        texts = [
            'Calculate distances', 'Show distance\nconstraints',
            'Show anti-distance\nconstraints'
        ]
        commands = [
            self.calculateDistances, self.showConstraints,
            self.showAntiConstraints
        ]
        self.midgeButtons = ButtonList(frame1,
                                       expands=1,
                                       texts=texts,
                                       commands=commands)
        self.midgeButtons.grid(row=f1row,
                               column=0,
                               columnspan=4,
                               sticky=Tkinter.NSEW)

        f1row += 1
        self.distConstrLabel = Label(frame1, text='Distance constraints:')
        self.distConstrLabel.grid(row=f1row,
                                  column=0,
                                  columnspan=2,
                                  sticky=Tkinter.NW)
        self.antiConstrLabel = Label(frame1, text='Anti-distance constraints:')
        self.antiConstrLabel.grid(row=f1row,
                                  column=2,
                                  columnspan=2,
                                  sticky=Tkinter.NW)

        row += 1
        guiFrame.grid_rowconfigure(row, weight=1)
        frame2 = LabelFrame(guiFrame, text='Proton cloud molecular dynamics')
        frame2.grid(row=row, column=0, sticky=Tkinter.NSEW)
        frame2.grid_columnconfigure(1, weight=1)

        f2row = 0
        frame2.grid_rowconfigure(f2row, weight=1)
        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate
        ]
        colHeadings = [
            'Step', 'Initial temp.', 'Final temp.', 'Cooling steps',
            'MD steps', 'MD tau', 'Rep. scale'
        ]
        editWidgets = [
            None, self.mdInitTempEntry, self.mdFinTempEntry,
            self.mdCoolStepsEntry, self.mdSimStepsEntry, self.mdTauEntry,
            self.mdRepScaleEntry
        ]
        editGetCallbacks = [
            None, self.getMdInitTemp, self.getMdFinTemp, self.getMdCoolSteps,
            self.getMdSimSteps, self.getMdTau, self.getMdRepScale
        ]
        editSetCallbacks = [
            None, self.setMdInitTemp, self.setMdFinTemp, self.setMdCoolSteps,
            self.setMdSimSteps, self.setMdTau, self.setMdRepScale
        ]
        self.coolingSchemeMatrix = ScrolledMatrix(
            frame2,
            editSetCallbacks=editSetCallbacks,
            editGetCallbacks=editGetCallbacks,
            editWidgets=editWidgets,
            maxRows=9,
            initialRows=12,
            headingList=colHeadings,
            callback=self.selectCoolingStep,
            objectList=self.coolingScheme,
            textMatrix=self.coolingScheme)
        self.coolingSchemeMatrix.grid(row=f2row,
                                      column=0,
                                      columnspan=4,
                                      sticky=Tkinter.NSEW)

        f2row += 1
        texts = ['Move earlier', 'Move later', 'Add step', 'Remove step']
        commands = [
            self.moveStepEarlier, self.moveStepLater, self.addCoolingStep,
            self.removeCoolingStep
        ]
        self.coolingSchemeButtons = ButtonList(frame2,
                                               expands=1,
                                               commands=commands,
                                               texts=texts)
        self.coolingSchemeButtons.grid(row=f2row,
                                       column=0,
                                       columnspan=4,
                                       sticky=Tkinter.EW)

        f2row += 1
        label20 = Label(frame2, text='Number of clouds:')
        label20.grid(row=f2row, column=0, sticky=Tkinter.NW)
        self.numCloudsEntry = FloatEntry(frame2,
                                         text=100,
                                         returnCallback=self.setNumClouds,
                                         width=10)
        self.numCloudsEntry.grid(row=f2row, column=1, sticky=Tkinter.NW)
        label21 = Label(frame2, text='Cloud file prefix:')
        label21.grid(row=f2row, column=2, sticky=Tkinter.NW)
        self.filePrefixEntry = Entry(frame2,
                                     text='cloud_',
                                     returnCallback=self.setFilePrefix,
                                     width=10)
        self.filePrefixEntry.grid(row=f2row, column=3, sticky=Tkinter.NW)

        f2row += 1
        texts = ['Start molecular dynamics', 'Show dynamics progress']
        commands = [self.startMd, self.showMdProgress]
        self.mdButtons = ButtonList(frame2,
                                    expands=1,
                                    commands=commands,
                                    texts=texts)
        self.mdButtons.grid(row=f2row,
                            column=0,
                            columnspan=4,
                            sticky=Tkinter.NSEW)

        row += 1
        self.bottomButtons = createDismissHelpButtonList(guiFrame,
                                                         expands=0,
                                                         help_url=None)
        self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW)

        self.setButtonStates()

    def getStructures(self):

        names = [
            '<None>',
        ]
        for molSystem in self.project.sortedMolSystems():
            for structure in molSystem.sortedStructureEnsembles():
                names.append('%s:%d' % (molSystem.name, structure.ensembleId))

        return names

    def setStructure(self, index, name=None):

        if index < 1:
            self.structure = None
        else:
            structures = []
            for molSystem in self.project.molSystems:
                for structure in molSystem.structureEnsembles:
                    structures.append(structure)

            self.structure = structures[index - 1]

    def getAdcAtomTypes(self):

        return ['HN', 'HN HA', 'HN HA HB']

    def setAdcAtomTypes(self, index, name=None):

        if name is None:
            name = self.adcAtomsPulldown.getSelected()

        self.adcAtomTypes = name

    def startMd(self):

        self.setNumClouds()
        self.setFilePrefix()
        if (self.distanceConstraintList and self.antiDistConstraintList
                and (self.numClouds > 0) and self.filePrefix):

            resDict = {}
            for resonance in self.guiParent.project.currentNmrProject.resonances:
                resDict[resonance.serial] = resonance

            resonances = []
            for constraint in self.distanceConstraintList.constraints:
                for item in constraint.items:
                    for fixedResonance in item.resonances:
                        if resDict.get(
                                fixedResonance.resonanceSerial) is not None:
                            resonances.append(
                                resDict[fixedResonance.resonanceSerial])
                            resDict[fixedResonance.resonanceSerial] = None

            startMdProcess(self.numClouds, self.distanceConstraintList,
                           resonances, self.coolingScheme, self.filePrefix)

            #structGen = self.distanceConstraintList.structureGeneration

            serials = []
            for resonance in resonances:
                serials.append(resonance.serial)
            clouds = []
            for i in range(self.numClouds):
                clouds.append('%s%3.3d.pdb' % (self.filePrefix, i))
            self.guiParent.application.setValues(
                self.distanceConstraintList.nmrConstraintStore,
                'clouds',
                values=clouds)
            self.guiParent.application.setValues(
                self.distanceConstraintList.nmrConstraintStore,
                'cloudsResonances',
                values=serials)

            # do better than this check for creation

    def showMdProgress(self):

        n = 0
        m = self.numClouds
        for i in range(m):
            pdbFileName = '%s%3.3d.pdb' % (self.filePrefix, i)
            if os.path.exists(pdbFileName):
                n += 1

        p = n * 100 / float(m)
        text = 'Done %d of %d clouds (%1.2f)%%' % (n, m, p)
        showInfo('MD Progress', text)

    def setFilePrefix(self, text=None):

        if not text:
            text = self.filePrefixEntry.get()

        if text:
            self.filePrefix = text

    def setNumClouds(self, n=None, *event):

        if not n:
            n = self.numCloudsEntry.get()

        if n:
            self.numClouds = int(n)

    def calculateDistances(self):

        # setup normalisation factor intensityMax

        # self.maxIter
        # what if failure ?

        resDict = {}
        for resonance in self.project.currentNmrProject.resonances:
            resDict[resonance.serial] = resonance

        self.resonances = self.origResonances
        intensityFactors = [1.0 for x in range(len(self.resonances))]

        # optimiseRelaxation will remove unconstrained resonances
        self.distanceConstraintList = optimiseRelaxation(
            self.resonances,
            self.noesyPeaks,
            intensityMax=self.maxIntens,
            intensityFactors=intensityFactors,
            tmix=self.mixTime,
            sf=self.specFreq,
            tcor=self.corrTime,
            rleak=self.leakRate)

        constrainSpinSystems(self.distanceConstraintList)
        # for testing calculate distances from structure overrides any resonances: uses assigned ones
        #(self.distanceConstraintList, self.resonances) = self.cheatForTesting()
        #self.antiDistConstraintList = self.distanceConstraintList
        protonNumbs = {'CH3': 3, 'Haro': 2, 'HN': 1, 'H': 1}

        PI = 3.1415926535897931
        GH = 2.6752e4
        HB = 1.05459e-27
        CONST = GH * GH * GH * GH * HB * HB
        tc = 1.0e-9 * self.corrTime
        wh = 2.0 * PI * self.specFreq * 1.0e6
        j0 = CONST * tc
        j1 = CONST * tc / (1.0 + wh * wh * tc * tc)
        j2 = CONST * tc / (1.0 + 4.0 * wh * wh * tc * tc)
        #jself = 6.0*j2 + 3.0*j1 + j0
        jcross = 6.0 * j2 - j0

        if self.distanceConstraintList:
            constraintStore = self.distanceConstraintList.nmrConstraintStore

            dict = {
                'HN': ['H'],
                'HN HA': ['H', 'HA', 'HA1', 'HA2'],
                'HN HA HB': ['H', 'HA', 'HA1', 'HA2', 'HB', 'HB2', 'HB3']
            }

            self.antiDistConstraintList = makeNoeAdcs(
                self.resonances,
                self.noesyPeakList.dataSource,
                constraintStore,
                allowedAtomTypes=dict[self.adcAtomTypes])

            if self.structure:

                N = len(self.resonances)
                sigmas = [[] for i in range(N)]
                for i in range(N):
                    sigmas[i] = [0.0 for j in range(N)]

                for constraint in self.distanceConstraintList.constraints:
                    resonances = list(constraint, findFirstItem().resonances)

                    ri = resDict[resonances[0].resonanceSerial]
                    rj = resDict[resonances[1].resonanceSerial]
                    i = self.resonances.index(ri)
                    j = self.resonances.index(rj)
                    atomSets1 = list(ri.resonanceSet.atomSets)
                    atomSets2 = list(rj.resonanceSet.atomSets)
                    if atomSets1 == atomSets2:
                        ass = list(atomSets1)
                        atomSets1 = [
                            ass[0],
                        ]
                        atomSets2 = [
                            ass[-1],
                        ]

                    distance = getAtomSetsDistance(atomSets1, atomSets2,
                                                   self.structure)
                    r = distance * 1e-8
                    nhs = protonNumbs[rj.name]
                    sigma = 0.1 * jcross * nhs / (r**6)
                    sigmas[i][j] = sigma

                    constraint.setDetails('Known Dist: %4.3f' % (distance))
                    #for constraint in self.antiDistConstraintList.constraints:
                    #  atomSets1 = list(resonances[0].resonanceSet.atomSets)
                    #  atomSets2 = list(resonances[1].resonanceSet.atomSets)
                    #  distance = getAtomSetsDistance(atomSets1, atomSets2, self.structure)
                    #  constraint.setDetails('Known Dist: %4.3f' % (distance))

                fp = open('sigmas.out', 'w')
                for i in range(N - 1):
                    for j in range(i + 1, N):
                        if sigmas[i][j] != 0.0:
                            fp.write('%3.1d  %3.1d   %9.2e\n' %
                                     (i, j, sigmas[i][j]))
                    #fp.write('\n')
                fp.close()

        self.setButtonStates()

    def cheatForTesting(self, atomSelection='H'):
        """ Makes a perfect cloud from a structure. """

        project = self.project
        structure = self.guiParent.argumentServer.getStructure()

        constraintStore = makeNmrConstraintStore(project)
        distConstraintList = NmrConstraint.DistanceConstraintList(
            constraintStore)

        chain = structure.findFirstCoodChain()
        structureGeneration.hydrogenResonances = []

        molSystem = structure.molSystem
        atomSets = []
        resonances = []
        i = 0
        for resonance in project.currentNmrProject.resonances:

            if resonance.isotopeCode == '1H':

                if resonance.resonanceSet:

                    atomSet = resonance.resonanceSet.findFirstAtomSet()
                    atom = atomSet.findFirstAtom()
                    seqId = atom.residue.seqId
                    if (seqId < 9) or (seqId > 78):
                        continue

                    if atom.residue.chain.molSystem is molSystem:

                        if atomSelection == 'methyl':
                            if len(atomSet.atoms) == 3:
                                if atom.residue.ccpCode not in ('Ala', 'Val',
                                                                'Ile', 'Leu',
                                                                'Thr', 'Met'):
                                    continue
                            elif atom.name != 'H':
                                continue

                        elif atomSelection == 'amide':
                            if atom.name != 'H':
                                continue

                        if atom.name == 'H':
                            resonance.name = 'HN'
                        else:
                            resonance.name = 'H'

                        resonances.append(resonance)
                        atomSets.append(list(resonance.resonanceSet.atomSets))
                        i += 1

        print "Found %d atomSets" % (len(atomSets))
        weight = 1
        adcWeight = 1
        constrDict = {}
        N = len(atomSets)
        for i in range(N - 1):
            atomSets0 = atomSets[i]
            residue0 = atomSets0[0].findFirstAtom().residue.seqId
            print "R", residue0

            for j in range(i + 1, N):
                if j == i:
                    continue
                atomSets1 = atomSets[j]

                dist = getAtomSetsDistance(atomSets0, atomSets1, structure)
                if not dist:
                    continue

                if dist < 5.5:
                    fixedResonance0 = getFixedResonance(
                        constraintStore, resonances[i])
                    fixedResonance1 = getFixedResonance(
                        constraintStore, resonances[j])
                    constrDict[i] = 1
                    constrDict[j] = 1
                    constraint = NmrConstraint.DistanceConstraint(
                        distConstraintList,
                        weight=weight,
                        targetValue=dist,
                        upperLimit=dist + (dist / 10),
                        lowerLimit=dist - (dist / 10),
                        error=dist / 5)
                    item = NmrConstraint.DistanceConstraintItem(
                        constraint,
                        resonances=[fixedResonance0, fixedResonance1])

                elif (atomSets1[0].findFirstAtom().name
                      == 'H') and (atomSets0[0].findFirstAtom().name
                                   == 'H') and (dist > 7):
                    #else:
                    fixedResonance0 = getFixedResonance(
                        constraintStore, resonances[i])
                    fixedResonance1 = getFixedResonance(
                        constraintStore, resonances[j])
                    constrDict[i] = 1
                    constrDict[j] = 1
                    constraint = NmrConstraint.DistanceConstraint(
                        distConstraintList,
                        weight=adcWeight,
                        targetValue=75,
                        upperLimit=175,
                        lowerLimit=5.0,
                        error=94.5)
                    item = NmrConstraint.DistanceConstraintItem(
                        constraint,
                        resonances=[fixedResonance0, fixedResonance1])

        return (distConstraintList, resonances)

    def showConstraints(self):

        if self.distanceConstraintList:
            self.guiParent.browseConstraints(
                constraintList=self.distanceConstraintList)

    def showAntiConstraints(self):

        if self.antiDistConstraintList:
            self.guiParent.browseConstraints(
                constraintList=self.antiDistConstraintList)

    def showPeaks(self):

        self.guiParent.viewPeaks(peaks=self.noesyPeaks)

    def showResonances(self):

        pass
        #self.guiParent.viewResonances(resonances=self.resonances)

    def setupResonances(self):

        if self.noesyPeakList and self.noesy3dPeakList and self.tocsyPeakList and self.hsqcPeakList:

            disambiguateNoesyPeaks(self.noesyPeakList, self.noesy3dPeakList,
                                   self.tocsyPeakList, self.hsqcPeakList)

            (self.origResonances, self.noesyPeaks,
             null) = getCloudsResonanceList(self.guiParent.argumentServer,
                                            hsqcPeakList=self.hsqcPeakList,
                                            tocsy3dPeakList=self.tocsyPeakList,
                                            noesy2dPeakList=self.noesyPeakList)
            self.setButtonStates()

    def setButtonStates(self):

        if self.origResonances:
            self.label03a.set('Resonances found: %d' %
                              (len(self.origResonances)))

        if self.noesyPeaks:
            self.label03b.set('NOESY peaks found: %d' % (len(self.noesyPeaks)))

        if self.noesyPeakList and self.tocsyPeakList and self.hsqcPeakList:
            self.setupButtons.buttons[0].enable()
        else:
            self.setupButtons.buttons[0].disable()

        if self.noesyPeaks:
            self.setupButtons.buttons[1].enable()
        else:
            self.setupButtons.buttons[1].disable()

        if self.origResonances:
            self.setupButtons.buttons[2].enable()
        else:
            self.setupButtons.buttons[2].disable()

        if self.noesyPeaks and self.origResonances:
            self.midgeButtons.buttons[0].enable()
        else:
            self.midgeButtons.buttons[0].disable()

        if self.distanceConstraintList:
            self.midgeButtons.buttons[1].enable()
            self.distConstrLabel.set(
                'Distance constraints: %d' %
                len(self.distanceConstraintList.constraints))
        else:
            self.distConstrLabel.set('Distance constraints:')
            self.midgeButtons.buttons[1].disable()

        if self.antiDistConstraintList:
            self.antiConstrLabel.set(
                'Anti-distance constraints: %d' %
                len(self.antiDistConstraintList.constraints))
            self.midgeButtons.buttons[2].enable()
        else:
            self.antiConstrLabel.set('Anti-distance constraints:')
            self.midgeButtons.buttons[2].disable()

        if (self.distanceConstraintList and self.antiDistConstraintList
                and (self.numClouds > 0) and self.filePrefix):
            self.mdButtons.buttons[0].enable()
            self.mdButtons.buttons[1].enable()
        else:
            self.mdButtons.buttons[0].disable()
            self.mdButtons.buttons[1].disable()

    def getNoesys(self):

        names = []
        spectra = getSpectraByType(self.project, '2dNOESY')
        for spectrum in spectra:
            for peakList in spectrum.peakLists:
                name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                     peakList.serial)
                names.append(name)
                self.peakListDict[name] = peakList
                if not self.noesyPeakList:
                    self.noesyPeakList = peakList

        return names

    def setNoesy(self, index, name=None):

        if not name:
            name = self.noesyPulldown.getSelected()

        self.noesyPeakList = self.peakListDict[name]
        self.setButtonStates()

    def getTocsys(self):

        names = []
        spectra = getSpectraByType(self.project, '3dTOCSY')
        for spectrum in spectra:
            for peakList in spectrum.peakLists:
                name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                     peakList.serial)
                names.append(name)
                self.peakListDict[name] = peakList
                if not self.tocsyPeakList:
                    self.tocsyPeakList = peakList

        return names

    def getNoesy3ds(self):

        names = []
        spectra = getSpectraByType(self.project, '3dNOESY')
        for spectrum in spectra:
            for peakList in spectrum.peakLists:
                name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                     peakList.serial)
                names.append(name)
                self.peakListDict[name] = peakList
                if not self.noesy3dPeakList:
                    self.noesy3dPeakList = peakList

        return names

    def setTocsy(self, index, name=None):

        if not name:
            name = self.tocsyPulldown.getSelected()

        self.tocsyPeakList = self.peakListDict[name]
        self.setButtonStates()

    def setNoesy3d(self, index, name=None):

        if not name:
            name = self.noesy3dPulldown.getSelected()

        self.noesy3dPeakList = self.peakListDict[name]
        self.setButtonStates()

    def getHsqcs(self):

        names = []
        spectra = getSpectraByType(self.project, 'HSQC')
        for spectrum in spectra:
            for peakList in spectrum.peakLists:
                name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                     peakList.serial)
                names.append(name)
                self.peakListDict[name] = peakList
                if not self.hsqcPeakList:
                    self.hsqcPeakList = peakList

        return names

    def setHsqc(self, index, name=None):

        if not name:
            name = self.hsqcPulldown.getSelected()

        self.hsqcPeakList = self.peakListDict[name]
        self.setButtonStates()

    def getMdInitTemp(self, coolingStep):

        self.mdInitTempEntry.set(coolingStep[1])

    def getMdFinTemp(self, coolingStep):

        self.mdFinTempEntry.set(coolingStep[2])

    def getMdCoolSteps(self, coolingStep):

        self.mdCoolStepsEntry.set(coolingStep[3])

    def getMdSimSteps(self, coolingStep):

        self.mdSimStepsEntry.set(coolingStep[4])

    def getMdTau(self, coolingStep):

        self.mdTauEntry.set(coolingStep[5])

    def getMdRepScale(self, coolingStep):

        self.mdRepScaleEntry.set(coolingStep[6])

    def setMdInitTemp(self, event):

        value = self.mdInitTempEntry.get()
        if value is not None:
            self.coolingStep[1] = value

        self.updateCoolingScheme()

    def setMdFinTemp(self, event):

        value = self.mdFinTempEntry.get()
        if value is not None:
            self.coolingStep[2] = value

        self.updateCoolingScheme()

    def setMdCoolSteps(self, event):

        value = self.mdCoolStepsEntry.get()
        if value is not None:
            self.coolingStep[3] = value

        self.updateCoolingScheme()

    def setMdSimSteps(self, event):

        value = self.mdSimStepsEntry.get()
        if value is not None:
            self.coolingStep[4] = value

        self.updateCoolingScheme()

    def setMdTau(self, event):

        value = self.mdTauEntry.get()
        if value is not None:
            self.coolingStep[5] = value

        self.updateCoolingScheme()

    def setMdRepScale(self, event):

        value = self.mdRepScaleEntry.get()
        if value is not None:
            self.coolingStep[6] = value

        self.updateCoolingScheme()

    def selectCoolingStep(self, object, row, col):

        self.coolingStep = object

    def moveStepEarlier(self):

        if self.coolingStep:
            i = self.coolingStep[0] - 1
            if i > 0:
                coolingStep = self.coolingScheme[i - 1]
                coolingStep[0] = i + 1
                self.coolingStep[0] = i
                self.coolingScheme[i - 1] = self.coolingStep
                self.coolingScheme[i] = coolingStep

                self.updateCoolingScheme()
                self.coolingSchemeMatrix.hilightObject(self.coolingStep)

    def moveStepLater(self):

        if self.coolingStep:
            i = self.coolingStep[0] - 1
            if i < len(self.coolingScheme) - 1:
                coolingStep = self.coolingScheme[i + 1]
                coolingStep[0] = i + 1
                self.coolingStep[0] = i + 2
                self.coolingScheme[i + 1] = self.coolingStep
                self.coolingScheme[i] = coolingStep

                self.updateCoolingScheme()
                self.coolingSchemeMatrix.hilightObject(self.coolingStep)

    def addCoolingStep(self):

        i = len(self.coolingScheme) + 1
        datum = [i, 3000, 100, 10, 2500, 0.001, 1]

        self.coolingScheme.append(datum)
        self.updateCoolingScheme()

    def removeCoolingStep(self):

        if self.coolingStep:
            coolingScheme = []
            i = 0
            for coolingStep in self.coolingScheme:
                if coolingStep is not self.coolingStep:
                    i += 1
                    coolingStep[0] = i
                    coolingScheme.append(coolingStep)

            self.coolingScheme = coolingScheme
            self.updateCoolingScheme()

    def updateCoolingScheme(self):

        objectList = self.coolingScheme
        textMatrix = self.coolingScheme
        self.coolingSchemeMatrix.update(objectList=objectList,
                                        textMatrix=textMatrix)

    def updateMidgeParams(self):

        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate, self.maxIntens
        ]

        self.midgeParamsMatrix.update(textMatrix=[
            data,
        ])

    def getSpecFreq(self, obj):

        self.specFreqEntry.set(self.specFreq)

    def getMaxIter(self, obj):

        self.maxIterEntry.set(self.maxIter)

    def getMixTime(self, obj):

        self.mixTimeEntry.set(self.mixTime)

    def getCorrTime(self, obj):

        self.corrTimeEntry.set(self.corrTime)

    def getLeakRate(self, obj):

        self.leakRateEntry.set(self.leakRate)

    def getMaxIntens(self, obj):

        self.maxIntensEntry.set(self.maxIntens)

    def setSpecFreq(self, event):

        value = self.specFreqEntry.get()
        if value is not None:
            self.specFreq = value

        self.updateMidgeParams()

    def setMaxIter(self, event):

        value = self.maxIterEntry.get()
        if value is not None:
            self.maxIter = value

        self.updateMidgeParams()

    def setMixTime(self, event):

        value = self.mixTimeEntry.get()
        if value is not None:
            self.mixTime = value

        self.updateMidgeParams()

    def setCorrTime(self, event):

        value = self.corrTimeEntry.get()
        if value is not None:
            self.corrTime = value

        self.updateMidgeParams()

    def setLeakRate(self, event):

        value = self.leakRateEntry.get()
        if value is not None:
            self.leakRate = value

        self.updateMidgeParams()

    def setMaxIntens(self, event):

        value = self.maxIntensEntry.get()
        if value is not None:
            self.maxIntens = value

        self.updateMidgeParams()

    def destroy(self):

        BasePopup.destroy(self)
示例#34
0
  def body(self, guiFrame):
  
    guiFrame.grid_columnconfigure(0, weight=1)
    guiFrame.grid_rowconfigure(0, weight=1)

    options = ['Parameters','Restraints','Alignment Media & Tensors','About Meccano']
    tabbedFrame = TabbedFrame(guiFrame, options=options)
    tabbedFrame.grid(row=0, column=0, sticky='nsew')
    
    frameA, frameB, frameC, frameD = tabbedFrame.frames
    frameA.grid_columnconfigure(1, weight=1)
    frameA.grid_rowconfigure(13, weight=1)
    frameB.grid_columnconfigure(1, weight=1)
    frameB.grid_rowconfigure(1, weight=1)
    frameC.grid_columnconfigure(0, weight=1)
    frameC.grid_rowconfigure(1, weight=1)
    frameD.grid_columnconfigure(0, weight=1)
    frameD.grid_rowconfigure(0, weight=1)
    
    texts = ['Run MECCANO!']
    commands = [self.runMeccano]
    bottomButtons = createDismissHelpButtonList(guiFrame, texts=texts,
                                                commands=commands, expands=True)
    bottomButtons.grid(row=1, column=0, sticky='ew')

    if not Meccano:
      bottomButtons.buttons[0].disable()
  
    # Parameters
        
    row = 0
    label = Label(frameA, text='Calculation Run:')
    label.grid(row=row,column=0,sticky='w')
    self.runPulldown = PulldownList(frameA, callback=self.selectRun)
    self.runPulldown.grid(row=row,column=1,sticky='w')
    
    row += 1    
    label = Label(frameA, text='Shift List (for CO):')
    label.grid(row=row,column=0,sticky='w')
    self.shiftListPulldown = PulldownList(frameA, callback=self.selectShiftList)
    self.shiftListPulldown.grid(row=row,column=1,sticky='w')
           
    row += 1    
    label = Label(frameA, text='Keep Copy of Used Shifts:')
    label.grid(row=row,column=0,sticky='w')
    self.toggleCopyShifts = CheckButton(frameA)
    self.toggleCopyShifts.grid(row=row,column=1,sticky='w')
    self.toggleCopyShifts.set(True)
        
    row += 1    
    label = Label(frameA, text='Molecular System:')
    label.grid(row=row,column=0,sticky='w')
    self.molSystemPulldown = PulldownList(frameA, callback=self.selectMolSystem)
    self.molSystemPulldown.grid(row=row,column=1,sticky='w')
        
    row += 1    
    label = Label(frameA, text='Chain:')
    label.grid(row=row,column=0,sticky='w')
    self.chainPulldown = PulldownList(frameA, callback=self.selectChain)
    self.chainPulldown.grid(row=row,column=1,sticky='w')
    self.chainPulldown.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='First Peptide Plane:')
    label.grid(row=row,column=0,sticky='w')
    self.firstResEntry = IntEntry(frameA, text=None, width=8)
    self.firstResEntry.grid(row=row,column=1,sticky='w')
    self.firstResEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Last Peptide Plane:')
    label.grid(row=row,column=0,sticky='w')
    self.lastResEntry = IntEntry(frameA, text=None, width=8)
    self.lastResEntry.grid(row=row,column=1,sticky='w')
    self.lastResEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Max Num Optimisation Steps:')
    label.grid(row=row,column=0,sticky='w')
    self.maxOptStepEntry = IntEntry(frameA, text=500, width=8)
    self.maxOptStepEntry.grid(row=row,column=1,sticky='w')
    self.maxOptStepEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Num Optimisation Peptide Planes:')
    label.grid(row=row,column=0,sticky='w')
    self.numOptPlaneEntry = IntEntry(frameA, text=2, width=8)
    self.numOptPlaneEntry.grid(row=row,column=1,sticky='w')
    self.numOptPlaneEntry.bind('<Leave>', self.updateRunParams) 
        
    row += 1    
    label = Label(frameA, text='Min Num Optimisation Hits:')
    label.grid(row=row,column=0,sticky='w')
    self.numOptHitsEntry = IntEntry(frameA, text=5, width=8)
    self.numOptHitsEntry.grid(row=row,column=1,sticky='w')
    self.numOptHitsEntry.bind('<Leave>', self.updateRunParams) 

    row += 1    
    label = Label(frameA, text='File Name Prefix:')
    label.grid(row=row,column=0,sticky='w')
    self.pdbFileEntry = Entry(frameA, text='Meccano', width=8)
    self.pdbFileEntry.grid(row=row,column=1,sticky='w')
    self.pdbFileEntry.bind('<Leave>', self.updateRunParams) 
           
    row += 1    
    label = Label(frameA, text='Write Output File (.out):')
    label.grid(row=row,column=0,sticky='w')
    self.toggleWriteOutFile = CheckButton(frameA)
    self.toggleWriteOutFile.grid(row=row,column=1,sticky='w')
    self.toggleWriteOutFile.set(False)
    self.toggleWriteOutFile.bind('<Leave>', self.updateRunParams) 
           
    row += 1    
    label = Label(frameA, text='Write PDB File (.pdb):')
    label.grid(row=row,column=0,sticky='w')
    self.toggleWritePdbFile = CheckButton(frameA)
    self.toggleWritePdbFile.grid(row=row,column=1,sticky='w')
    self.toggleWritePdbFile.set(True)
    self.toggleWritePdbFile.bind('<Leave>', self.updateRunParams) 
    
    if not Meccano:
      row += 1    
      label = Label(frameA, text='The Meccano executable is not available (it needs to be compiled)', fg='red')
      label.grid(row=row,column=0,columnspan=2,sticky='w')

    # Restraints
    
    label = Label(frameB, text='Constraint Set:')
    label.grid(row=0,column=0,sticky='w')
    
    self.constraintSetPulldown = PulldownList(frameB, callback=self.selectConstraintSet)
    self.constraintSetPulldown.grid(row=0,column=1,sticky='w')
    
    self.alignMediumPulldown= PulldownList(self, callback=self.setAlignMedium)
    
    headingList = ['#','List Type','Use?','Alignment\nMedium','Num\nRestraints']
    editWidgets      = [None,None,None,self.alignMediumPulldown,None]
    editGetCallbacks = [None,None,self.toggleUseRestraints,self.getAlignMedium,None]
    editSetCallbacks = [None,None,None,self.setAlignMedium,None]
    self.restraintMatrix = ScrolledMatrix(frameB,
                                          headingList=headingList,
                                          editSetCallbacks=editSetCallbacks,
                                          editGetCallbacks=editGetCallbacks, 
                                          editWidgets=editWidgets,
                                          callback=None,
                                          multiSelect=True)
    self.restraintMatrix.grid(row=1,column=0,columnspan=2,sticky='nsew')
    
    
    # Alignment Media
    
    div = LabelDivider(frameC,text='Alignment Media')
    div.grid(row=0,column=0,sticky='ew')
    
    self.mediumNameEntry = Entry(self, returnCallback=self.setMediumName)
    self.mediumDetailsEntry = Entry(self, returnCallback=self.setMediumDetails)
    
    headingList = ['#','Name','Details','Static Tensor','Dynamic Tensor']
    editWidgets      = [None, self.mediumNameEntry, self.mediumDetailsEntry, None, None]
    editGetCallbacks = [None, self.getMediumName, self.getMediumDetails, None, None]
    editSetCallbacks = [None, self.setMediumName, self.setMediumDetails, None, None]
    self.mediaMatrix = ScrolledMatrix(frameC,
                                      headingList=headingList,
                                      editSetCallbacks=editSetCallbacks,
                                      editGetCallbacks=editGetCallbacks, 
                                      editWidgets=editWidgets,
                                      callback=self.selectAlignMedium,
                                      multiSelect=True)
                                 
    self.mediaMatrix.grid(row=1,column=0,sticky='nsew')
     
    
    texts = ['Add Alignment medium','Remove Alignment Medium']
    commands = [self.addAlignMedium,self.removeAlignMedium]
    buttonList = ButtonList(frameC, texts=texts, commands=commands, expands=True)
    buttonList.grid(row=2,column=0,sticky='nsew')
    
    self.editAxialEntry = FloatEntry(self, returnCallback=self.setAxial)
    self.editRhombicEntry = FloatEntry(self, returnCallback=self.setRhombic)
    self.editAlphaEulerEntry = FloatEntry(self, returnCallback=self.setEulerAlpha)
    self.editBetaEulerEntry = FloatEntry(self, returnCallback=self.setEulerBeta)
    self.editGammaEulerEntry = FloatEntry(self, returnCallback=self.setEulerGamma)
    
    
    div = LabelDivider(frameC,text='Alignment Tensors')
    div.grid(row=3,column=0,sticky='ew')
    
    headingList = ['Type', u'Axial (\u03B6)',u'Rhombic (\u03B7)',
                   u'Euler \u03B1',u'Euler \u03B2',u'Euler \u03B3']
    editWidgets      = [None,self.editAxialEntry,
                        self.editRhombicEntry,self.editAlphaEulerEntry,
                        self.editBetaEulerEntry,self.editGammaEulerEntry]
    editSetCallbacks = [None,self.setAxial,self.setRhombic,
                        self.setEulerAlpha,self.setEulerBeta,self.setEulerGamma]
    editGetCallbacks = [None,self.getAxial,self.getRhombic,
                        self.getEulerAlpha,self.getEulerBeta,self.getEulerGamma]
                   
    self.tensorMatrix = ScrolledMatrix(frameC, maxRows=2,
                                       headingList=headingList,
                                       editSetCallbacks=editSetCallbacks,
                                       editGetCallbacks=editGetCallbacks, 
                                       editWidgets=editWidgets,
                                       callback=self.selectTensor,
                                       multiSelect=True)
                                          
    self.tensorMatrix.grid(row=4,column=0,sticky='nsew')
    
    texts = ['Add Static Tensor','Add Dynamic Tensor','Remove Tensor']
    commands = [self.addStaticTensor,self.addDynamicTensor,self.removeTensor]
    buttonList = ButtonList(frameC,texts=texts, commands=commands, expands=True)
    buttonList.grid(row=5,column=0,sticky='ew')
       
    # About
    
    label = Label(frameD, text='About Meccano...')
    label.grid(row=0,column=0,sticky='w')
  
    #
  
    self.geometry('500x400')

    self.updateShiftLists()
    self.updateMolSystems()
    self.updateResidueRanges()
    self.updateConstraintSets()
    self.updateAlignMedia()
    self.updateRuns()
示例#35
0
class EditExperimentSeriesPopup(BasePopup):
  """
  **Setup Experiment Series for Chemical Shift and Intensity Changes**
  
  The purpose of this popup is to setup ordered groups of experiments that are
  related by the variation in some condition or parameter, but otherwise the
  kind of experiment being run is the same. For example the user could setup
  experiments for a temperature series, ligand binding titration or relaxation
  rate measurement.

  The layout is divided into two tables. The upper table shows all of the series
  that are known to the current project and the lower table shows all of the
  experiments or planes that comprise the selected series. These series relate
  to both groups of separate experiments (and hence spectra) and also single
  experiment where one dimension is not for NMR frequency but rather a "sampled"
  dimension and thus effectively combines many experiments (e.g. for different
  T1 values) as different planes. A stack of effectively 2D experiments combined
  in this manner is typically referred to as pseudo-3D. - The experiment is 3D
  but there are only two NMR dimensions.

  Series which are stacks of planes in a single experiment entity are
  automatically detected and entered into the table once they are loaded. Series
  that are constructed from multiple, separate experiments however must be setup
  by the user. To setup a new series of this kind [Add Series] makes a new,
  empty NMR series. Next the user should change the "Parameter varied" column to
  specify what type of thing is varied between the different experiments. The
  user then adds experiments into this series with the [Add Series Point]
  function at the bottom. Once the points have been added to the series the name
  of the experiment for each point may be changed. Initially, arbitrary
  experiments appear for the series points, so these almost always have to be
  adjusted.

  Once a stacked-plane experiment or series of experiments is setup, the user
  next sets (or checks) the value of the parameter associated with each point in
  the lower table. When loading stacked-plane experiments these values may come
  though automatically, if they are present in the spectrum header or parameter
  file. Given a completed NMR series specification the user may then extract the
  relevant data from the series using one of the analysis tools like `Follow
  Intensity Changes`_ or `Follow Shift Changes`_.

  **Caveats & Tips**

  Make sure the "Parameter Varied" for a given NMR series is appropriate to the
  type of analysis being performed. Many tools that extract T1 or Kd
  measurements for example look for specific types of series.

  The "Set/Unset Ref Plane" function is only used in certain kinds of series
  such as those that use trains of CPMG pulses. 

  .. _`Follow Intensity Changes`: CalcRatesPopup.html
  .. _`Follow Shift Changes`: FollowShiftChangesPopup.html

  """

  def __init__(self, parent, *args, **kw):

    self.guiParent   = parent
    self.expSeries   = None
    self.conditionPoint   = None
    self.waiting     = 0
  
    BasePopup.__init__(self, parent, title="Experiment : NMR Series", **kw)

  def body(self, guiFrame):

    self.geometry("500x500")

    self.nameEntry  = Entry(self, text='', returnCallback=self.setName,    width=12)
    self.detailsEntry = Entry(self, text='', returnCallback=self.setDetails, width=16)
    self.valueEntry = FloatEntry(self, text='', returnCallback=self.setValue, width=10)
    self.errorEntry = FloatEntry(self, text='', returnCallback=self.setError, width=8)
    
    self.conditionNamesPulldown = PulldownList(self, callback=self.setConditionName,
                                               texts=self.getConditionNames())
    self.unitPulldown = PulldownList(self, callback=self.setUnit,
                                     texts=self.getUnits())
    self.experimentPulldown = PulldownList(self, callback=self.setExperiment)

    guiFrame.grid_columnconfigure(0, weight=1)

    row = 0
    frame = Frame(guiFrame, grid=(row, 0))
    frame.expandGrid(None,0)
    div = LabelDivider(frame, text='Current Series', grid=(0, 0))
    utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0,1))

    row += 1
    frame0 = Frame(guiFrame, grid=(row, 0))
    frame0.expandGrid(0,0)
    tipTexts = ['The serial number of the experiment series, but left blank if the series as actually a pseudo-nD experiment (with a sampled non-frequency axis)',
                'The name of the experiment series, which may be a single pseudo-nD experiment',
                'The number of separate experiments (and hence spectra) present in the series',
                'The kind of quantity that varies for different experiments/planes within the NMR series, e.g. delay time, temperature, ligand concentration etc.',
                'The number of separate points, each with a separate experiment/plane and parameter value, in the series']
    headingList      = ['#','Name','Experiments','Parameter\nVaried','Num\nPoints']
    editWidgets      = [None, self.nameEntry, None, self.conditionNamesPulldown, None]
    editGetCallbacks = [None, self.getName,   None, self.getConditionName, None]
    editSetCallbacks = [None, self.setName,   None, self.setConditionName, None]
    self.seriesMatrix = ScrolledMatrix(frame0, tipTexts=tipTexts,
                                       editSetCallbacks=editSetCallbacks,
                                       editGetCallbacks=editGetCallbacks,
                                       editWidgets=editWidgets,
                                       headingList=headingList,
                                       callback=self.selectExpSeries,
                                       deleteFunc=self.deleteExpSeries,
                                       grid=(0,0), gridSpan=(None, 3))

    tipTexts = ['Make a new, blank NMR series specification in the CCPN project',
                'Delete the selected NMR series from the project, although any component experiments remain. Note you cannot delete pseudo-nD series; delete the actual experiment instead',
                'Colour the spectrum contours for each experiment in the selected series (not pseudo-nD) using a specified scheme']
    texts    = ['Add Series','Delete Series',
                'Auto Colour Spectra']
    commands = [self.addExpSeries,self.deleteExpSeries,
                self.autoColorSpectra]
                
    self.seriesButtons = ButtonList(frame0, texts=texts, commands=commands,
                                    grid=(1,0), tipTexts=tipTexts)

    label = Label(frame0, text='Scheme:', grid=(1,1))
    
    tipText = 'Selects which colour scheme to apply to the contours of (separate) experiments within an NMR series'
    self.colorSchemePulldown = PulldownList(frame0, grid=(1,2), tipText=tipText)

    row += 1
    div = LabelDivider(guiFrame, text='Experimental Parameters & Conditions', grid=(row, 0))

    row += 1
    guiFrame.grid_rowconfigure(row, weight=1)
    frame1 = Frame(guiFrame, grid=(row, 0))
    frame1.expandGrid(0,0)
    tipTexts = ['The kind of experimental parameter that is being used to define the NMR series',
                'The experiment that corresponds to the specified parameter value; can be edited from an arbitrary initial experiment',
                'The numeric value of the parameter (condition) that relates to the experiment or point in the NMR series',
                'The estimated error in value of the condition',
                'The measurement unit in which the value of the condition is represented']
    headingList      = ['Parameter','Experiment','Value','Error','Unit']
    editWidgets      = [None,self.experimentPulldown,self.valueEntry,self.errorEntry, self.unitPulldown]
    editGetCallbacks = [None,self.getExperiment,     self.getValue,  self.getError,   self.getUnit]
    editSetCallbacks = [None,self.setExperiment,     self.setValue,  self.setError,   self.setUnit]
    self.conditionPointsMatrix = ScrolledMatrix(frame1, grid=(0,0), tipTexts=tipTexts,
                                                editSetCallbacks=editSetCallbacks,
                                                editGetCallbacks=editGetCallbacks,
                                                editWidgets=editWidgets,
                                                headingList=headingList,
                                                callback=self.selectConditionPoint,
                                                deleteFunc=self.deleteConditionPoint)
    
    self.conditionPointsMatrix.doEditMarkExtraRules = self.conditionTableShow 
    tipTexts = ['Add a new point to the NMR series with an associated parameter value and experiment',
                'Remove the selected point from the series, including any associated parameter value',
                'For appropriate kinds of NMR series, set or unset a point as representing the plane to use as a reference']
    texts    = ['Add Series Point','Delete Series Point','Set/Unset Ref Plane']
    commands = [self.addConditionPoint,self.deleteConditionPoint,self.setSampledReferencePlane]
    self.conditionPointsButtons = ButtonList(frame1, texts=texts, commands=commands,
                                             tipTexts=tipTexts, grid=(1,0))
    
    self.updateAfter()
    self.updateColorSchemes()

    self.administerNotifiers(self.registerNotify)
    
  def administerNotifiers(self, notifyFunc):

    #for func in ('__init__', 'delete','setName'):
    for func in ('__init__', 'delete','setName','setConditionNames',
                 'addConditionName','removeConditionName'):
      notifyFunc(self.updateAfter,'ccp.nmr.Nmr.NmrExpSeries', func)

    for func in ('__init__', 'delete','setName'):
      notifyFunc(self.updateExperiments,'ccp.nmr.Nmr.Experiment', func)

    for func in ('__init__', 'delete'):
      notifyFunc(self.updateDataDim,'ccp.nmr.Nmr.SampledDataDim', func)

    for func in ('__init__', 'delete','setCondition','setUnit','setValue','setError'):
      notifyFunc(self.updateConditionsAfter,'ccp.nmr.Nmr.SampleCondition', func)

    for func in ('__init__', 'delete','setCondition'):
      notifyFunc(self.updateAfter,'ccp.nmr.Nmr.SampleCondition', func)
      
    for func in ('setConditionVaried', 'setPointErrors', 
                 'addPointError', 'removePointError', 
                 'setPointValues','addPointValue', 
                 'removePointValue','setUnit'): 
      notifyFunc(self.updateAfter,'ccp.nmr.Nmr.SampledDataDim', func)    

    for func in ('__init__', 'delete'):
      notifyFunc(self.updateColorSchemes,'ccpnmr.AnalysisProfile.ColorScheme', func)  

  def open(self):
  
    self.updateAfter()
    BasePopup.open(self)
  
  def updateColorSchemes(self, scheme=None):
    
    index = 0
    prevScheme = self.colorSchemePulldown.getObject()
    
    schemes = getHueSortedColorSchemes(self.analysisProfile)
    schemes = [s for s in schemes if len(s.colors) > 1]
    colors = [list(s.colors) for s in schemes]
    
    if schemes:
      names = [s.name for s in schemes]
      
      if prevScheme in schemes:
        index = schemes.index(prevScheme)
    
    else:
      names  = []
  
    self.colorSchemePulldown.setup(names, schemes, index, colors)
  
  def autoColorSpectra(self):
  
    if self.expSeries and (self.expSeries.className != 'Experiment'):
      scheme = self.colorSchemePulldown.getObject()
      
      if scheme:
        colors = scheme.colors
      else:
        colors = ['#FF0000','#00FF00','#0000FF']  
      
      cdict = getNmrExpSeriesSampleConditions(self.expSeries)
      conditionName = list(self.expSeries.conditionNames)[0]
      expList = []
       
      for sampleCondition in cdict.get(conditionName, []):
        expList.append( (sampleCondition.value, sampleCondition.parent.experiments) )
 
      expList.sort()
      m = len(expList)-1.0
      c = len(colors)-1
       
      for i, (value, experiments) in enumerate(expList):
        p = c*i/m
        j = int(p)
        
        r1, g1, b1 = Color.hexToRgb(colors[j])
        r2, g2, b2 = Color.hexToRgb(colors[min(c,j+1)])
        
        f2 = p-j
        f1 = 1.0-f2
      
        r = (r1*f1)+(r2*f2)
        g = (g1*f1)+(g2*f2)
        b = (b1*f1)+(b2*f2)

        hexColor = Color.hexRepr(r,g,b)
       
        for experiment in experiments:
          for spectrum in experiment.dataSources:
            if spectrum.dataType == 'processed':
              analysisSpec = getAnalysisSpectrum(spectrum)
              
              if analysisSpec.posColors:
                analysisSpec.posColors = [hexColor,]
              elif analysisSpec.negColors:
                analysisSpec.negColors = [hexColor,]
  
  def getUnusedExperiments(self):
  
    sampleExperiments = getSampledDimExperiments(self.nmrProject)
    
    experiments = []
    for experiment in self.nmrProject.sortedExperiments():
      if experiment in sampleExperiments:
        continue
    
      if self.expSeries and (self.expSeries.className != 'Experiment'):
        if experiment in self.expSeries.experiments:
          continue
            
      experiments.append(experiment)
    
    return experiments
  
  def conditionTableShow(self, object, row, col):
  
    if type(object) is type(()):
      dataDim, index = object
      refPlane = dataDim.analysisDataDim.refSamplePlane
      if refPlane == index:
        return False
      if col == 1:
        return False
      
    return True
  
  def setSampledReferencePlane(self):
  
    if self.expSeries and (self.expSeries.className == 'Experiment'):
      if self.conditionPoint:
        dataDim, point = self.conditionPoint
        analysisDataDim = dataDim.analysisDataDim
        refPoint = analysisDataDim.refSamplePlane
        
        if refPoint == point:
          analysisDataDim.refSamplePlane = None
        else:
          analysisDataDim.refSamplePlane = point
    
        self.updateAfter()
    
  def checkAddSampleCondition(self, experiment):

    conditionSet = getExperimentConditionSet(experiment)
    conditionName = self.expSeries.conditionNames[0]
    condDict = getNmrExpSeriesSampleConditions(self.expSeries)

    sampleConditions = condDict.get(conditionName, [])
    units = [sc.unit for sc in sampleConditions if sc.unit]

    if units:
      sortList = list(set(units))
      sortList.sort(key = lambda u:units.count(u))
      unit = sortList[-1]
    else:
      unit = CONDITION_UNITS_DICT[conditionName][0]

    condition = conditionSet.findFirstSampleCondition(condition=conditionName)
    if not condition:
      condition = conditionSet.newSampleCondition(condition=conditionName,
                                                  unit=unit, value=0.0, error=0.0)
                                                  
  def addConditionPoint(self):
  
    if self.expSeries and (self.expSeries.className != 'Experiment'):
      
      experiments = self.getUnusedExperiments()
      if not experiments:
        showWarning('Warning','No experiments available', parent=self)
        return
      
      experiment = experiments[0]
      
      if experiment not in self.expSeries.experiments:
        self.expSeries.addExperiment(experiment)
      
      self.checkAddSampleCondition(experiment)
      self.updateAfter()

  def deleteConditionPoint(self, *event):
  
    if self.conditionPoint and (self.expSeries.className != 'Experiment'):
      if showOkCancel('Confirm','Really delete series point?', parent=self):
        conditionSet = self.conditionPoint.sampleConditionSet 
        
        experiments = [e for e in conditionSet.experiments if e in self.expSeries.experiments]
        
        for experiment in experiments:
          self.expSeries.removeExperiment(experiment)

        for experiment in experiments:
          for expSeries in experiment.nmrExpSeries:
             if self.conditionPoint.condition in self.expSeries.conditionNames:
               break
          else:
            continue
          break
          
        else:    
          self.conditionPoint.delete()
          
        self.conditionPoint = None
           

  def selectConditionPoint(self, object, row, col):
  
    if object:
      self.conditionPoint = object
      self.updateButtons()

  def selectExpSeries(self, object, row, col):

    if object:
      self.expSeries = object
      self.checkExperimentConditionsConsistent()
      self.updateConditions()

  def checkExperimentConditionsConsistent(self):

    if self.expSeries.className != 'Experiment':
      for experiment in self.expSeries.experiments:
        self.checkAddSampleCondition(experiment)

  def getUnits(self):
  
    units = []
    if self.expSeries:
      if self.expSeries.className == 'Experiment':
        conditionName = getExperimentSampledDim(self.expSeries).conditionVaried
     
      else:
        conditionName = self.expSeries.conditionNames[0]
        
      units = CONDITION_UNITS_DICT.get(conditionName)
      if not units:
        units = ['?',]
    
    return units


  def getUnit(self, sampleCondition):

    index = -1
    units = self.getUnits()
    if units:
      if sampleCondition:
        if type(sampleCondition) is type(()):
          dataDim, index = sampleCondition
          unit = dataDim.unit
        else:
          unit = sampleCondition.unit
      
      if unit not in units:
        unit = units[0]
      
      index = units.index(unit)
    
    self.unitPulldown.setup(units,units,index)
  
  def setUnit(self, obj):
  
    name = self.unitPulldown.getObject()
      
    if self.conditionPoint:
      if type(self.conditionPoint) is type(()):
        dataDim, index = self.conditionPoint
        dataDim.setUnit(name)
      
      else:
        self.conditionPoint.setUnit(name)

  def getConditionNames(self):
    
    if self.expSeries and (self.expSeries.className == 'Experiment'):
      names = ['delay time','mixing time','num delays','pulsing frequency','gradient strength']
    else:
      names = CONDITION_UNITS_DICT.keys()
      names.sort()
      
    return names

  def setConditionName(self, obj):
  
    name = self.conditionNamesPulldown.getObject()
  
    if self.expSeries:
      if self.expSeries.className == 'Experiment':
        dataDim = getExperimentSampledDim(self.expSeries)
        dataDim.conditionVaried = name
        
      else:
        self.expSeries.setConditionNames([name,])

  def getConditionName(self, expSeries):
  
    index = 0
    names = self.getConditionNames()
    
    if names:
    
      if expSeries:
        if expSeries.className == 'Experiment':
          name  = getExperimentSampledDim(expSeries).conditionVaried
        else:
          name  = expSeries.conditionNames[0]
        
        if name:  
          index = names.index(name)
      
      else:
        index = 0
    
    self.conditionNamesPulldown.setup(names,names,index)

  def getName(self, expSeries):
    
    if expSeries :
      self.nameEntry.set(expSeries.name)
 
  def setName(self, event):

    text = self.nameEntry.get()
    if text and text != ' ':
      self.expSeries.setName( text )

  def getValue(self, conditionPoint):
    
    if conditionPoint:
      if type(self.conditionPoint) is type(()):
        dataDim, index = conditionPoint
        value = dataDim.pointValues[index]
        
      else:
        value = conditionPoint.value
        
      self.valueEntry.set(value)
 
  def setValue(self, event):

    value = self.valueEntry.get()
    if value is not None:
      if type(self.conditionPoint) is type(()):
        dataDim, index = self.conditionPoint
        values = list(dataDim.pointValues)
        values[index] = value
        dataDim.setPointValues(values)
        
      else:
        self.conditionPoint.setValue( value )

  def getError(self, conditionPoint):
    
    if conditionPoint:
      if type(self.conditionPoint) is type(()):
        dataDim, index = conditionPoint
        
        if index < len(dataDim.pointErrors):
          error = dataDim.pointValues[index]
        else:
          error = 0.0
      
      else:
        error = conditionPoint.error
      
      self.errorEntry.set(error)
 
  def setError(self, event):

    value = self.errorEntry.get()
    if value is not None:
      if type(self.conditionPoint) is type(()):
        dataDim, index = self.conditionPoint
        pointErrors = dataDim.pointErrors
        if pointErrors:
          values = list(pointErrors)
        else:
          values = [0.0] * dataDim.numPoints
 
        values[index] = value
        dataDim.setPointErrors(values)
        
      else:  
        self.conditionPoint.setError( value )
  
  def getDetails(self, expSeries):
    
    if expSeries :
      self.detailsEntry.set(expSeries.details)
 
  def setDetails(self, event):

    text = self.detailsEntry.get()
    if text and text != ' ':
      self.expSeries.setDetails( text )

  def addExpSeries(self):
    
    expSeries = self.nmrProject.newNmrExpSeries(conditionNames=['delay time',])

  def deleteExpSeries(self, *event):
    
    if self.expSeries and (self.expSeries.className != 'Experiment'):
      if showOkCancel('Confirm','Really delete series?', parent=self):
        self.expSeries.delete()
        self.expSeries = None
        self.conditionPoint = None

  def getExperiments(self):
        
    if self.expSeries and (self.expSeries.className == 'Experiment'):
      return [self.expSeries,]
    
    else:
      return self.nmrProject.sortedExperiments()

  def getExperiment(self, sampleCondition):

    index = 0
    names = []
    
    if self.conditionPoint and (type(self.conditionPoint) != type(())):
      index = 0
      experiment = self.conditionPoint.parent.findFirstExperiment()
      experiments = self.getUnusedExperiments()
      
      name  = experiment.name
      names = [name] + [e.name for e in experiments]
      experiments = [experiment,] + experiments
    
    self.experimentPulldown.setup(names,experiments,index)
    
  def setExperiment(self, obj):
    
    experiment = self.experimentPulldown.getObject()
       
    if self.conditionPoint and (type(self.conditionPoint) != type(())):
      conditionSet = getExperimentConditionSet(experiment)
      
      if conditionSet is not self.conditionPoint.parent:
      
        if experiment not in self.expSeries.experiments:
          self.expSeries.addExperiment(experiment)
      
        unit = self.conditionPoint.unit
        if not unit:
          unit = CONDITION_UNITS_DICT[self.expSeries.conditionNames[0]]
        
        condition = self.conditionPoint.condition
      
        experiments = set(self.expSeries.experiments)
        for experiment0 in self.conditionPoint.parent.experiments:
          if experiment0 in experiments:
            experiments.remove(experiment0)
        self.expSeries.experiments = experiments
      
        value = self.conditionPoint.value
        error = self.conditionPoint.error
        self.conditionPoint.delete()
        
        self.conditionPoint = conditionSet.findFirstSampleCondition(condition=condition)
        if self.conditionPoint:
          self.conditionPoint.unit  = unit 
          self.updateAfter()          
        else:
          self.conditionPoint = conditionSet.newSampleCondition(condition=condition,unit=unit,
                                                                value=value,error=error)

  def updateDataDim(self, sampledDataDim):
  
    experiment = sampledDataDim.dataSource.experiment
    self.updateExperiments(experiment)

  def updateExperiments(self, experiment):
    
    experiments = self.getExperiments()
    names = [e.name for e in experiments]
    self.experimentPulldown.setup(names, experiments,0)
    
    if getExperimentSampledDim(experiment):
      self.updateAfter()
  
    elif self.expSeries:
      if self.expSeries.className == 'Experiment':
        if experiment is self.expSeries:
          self.updateConditionsAfter()

      elif experiment in self.expSeries.experiments:
        self.updateConditionsAfter()
 
 
  def updateConditionsAfter(self, sampleCondition=None):


    if self.waitingConditions:
      return
    
    if sampleCondition:
      experiments = sampleCondition.sampleConditionSet.experiments
      for experiment in experiments:
         if self.expSeries.className == 'Experiment':
           if experiment is self.expSeries:
             self.waitingConditions = True
             self.after_idle(self.updateConditions)
             break
      
         elif experiment in self.expSeries.experiments:
          self.waitingConditions = True
          self.after_idle(self.updateConditions)
          break

    else:
      self.waitingConditions = True
      self.after_idle(self.updateConditions)
      
  def updateConditions(self):
  
    self.updateButtons()
    objectList = []
    textMatrix = []
    colorMatrix = []
    nCols = len(self.conditionPointsMatrix.headingList)
    defaultColors = [None] * nCols
    if self.expSeries:
      if self.expSeries.className == 'Experiment':
        dataDim     = getExperimentSampledDim(self.expSeries)
        analysisDataDim = getAnalysisDataDim(dataDim)
        conditionVaried =  dataDim.conditionVaried
        expName     = self.expSeries.name
        unit        = dataDim.unit
        pointValues = dataDim.pointValues
        pointErrors = dataDim.pointErrors
        refPlane    = analysisDataDim.refSamplePlane
        
        for i in range(dataDim.numPoints):
          if i < len(pointErrors):
            error = pointErrors[i]
          else:
            error = None  
          
          pointText = ':%3d' % (i+1)
          if i == refPlane:
            datum      = ['* Ref Plane *',
                          expName+pointText,
                          None,
                          None,
                          None]
            colorMatrix.append(['#f08080'] * nCols)
          else:
            datum      = [conditionVaried ,
                          expName+pointText,
                          pointValues[i],
                          error,
                          unit]
            colorMatrix.append(defaultColors)
 

          textMatrix.append(datum)
          objectList.append((dataDim, i))
             
      else:
        condDict = getNmrExpSeriesSampleConditions(self.expSeries)
        conditionNames = self.expSeries.conditionNames
        
        for conditionName in conditionNames:
          for sampleCondition in condDict.get(conditionName, []):
 
            datum      = [sampleCondition.condition,
                          ' '.join([e.name for e in sampleCondition.parent.experiments]),
                          sampleCondition.value,
                          sampleCondition.error,
                          sampleCondition.unit]
 
            textMatrix.append(datum)
            objectList.append(sampleCondition)
            colorMatrix.append(defaultColors)

    self.conditionPointsMatrix.update(objectList=objectList,
                                      colorMatrix=colorMatrix,
                                      textMatrix=textMatrix)
    
    self.waitingConditions = 0

  def updateAfter(self, object=None):
  
    if self.waiting:
      return
    else:
      self.waiting = True
      self.after_idle(self.update)
 
  def updateButtons(self):
  
    if self.expSeries is None:
      self.seriesButtons.buttons[1].disable()
      self.seriesButtons.buttons[2].disable()
      self.conditionPointsButtons.buttons[0].disable()
      self.conditionPointsButtons.buttons[1].disable()
      self.conditionPointsButtons.buttons[2].disable()

    elif self.expSeries.className == 'Experiment':
      self.seriesButtons.buttons[1].disable()
      self.seriesButtons.buttons[2].disable()
      self.conditionPointsButtons.buttons[0].disable()
      self.conditionPointsButtons.buttons[1].disable()
      self.conditionPointsButtons.buttons[2].enable()
    
    else:
      self.seriesButtons.buttons[1].enable()
      self.seriesButtons.buttons[2].enable()
      self.conditionPointsButtons.buttons[0].enable()
      self.conditionPointsButtons.buttons[2].disable()
      
      if self.conditionPoint is None:
        self.conditionPointsButtons.buttons[1].disable()
      else:
        self.conditionPointsButtons.buttons[1].enable()
 
 
  def update(self):
    
    self.updateButtons()
    
    objectList = []
    textMatrix = []
    for experiment in getSampledDimExperiments(self.nmrProject):
      
      getExperimentConditionSet(experiment)
      sampledDim = getExperimentSampledDim(experiment)
      datum      = [None,
                    experiment.name,
                    1,
                    sampledDim.conditionVaried,
                    sampledDim.numPoints]
 
      textMatrix.append(datum)
      objectList.append(experiment)    
    
    for expSeries in self.nmrProject.sortedNmrExpSeries():

      experiments   = expSeries.experiments
      conditionSets = len([e.sampleConditionSet for e in experiments if e.sampleConditionSet])
      
      datum      = [expSeries.serial,
                    expSeries.name or ' ',
                    len(experiments),
                    ','.join(expSeries.conditionNames),
                    conditionSets]
 
      textMatrix.append(datum)
      objectList.append(expSeries)
       
    self.seriesMatrix.update(objectList=objectList, textMatrix=textMatrix)
    self.updateConditions()

    self.waiting = False
    
  def destroy(self):

    self.administerNotifiers(self.unregisterNotify)
    BasePopup.destroy(self)
    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)