Exemplo n.º 1
0
    def body(self, master):

        self.alarm_id = None
        self.root_widget = getRoot(self)

        row = 0
        label = Label(master, text='Widget count:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.count_label = Label(master,
                                 text='',
                                 tipText='Number of Tkinter widget objects')
        self.count_label.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1
        ind = 1
        label = Label(master, text='Auto count:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.on_off_buttons = RadioButtons(master,
                                           entries=self.on_off_entries,
                                           select_callback=self.applyAuto,
                                           selected_index=ind)
        self.on_off_buttons.grid(row=row, column=1, sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text='Auto frequency:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.freq_entry = IntEntry(master,
                                   text=60,
                                   returnCallback=self.applyAuto)
        self.freq_entry.grid(row=row, column=1, sticky=Tkinter.EW)
        label = Label(master, text='seconds')
        label.grid(row=row, column=2, sticky=Tkinter.W)

        row = row + 1
        texts = ['Do Immediate Count']
        commands = [self.applyManual]
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              help_msg=self.help_msg,
                                              help_url=self.help_url)
        buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW)

        self.doCount()
Exemplo n.º 2
0
  def body(self, guiFrame):

    self.geometry('600x350')

    project = self.project
    analysisProject = self.analysisProject

    guiFrame.grid_columnconfigure(1, weight=1)

    row = 0
    frame = Frame(guiFrame, grid=(0,0))
    label = Label(frame, text=' Window:', grid=(0,0))
    self.windowPulldown = PulldownList(frame, grid=(0,1),
                                      tipText='The window that will be printed out',
                                      callback=self.selectWindow)
                                      
    tipTexts = ['For the window pulldown, show all of the spectrum windows in the current project, irrespective of the active group',
                'For the window pulldown, show only spectrum windows that are in the currently active window group']
    self.whichWindows = RadioButtons(frame, grid=(0,2),
                                     entries=ACTIVE_OPTIONS, tipTexts=tipTexts,
                                     select_callback=self.updateWindows)
    
    texts = [ 'Save Print File' ]
    tipTexts = [ 'Save the printout to the specified file' ]
    commands = [ self.saveFile ]
    buttons = UtilityButtonList(guiFrame, helpUrl=self.help_url, grid=(row,2),
                                commands=commands, texts=texts, tipTexts=tipTexts)
    self.buttons = buttons
    buttons.buttons[0].config(bg='#B0FFB0')
    
    row += 1
    guiFrame.grid_rowconfigure(row, weight=1)
    options = ['Options', 'Spectra', 'Peak Lists', 'Region']
    tipTexts = ['Optional settings for spectra', 'Optional settings for peak lists', 'Optional settings for the region']
    tabbedFrame = TabbedFrame(guiFrame, options=options, tipTexts=tipTexts)
    tabbedFrame.grid(row=row, column=0, columnspan=3, sticky='nsew')
    self.tabbedFrame = tabbedFrame

    optionFrame, spectrumFrame, peakListFrame, regionFrame = tabbedFrame.frames

    optionFrame.expandGrid(0, 0)
    getOption = lambda key, defaultValue: PrintBasic.getPrintOption(analysisProject, key, defaultValue)
    setOption = lambda key, value: PrintBasic.setPrintOption(analysisProject, key, value)
    self.printFrame = PrintFrame(optionFrame, getOption=getOption,
                                 grid=(0,0), gridSpan=(1,1),
                                 setOption=setOption, haveTicks=True,
                                 doOutlineBox=False)

    spectrumFrame.expandGrid(0, 0)
    frame = Frame(spectrumFrame, grid=(0,0), gridSpan=(1,1))
    frame.expandGrid(1,0)

    self.overrideSpectrum = CheckButton(frame,
       text='Use below settings when printing',
       tipText='Use below settings when printing instead of the window values',
       grid=(0,0), sticky='w')

    tipText = 'Change the settings of the selected spectra back to their window values'
    button = Button(frame, text='Reset Selected', tipText=tipText,
                    command=self.resetSelected, grid=(0,1), sticky='e')

    self.posColorPulldown = PulldownList(self, callback=self.setPosColor)
    self.negColorPulldown = PulldownList(self, callback=self.setNegColor)
    headings = ['Spectrum', 'Pos. Contours\nDrawn', 'Neg. Contours\nDrawn', 'Positive\nColours', 'Negative\nColours']
    tipTexts = ['Spectrum in window', 'Whether the positive contours should be drawn', 'Whether the negative contours should be drawn',
      'Colour scheme for positive contours (can be a single colour)', 'Colour scheme for negative contours (can be a single colour)']

    editWidgets      = [ None, None, None, self.posColorPulldown, self.negColorPulldown]
    editGetCallbacks = [ None, self.togglePos, self.toggleNeg, self.getPosColor, self.getNegColor]
    editSetCallbacks = [ None, None, None, self.setPosColor, self.setNegColor]
    self.spectrumTable = ScrolledMatrix(frame, headingList=headings,
                                        tipTexts=tipTexts,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        grid=(1,0), gridSpan=(1,2))

    peakListFrame.expandGrid(0, 0)
    frame = Frame(peakListFrame, grid=(0,0), gridSpan=(1,3))
    frame.expandGrid(1,0)

    self.overridePeakList = CheckButton(frame,
       text='Use below settings when printing',
       tipText='Use below settings when printing instead of the window values',
       grid=(0,0))

    tipText = 'Change the settings of the selected peak lists back to their window values'
    button = Button(frame, text='Reset Selected', tipText=tipText,
                    command=self.resetSelected, grid=(0,1), sticky='e')

    colors = Color.standardColors
    self.peakColorPulldown = PulldownList(self, callback=self.setPeakColor,
                                        texts=[c.name for c in colors],
                                        objects=[c.hex for c in colors],
                                        colors=[c.hex for c in colors])
    headings = [ 'Peak List', 'Symbols Drawn', 'Peak Font', 'Peak Colour']
    self.fontMenu = FontList(self, mode='Print', extraTexts=[no_peak_text])
    editWidgets      = [ None, None, self.fontMenu, self.peakColorPulldown]
    editGetCallbacks = [ None, self.togglePeaks, self.getPeakFont, self.getPeakColor ]
    editSetCallbacks = [ None, None, self.setPeakFont, self.setPeakColor ]
    self.peakListTable = ScrolledMatrix(frame, headingList=headings,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        grid=(1,0), gridSpan=(1,2))

    regionFrame.expandGrid(0, 0)
    frame = Frame(regionFrame, grid=(0,0), gridSpan=(1,3))
    frame.expandGrid(3,0)
    tipText = 'Use the specified override region when printing rather than the window values'
    self.overrideButton = CheckButton(frame, text='Use override region when printing',
                                      tipText=tipText,
                                      callback=self.toggledOverride, grid=(0,0))

    tipTexts = ('Use min and max to specify override region', 'Use center and width to specify override region')
    self.use_entry = USE_ENTRIES[0]
    self.useButtons = RadioButtons(frame, entries=USE_ENTRIES,
                                      tipTexts=tipTexts,
                                      select_callback=self.changedUseEntry,
                                      grid=(1,0))

    texts = ('Set Region from Window', 'Set Center from Window', 'Set Width from Window')
    tipTexts = ('Set the override region to be the current window region',
                'Set the center of the override region to be the center of the current window region',
                'Set the width of the override region to be the width of the current window region')
    commands = (self.setRegionFromWindow, self.setCenterFromWindow, self.setWidthFromWindow)
    self.setRegionButton = ButtonList(frame, texts=texts,
                                      tipTexts=tipTexts,
                                      commands=commands, grid=(2,0))

    self.minRegionWidget = FloatEntry(self, returnCallback=self.setMinRegion, width=10)
    self.maxRegionWidget = FloatEntry(self, returnCallback=self.setMaxRegion, width=10)
    headings = MIN_MAX_HEADINGS
    editWidgets      = [ None, None, self.minRegionWidget, self.maxRegionWidget ]
    editGetCallbacks = [ None, None, self.getMinRegion,    self.getMaxRegion ]
    editSetCallbacks = [ None, None, self.setMinRegion,    self.setMaxRegion ]
    self.regionTable = RegionScrolledMatrix(frame, headingList=headings,
                                            editWidgets=editWidgets,
                                            editGetCallbacks=editGetCallbacks,
                                            editSetCallbacks=editSetCallbacks,
                                            grid=(3,0))

    self.updateWindows()
    self.updateAfter()
    
    self.administerNotifiers(self.registerNotify)
Exemplo n.º 3
0
    def body(self):
        '''Describes the body of this tab. It consists
           out of a number of radio buttons, check buttons
           and number entries that allow the user to
           indicate which assignments should be transferred.
        '''

        # self.frame.expandColumn(0)
        self.frame.expandGrid(8, 0)
        self.frame.expandGrid(8, 1)

        typeOfAssignmentFrame = LabelFrame(
            self.frame, text='type of assignment')
        typeOfAssignmentFrame.grid(row=0, column=0, sticky='nesw')
        # typeOfAssignmentFrame.expandGrid(0,5)

        peakSelectionFrame = LabelFrame(
            self.frame, text='which peaks to assign')
        peakSelectionFrame.grid(row=0, column=1, sticky='nesw', rowspan=2)

        spinSystemSelectionFrame = LabelFrame(self.frame,
                                              text='Which spin-systems to use')
        spinSystemSelectionFrame.grid(row=2, column=0, sticky='nesw')

        tipText = 'What to do when a residue has already a spin system assigned to it.'
        assignedResidueFrame = LabelFrame(self.frame,
                                          text='if residue already has spin-system',
                                          tipText=tipText)
        assignedResidueFrame.grid(row=2, column=1, sticky='nesw')

        spectrumSelectionFrame = LabelFrame(self.frame, text='spectra')
        spectrumSelectionFrame.grid(row=1, column=0, sticky='nesw')

        row = 0

        Label(typeOfAssignmentFrame,
              text='Resonances to Peak Dimensions',
              grid=(row, 0))
        self.peaksCheckButton = CheckButton(typeOfAssignmentFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(typeOfAssignmentFrame,
              text='SpinSystems to Residues',
              grid=(row, 0))
        self.residuesCheckButton = CheckButton(
            typeOfAssignmentFrame, selected=True, grid=(row, 1))

        row = 0

        Label(peakSelectionFrame, text='Intra-Residual', grid=(row, 0))
        self.intraCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        row += 1

        Label(peakSelectionFrame, text='Sequential', grid=(row, 0))
        self.sequentialCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        row += 1

        Label(peakSelectionFrame,
              text='Do not assign diagonal peaks',
              grid=(row, 0))
        self.noDiagonalCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        entries = ['Only assigned spin systems',
                   'All that have a score of at least: ',
                   'User Defined',
                   'Solution number:']
        tipTexts = ['Only assign resonances of spin systems that already have a sequential assignment for the assignment of peak dimensions. Spin system to residue assignment is not relevant in this case.',
                    'Assign all spin systems that have a score of at least a given percentage. 50% or lower is not possible, because than spin systems might have to be assigned to more than 1 residue, which is impossible.',
                    "As defined in the lower row of buttons in the 'results' tab.",
                    'One of the single solutions of the annealing.']
        self.spinSystemTypeSelect = RadioButtons(spinSystemSelectionFrame,
                                                 entries=entries, grid=(0, 0),
                                                 select_callback=None,
                                                 direction=VERTICAL,
                                                 gridSpan=(4, 1),
                                                 tipTexts=tipTexts)

        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minScoreEntry = FloatEntry(spinSystemSelectionFrame,
                                        grid=(1, 1), width=7,
                                        text=str(self.minScore),
                                        returnCallback=self.changeMinScore,
                                        tipText=tipText)
        self.minScoreEntry.bind('<Leave>', self.changeMinScore, '+')

        self.solutionNumberEntry = IntEntry(spinSystemSelectionFrame,
                                            grid=(3, 1), width=7, text=1,
                                            returnCallback=self.solutionUpdate,
                                            tipText=tipText)
        self.solutionNumberEntry.bind('<Leave>', self.solutionUpdate, '+')

        #self.solutionPullDown = PulldownList(spinSystemSelectionFrame, None, grid=(3,1), sticky='w')

        entries = ['all spectra', 'only:']
        tipTexts = ['Assign peaks in all the spectra that where selected before the annealing ran.',
                    'Only assign peaks in one particular spectrum. You can of course repeat this multiple times for different spectra.']
        self.spectrumSelect = RadioButtons(spectrumSelectionFrame,
                                           entries=entries,
                                           grid=(0, 0),
                                           select_callback=None,
                                           direction=VERTICAL,
                                           gridSpan=(2, 1), tipTexts=tipTexts)

        self.spectraPullDown = PulldownList(spectrumSelectionFrame,
                                            self.changeSpectrum,
                                            grid=(1, 1), sticky='w')

        entries = ['skip this residue',
                   'de-assign old spin system from residue',
                   'assign, but never merge',
                   'warn to merge']
        tipTexts = ["Don't assign the new spin system to the residue. The residue is not skipped when the old spin system does not contain any resonances",
                    "De-assign old spin system from residue, unless the old spin system is a spin system without any resonances.",
                    "Don't merge any spin systems, merging can be performed later if nescesary in the Resonance --> SpinSystems window.",
                    "Ask to merge individually for each spin system, this might result in clicking on a lot of popups."]
        self.assignedResidueStrategySelect = RadioButtons(assignedResidueFrame,
                                                          entries=entries,
                                                          grid=(0, 0),
                                                          select_callback=None,
                                                          direction=VERTICAL,
                                                          gridSpan=(2, 1),
                                                          tipTexts=tipTexts)

        texts = ['Transfer Assignments']
        commands = [self.transferAssignments]
        self.transferButton = ButtonList(
            self.frame, commands=commands, texts=texts)
        self.transferButton.grid(row=5, column=0, sticky='nsew', columnspan=2)
Exemplo n.º 4
0
class TasksFrame(Frame):

  
  def __init__(self, guiParent, basePopup):

    self.guiParent = guiParent
    self.basePopup = basePopup

    # selection hash. This needs to be stored so that we can
    # refresh with the same criteria
    self.select = None

    # should the screen autorefresh
    self.autoRefresh = False
    
    # add this to shortcuts to ease navigation    
    self.basePopup.frameShortcuts['Tasks'] = self

    #self.registerNotify=basePopup.registerNotify
    #self.unregisterNotify=basePopup.unregisterNotify

    #self.frames = []

    # FIXME JMCI

    # This frame is specific for a single repository so we need a
    # method for identifying one from the whole set (or could have
    # subtabs)

    Frame.__init__(self, guiParent)
  
    # set up the grid

    self.grid_columnconfigure(0, weight=0, minsize=20)
    self.grid_columnconfigure(1, weight=1, minsize=30)
    self.grid_columnconfigure(2, weight=0, minsize=40)

    self.grid_rowconfigure(0, weight=0, minsize=20)
    self.grid_rowconfigure(1, weight=0, minsize=10)
    self.grid_rowconfigure(2, weight=0, minsize=0)
    self.grid_rowconfigure(3, weight=0, minsize=0)
    self.grid_rowconfigure(4, weight=0, minsize=0)
    self.grid_rowconfigure(5, weight=1, minsize=0)
    self.grid_rowconfigure(6, weight=0, minsize=10)
    self.grid_rowconfigure(7, weight=0, minsize=10)


    initial_cols = ['ID','Task','User','Status']
    self.task_matrix = ScrolledMatrix(self, headingList=initial_cols, initialRows=15,
                                      doubleCallback=self.goto_task_tab)

    # Filters for narrowing down tasks. should probably code this
    # specifically inside this package    
    #self.filter = FilterFrame(self, self.basePopup, text='Filter')
    self.filter = TaskFilterFrame(self, self.basePopup, text='Filter')

    # Frame for controlling the main client side daemon
    # seems to be a problem. add a simple button for now
    opts = ['Client','Server']
    self.daemonFrame = TabbedFrame(self, options=opts,
                                   toggleOff=False, selected=0)

    self.daemonSwitchLabel = Label(self, text= 'Task Daemon')
    self.daemonSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_daemon, selected_index = 1)

    sel = 1
    if self.autoRefresh:
      sel = 0
    self.autoRefreshSwitchLabel = Label(self, text= 'Auto Refresh')
    self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_refresh, selected_index = sel)

    self.label_rep = Label(self, text='', font='Helvetica16')

    # set up a loop
    self.refresh()


  def drawFrame(self):

    # build up the body.

    # This is a very simple mock up. In reality we need to be
    # able to select a number of different input files that
    # depend on the task type

    # we need to have the current repository in context
    self.repository = self.basePopup.repList.currentRepository

    if self.repository == None:

      self.label_rep.grid_remove()
      self.task_matrix.grid_remove()
      self.filter.grid_remove()
      self.daemonSwitchLabel.grid_remove()
      self.daemonSwitch.grid_remove()
      
    else:
      
      strg = self.repository.user + '@' + self.repository.name + ' (' + self.repository.connect + ')'

      self.label_rep.set('TaskManager: Repository ' + strg)
      self.label_rep.grid(row=1, column=1, columnspan=2, sticky='w')

      self.task_matrix.grid(row=2, column=1, rowspan=4, sticky='nsew')


      loc = SharedBeanServiceLocator()
      port = loc.getSharedBean()

      request1 = getList();

      request1._arg0 = 'org.pimslims.applet.server.TaskBean';
      request1._arg1 = 'getListWithFields';

      if self.select==None:
        request1._arg2 = ''
      else:
        wsstr_in = WSString(self.select)
        request1._arg2 = wsstr_in.str
        

      response1 = port.getList(request1)

      wsstr1 = WSString(response1._return)
      ss1 = wsstr1.getStruct()

      matrix = [];
      objs = [];

      for el in ss1:
        new_row = (el['serial'], 'TestTask1', 'jionides', el['status'])
        matrix.append(new_row)
        objs.append(el)

      self.task_matrix.update(objectList=objs, textMatrix=matrix)

      self.filter.grid(row=2, column=2, sticky='n')

      # FIXME JMCI

      # The tabbed frame seems to cause the GUI to hang over expansion.
      # use a simple radio button for now

      # self.daemonFrame.grid(row=3, column=2, padx=10, sticky='nsew')
      self.daemonSwitchLabel.grid(row=3, column=2, padx=10, sticky='n')
      self.daemonSwitch.grid(row=4, column=2, padx=10, sticky='n')

      self.autoRefreshSwitchLabel.grid(row=6, column=1, padx=10, sticky='w')
      self.autoRefreshSwitch.grid(row=6, column=1, padx=10, sticky='e')

  def selectTask(self):

    row = self.task_matrix.currentCell
    print 'in select task ', row


  def set_daemon(self, text):

    print 'setting daemon ', text

    if text == 'on':
      self.basePopup.taskDaemon.active = True
    else:
      self.basePopup.taskDaemon.active = False
    
  def set_refresh(self, text):

    print 'setting refresh ', text

    if text == 'on':
      self.autoRefresh = True
    else:
      self.autoRefresh = False


  def refresh(self):

    if self.autoRefresh:
      print 'refreshing frame ', time.time()
      self.drawFrame()
      
    self.after(5000, self.refresh)

  def goto_task_tab(self, obj, row, col):

    print obj
    self.basePopup.currentTask =  obj['serial'].__str__()   

    # This is really awkward because we actually have to go to the
    # correct tab. We have some horrible hacks here. Need a dictionary
    # that can take us straight to the correct frame based on a
    # keyword

    self.basePopup.tabbedFrame.select(2)
    #for ff in self.basePopup.tabbedFrame.frames[2].children.values():
    #  ff.tabbedFrame.select(0)

    if self.basePopup.frameShortcuts.has_key('Task'):
      taskFrame = self.basePopup.frameShortcuts['Task']
      # really need to check on the type of task
      if taskFrame.frameShortcuts.has_key('Test1'):
        taskFrame.frameShortcuts['Test1'].drawFrame()
    # also need to select the current tabbed frame
    self.basePopup.tabbedFrame.select(2)
        

  def administerNotifiers(self, notifyFunc):

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

  def updateAllAfter(self, obj):

    self.after_idle(self.updateAll)

  def updateAll(self, project=None):

      return

  def quit(self):
  
    self.guiParent.parent.destroy()
    
  def destroy(self):
  
    #self.administerNotifiers(self.basePopup.unregisterNotify)
    Frame.destroy(self)
Exemplo n.º 5
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)
Exemplo n.º 6
0
    def body(self):
        '''Describes the body of this tab. It consists
           out of a number of radio buttons, check buttons
           and number entries that allow the user to
           indicate which assignments should be transferred.
        '''

        # self.frame.expandColumn(0)
        self.frame.expandGrid(8, 0)
        self.frame.expandGrid(8, 1)

        typeOfAssignmentFrame = LabelFrame(self.frame,
                                           text='type of assignment')
        typeOfAssignmentFrame.grid(row=0, column=0, sticky='nesw')
        # typeOfAssignmentFrame.expandGrid(0,5)

        peakSelectionFrame = LabelFrame(self.frame,
                                        text='which peaks to assign')
        peakSelectionFrame.grid(row=0, column=1, sticky='nesw', rowspan=2)

        spinSystemSelectionFrame = LabelFrame(self.frame,
                                              text='Which spin-systems to use')
        spinSystemSelectionFrame.grid(row=2, column=0, sticky='nesw')

        tipText = 'What to do when a residue has already a spin system assigned to it.'
        assignedResidueFrame = LabelFrame(
            self.frame,
            text='if residue already has spin-system',
            tipText=tipText)
        assignedResidueFrame.grid(row=2, column=1, sticky='nesw')

        spectrumSelectionFrame = LabelFrame(self.frame, text='spectra')
        spectrumSelectionFrame.grid(row=1, column=0, sticky='nesw')

        row = 0

        Label(typeOfAssignmentFrame,
              text='Resonances to Peak Dimensions',
              grid=(row, 0))
        self.peaksCheckButton = CheckButton(typeOfAssignmentFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(typeOfAssignmentFrame,
              text='SpinSystems to Residues',
              grid=(row, 0))
        self.residuesCheckButton = CheckButton(typeOfAssignmentFrame,
                                               selected=True,
                                               grid=(row, 1))

        row = 0

        Label(peakSelectionFrame, text='Intra-Residual', grid=(row, 0))
        self.intraCheckButton = CheckButton(peakSelectionFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(peakSelectionFrame, text='Sequential', grid=(row, 0))
        self.sequentialCheckButton = CheckButton(peakSelectionFrame,
                                                 selected=True,
                                                 grid=(row, 1))

        row += 1

        Label(peakSelectionFrame,
              text='Do not assign diagonal peaks',
              grid=(row, 0))
        self.noDiagonalCheckButton = CheckButton(peakSelectionFrame,
                                                 selected=True,
                                                 grid=(row, 1))

        entries = [
            'Only assigned spin systems',
            'All that have a score of at least: ', 'User Defined',
            'Solution number:'
        ]
        tipTexts = [
            'Only assign resonances of spin systems that already have a sequential assignment for the assignment of peak dimensions. Spin system to residue assignment is not relevant in this case.',
            'Assign all spin systems that have a score of at least a given percentage. 50% or lower is not possible, because than spin systems might have to be assigned to more than 1 residue, which is impossible.',
            "As defined in the lower row of buttons in the 'results' tab.",
            'One of the single solutions of the annealing.'
        ]
        self.spinSystemTypeSelect = RadioButtons(spinSystemSelectionFrame,
                                                 entries=entries,
                                                 grid=(0, 0),
                                                 select_callback=None,
                                                 direction=VERTICAL,
                                                 gridSpan=(4, 1),
                                                 tipTexts=tipTexts)

        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minScoreEntry = FloatEntry(spinSystemSelectionFrame,
                                        grid=(1, 1),
                                        width=7,
                                        text=str(self.minScore),
                                        returnCallback=self.changeMinScore,
                                        tipText=tipText)
        self.minScoreEntry.bind('<Leave>', self.changeMinScore, '+')

        self.solutionNumberEntry = IntEntry(spinSystemSelectionFrame,
                                            grid=(3, 1),
                                            width=7,
                                            text=1,
                                            returnCallback=self.solutionUpdate,
                                            tipText=tipText)
        self.solutionNumberEntry.bind('<Leave>', self.solutionUpdate, '+')

        #self.solutionPullDown = PulldownList(spinSystemSelectionFrame, None, grid=(3,1), sticky='w')

        entries = ['all spectra', 'only:']
        tipTexts = [
            'Assign peaks in all the spectra that where selected before the annealing ran.',
            'Only assign peaks in one particular spectrum. You can of course repeat this multiple times for different spectra.'
        ]
        self.spectrumSelect = RadioButtons(spectrumSelectionFrame,
                                           entries=entries,
                                           grid=(0, 0),
                                           select_callback=None,
                                           direction=VERTICAL,
                                           gridSpan=(2, 1),
                                           tipTexts=tipTexts)

        self.spectraPullDown = PulldownList(spectrumSelectionFrame,
                                            self.changeSpectrum,
                                            grid=(1, 1),
                                            sticky='w')

        entries = [
            'skip this residue', 'de-assign old spin system from residue',
            'assign, but never merge', 'warn to merge'
        ]
        tipTexts = [
            "Don't assign the new spin system to the residue. The residue is not skipped when the old spin system does not contain any resonances",
            "De-assign old spin system from residue, unless the old spin system is a spin system without any resonances.",
            "Don't merge any spin systems, merging can be performed later if nescesary in the Resonance --> SpinSystems window.",
            "Ask to merge individually for each spin system, this might result in clicking on a lot of popups."
        ]
        self.assignedResidueStrategySelect = RadioButtons(assignedResidueFrame,
                                                          entries=entries,
                                                          grid=(0, 0),
                                                          select_callback=None,
                                                          direction=VERTICAL,
                                                          gridSpan=(2, 1),
                                                          tipTexts=tipTexts)

        texts = ['Transfer Assignments']
        commands = [self.transferAssignments]
        self.transferButton = ButtonList(self.frame,
                                         commands=commands,
                                         texts=texts)
        self.transferButton.grid(row=5, column=0, sticky='nsew', columnspan=2)
Exemplo n.º 7
0
    def body(self, guiFrame):

        self.geometry('600x350')

        guiFrame.expandGrid(0, 0)

        tipTexts = ['', '', '', '']
        options = [
            'Find Parameters', 'Spectrum Widths', 'Diagonal Exclusions',
            'Region Peak Find'
        ]
        tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0))

        frameA, frameB, frameC, frameD = tabbedFrame.frames
        self.tabbedFrame = tabbedFrame

        # Find Params

        frameA.expandGrid(2, 0)

        row = 0
        label = LabelFrame(frameA,
                           text='Extrema to search for:',
                           grid=(row, 0),
                           gridSpan=(1, 2))
        label.expandGrid(0, 1)

        entries = ['positive and negative', 'positive only', 'negative only']
        tipTexts = [
            'Sets whether peak picking within spectra find intensity maxima, minima or both maxima and minima',
        ]
        self.extrema_buttons = RadioButtons(label,
                                            entries=entries,
                                            select_callback=self.apply,
                                            direction='horizontal',
                                            grid=(0, 0),
                                            tipTexts=tipTexts)

        row += 1
        label = LabelFrame(frameA,
                           text='Nearby points to check:',
                           grid=(row, 0),
                           gridSpan=(1, 2))
        label.expandGrid(None, 1)

        entries = ['+-1 in at most one dim', '+-1 allowed in any dim']
        tipTexts = [
            'Sets how permissive the peak picking in when searching for intensity extrema; by adding extra points to the selected search region',
        ]
        self.adjacent_buttons = RadioButtons(label,
                                             entries=entries,
                                             select_callback=self.apply,
                                             direction='horizontal',
                                             grid=(0, 0),
                                             tipTexts=tipTexts)

        row += 1
        labelFrame = LabelFrame(frameA,
                                text='Other parameters:',
                                grid=(row, 0),
                                gridSpan=(1, 2))
        labelFrame.expandGrid(5, 2)

        frow = 0
        label = Label(labelFrame,
                      text='Scale relative to contour levels:',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Threshold above which peaks are picked, relative to the lowest displayed contour; 1.0 means picking exactly what is visible'
        self.scale_entry = FloatEntry(labelFrame,
                                      grid=(frow, 1),
                                      tipText=tipText,
                                      returnCallback=self.apply,
                                      width=10)
        self.scale_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Exclusion buffer around peaks (in points):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'The size of the no-pick region, in data points, around existing picked peaks; eliminates duplicate picking'
        self.buffer_entry = IntEntry(labelFrame,
                                     returnCallback=self.apply,
                                     grid=(frow, 1),
                                     width=10,
                                     tipText=tipText)
        self.buffer_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Extra thickness in orthogonal dims (in points):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Sets whether to consider any additional planes (Z dimension) when calculating peak volume integrals'
        self.thickness_entry = IntEntry(labelFrame,
                                        returnCallback=self.apply,
                                        width=10,
                                        grid=(frow, 1),
                                        tipText=tipText)
        self.thickness_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Minimum drop factor (0.0-1.0):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = ''
        self.drop_entry = FloatEntry(labelFrame,
                                     returnCallback=self.apply,
                                     width=10,
                                     grid=(frow, 1),
                                     tipText=tipText)
        self.drop_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Volume method:',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Selects which method to use to calculate peak volume integrals when peaks are picked; box sizes are specified in "Spectrum Widths"'
        self.method_menu = PulldownList(labelFrame,
                                        texts=PeakBasic.PEAK_VOLUME_METHODS,
                                        grid=(frow, 1),
                                        callback=self.apply,
                                        tipText=tipText)

        # Spectrum widths

        frameB.expandGrid(1, 1)

        label = Label(frameB, text='Spectrum: ')
        label.grid(row=0, column=0, sticky='e')

        tipText = 'The spectrum which determines the widths being shown'
        self.expt_spectrum = PulldownList(frameB,
                                          tipText=tipText,
                                          callback=self.setSpectrumProperties)
        self.expt_spectrum.grid(row=0, column=1, sticky='w')

        self.editLinewidthEntry = FloatEntry(self,
                                             text='',
                                             returnCallback=self.setLinewidth,
                                             width=10)
        self.editBoxwidthEntry = FloatEntry(self,
                                            text='',
                                            returnCallback=self.setBoxwidth,
                                            width=10)
        tipTexts = [
            'The number of the spectrum dimension to which the settings apply',
            'The nuclear isotope measures in the spectrum dimension',
            'The smallest value for the linewidth of a peak for it to be picked',
            'The size of the spectrum region to perform the volume integral over'
        ]
        headingList = [
            'Dimension', 'Isotope', 'Minimum Linewidth (Hz)', 'Boxwidth'
        ]
        editSetCallbacks = [None, None, self.setLinewidth, self.setBoxwidth]
        editGetCallbacks = [None, None, self.getLinewidth, self.getBoxwidth]
        editWidgets = [
            None, None, self.editLinewidthEntry, self.editBoxwidthEntry
        ]
        self.spectrumMatrix = ScrolledMatrix(frameB,
                                             initialRows=6,
                                             editSetCallbacks=editSetCallbacks,
                                             editGetCallbacks=editGetCallbacks,
                                             editWidgets=editWidgets,
                                             headingList=headingList,
                                             callback=self.selectCell,
                                             tipTexts=tipTexts)
        self.spectrumMatrix.grid(row=1, column=0, columnspan=2, sticky='nsew')

        # Diagonal Exclusions

        frameC.expandGrid(0, 0)

        tipTexts = [
            'The isotope as measures on the axis of a spectrum window',
            'The distance from the homonuclear diagonal line within which no peak picking can occur'
        ]
        self.exclusionEntry = FloatEntry(self,
                                         text='',
                                         returnCallback=self.setExclusion,
                                         width=10)
        headingList = ['Isotope', 'Diagonal Exclusion (ppm)']
        editSetCallbacks = [None, self.setExclusion]
        editGetCallbacks = [None, self.getExclusion]
        editWidgets = [None, self.exclusionEntry]
        self.isotopeMatrix = ScrolledMatrix(frameC,
                                            editSetCallbacks=editSetCallbacks,
                                            editGetCallbacks=editGetCallbacks,
                                            editWidgets=editWidgets,
                                            headingList=headingList,
                                            grid=(0, 0),
                                            tipTexts=tipTexts)

        # Region peak find

        self.regionFindPeakList = None
        self.regionCondition = None
        self.regionConditions = []
        self.regionCol = 1

        row = 0

        label = Label(frameD, text='Peak List: ', grid=(0, 0))
        tipText = 'Selects which peak list to perform region-wide peak picking for'
        self.regionPeakListPulldown = PulldownList(
            frameD,
            callback=self.changeRegionPeakList,
            grid=(0, 1),
            tipText=tipText)

        row += 1
        frameD.expandGrid(row, 1)

        self.regionEntry = FloatEntry(self,
                                      text='',
                                      returnCallback=self.setRegion,
                                      width=10)
        self.conditionMenu = PulldownList(self,
                                          texts=('include', 'exclude'),
                                          callback=self.setCondition)

        tipTexts = [
            'Whether to include or exclude the states region from region-wide peak picking',
        ]
        headingList = ['Condition']
        editSetCallbacks = [None]
        editGetCallbacks = [None]
        editWidgets = [self.conditionMenu]
        self.regionFindMatrix = ScrolledMatrix(
            frameD,
            headingList=headingList,
            callback=self.selectRegionCell,
            editWidgets=editWidgets,
            editGetCallbacks=editGetCallbacks,
            editSetCallbacks=editSetCallbacks,
            grid=(row, 0),
            gridSpan=(1, 2))

        row += 1
        tipTexts = [
            'Sets the currently selected region row to cover the whole spectrum',
            'Add a new region row, which may them be set for exclusion or inclusion when peak picking large areas',
            'Remove the selected region specification',
            'Go to the panel for setting the parameters that control how peaks extrema are picked',
            'Using the stated regions and parameters, perform region-wide peak picking'
        ]
        texts = [
            'Whole Region', 'Add Region', 'Delete Region', 'Adjust Params',
            'Find Peaks!'
        ]
        commands = [
            self.wholeRegion, self.addCondition, self.deleteCondition,
            self.adjustParams, self.regionFindPeaks
        ]

        buttons = ButtonList(frameD,
                             texts=texts,
                             commands=commands,
                             grid=(row, 0),
                             gridSpan=(1, 2),
                             tipTexts=tipTexts)
        buttons.buttons[4].config(bg='#B0FFB0')

        utilButtons = UtilityButtonList(tabbedFrame.sideFrame,
                                        grid=(0, 0),
                                        helpUrl=self.help_url,
                                        sticky='e')

        self.dataDim = None
        self.setParamsEntries()
        self.updateSpectrum()
        self.setIsotopeProperties()
        self.updateRegionPeakLists()

        self.administerNotifiers(self.registerNotify)
Exemplo n.º 8
0
    def body(self, guiFrame):

        self.geometry('500x130')

        guiFrame.grid_columnconfigure(2, weight=1)
        guiFrame.grid_rowconfigure(3, weight=1)

        self.alarm_id = None

        row = 0
        tipText = 'Browse for the directory into which project backups will be made'
        button = Button(guiFrame,
                        text='Directory:',
                        command=self.selectDir,
                        grid=(row, 0),
                        tipText=tipText,
                        sticky='ew')

        repository = self.project.findFirstRepository(name='backup')
        if repository:
            text = repository.url.path
        else:  # this is trouble, but should not happen
            text = ''

        tipText = 'Enter the name of the directory into which project backups will be made'
        self.dir_entry = Entry(guiFrame,
                               text=text,
                               tipText=tipText,
                               width=40,
                               returnCallback=self.applyAuto,
                               grid=(row, 1),
                               gridSpan=(1, 2),
                               sticky='ew')

        row += 1
        label = Label(guiFrame, text='Auto-backup:', grid=(row, 0))
        if self.analysisProject.doAutoBackup:
            ind = 0
        else:
            ind = 1

        tipTexts = [
            'Toggle the timed automatic backup on',
            'Toggle the timed automatic backup off'
        ]
        self.on_off_buttons = RadioButtons(guiFrame,
                                           entries=self.on_off_entries,
                                           tipTexts=tipTexts,
                                           select_callback=self.applyAuto,
                                           selected_index=ind,
                                           grid=(row, 1))

        row += 1
        tipText = 'The number of minutes to wait before automatic project backups'
        label = Label(guiFrame, text='Auto-backup frequency:', grid=(row, 0))

        self.freq_entry = IntEntry(guiFrame,
                                   text=self.analysisProject.autoBackupFreq,
                                   returnCallback=self.applyAuto,
                                   tipText=tipText)
        self.freq_entry.grid(row=row, column=1)

        label = Label(guiFrame, text=' (minutes)', grid=(row, 2))

        row = row + 1
        # Blank for expansion

        row = row + 1
        texts = ['Apply Auto Settings', 'Do Immediate Backup']
        commands = [self.applyAuto, self.applyManual]
        tipTexts = [
            'Commit the specified settings and commence automated CCPN project backup',
            'Backup the CCPN project now, into the specified backup directory'
        ]
        buttons = UtilityButtonList(guiFrame,
                                    texts=texts,
                                    commands=commands,
                                    doClone=False,
                                    helpMsg=self.help_msg,
                                    helpUrl=self.help_url,
                                    tipTexts=tipTexts,
                                    grid=(row, 0),
                                    gridSpan=(1, 3),
                                    sticky='nsew')
Exemplo n.º 9
0
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
Exemplo n.º 10
0
  def body(self, master):

    pseudoExpts = getSampledDimExperiments(self.parent.nmrProject)

    master.rowconfigure(0, weight=1)
    master.rowconfigure(1, weight=1)
    master.columnconfigure(0, weight=1)

    tipTexts = ['The experiment is pseudo-N dimensional, with a sampled axis',
                'The experiment is the regular kind with only NMR frequency axes']
    self.pseudoEntries = [x % len(self.params.npts) for x in PSEUDO_ENTRIES]            
    self.pseudoButton = RadioButtons(master, entries=self.pseudoEntries,
                                     select_callback=self.changedPseudoMode,
                                     grid=(0,0), sticky='nw', tipTexts=tipTexts)

    frame = self.pseudoFrame = Frame(master)
    self.pseudoFrame.grid(row=1, column=0, sticky='nsew')

    row = 0
    if pseudoExpts:
      tipText = 'Select from existing pseudo nD experiments to copy sampled axis values from'
      texts = [x.name for x in pseudoExpts]
      label = Label(frame, text='Existing pseudo expts: ')
      label.grid(row=row, column=0, sticky='e')
      self.pseudoList = PulldownList(frame, texts=texts, objects=pseudoExpts, tipText=tipText)
      self.pseudoList.grid(row=row, column=1, sticky='w')
      tipText = 'Transfer the sampled axis values from the existing experiment to the new one'
      Button(frame, text='Copy values down', command=self.copyValues,
             tipText=tipText, grid=(row,2))
      
      row += 1

    npts = self.params.npts[self.dim]
    tipText = 'Number of data points (planes) along sampled axis'
    label = Label(frame, text='Number of points: ')
    label.grid(row=row, column=0, sticky='e')
    self.nptsEntry = IntEntry(frame, text=npts, tipText=tipText, width=8, grid=(row,1))
     
    tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values'
    Button(frame, text='Load File', command=self.loadValues,
           tipText=tipText, grid=(row,2), sticky='ew')
     
    row += 1

    tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis'
    label = Label(frame, text='Point values: ')
    label.grid(row=row, column=0, sticky='e')
    self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText)
    #minRows = self.params.npts[self.dim]
    #self.valueEntry = MultiWidget(frame, FloatEntry, callback=None, minRows=minRows, maxRows=None,
    #                              options=None, values=[], useImages=False)
    self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew')
    row += 1

    label = Label(frame, text='(requires comma-separated list, of length number of points)')
    label.grid(row=row, column=1, columnspan=2, sticky='w')
    row += 1

    for n in range(row):
      frame.rowconfigure(n, weight=1)
    frame.columnconfigure(1, weight=1)

    buttons = UtilityButtonList(master, closeText='Ok', closeCmd=self.updateParams,
                                helpUrl=self.help_url)
    buttons.grid(row=row, column=0, sticky='ew')
Exemplo n.º 11
0
class BackupProjectPopup(BasePopup):
    """
  **Create Automatic Project Backup**

  The purpose of this dialog is to allow the user to create backups
  of their project automatically.  The XML files for the backup go
  into a separate directory from the project itself.  If the project
  directory is called PROJECTDIR then the default for the backup
  directory is PROJECTDIR_backup, although that can be changed to
  something else in this dialog.

  Other than the backup directory, the user can specify the frequency
  of the backup, in minutes.

  The "Apply Auto Settings" does not have to be applied if the user
  has changed the on/off setting or if the user has changed the
  Auto-backup frequency and entered a carriage return.

  The "Do Immediate Backup" is in case the user wants to do a backup
  then and there.

  There is no backup for the backup.
  """

    on_off_entries = ['on', 'off']

    def __init__(self, parent, help_msg='', help_url='', *args, **kw):

        self.help_msg = help_msg
        self.help_url = help_url

        BasePopup.__init__(self, parent=parent, title='Project : Backup', **kw)

    def body(self, guiFrame):

        self.geometry('500x130')

        guiFrame.grid_columnconfigure(2, weight=1)
        guiFrame.grid_rowconfigure(3, weight=1)

        self.alarm_id = None

        row = 0
        tipText = 'Browse for the directory into which project backups will be made'
        button = Button(guiFrame,
                        text='Directory:',
                        command=self.selectDir,
                        grid=(row, 0),
                        tipText=tipText,
                        sticky='ew')

        repository = self.project.findFirstRepository(name='backup')
        if repository:
            text = repository.url.path
        else:  # this is trouble, but should not happen
            text = ''

        tipText = 'Enter the name of the directory into which project backups will be made'
        self.dir_entry = Entry(guiFrame,
                               text=text,
                               tipText=tipText,
                               width=40,
                               returnCallback=self.applyAuto,
                               grid=(row, 1),
                               gridSpan=(1, 2),
                               sticky='ew')

        row += 1
        label = Label(guiFrame, text='Auto-backup:', grid=(row, 0))
        if self.analysisProject.doAutoBackup:
            ind = 0
        else:
            ind = 1

        tipTexts = [
            'Toggle the timed automatic backup on',
            'Toggle the timed automatic backup off'
        ]
        self.on_off_buttons = RadioButtons(guiFrame,
                                           entries=self.on_off_entries,
                                           tipTexts=tipTexts,
                                           select_callback=self.applyAuto,
                                           selected_index=ind,
                                           grid=(row, 1))

        row += 1
        tipText = 'The number of minutes to wait before automatic project backups'
        label = Label(guiFrame, text='Auto-backup frequency:', grid=(row, 0))

        self.freq_entry = IntEntry(guiFrame,
                                   text=self.analysisProject.autoBackupFreq,
                                   returnCallback=self.applyAuto,
                                   tipText=tipText)
        self.freq_entry.grid(row=row, column=1)

        label = Label(guiFrame, text=' (minutes)', grid=(row, 2))

        row = row + 1
        # Blank for expansion

        row = row + 1
        texts = ['Apply Auto Settings', 'Do Immediate Backup']
        commands = [self.applyAuto, self.applyManual]
        tipTexts = [
            'Commit the specified settings and commence automated CCPN project backup',
            'Backup the CCPN project now, into the specified backup directory'
        ]
        buttons = UtilityButtonList(guiFrame,
                                    texts=texts,
                                    commands=commands,
                                    doClone=False,
                                    helpMsg=self.help_msg,
                                    helpUrl=self.help_url,
                                    tipTexts=tipTexts,
                                    grid=(row, 0),
                                    gridSpan=(1, 3),
                                    sticky='nsew')

    def selectDir(self):

        popup = FileSelectPopup(self, show_file=False)
        dir = popup.getDirectory()
        popup.destroy()

        if (dir):
            self.dir_entry.set(dir)
            self.setDir()

    def setDir(self):

        directory = self.dir_entry.get()
        if not directory:
            showWarning('No directory',
                        'No directory specified, not setting backup directory',
                        parent=self)
            return

        if not os.path.abspath(directory):
            directory = joinPath(os.getcwd(), directory)

        if os.path.exists(directory):
            if not os.path.isdir(directory):
                showWarning('Path not directory',
                            'Path "%s" exists but is not a directory' %
                            directory,
                            parent=self)
                return
        else:
            if showYesNo(
                    'Directory does not exist',
                    'Directory "%s" does not exist, should it be created?' %
                    directory,
                    parent=self):
                os.mkdir(directory)
            else:
                showWarning(
                    'Directory not created',
                    'Directory "%s" not created so not setting backup directory'
                    % directory,
                    parent=self)
                return

        repository = self.project.findFirstRepository(name='backup')
        if not repository:
            showWarning(
                'No backup repository',
                'No backup repository found (something wrong somewhere)',
                parent=self)
            return

        url = repository.url
        if url.path != directory:
            repository.url = Url(path=normalisePath(directory))

    def setFreq(self):

        freq = self.freq_entry.get()

        if (freq is None):
            freq = 0

        self.analysisProject.autoBackupFreq = freq

    def setInfo(self):

        self.setFreq()
        self.setDir()

        on_off = (self.on_off_buttons.get() == 'on')
        self.analysisProject.doAutoBackup = on_off

    def applyAuto(self, *event):

        self.setInfo()
        on_off = self.on_off_buttons.get()
        if on_off == 'on':
            self.parent.setBackupOn()
        else:
            self.parent.setBackupOff()

    def applyManual(self):

        self.setDir()
        self.parent.doBackup()
Exemplo n.º 12
0
class BrukerPseudoPopup(BasePopup):

  def __init__(self, parent, params, dim, *args, **kw):

    self.dim = dim
    self.params = params

    BasePopup.__init__(self, parent=parent, title='Bruker Pseudo Data', modal=True, **kw)

  def body(self, master):

    pseudoExpts = getSampledDimExperiments(self.parent.nmrProject)

    master.rowconfigure(0, weight=1)
    master.rowconfigure(1, weight=1)
    master.columnconfigure(0, weight=1)

    tipTexts = ['The experiment is pseudo-N dimensional, with a sampled axis',
                'The experiment is the regular kind with only NMR frequency axes']
    self.pseudoEntries = [x % len(self.params.npts) for x in PSEUDO_ENTRIES]            
    self.pseudoButton = RadioButtons(master, entries=self.pseudoEntries,
                                     select_callback=self.changedPseudoMode,
                                     grid=(0,0), sticky='nw', tipTexts=tipTexts)

    frame = self.pseudoFrame = Frame(master)
    self.pseudoFrame.grid(row=1, column=0, sticky='nsew')

    row = 0
    if pseudoExpts:
      tipText = 'Select from existing pseudo nD experiments to copy sampled axis values from'
      texts = [x.name for x in pseudoExpts]
      label = Label(frame, text='Existing pseudo expts: ')
      label.grid(row=row, column=0, sticky='e')
      self.pseudoList = PulldownList(frame, texts=texts, objects=pseudoExpts, tipText=tipText)
      self.pseudoList.grid(row=row, column=1, sticky='w')
      tipText = 'Transfer the sampled axis values from the existing experiment to the new one'
      Button(frame, text='Copy values down', command=self.copyValues,
             tipText=tipText, grid=(row,2))
      
      row += 1

    npts = self.params.npts[self.dim]
    tipText = 'Number of data points (planes) along sampled axis'
    label = Label(frame, text='Number of points: ')
    label.grid(row=row, column=0, sticky='e')
    self.nptsEntry = IntEntry(frame, text=npts, tipText=tipText, width=8, grid=(row,1))
     
    tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values'
    Button(frame, text='Load File', command=self.loadValues,
           tipText=tipText, grid=(row,2), sticky='ew')
     
    row += 1

    tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis'
    label = Label(frame, text='Point values: ')
    label.grid(row=row, column=0, sticky='e')
    self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText)
    #minRows = self.params.npts[self.dim]
    #self.valueEntry = MultiWidget(frame, FloatEntry, callback=None, minRows=minRows, maxRows=None,
    #                              options=None, values=[], useImages=False)
    self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew')
    row += 1

    label = Label(frame, text='(requires comma-separated list, of length number of points)')
    label.grid(row=row, column=1, columnspan=2, sticky='w')
    row += 1

    for n in range(row):
      frame.rowconfigure(n, weight=1)
    frame.columnconfigure(1, weight=1)

    buttons = UtilityButtonList(master, closeText='Ok', closeCmd=self.updateParams,
                                helpUrl=self.help_url)
    buttons.grid(row=row, column=0, sticky='ew')

  def loadValues(self):
  
    directory = self.parent.fileSelect.getDirectory()
    fileSelectPopup = FileSelectPopup(self, title='Select Sampled Data File',
                                      dismiss_text='Cancel',
                                      selected_file_must_exist=True,
                                      multiSelect=False,
                                      directory=directory)
 

    fileName = fileSelectPopup.file_select.getFile()
    
    fileObj = open(fileName, 'rU')
    
    data = ''
    line = fileObj.readline()
    while line:
      data += line
      line = fileObj.readline()
    
    data = re.sub(',\s+', ',', data)
    data = re.sub('\s+', ',', data)
    data = re.sub(',,', ',', data)
    data = re.sub('[^0-9,.\-+eE]', '', data)
      
    self.valueEntry.set(data)

  def copyValues(self):

    expt = self.pseudoList.getObject()
    if expt:
      dataDim = getExperimentSampledDim(expt)
      values = dataDim.pointValues
      self.nptsEntry.set(len(values))
      self.valueEntry.set(values)

  def updateParams(self):

    params = self.params
    if self.pseudoButton.get() == self.pseudoEntries[0]:
      npts = self.nptsEntry.get()
      params.npts[self.dim] = npts
      values = self.valueEntry.get()
      try:
        params.setSampledDim(self.dim, values)
      except ApiError, e:
        showError('Set Sampled Dim', e.error_msg, parent=self)
        return
    else:
Exemplo n.º 13
0
class EditContourLevelsPopup(BasePopup):
    """
  **Change Levels in Spectrum Contour Displays**
  
  This popup window is used to specify which contour levels (lines of constant
  intensity) are drawn for spectra within the spectrum windows of Analysis. A
  spectrum can have both positive and negative levels, and the user can set
  these on an individual basis or as a regular incremental (usually geometric)
  series. It should be noted that spectrum contour colours, which may be
  different for positive and negative levels, is set elsewhere, in the main
  Spectra_ table.

  In normal operation the user first selects the spectrum to change the contours
  for in the upper left pulldown menu. Although contour levels are specified 
  for individual spectra, if there are several spectra that share the same
  levels (for example if they form a series of some kind) then the user may
  spread the contour level information from one to many via the [Propagate
  Contours] function within the "Display Options" of the main Spectra_ table.
  The user may also affect the contour levels of multiple spectra by changing
  the "Global scale" settings. This global scale will affect *all spectra* in
  the project; the scale value multiplies all of the contour levels for all
  spectra, although in practice it is rarely changed. Using a global scale gives
  the advantage of being able to specify smaller numbers for the levels. 

  The individual contour levels for a spectrum are listed in the "positive
  levels" and "Negative levels" fields. They are multiplied by the global scale
  factor when they are used for spectrum display. The user may type in values
  for the levels directly into these field, or they can be filled using the
  "Auto contour levels" mechanism. If manual levels are specified the user
  should press [Apply manual Levels] when done to commit the changes and see the
  results. The [Apply Auto Levels] function differs in that it always applies a
  regular series of levels, according to the settings, and these will overwrite
  any manual specifications when committed; the actual levels applied are always
  displayed in the levels field.

  The setting of "Auto" levels using a series involves choosing a base level,
  which represents the first contour (closest to zero). This base level is
  usually set according to the level of noise in the spectrum. Typically it is a
  value just above most of the noise, so the noise is not seen, but it may be
  set lower in some instances to show weak signals. The base level applies to
  both positive and negative contour series, although for the negative side it
  is naturally used with negative sign. The user sets how many levels there should be in total; the subsequent levels
  start from the base level and move away from zero. Normally this involves a
  geometric series, with a constant multiplication factor applied to a value to
  generate the next in the series. This factor is set in the "Level multiplier",
  although some of the commonly used values are quickly set via the adjacent
  buttons. Under a few special circumstances it is helpful to  have a constant
  difference  between levels, in which case "Add levels" may be used instead of
  "Multiply levels". 

  **Caveats & Tips**

  Often it is useful to initially setup contours using an "Auto" series, but
  then manually remove some of the levels. For example having all the positive
  levels but only the first negative level may be helpful to show where peaks
  are truncated.

  Note this system sets the levels that would be used to make any contour files
  (an optional way of working, especially for 4D spectra etc.). However,
  once contour files are made then this system will not affect the levels
  within the files.

  .. _Spectra: EditSpectrumPopup.html

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

        BasePopup.__init__(self,
                           parent=parent,
                           title='Spectrum Contour Levels',
                           **kw)

    def body(self, guiFrame):

        self.doUpdateForm = True
        self.spectrum = None

        guiFrame.grid_columnconfigure(1, weight=1)

        row = 0

        specFrame = LabelFrame(guiFrame, text='Spectrum', grid=(row, 0))

        tipText = 'The spectrum for which you are setting the contour levels'
        self.expt_spectrum = PulldownList(specFrame,
                                          grid=(0, 0),
                                          tipText=tipText,
                                          callback=self.setSpectrumDetails)

        tipText = 'Open the edit spectrum table to view and change other properties associated with the selected spectrum'
        button = Button(specFrame,
                        text='Spectrum Properties',
                        command=self.editProperties,
                        borderwidth=1,
                        grid=(1, 0),
                        sticky='ew',
                        tipText=tipText)

        globalFrame = LabelFrame(guiFrame, text='Global scale')
        globalFrame.grid(row=row, column=1, sticky='nsew')
        globalFrame.grid_columnconfigure(0, weight=1)

        tipText = 'The value by which all contour levels in all spectra are multiplied; to give the actual contour level in terms of the stored spectrum data'
        self.global_entry = FloatEntry(
            globalFrame,
            width=10,
            tipText=tipText,
            text=self.analysisProject.globalContourScale,
            returnCallback=self.applyAuto,
            grid=(0, 0),
            gridSpan=(1, 2),
            sticky='ew')

        tipText = 'Divide the global scaling factor by two; moving all contour for all spectra levels closer to zero'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='/2',
                        sticky='ew',
                        tipText=tipText,
                        command=lambda: self.changeGlobalScale(0.5),
                        grid=(0, 2))

        tipText = 'Multiple the global scaling factor by two; moving all contour for all spectra levels away from zero'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='*2',
                        sticky='ew',
                        tipText=tipText,
                        command=lambda: self.changeGlobalScale(2.0),
                        grid=(0, 3))

        tipText = 'Set the global contour scale for all spectra to the default of 100,000'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='10^5',
                        tipText=tipText,
                        command=self.defaultGlobalScale,
                        grid=(1, 0))

        tipText = 'Click to decrease "-" or increase "+" the global contour scale by small amounts'
        frame = ValueRamp(globalFrame,
                          callback=self.changeGlobalScale,
                          tipText=tipText)
        frame.grid(row=1, column=1, columnspan=3, sticky='e')

        row += 1
        self.autoFrame = LabelFrame(guiFrame, text='Auto contour levels')
        self.autoFrame.grid(row=row, column=0, columnspan=5, sticky='nsew')
        self.autoFrame.grid_columnconfigure(1, weight=1)
        frow = 0

        label = Label(self.autoFrame,
                      text='Base level:',
                      grid=(frow, 0),
                      sticky='e')

        tipText = 'The first contour level (closest to zero) for an automated series of levels: the start of a geometric or arithmetic series defining levels'
        self.base_entry = FloatEntry(self.autoFrame,
                                     returnCallback=self.applyAuto,
                                     width=10,
                                     grid=(frow, 1),
                                     sticky='ew',
                                     tipText=tipText)

        command = lambda: self.changeBaseLevel(0.5)
        tipText = 'Lower the base contour level so that it is half of the previous value; moving the series of contour levels closer to zero'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='/2',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 2),
                        sticky='ew')

        command = lambda: self.changeBaseLevel(2.0)
        tipText = 'Raise the base contour level so that it is double the previous value; moving the series of contour levels further from zero'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='*2',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 3),
                        sticky='ew')

        tipText = 'Click to decrease "-" or increase "+" the base contour level by small amounts'
        frame = ValueRamp(self.autoFrame,
                          callback=self.changeBaseLevel,
                          tipText=tipText)
        frame.grid(row=frow, column=4, columnspan=3, sticky='ew')

        frow += 1
        label = Label(self.autoFrame,
                      text='Number of levels:',
                      grid=(frow, 0),
                      sticky='e')
        #self.numberEntry = IntEntry(guiFrame, text=numberLevels,
        #                            returnCallback=self.applyAuto)
        tipText = 'The number of contour levels to make in the automated series'
        self.numberEntry = IntEntry(self.autoFrame,
                                    returnCallback=self.applyAuto,
                                    width=10,
                                    grid=(frow, 1),
                                    sticky='ew',
                                    tipText=tipText)

        command = lambda w=-1: self.changeNumberLevels(w)
        tipText = 'Decrease the number of contour levels in the series by one'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='-1',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 2),
                        sticky='ew')

        command = lambda w=1: self.changeNumberLevels(w)
        tipText = 'Increase the number of contour levels in the series by one'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='+1',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 3),
                        sticky='ew')

        n = 4
        for w in (5, 10, 15, 20):
            tipText = 'Set the number of contour levels in the series to %d' % w
            command = lambda w=w: self.setNumberLevels(w)
            button = Button(self.autoFrame,
                            borderwidth=1,
                            text='%d' % w,
                            command=command,
                            grid=(frow, n),
                            sticky='ew',
                            tipText=tipText)
            n += 1

        frow += 1
        self.change_label = Label(self.autoFrame,
                                  text='%s:' % multiplier_text,
                                  grid=(frow, 0),
                                  sticky='e')

        tipText = 'The multiplication factor (or increment if adding levels) to repetitively apply to the base level to generate the series of levels'
        self.change_entry = FloatEntry(self.autoFrame,
                                       returnCallback=self.applyAuto,
                                       width=10,
                                       grid=(frow, 1),
                                       sticky='ew',
                                       tipText=tipText)

        self.change_level_buttons = []
        n = 2
        for w in multiplier_changes:
            tipText = 'Set the automated series multiplication factor or increment to %f' % w
            command = lambda w=w: self.setChange(w)
            button = Button(self.autoFrame,
                            borderwidth=1,
                            text=str(w),
                            command=command,
                            grid=(frow, n),
                            sticky='ew',
                            tipText=tipText)
            self.change_level_buttons.append(button)
            n += 1

        frow += 1
        frame = Frame(self.autoFrame,
                      grid=(frow, 0),
                      gridSpan=(1, 7),
                      sticky='ew')

        tipTexts = [
            'Toggles whether positive contour levels from the automated series will be used. Overrides any manual settings',
            'Toggles whether negative contour levels from the automated series will be used. Overrides any manual settings'
        ]
        entries = ('Positive', 'Negative')
        selected = (True, False)
        self.which_buttons = CheckButtons(frame,
                                          entries,
                                          selected=selected,
                                          select_callback=self.applyAuto,
                                          grid=(0, 0),
                                          sticky='w',
                                          tipTexts=tipTexts)

        tipTexts = [
            'Set the contour level generation to use a geometric series, starting from the base level and using the specified factor',
            'Set the contour level generation to use an arithmetic series, starting from the base level and using the specified increment'
        ]
        entries = ('Multiply levels', 'Add levels')
        self.change_mode_buttons = RadioButtons(
            frame,
            entries,
            grid=(0, 1),
            sticky='ew',
            select_callback=self.modeChanged,
            tipTexts=tipTexts)

        row += 1
        manualFrame = LabelFrame(guiFrame,
                                 text='Positive levels',
                                 grid=(row, 0),
                                 gridSpan=(1, 2))
        manualFrame.expandGrid(None, 0)
        tipText = 'The positive contour levels that will be used for the spectrum; filled in by the automation or set/modified manually'
        self.posLevelsEntry = FloatEntry(manualFrame,
                                         isArray=True,
                                         width=60,
                                         returnCallback=self.applyManual,
                                         tipText=tipText,
                                         grid=(0, 0),
                                         sticky='ew')

        row += 1
        manualFrame = LabelFrame(guiFrame,
                                 text='Negative levels',
                                 grid=(row, 0),
                                 gridSpan=(1, 2))
        manualFrame.expandGrid(None, 0)
        tipText = 'The negative contour levels that will be used for the spectrum; filled in by the automation or set/modified manually'
        self.negLevelsEntry = FloatEntry(manualFrame,
                                         isArray=True,
                                         width=60,
                                         returnCallback=self.applyManual,
                                         tipText=tipText,
                                         grid=(0, 0),
                                         sticky='ew')

        row += 1
        tipTexts = [
            'Set the spectrum contour levels, updating the display, to the automated series, ignoring any manual edits.',
            'Set the spectrum contour levels, updating the display, to the values displayed in the level entry fields'
        ]
        texts = ['Apply Auto Levels', 'Apply Manual Edits']
        commands = [self.applyAuto, self.applyManual]
        self.buttons = UtilityButtonList(guiFrame,
                                         texts=texts,
                                         commands=commands,
                                         helpUrl=self.help_url,
                                         grid=(row, 0),
                                         gridSpan=(1, 2),
                                         tipTexts=tipTexts)
        guiFrame.grid_rowconfigure(row, weight=1)

        self.curateNotifiers(self.registerNotify)
        self.update()

    def update(self, spectrum=None):

        if not spectrum:
            spectrum = self.spectrum

        spectra = self.parent.getSpectra()
        if spectra:
            if spectrum not in spectra:
                spectrum = spectra[0]
            index = spectra.index(spectrum)
            names = ['%s:%s' % (x.experiment.name, x.name) for x in spectra]
        else:
            index = 0
            names = []

        self.expt_spectrum.setup(names, spectra, index)

        self.setSpectrumDetails(spectrum)

    def updateNotifier(self, *extra):

        self.update()

    def open(self):

        self.updateForm()
        BasePopup.open(self)

    def modeChanged(self, *entry):

        spectrum = self.spectrum
        if not spectrum or spectrum.isDeleted:
            return

        analysisSpectrum = spectrum.analysisSpectrum

        changeMode = self.change_mode_buttons.getIndex(
        ) and 'add' or 'multiply'
        if changeMode == 'add':
            text = adder_text
            changes = adder_changes
        else:
            text = multiplier_text
            changes = multiplier_changes

        self.change_label.set('%s:' % text)
        n = 0
        for button in self.change_level_buttons:
            w = changes[n]
            command = lambda w=w: self.setChange(w)
            button.config(command=command)
            button.setText(str(w))
            n = n + 1

        levelChanger = changes[2]
        self.doUpdateForm = False

        analysisSpectrum.autoLevelChanger = levelChanger
        analysisSpectrum.autoLevelMode = changeMode

        self.doUpdateForm = True
        self.setContourLevels()

    def defaultGlobalScale(self):

        self.global_entry.set(100000)
        self.applyAuto()

    def close(self):

        self.applyManual()
        BasePopup.close(self)

    def destroy(self):

        self.curateNotifiers(self.unregisterNotify)

        BasePopup.destroy(self)

    def curateNotifiers(self, notifyFunc):

        notifyFunc(self.updateContourLevels,
                   'ccpnmr.Analysis.AnalysisSpectrum', 'setPosLevels')
        notifyFunc(self.updateContourLevels,
                   'ccpnmr.Analysis.AnalysisSpectrum', 'setNegLevels')
        notifyFunc(self.updateForm, 'ccpnmr.Analysis.AnalysisSpectrum',
                   'setAutoLevelChanger')
        notifyFunc(self.updateForm, 'ccpnmr.Analysis.AnalysisSpectrum',
                   'setAutoLevelMode')
        notifyFunc(self.updateForm, 'ccpnmr.Analysis.AnalysisSpectrum',
                   'setAutoNumLevels')
        notifyFunc(self.updateForm, 'ccpnmr.Analysis.AnalysisSpectrum',
                   'setAutoBaseLevel')

        notifyFunc(self.updateForm, 'ccpnmr.Analysis.AnalysisProject',
                   'setGlobalContourScale')

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

    def editProperties(self):

        self.parent.editSpectrum(self.spectrum)

    def updateForm(self, *extra):

        #print 'updateForm'
        if (not self.doUpdateForm):
            return

        self.global_entry.set(self.analysisProject.globalContourScale)
        spectrum = self.spectrum
        if spectrum and not spectrum.isDeleted:
            analysisSpectrum = spectrum.analysisSpectrum

            self.base_entry.set(analysisSpectrum.autoBaseLevel)
            self.numberEntry.set(analysisSpectrum.autoNumLevels)
            self.change_entry.set(analysisSpectrum.autoLevelChanger)

            if analysisSpectrum.autoLevelMode == 'add':
                i = 1
            else:
                i = 0

            self.change_mode_buttons.setIndex(i)

    def updateContourLevels(self, analysisSpectrum):

        spectrum = self.spectrum
        if spectrum and not spectrum.isDeleted:
            analysisSpectrum = spectrum.analysisSpectrum

            posLevels = list(analysisSpectrum.posLevels)
            negLevels = list(analysisSpectrum.negLevels)

            self.posLevelsEntry.set(posLevels)
            self.negLevelsEntry.set(negLevels)

            self.doUpdateForm = False
            updateSpectrumLevelParams(analysisSpectrum, posLevels, negLevels)

            self.doUpdateForm = True
            self.base_entry.set(analysisSpectrum.autoBaseLevel)
            self.numberEntry.set(analysisSpectrum.autoNumLevels)
            self.change_entry.set(analysisSpectrum.autoLevelChanger)

            self.setWhichLevels(spectrum)

            if analysisSpectrum.autoLevelMode == 'add':
                i = 1
            else:
                i = 0

            self.change_mode_buttons.setIndex(i)

    def setWhichLevels(self, spectrum):

        analysisSpectrum = spectrum.analysisSpectrum

        posLevels = analysisSpectrum.posLevels
        negLevels = analysisSpectrum.negLevels

        if posLevels:
            isSelected = True
        else:
            isSelected = False
        self.which_buttons.setIndexSelection(0, isSelected)

        if negLevels:
            isSelected = True
        else:
            isSelected = False

        self.which_buttons.setIndexSelection(1, isSelected)

    def setSpectrum(self, spectrum):

        if spectrum is not self.spectrum:
            self.update(spectrum)

        #if (spectrum and not spectrum.isDeleted):
        #  self.setWhichLevels(spectrum)

    speed_scale = 6.0
    speed_delay = 50  # msec

    def changeGlobalScale(self, multiplier):

        self.analysisProject.globalContourScale = multiplier * self.analysisProject.globalContourScale

    def changeBaseLevel(self, multiplier):

        spectrum = self.spectrum
        if (not spectrum or spectrum.isDeleted is True):
            return

        analysisSpectrum = spectrum.analysisSpectrum
        baseLevel = multiplier * analysisSpectrum.autoBaseLevel
        self.base_entry.set(baseLevel)
        self.doUpdateForm = False

        analysisSpectrum.autoBaseLevel = abs(baseLevel)

        self.doUpdateForm = True
        self.setContourLevels()

    def changeNumberLevels(self, change):

        spectrum = self.spectrum
        if not spectrum or spectrum.isDeleted is True:
            return

        analysisSpectrum = spectrum.analysisSpectrum
        numberLevels = analysisSpectrum.autoNumLevels + change
        self.numberEntry.set(numberLevels)
        self.doUpdateForm = False

        analysisSpectrum.autoNumLevels = numberLevels

        self.doUpdateForm = True
        self.setContourLevels()

    def setChange(self, levelChanger):

        spectrum = self.spectrum
        if not spectrum or spectrum.isDeleted:
            return

        self.doUpdateForm = False
        analysisSpectrum = spectrum.analysisSpectrum
        analysisSpectrum.autoLevelChanger = levelChanger
        self.doUpdateForm = True

        self.setContourLevels()

    def setNumberLevels(self, numberLevels):

        spectrum = self.spectrum
        if (not spectrum or spectrum.isDeleted is True):
            return

        self.doUpdateForm = False
        analysisSpectrum = spectrum.analysisSpectrum
        analysisSpectrum.autoNumLevels = numberLevels
        self.doUpdateForm = True

        self.setContourLevels()

    def setSpectrumDetails(self, spectrum):

        if spectrum is self.spectrum:
            return

        self.spectrum = spectrum
        if spectrum and not spectrum.isDeleted:
            analysisSpectrum = spectrum.analysisSpectrum

            posLevels = list(analysisSpectrum.posLevels)
            negLevels = list(analysisSpectrum.negLevels)

            self.posLevelsEntry.set(posLevels)
            self.negLevelsEntry.set(negLevels)

            self.doUpdateForm = False
            updateSpectrumLevelParams(analysisSpectrum, posLevels, negLevels)

            self.doUpdateForm = True
            self.base_entry.set(analysisSpectrum.autoBaseLevel)
            self.numberEntry.set(analysisSpectrum.autoNumLevels)
            self.change_entry.set(analysisSpectrum.autoLevelChanger)
            self.autoFrame.setText('Auto contour levels - %s:%s' %
                                   (spectrum.experiment.name, spectrum.name))
            self.setWhichLevels(spectrum)

        else:
            self.posLevelsEntry.set('')
            self.negLevelsEntry.set('')
            self.autoFrame.setText('Auto contour levels')

    def setContourLevels(self):

        spectrum = self.spectrum
        if not spectrum or spectrum.isDeleted is True:
            return

        try:
            analysisSpectrum = spectrum.analysisSpectrum
            baseLevel = analysisSpectrum.autoBaseLevel
            numberLevels = analysisSpectrum.autoNumLevels
            levelChanger = analysisSpectrum.autoLevelChanger
            changeMode = analysisSpectrum.autoLevelMode

            posLevels = []
            if self.which_buttons.isIndexSelected(0):
                posLevels.extend(
                    calcContourLevels(baseLevel, numberLevels, levelChanger,
                                      changeMode))

            negLevels = []
            if self.which_buttons.isIndexSelected(1):
                if changeMode == 'add':
                    levelChanger = -levelChanger
                negLevels.extend(
                    calcContourLevels(-baseLevel, numberLevels, levelChanger,
                                      changeMode))

            self.posLevelsEntry.set(posLevels)
            self.negLevelsEntry.set(negLevels)
            analysisSpectrum.posLevels = posLevels
            analysisSpectrum.negLevels = negLevels

        except Implementation.ApiError, e:
            showError('Contour levels error', e.error_msg, parent=self)
Exemplo n.º 14
0
    def body(self, guiFrame):

        self.doUpdateForm = True
        self.spectrum = None

        guiFrame.grid_columnconfigure(1, weight=1)

        row = 0

        specFrame = LabelFrame(guiFrame, text='Spectrum', grid=(row, 0))

        tipText = 'The spectrum for which you are setting the contour levels'
        self.expt_spectrum = PulldownList(specFrame,
                                          grid=(0, 0),
                                          tipText=tipText,
                                          callback=self.setSpectrumDetails)

        tipText = 'Open the edit spectrum table to view and change other properties associated with the selected spectrum'
        button = Button(specFrame,
                        text='Spectrum Properties',
                        command=self.editProperties,
                        borderwidth=1,
                        grid=(1, 0),
                        sticky='ew',
                        tipText=tipText)

        globalFrame = LabelFrame(guiFrame, text='Global scale')
        globalFrame.grid(row=row, column=1, sticky='nsew')
        globalFrame.grid_columnconfigure(0, weight=1)

        tipText = 'The value by which all contour levels in all spectra are multiplied; to give the actual contour level in terms of the stored spectrum data'
        self.global_entry = FloatEntry(
            globalFrame,
            width=10,
            tipText=tipText,
            text=self.analysisProject.globalContourScale,
            returnCallback=self.applyAuto,
            grid=(0, 0),
            gridSpan=(1, 2),
            sticky='ew')

        tipText = 'Divide the global scaling factor by two; moving all contour for all spectra levels closer to zero'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='/2',
                        sticky='ew',
                        tipText=tipText,
                        command=lambda: self.changeGlobalScale(0.5),
                        grid=(0, 2))

        tipText = 'Multiple the global scaling factor by two; moving all contour for all spectra levels away from zero'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='*2',
                        sticky='ew',
                        tipText=tipText,
                        command=lambda: self.changeGlobalScale(2.0),
                        grid=(0, 3))

        tipText = 'Set the global contour scale for all spectra to the default of 100,000'
        button = Button(globalFrame,
                        borderwidth=1,
                        text='10^5',
                        tipText=tipText,
                        command=self.defaultGlobalScale,
                        grid=(1, 0))

        tipText = 'Click to decrease "-" or increase "+" the global contour scale by small amounts'
        frame = ValueRamp(globalFrame,
                          callback=self.changeGlobalScale,
                          tipText=tipText)
        frame.grid(row=1, column=1, columnspan=3, sticky='e')

        row += 1
        self.autoFrame = LabelFrame(guiFrame, text='Auto contour levels')
        self.autoFrame.grid(row=row, column=0, columnspan=5, sticky='nsew')
        self.autoFrame.grid_columnconfigure(1, weight=1)
        frow = 0

        label = Label(self.autoFrame,
                      text='Base level:',
                      grid=(frow, 0),
                      sticky='e')

        tipText = 'The first contour level (closest to zero) for an automated series of levels: the start of a geometric or arithmetic series defining levels'
        self.base_entry = FloatEntry(self.autoFrame,
                                     returnCallback=self.applyAuto,
                                     width=10,
                                     grid=(frow, 1),
                                     sticky='ew',
                                     tipText=tipText)

        command = lambda: self.changeBaseLevel(0.5)
        tipText = 'Lower the base contour level so that it is half of the previous value; moving the series of contour levels closer to zero'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='/2',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 2),
                        sticky='ew')

        command = lambda: self.changeBaseLevel(2.0)
        tipText = 'Raise the base contour level so that it is double the previous value; moving the series of contour levels further from zero'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='*2',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 3),
                        sticky='ew')

        tipText = 'Click to decrease "-" or increase "+" the base contour level by small amounts'
        frame = ValueRamp(self.autoFrame,
                          callback=self.changeBaseLevel,
                          tipText=tipText)
        frame.grid(row=frow, column=4, columnspan=3, sticky='ew')

        frow += 1
        label = Label(self.autoFrame,
                      text='Number of levels:',
                      grid=(frow, 0),
                      sticky='e')
        #self.numberEntry = IntEntry(guiFrame, text=numberLevels,
        #                            returnCallback=self.applyAuto)
        tipText = 'The number of contour levels to make in the automated series'
        self.numberEntry = IntEntry(self.autoFrame,
                                    returnCallback=self.applyAuto,
                                    width=10,
                                    grid=(frow, 1),
                                    sticky='ew',
                                    tipText=tipText)

        command = lambda w=-1: self.changeNumberLevels(w)
        tipText = 'Decrease the number of contour levels in the series by one'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='-1',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 2),
                        sticky='ew')

        command = lambda w=1: self.changeNumberLevels(w)
        tipText = 'Increase the number of contour levels in the series by one'
        button = Button(self.autoFrame,
                        borderwidth=1,
                        text='+1',
                        tipText=tipText,
                        command=command,
                        grid=(frow, 3),
                        sticky='ew')

        n = 4
        for w in (5, 10, 15, 20):
            tipText = 'Set the number of contour levels in the series to %d' % w
            command = lambda w=w: self.setNumberLevels(w)
            button = Button(self.autoFrame,
                            borderwidth=1,
                            text='%d' % w,
                            command=command,
                            grid=(frow, n),
                            sticky='ew',
                            tipText=tipText)
            n += 1

        frow += 1
        self.change_label = Label(self.autoFrame,
                                  text='%s:' % multiplier_text,
                                  grid=(frow, 0),
                                  sticky='e')

        tipText = 'The multiplication factor (or increment if adding levels) to repetitively apply to the base level to generate the series of levels'
        self.change_entry = FloatEntry(self.autoFrame,
                                       returnCallback=self.applyAuto,
                                       width=10,
                                       grid=(frow, 1),
                                       sticky='ew',
                                       tipText=tipText)

        self.change_level_buttons = []
        n = 2
        for w in multiplier_changes:
            tipText = 'Set the automated series multiplication factor or increment to %f' % w
            command = lambda w=w: self.setChange(w)
            button = Button(self.autoFrame,
                            borderwidth=1,
                            text=str(w),
                            command=command,
                            grid=(frow, n),
                            sticky='ew',
                            tipText=tipText)
            self.change_level_buttons.append(button)
            n += 1

        frow += 1
        frame = Frame(self.autoFrame,
                      grid=(frow, 0),
                      gridSpan=(1, 7),
                      sticky='ew')

        tipTexts = [
            'Toggles whether positive contour levels from the automated series will be used. Overrides any manual settings',
            'Toggles whether negative contour levels from the automated series will be used. Overrides any manual settings'
        ]
        entries = ('Positive', 'Negative')
        selected = (True, False)
        self.which_buttons = CheckButtons(frame,
                                          entries,
                                          selected=selected,
                                          select_callback=self.applyAuto,
                                          grid=(0, 0),
                                          sticky='w',
                                          tipTexts=tipTexts)

        tipTexts = [
            'Set the contour level generation to use a geometric series, starting from the base level and using the specified factor',
            'Set the contour level generation to use an arithmetic series, starting from the base level and using the specified increment'
        ]
        entries = ('Multiply levels', 'Add levels')
        self.change_mode_buttons = RadioButtons(
            frame,
            entries,
            grid=(0, 1),
            sticky='ew',
            select_callback=self.modeChanged,
            tipTexts=tipTexts)

        row += 1
        manualFrame = LabelFrame(guiFrame,
                                 text='Positive levels',
                                 grid=(row, 0),
                                 gridSpan=(1, 2))
        manualFrame.expandGrid(None, 0)
        tipText = 'The positive contour levels that will be used for the spectrum; filled in by the automation or set/modified manually'
        self.posLevelsEntry = FloatEntry(manualFrame,
                                         isArray=True,
                                         width=60,
                                         returnCallback=self.applyManual,
                                         tipText=tipText,
                                         grid=(0, 0),
                                         sticky='ew')

        row += 1
        manualFrame = LabelFrame(guiFrame,
                                 text='Negative levels',
                                 grid=(row, 0),
                                 gridSpan=(1, 2))
        manualFrame.expandGrid(None, 0)
        tipText = 'The negative contour levels that will be used for the spectrum; filled in by the automation or set/modified manually'
        self.negLevelsEntry = FloatEntry(manualFrame,
                                         isArray=True,
                                         width=60,
                                         returnCallback=self.applyManual,
                                         tipText=tipText,
                                         grid=(0, 0),
                                         sticky='ew')

        row += 1
        tipTexts = [
            'Set the spectrum contour levels, updating the display, to the automated series, ignoring any manual edits.',
            'Set the spectrum contour levels, updating the display, to the values displayed in the level entry fields'
        ]
        texts = ['Apply Auto Levels', 'Apply Manual Edits']
        commands = [self.applyAuto, self.applyManual]
        self.buttons = UtilityButtonList(guiFrame,
                                         texts=texts,
                                         commands=commands,
                                         helpUrl=self.help_url,
                                         grid=(row, 0),
                                         gridSpan=(1, 2),
                                         tipTexts=tipTexts)
        guiFrame.grid_rowconfigure(row, weight=1)

        self.curateNotifiers(self.registerNotify)
        self.update()
Exemplo n.º 15
0
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
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
class NmrPipePseudoPopup(BasePopup):

    pseudoEntries = ('Is Pseudo Expt', 'Is Not Pseudo Expt')

    def __init__(self, parent, params, dim, fileName='', *args, **kw):

        self.dim = dim
        self.params = params
        self.fileName = fileName

        m = template_re.match(fileName)
        if m:
            n = len(m.groups(2))
            ss = '%%0%dd' % n
            template = re.sub(template_re, r'\1%s\3' % ss, fileName)
        else:
            template = fileName
        self.template = template

        BasePopup.__init__(self,
                           parent=parent,
                           title='NMRPipe Pseudo Data',
                           modal=True,
                           **kw)

    def body(self, master):

        fileName = self.fileName
        directory = os.path.dirname(fileName)
        if not directory:
            directory = os.getcwd()
        fileName = os.path.basename(fileName)

        m = template_re.match(fileName)
        if m:
            n = len(m.groups(2))
            ss = '%%0%dd' % n
            template = re.sub(template_re, r'\1%s\3' % ss, fileName)
        else:
            template = fileName

        master.rowconfigure(0, weight=1)
        master.rowconfigure(1, weight=1)
        master.columnconfigure(1, weight=1)

        tipTexts = [
            'The experiment is pseudo-N dimensional, with a sampled axis',
            'The experiment is the regular kind with only NMR frequency axes'
        ]
        self.pseudoButton = RadioButtons(
            master,
            entries=self.pseudoEntries,
            select_callback=self.changedPseudoMode,
            grid=(0, 0),
            sticky='nw',
            tipTexts=tipTexts)

        frame = self.pseudoFrame = Frame(master)
        self.pseudoFrame.grid(row=1, column=0, sticky='nsew')

        row = 0
        npts = self.params.npts[self.dim]
        tipText = 'Number of data points (planes) along sampled axis'
        label = Label(frame, text='Number of points: ')
        label.grid(row=row, column=0, sticky='e')
        self.nptsEntry = IntEntry(frame,
                                  text=npts,
                                  tipText=tipText,
                                  width=8,
                                  grid=(row, 1))

        tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values'
        Button(frame,
               text='Load values from text file',
               command=self.loadValues,
               tipText=tipText,
               grid=(row, 2),
               sticky='ew')

        row = row + 1
        tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis'
        label = Label(frame, text='Point values: ')
        label.grid(row=row, column=0, sticky='e')
        self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText)
        self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        row = row + 1
        tipText = 'Fetch the Point values from the files given by the NMRPipe template'
        button = Button(
            frame,
            text='Fetch values from file(s) specified by template below',
            command=self.fetchValues,
            tipText=tipText)
        button.grid(row=row, column=1, columnspan=2, sticky='w')

        row = row + 1
        tipText = 'The directory where the data files reside'
        button = Button(frame,
                        text='Data directory: ',
                        command=self.chooseDirectory)
        button.grid(row=row, column=0, sticky='e')
        self.directoryEntry = Entry(frame,
                                    text=directory,
                                    width=40,
                                    tipText=tipText)
        self.directoryEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        row = row + 1
        tipText = 'The NMRPipe template for the data files, if you want to use these to fetch the point values from'
        button = Button(frame,
                        text='NMRPipe template: ',
                        command=self.chooseFile)
        button.grid(row=row, column=0, sticky='e')
        self.templateEntry = Entry(frame, text=template, tipText=tipText)
        self.templateEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        for n in range(row):
            frame.rowconfigure(n, weight=1)
        frame.columnconfigure(1, weight=1)

        buttons = UtilityButtonList(master,
                                    closeText='Ok',
                                    doClone=False,
                                    closeCmd=self.updateParams,
                                    helpUrl=self.help_url)
        buttons.grid(row=2, column=0, sticky='ew')

    def loadValues(self):

        directory = self.parent.fileSelect.getDirectory()
        fileSelectPopup = FileSelectPopup(self,
                                          title='Select Sampled Data File',
                                          dismiss_text='Cancel',
                                          selected_file_must_exist=True,
                                          multiSelect=False,
                                          directory=directory)

        fileName = fileSelectPopup.file_select.getFile()

        if not fileName:
            return

        fileObj = open(fileName, 'rU')

        data = ''
        line = fileObj.readline()
        while line:
            data += line
            line = fileObj.readline()

        fileObj.close()

        data = re.sub(',\s+', ',', data)
        data = re.sub('\s+', ',', data)
        data = re.sub(',,', ',', data)
        data = re.sub('[^0-9,.\-+eE]', '', data)

        self.valueEntry.set(data)

    def chooseDirectory(self):

        directory = os.path.dirname(self.fileName)
        if not directory:
            directory = os.getcwd()
        popup = FileSelectPopup(self, directory=directory, show_file=False)
        directory = popup.getDirectory()
        popup.destroy()

        if directory:
            self.directoryEntry.set(directory)

    def chooseFile(self):

        directory = self.directoryEntry.get()
        if not directory:
            directory = os.getcwd()
        popup = FileSelectPopup(self, directory=directory)
        file = popup.getFile()
        popup.destroy()

        if file:
            template = os.path.basename(file)
            self.templateEntry.set(template)

    def updateParams(self):

        params = self.params
        if self.pseudoButton.get() == self.pseudoEntries[0]:
            npts = self.nptsEntry.get()
            params.npts[self.dim] = npts
            values = self.valueEntry.get()
            try:
                params.setSampledDim(self.dim, values)
            except ApiError, e:
                showError('Set Sampled Dim', e.error_msg, parent=self)
                return
            params.fixNullDims(ignoreDim=self.dim)
        else:
Exemplo n.º 19
0
class AssignMentTransferTab(object):
    '''the tab in the GUI where assignments
       can be transferred in bulk to the ccpn analysis
       project. A difference is made between two types
       of assignments:
           1) spin systems to residues, which also
              implies resonanceSets to atomSets.
           2) resonances to peak dimensions.
       The user is able to configure which assignments
       should be transferred to the project.

      Attributes:

          guiParent: gui object this tab is part of.

          frame: the frame in which this element lives.

          dataModel(src.cython.malandro.DataModel): dataModel
              object describing the assignment proposed by
              the algorithm.

          selectedSolution (int): The index of the solution/run
              that is used asa the template to make the assignments.

          resonanceToDimension (bool): True if resonances should
              be assigned to peak dimensions. False if not.

          spinSystemToResidue (bool): True if spin system to
              residue assignment should be carried out.

          minScore (float): The minimal score of a spin system
              assignment to a residue to be allowed
              to transfer this assignment to the project

          intra (bool): True if intra-residual peaks should be
              assigned.

          sequential (bool): True if sequential peaks should be
              assigned.

          noDiagonal (bool): If True, purely diagonal peaks are
              ignored during the transfer of assignments.

          allSpectra (bool): If True, all spectra will be assigned.
              If False, one specified spectrum will be assigned.

          spectrum (src.cython.malandro.Spectrum): The spectrum
              that should be assigned.
    '''
    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

        # Buttons and fields,
        # will be set in body():
        self.peaksCheckButton = None
        self.residuesCheckButton = None
        self.intraCheckButton = None
        self.sequentialCheckButton = None
        self.noDiagonalCheckButton = None
        self.spinSystemTypeSelect = None
        self.minScoreEntry = None
        self.solutionNumberEntry = None
        self.spectrumSelect = None
        self.spectraPullDown = None
        self.assignedResidueStrategySelect = None
        self.transferButton = None

        # Settings that determine how assignments
        # are transferred to the analysis project:
        self.minScore = 80.0
        self.dataModel = None
        self.spectrum = None
        self.selectedSolution = 1
        self.body()
        self.resonanceToDimension = True
        self.spinSystemToResidue = True
        self.intra = True
        self.sequential = True
        self.noDiagonal = True
        self.allSpectra = True
        self.spinSystemType = 0
        self.strategy = 0

    def body(self):
        '''Describes the body of this tab. It consists
           out of a number of radio buttons, check buttons
           and number entries that allow the user to
           indicate which assignments should be transferred.
        '''

        # self.frame.expandColumn(0)
        self.frame.expandGrid(8, 0)
        self.frame.expandGrid(8, 1)

        typeOfAssignmentFrame = LabelFrame(self.frame,
                                           text='type of assignment')
        typeOfAssignmentFrame.grid(row=0, column=0, sticky='nesw')
        # typeOfAssignmentFrame.expandGrid(0,5)

        peakSelectionFrame = LabelFrame(self.frame,
                                        text='which peaks to assign')
        peakSelectionFrame.grid(row=0, column=1, sticky='nesw', rowspan=2)

        spinSystemSelectionFrame = LabelFrame(self.frame,
                                              text='Which spin-systems to use')
        spinSystemSelectionFrame.grid(row=2, column=0, sticky='nesw')

        tipText = 'What to do when a residue has already a spin system assigned to it.'
        assignedResidueFrame = LabelFrame(
            self.frame,
            text='if residue already has spin-system',
            tipText=tipText)
        assignedResidueFrame.grid(row=2, column=1, sticky='nesw')

        spectrumSelectionFrame = LabelFrame(self.frame, text='spectra')
        spectrumSelectionFrame.grid(row=1, column=0, sticky='nesw')

        row = 0

        Label(typeOfAssignmentFrame,
              text='Resonances to Peak Dimensions',
              grid=(row, 0))
        self.peaksCheckButton = CheckButton(typeOfAssignmentFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(typeOfAssignmentFrame,
              text='SpinSystems to Residues',
              grid=(row, 0))
        self.residuesCheckButton = CheckButton(typeOfAssignmentFrame,
                                               selected=True,
                                               grid=(row, 1))

        row = 0

        Label(peakSelectionFrame, text='Intra-Residual', grid=(row, 0))
        self.intraCheckButton = CheckButton(peakSelectionFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(peakSelectionFrame, text='Sequential', grid=(row, 0))
        self.sequentialCheckButton = CheckButton(peakSelectionFrame,
                                                 selected=True,
                                                 grid=(row, 1))

        row += 1

        Label(peakSelectionFrame,
              text='Do not assign diagonal peaks',
              grid=(row, 0))
        self.noDiagonalCheckButton = CheckButton(peakSelectionFrame,
                                                 selected=True,
                                                 grid=(row, 1))

        entries = [
            'Only assigned spin systems',
            'All that have a score of at least: ', 'User Defined',
            'Solution number:'
        ]
        tipTexts = [
            'Only assign resonances of spin systems that already have a sequential assignment for the assignment of peak dimensions. Spin system to residue assignment is not relevant in this case.',
            'Assign all spin systems that have a score of at least a given percentage. 50% or lower is not possible, because than spin systems might have to be assigned to more than 1 residue, which is impossible.',
            "As defined in the lower row of buttons in the 'results' tab.",
            'One of the single solutions of the annealing.'
        ]
        self.spinSystemTypeSelect = RadioButtons(spinSystemSelectionFrame,
                                                 entries=entries,
                                                 grid=(0, 0),
                                                 select_callback=None,
                                                 direction=VERTICAL,
                                                 gridSpan=(4, 1),
                                                 tipTexts=tipTexts)

        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minScoreEntry = FloatEntry(spinSystemSelectionFrame,
                                        grid=(1, 1),
                                        width=7,
                                        text=str(self.minScore),
                                        returnCallback=self.changeMinScore,
                                        tipText=tipText)
        self.minScoreEntry.bind('<Leave>', self.changeMinScore, '+')

        self.solutionNumberEntry = IntEntry(spinSystemSelectionFrame,
                                            grid=(3, 1),
                                            width=7,
                                            text=1,
                                            returnCallback=self.solutionUpdate,
                                            tipText=tipText)
        self.solutionNumberEntry.bind('<Leave>', self.solutionUpdate, '+')

        #self.solutionPullDown = PulldownList(spinSystemSelectionFrame, None, grid=(3,1), sticky='w')

        entries = ['all spectra', 'only:']
        tipTexts = [
            'Assign peaks in all the spectra that where selected before the annealing ran.',
            'Only assign peaks in one particular spectrum. You can of course repeat this multiple times for different spectra.'
        ]
        self.spectrumSelect = RadioButtons(spectrumSelectionFrame,
                                           entries=entries,
                                           grid=(0, 0),
                                           select_callback=None,
                                           direction=VERTICAL,
                                           gridSpan=(2, 1),
                                           tipTexts=tipTexts)

        self.spectraPullDown = PulldownList(spectrumSelectionFrame,
                                            self.changeSpectrum,
                                            grid=(1, 1),
                                            sticky='w')

        entries = [
            'skip this residue', 'de-assign old spin system from residue',
            'assign, but never merge', 'warn to merge'
        ]
        tipTexts = [
            "Don't assign the new spin system to the residue. The residue is not skipped when the old spin system does not contain any resonances",
            "De-assign old spin system from residue, unless the old spin system is a spin system without any resonances.",
            "Don't merge any spin systems, merging can be performed later if nescesary in the Resonance --> SpinSystems window.",
            "Ask to merge individually for each spin system, this might result in clicking on a lot of popups."
        ]
        self.assignedResidueStrategySelect = RadioButtons(assignedResidueFrame,
                                                          entries=entries,
                                                          grid=(0, 0),
                                                          select_callback=None,
                                                          direction=VERTICAL,
                                                          gridSpan=(2, 1),
                                                          tipTexts=tipTexts)

        texts = ['Transfer Assignments']
        commands = [self.transferAssignments]
        self.transferButton = ButtonList(self.frame,
                                         commands=commands,
                                         texts=texts)
        self.transferButton.grid(row=5, column=0, sticky='nsew', columnspan=2)

    def update(self):
        '''Update the nescesary elements in the
           tab. Is called when the algorithm
           has produced possible assignments.
           The only thing that has to be updated
           in practice in this tab is the pulldown
           with spectra.
        '''

        self.dataModel = self.guiParent.connector.results
        self.updateSpectra()

    def setDataModel(self, dataModel):
        '''Here the dataModel, which is the dataModel
           containing the suggested assignments body
           the algorithm, can be set.
        '''

        self.dataModel = dataModel
        self.update()

    def updateSpectra(self, *opt):
        '''Updates the spectra shown in the spectra
           pulldown. These are only the spectra that
           were used by the algorithm. All other spectra
           in the project are not relevant since for those
           no simulated peaks have been matched to real
           peaks.
        '''

        if not self.dataModel:

            return

        spectrum = self.spectrum

        spectra = self.dataModel.getSpectra()

        if spectra:

            names = [spectrum.name for spectrum in spectra]
            index = 0

            if self.spectrum not in spectra:

                self.spectrum = spectra[0]

            else:

                index = spectra.index(self.spectrum)

        self.spectraPullDown.setup(names, spectra, index)

    def changeSpectrum(self, spectrum):
        '''Select a spectum to be assigned.'''

        self.spectrum = spectrum

    def solutionUpdate(self, event=None, value=None):
        '''Select a solution. A solution is a
           one to one mapping of spin systems
           to residues produced by one run of
           the algorithm.
               args: event: event object, this is
                            one of the values the number
                            entry calls his callback
                            function with.
                     value: the index of the solution/run.
        '''

        if not self.dataModel:

            return

        Nsolutions = len(self.dataModel.chain.residues[0].solutions)

        if value is None:

            value = self.solutionNumberEntry.get()

        if value == self.selectedSolution:
            return
        else:
            self.selectedSolution = value
        if value < 1:
            self.solutionNumberEntry.set(1)
            self.selectedSolution = 1
        elif value > Nsolutions:
            self.selectedSolution = Nsolutions
            self.solutionNumberEntry.set(self.selectedSolution)
        else:
            self.solutionNumberEntry.set(self.selectedSolution)

    def fetchOptions(self):
        '''Fetches user set options from the gui in
           one go and stores them in their corresponding
           instance variables.
        '''

        self.resonanceToDimension = self.peaksCheckButton.get()
        self.spinSystemToResidue = self.residuesCheckButton.get()
        self.intra = self.intraCheckButton.get()
        self.sequential = self.sequentialCheckButton.get()
        self.noDiagonal = self.noDiagonalCheckButton.get()
        self.spinSystemType = self.spinSystemTypeSelect.getIndex()
        self.strategy = ['skip', 'remove', 'noMerge',
                         None][self.assignedResidueStrategySelect.getIndex()]
        self.allSpectra = [True, False][self.spectrumSelect.getIndex()]

    def changeMinScore(self, event=None):
        '''Set the minimal score for which a spin system
           to residue assignment gets transferred to the
           ccpn analysis project.
        '''

        newMinScore = self.minScoreEntry.get()

        if self.minScore != newMinScore:

            if newMinScore <= 50.0:

                self.minScore = 51.0
                self.minScoreEntry.set(51.0)

            elif newMinScore > 100.0:

                self.minScore = 100.0
                self.minScoreEntry.set(100.0)

            else:

                self.minScore = newMinScore

    def transferAssignments(self):
        '''Transfer assignments to project depending
           on the settings from the GUI.
        '''

        self.fetchOptions()

        if not self.dataModel or (not self.resonanceToDimension
                                  and not self.spinSystemToResidue):

            return

        strategy = self.strategy

        lookupSpinSystem = [
            self.getAssignedSpinSystem, self.getBestScoringSpinSystem,
            self.getUserDefinedSpinSystem, self.getSelectedSolutionSpinSystem
        ][self.spinSystemType]

        residues = self.dataModel.chain.residues

        spinSystemSequence = [lookupSpinSystem(res) for res in residues]

        ccpnSpinSystems = []
        ccpnResidues = []

        # if self.spinSystemType == 0 it means that it for sure already
        # assigned like this
        if self.spinSystemToResidue and not self.spinSystemType == 0:

            for spinSys, res in zip(spinSystemSequence, residues):

                if spinSys and res:

                    ccpnSpinSystems.append(spinSys.getCcpnResonanceGroup())
                    ccpnResidues.append(res.getCcpnResidue())

            assignSpinSystemstoResidues(ccpnSpinSystems,
                                        ccpnResidues,
                                        strategy=strategy,
                                        guiParent=self.guiParent)

        if self.resonanceToDimension:

            allSpectra = self.allSpectra

            if self.intra:

                for residue, spinSystem in zip(residues, spinSystemSequence):

                    if not spinSystem:

                        continue

                    intraLink = residue.getIntraLink(spinSystem)

                    for pl in intraLink.getPeakLinks():

                        peak = pl.getPeak()

                        if not allSpectra and peak.getSpectrum(
                        ) is not self.spectrum:

                            continue

                        if not peak:

                            continue

                        resonances = pl.getResonances()

                        if self.noDiagonal and len(
                                set(resonances)) < len(resonances):

                            continue

                        for resonance, dimension in zip(
                                resonances, peak.getDimensions()):

                            ccpnResonance = resonance.getCcpnResonance()
                            ccpnDimension = dimension.getCcpnDimension()
                            assignResToDim(ccpnDimension, ccpnResonance)

            if self.sequential:

                for residue, spinSystemA, spinSystemB in zip(
                        residues, spinSystemSequence, spinSystemSequence[1:]):

                    if not spinSystemA or not spinSystemB:

                        continue

                    link = residue.getLink(spinSystemA, spinSystemB)

                    for pl in link.getPeakLinks():

                        peak = pl.getPeak()

                        if not allSpectra and peak.getSpectrum(
                        ) is not self.spectrum:

                            continue

                        if not peak:

                            continue

                        resonances = pl.getResonances()

                        if self.noDiagonal and len(
                                set(resonances)) < len(resonances):

                            continue

                        for resonance, dimension in zip(
                                resonances, peak.getDimensions()):

                            ccpnResonance = resonance.getCcpnResonance()
                            ccpnDimension = dimension.getCcpnDimension()

                            assignResToDim(ccpnDimension, ccpnResonance)

        self.guiParent.resultsTab.update()

    def getAssignedSpinSystem(self, residue):
        '''Get the spinSystem that is assigned in the project
           to a residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        ccpCode = residue.ccpCode
        seqCode = residue.getSeqCode()
        spinSystems = self.dataModel.getSpinSystems()[ccpCode]

        ccpnResidue = residue.getCcpnResidue()
        if ccpnResidue:
            assignedResonanceGroups = ccpnResidue.getResonanceGroups()
            if len(assignedResonanceGroups) > 1:
                print 'There is more than one spin system assigned to residue %s, did not know which one to use to assign peaks. Therefor this residue is skipped.' % (
                    seqCode)
                return

            assignedResonanceGroup = ccpnResidue.findFirstResonanceGroup()

            if assignedResonanceGroup:

                for spinSystem in spinSystems:

                    if spinSystem.getSerial() == assignedResonanceGroup.serial:
                        # Just checking to make sure, analysis project could
                        # have changed
                        if not self.skipResidue(residue, spinSystem):

                            return spinSystem

    def getBestScoringSpinSystem(self, residue):
        '''Get the spinSystem that scores the highest,
           i.e. is assigned in most of the runs to the
           given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        solutions = residue.solutions
        weigth = 1.0 / len(solutions)
        score, bestSpinSystem = max([
            (solutions.count(solution) * weigth * 100.0, solution)
            for solution in solutions
        ])

        if score >= self.minScore and not bestSpinSystem.getIsJoker(
        ) and not self.skipResidue(residue, bestSpinSystem):

            return bestSpinSystem

        return None

    def getUserDefinedSpinSystem(self, residue):
        '''Get the spinSystem that is defined by the user
           (probably in the resultsTab) as the correct
           assignment of the given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        userDefinedSpinSystem = residue.userDefinedSolution

        if userDefinedSpinSystem and not userDefinedSpinSystem.getIsJoker(
        ) and not self.skipResidue(residue, userDefinedSpinSystem):

            return userDefinedSpinSystem

        return None

    def getSelectedSolutionSpinSystem(self, residue):
        '''I a solution corresponding to one specific run
           of the algorithm is defined, return which spinSystem
           in that run got assigned to the given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        solutions = residue.solutions

        spinSystem = solutions[self.selectedSolution - 1]

        if not spinSystem.getIsJoker() and not self.skipResidue(
                residue, spinSystem):

            return spinSystem

        return None

    def skipResidue(self, residue, spinSystem):
        '''One strategy is to skip all residues that
           already have a spin system assignment.
           If that is the case determine whether to
           skip the given residue.
           args: residue (src.cython.malandro.Residue)
                 spinSystem (src.cython.malandro.SpinSystem)
           return: boolean, True if residue should be skipped.
        '''

        if self.strategy == 0:

            assignedGroups = residue.getCcpnResidue().getResonanceGroups()
            assignedSerials = set(
                [spinSys.serial for spinSys in assignedGroups])

            if assignedSerials and spinSystem.getSerial(
            ) not in assignedSerials:

                return True

        return False
Exemplo n.º 20
0
    def body(self, master):

        fileName = self.fileName
        directory = os.path.dirname(fileName)
        if not directory:
            directory = os.getcwd()
        fileName = os.path.basename(fileName)

        m = template_re.match(fileName)
        if m:
            n = len(m.groups(2))
            ss = '%%0%dd' % n
            template = re.sub(template_re, r'\1%s\3' % ss, fileName)
        else:
            template = fileName

        master.rowconfigure(0, weight=1)
        master.rowconfigure(1, weight=1)
        master.columnconfigure(1, weight=1)

        tipTexts = [
            'The experiment is pseudo-N dimensional, with a sampled axis',
            'The experiment is the regular kind with only NMR frequency axes'
        ]
        self.pseudoButton = RadioButtons(
            master,
            entries=self.pseudoEntries,
            select_callback=self.changedPseudoMode,
            grid=(0, 0),
            sticky='nw',
            tipTexts=tipTexts)

        frame = self.pseudoFrame = Frame(master)
        self.pseudoFrame.grid(row=1, column=0, sticky='nsew')

        row = 0
        npts = self.params.npts[self.dim]
        tipText = 'Number of data points (planes) along sampled axis'
        label = Label(frame, text='Number of points: ')
        label.grid(row=row, column=0, sticky='e')
        self.nptsEntry = IntEntry(frame,
                                  text=npts,
                                  tipText=tipText,
                                  width=8,
                                  grid=(row, 1))

        tipText = 'Load the values for the sampled axis from a text file containing a list of numeric values'
        Button(frame,
               text='Load values from text file',
               command=self.loadValues,
               tipText=tipText,
               grid=(row, 2),
               sticky='ew')

        row = row + 1
        tipText = 'The values (e.g. T1, T2) corresponding to each data point (plane) along sampled axis'
        label = Label(frame, text='Point values: ')
        label.grid(row=row, column=0, sticky='e')
        self.valueEntry = FloatEntry(frame, isArray=True, tipText=tipText)
        self.valueEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        row = row + 1
        tipText = 'Fetch the Point values from the files given by the NMRPipe template'
        button = Button(
            frame,
            text='Fetch values from file(s) specified by template below',
            command=self.fetchValues,
            tipText=tipText)
        button.grid(row=row, column=1, columnspan=2, sticky='w')

        row = row + 1
        tipText = 'The directory where the data files reside'
        button = Button(frame,
                        text='Data directory: ',
                        command=self.chooseDirectory)
        button.grid(row=row, column=0, sticky='e')
        self.directoryEntry = Entry(frame,
                                    text=directory,
                                    width=40,
                                    tipText=tipText)
        self.directoryEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        row = row + 1
        tipText = 'The NMRPipe template for the data files, if you want to use these to fetch the point values from'
        button = Button(frame,
                        text='NMRPipe template: ',
                        command=self.chooseFile)
        button.grid(row=row, column=0, sticky='e')
        self.templateEntry = Entry(frame, text=template, tipText=tipText)
        self.templateEntry.grid(row=row, column=1, columnspan=2, sticky='ew')

        for n in range(row):
            frame.rowconfigure(n, weight=1)
        frame.columnconfigure(1, weight=1)

        buttons = UtilityButtonList(master,
                                    closeText='Ok',
                                    doClone=False,
                                    closeCmd=self.updateParams,
                                    helpUrl=self.help_url)
        buttons.grid(row=2, column=0, sticky='ew')
Exemplo n.º 21
0
class EditPeakFindParamsPopup(BasePopup):
    """
  ** Peak Settings and Non-Interactive Peak Finding **
  
  The purpose of this dialog is to allow the user to select settings for
  finding and integrating peaks, and also to be able to find peaks in an
  arbitrary region that is specified in a table rather than via a spectrum
  window.
  
  ** Find Parameters tab **

  This can be used to specify how peak finding works.

  First of all, you can search for just positive peaks, just negative
  peaks or both, and the default is that it is just positive peaks.
  However, this is further filtered by what the contour levels are.
  If there are no positive contour levels for a given spectrum then
  positive peaks are not found even if this dialog says they can be,
  and similarly if there are no negative contour levels for a given
  spectrum then negative peaks are not found even if this dialog says
  they can be.

  The peak finding algorithm looks for local extrema (maximum for
  positive peaks and minima for negative peaks).  But on a grid there
  are various ways to define what you mean by an extremum.  Suppose
  you are trying to determine if point p is a maximum (similar
  considerations apply for minimum).  You would want the intensity
  at all nearby points to be less than or equal to the intensity at p.
  You can just check points that are just +- one point from p in each
  dimension, or you can also check "diagonal" points.  For
  example, if you are looking at point p = (x, y) in 2D, then the
  former would mean checking the four points (x-1, y), (x+1, y)
  (x, y-1) and (x, y+1), whereas for the latter you would also have
  to check (x-1, y-1), (x-1, y+1), (x+1, y-1) and (x+1, y+1).  In
  N dimensions the "diagonal" method involves checking 3^N-1 points
  whereas the "non-diagonal" method involves checking only 2N points.
  In general the "non-diagonal" method is probably the one to use,
  and it is the default.

  Peaks are only found above (for positive peaks) or below (for negative
  peaks) some threshold.  By default this is determined by the contour level
  for the spectrum.  For positive peaks the threshold is the minimum
  positive contour level, and for negative peaks the threshold is the
  maximum negative contour level.  However these levels can be scaled up
  (or down) using the "Scale relative to contour levels" option (default
  value 1).  For example, if you have drawn the contour levels low to
  show a bit of noise, but do not want the noise picked as peaks, then
  you could select a scale of 2 (or whatever) to increase the threshold.

  The "Exclusion buffer around peaks" is so that in crowded regions you
  do not get too many peaks near one location.  By default the exclusion
  buffer is 1 point in each dimension, but this can be increased to make
  the algorithm find fewer peaks.

  By default the peak finding only looks at the orthogonal region that
  is displayed in the given window where peak finding is taking place.
  Sometimes it looks like a peak should be found because in x, y you
  can see an extremum, but unless it is also an extremum in the orthogonal
  dimensions it is not picked.  You can widen out the points being
  examined in the orthogonal dimensions by using the "Extra thickness in
  orthogonal dims" option, which is specified in points.

  The "Minimum drop factor" is by what factor the intensity needs to drop
  from its extreme value for there to be considered to be a peak.  This
  could help remove sinc wiggle peaks, for example.  The default is that
  the drop factor is 0, which in effect means that there is no condition.

  The "Volume method" is what is used to estimate the volume of peaks that
  are found.  The default is "box sum", which just looks at a fixed size
  box around the peak centre and sums the intensities in that.  The size
  of the box is set in the table in the Spectrum Widths tab.  The
  "truncated box sum" is the same as "box sum" except that the summing
  stops in a given direction when (if) the intensities start increasing.
  The "parabolic" fit fits a quadratic equation in each dimension to the
  intensity at the peak centre and ad +- 1 points and then uses the
  equivalent Gaussian fit to estimate the volume.

  ** Spectrum Widths **

  This can be used to specify minimum linewidths (in Hz) for there to be
  considered a peak to exist in the peak finding algorithm.  It is also
  where the Boxwidth for each dimension in each spectrum is specified.

  ** Diagonal Exclusions **

  This can be used to exclude peaks from being found in regions near
  the diagonal (so in homonuclear experiments).  The exclusion region
  is specified in ppm and is independent of spectrum.

  ** Region Peak Find **

  This can be used to find peaks non-interactively (so not having to
  control shift drag inside a spectrum window).  The region being
  analysed is specified in the table.  There are two types of conditions
  that can be specified, "include" for regions that should be included
  and "exclude" for regions that should be excluded.  The regions are
  specified in ppm.

  The "Whole Region" button will set the selected row in the table to be
  the entire fundamental region of the spectrum.

  The "Add Region" button adds an extra row to the table, and the "Delete
  Region" button removes the selected row.

  The "Adjust Params" button goes to the Find Parameters tab.

  The "Find Peaks!" button does the peak finding.

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

        self.spectrum = None

        BasePopup.__init__(self,
                           parent=parent,
                           title='Peak : Peak Finding',
                           **kw)

    def body(self, guiFrame):

        self.geometry('600x350')

        guiFrame.expandGrid(0, 0)

        tipTexts = ['', '', '', '']
        options = [
            'Find Parameters', 'Spectrum Widths', 'Diagonal Exclusions',
            'Region Peak Find'
        ]
        tabbedFrame = TabbedFrame(guiFrame, options=options, grid=(0, 0))

        frameA, frameB, frameC, frameD = tabbedFrame.frames
        self.tabbedFrame = tabbedFrame

        # Find Params

        frameA.expandGrid(2, 0)

        row = 0
        label = LabelFrame(frameA,
                           text='Extrema to search for:',
                           grid=(row, 0),
                           gridSpan=(1, 2))
        label.expandGrid(0, 1)

        entries = ['positive and negative', 'positive only', 'negative only']
        tipTexts = [
            'Sets whether peak picking within spectra find intensity maxima, minima or both maxima and minima',
        ]
        self.extrema_buttons = RadioButtons(label,
                                            entries=entries,
                                            select_callback=self.apply,
                                            direction='horizontal',
                                            grid=(0, 0),
                                            tipTexts=tipTexts)

        row += 1
        label = LabelFrame(frameA,
                           text='Nearby points to check:',
                           grid=(row, 0),
                           gridSpan=(1, 2))
        label.expandGrid(None, 1)

        entries = ['+-1 in at most one dim', '+-1 allowed in any dim']
        tipTexts = [
            'Sets how permissive the peak picking in when searching for intensity extrema; by adding extra points to the selected search region',
        ]
        self.adjacent_buttons = RadioButtons(label,
                                             entries=entries,
                                             select_callback=self.apply,
                                             direction='horizontal',
                                             grid=(0, 0),
                                             tipTexts=tipTexts)

        row += 1
        labelFrame = LabelFrame(frameA,
                                text='Other parameters:',
                                grid=(row, 0),
                                gridSpan=(1, 2))
        labelFrame.expandGrid(5, 2)

        frow = 0
        label = Label(labelFrame,
                      text='Scale relative to contour levels:',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Threshold above which peaks are picked, relative to the lowest displayed contour; 1.0 means picking exactly what is visible'
        self.scale_entry = FloatEntry(labelFrame,
                                      grid=(frow, 1),
                                      tipText=tipText,
                                      returnCallback=self.apply,
                                      width=10)
        self.scale_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Exclusion buffer around peaks (in points):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'The size of the no-pick region, in data points, around existing picked peaks; eliminates duplicate picking'
        self.buffer_entry = IntEntry(labelFrame,
                                     returnCallback=self.apply,
                                     grid=(frow, 1),
                                     width=10,
                                     tipText=tipText)
        self.buffer_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Extra thickness in orthogonal dims (in points):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Sets whether to consider any additional planes (Z dimension) when calculating peak volume integrals'
        self.thickness_entry = IntEntry(labelFrame,
                                        returnCallback=self.apply,
                                        width=10,
                                        grid=(frow, 1),
                                        tipText=tipText)
        self.thickness_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Minimum drop factor (0.0-1.0):',
                      grid=(frow, 0),
                      sticky='e')
        tipText = ''
        self.drop_entry = FloatEntry(labelFrame,
                                     returnCallback=self.apply,
                                     width=10,
                                     grid=(frow, 1),
                                     tipText=tipText)
        self.drop_entry.bind('<Leave>', self.apply, '+')

        frow += 1
        label = Label(labelFrame,
                      text='Volume method:',
                      grid=(frow, 0),
                      sticky='e')
        tipText = 'Selects which method to use to calculate peak volume integrals when peaks are picked; box sizes are specified in "Spectrum Widths"'
        self.method_menu = PulldownList(labelFrame,
                                        texts=PeakBasic.PEAK_VOLUME_METHODS,
                                        grid=(frow, 1),
                                        callback=self.apply,
                                        tipText=tipText)

        # Spectrum widths

        frameB.expandGrid(1, 1)

        label = Label(frameB, text='Spectrum: ')
        label.grid(row=0, column=0, sticky='e')

        tipText = 'The spectrum which determines the widths being shown'
        self.expt_spectrum = PulldownList(frameB,
                                          tipText=tipText,
                                          callback=self.setSpectrumProperties)
        self.expt_spectrum.grid(row=0, column=1, sticky='w')

        self.editLinewidthEntry = FloatEntry(self,
                                             text='',
                                             returnCallback=self.setLinewidth,
                                             width=10)
        self.editBoxwidthEntry = FloatEntry(self,
                                            text='',
                                            returnCallback=self.setBoxwidth,
                                            width=10)
        tipTexts = [
            'The number of the spectrum dimension to which the settings apply',
            'The nuclear isotope measures in the spectrum dimension',
            'The smallest value for the linewidth of a peak for it to be picked',
            'The size of the spectrum region to perform the volume integral over'
        ]
        headingList = [
            'Dimension', 'Isotope', 'Minimum Linewidth (Hz)', 'Boxwidth'
        ]
        editSetCallbacks = [None, None, self.setLinewidth, self.setBoxwidth]
        editGetCallbacks = [None, None, self.getLinewidth, self.getBoxwidth]
        editWidgets = [
            None, None, self.editLinewidthEntry, self.editBoxwidthEntry
        ]
        self.spectrumMatrix = ScrolledMatrix(frameB,
                                             initialRows=6,
                                             editSetCallbacks=editSetCallbacks,
                                             editGetCallbacks=editGetCallbacks,
                                             editWidgets=editWidgets,
                                             headingList=headingList,
                                             callback=self.selectCell,
                                             tipTexts=tipTexts)
        self.spectrumMatrix.grid(row=1, column=0, columnspan=2, sticky='nsew')

        # Diagonal Exclusions

        frameC.expandGrid(0, 0)

        tipTexts = [
            'The isotope as measures on the axis of a spectrum window',
            'The distance from the homonuclear diagonal line within which no peak picking can occur'
        ]
        self.exclusionEntry = FloatEntry(self,
                                         text='',
                                         returnCallback=self.setExclusion,
                                         width=10)
        headingList = ['Isotope', 'Diagonal Exclusion (ppm)']
        editSetCallbacks = [None, self.setExclusion]
        editGetCallbacks = [None, self.getExclusion]
        editWidgets = [None, self.exclusionEntry]
        self.isotopeMatrix = ScrolledMatrix(frameC,
                                            editSetCallbacks=editSetCallbacks,
                                            editGetCallbacks=editGetCallbacks,
                                            editWidgets=editWidgets,
                                            headingList=headingList,
                                            grid=(0, 0),
                                            tipTexts=tipTexts)

        # Region peak find

        self.regionFindPeakList = None
        self.regionCondition = None
        self.regionConditions = []
        self.regionCol = 1

        row = 0

        label = Label(frameD, text='Peak List: ', grid=(0, 0))
        tipText = 'Selects which peak list to perform region-wide peak picking for'
        self.regionPeakListPulldown = PulldownList(
            frameD,
            callback=self.changeRegionPeakList,
            grid=(0, 1),
            tipText=tipText)

        row += 1
        frameD.expandGrid(row, 1)

        self.regionEntry = FloatEntry(self,
                                      text='',
                                      returnCallback=self.setRegion,
                                      width=10)
        self.conditionMenu = PulldownList(self,
                                          texts=('include', 'exclude'),
                                          callback=self.setCondition)

        tipTexts = [
            'Whether to include or exclude the states region from region-wide peak picking',
        ]
        headingList = ['Condition']
        editSetCallbacks = [None]
        editGetCallbacks = [None]
        editWidgets = [self.conditionMenu]
        self.regionFindMatrix = ScrolledMatrix(
            frameD,
            headingList=headingList,
            callback=self.selectRegionCell,
            editWidgets=editWidgets,
            editGetCallbacks=editGetCallbacks,
            editSetCallbacks=editSetCallbacks,
            grid=(row, 0),
            gridSpan=(1, 2))

        row += 1
        tipTexts = [
            'Sets the currently selected region row to cover the whole spectrum',
            'Add a new region row, which may them be set for exclusion or inclusion when peak picking large areas',
            'Remove the selected region specification',
            'Go to the panel for setting the parameters that control how peaks extrema are picked',
            'Using the stated regions and parameters, perform region-wide peak picking'
        ]
        texts = [
            'Whole Region', 'Add Region', 'Delete Region', 'Adjust Params',
            'Find Peaks!'
        ]
        commands = [
            self.wholeRegion, self.addCondition, self.deleteCondition,
            self.adjustParams, self.regionFindPeaks
        ]

        buttons = ButtonList(frameD,
                             texts=texts,
                             commands=commands,
                             grid=(row, 0),
                             gridSpan=(1, 2),
                             tipTexts=tipTexts)
        buttons.buttons[4].config(bg='#B0FFB0')

        utilButtons = UtilityButtonList(tabbedFrame.sideFrame,
                                        grid=(0, 0),
                                        helpUrl=self.help_url,
                                        sticky='e')

        self.dataDim = None
        self.setParamsEntries()
        self.updateSpectrum()
        self.setIsotopeProperties()
        self.updateRegionPeakLists()

        self.administerNotifiers(self.registerNotify)

    def administerNotifiers(self, notifyFunc):

        # Many more needed here, esp on the AnalysisProject prams

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

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

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

        for func in ('setPeakFindBoxWidth', 'setPeakFindMinLineWidth'):
            notifyFunc(self.updateSpectrumTable,
                       'ccpnmr.Analysis.AnalysisDataDim', func)

    def destroy(self):

        self.administerNotifiers(self.unregisterNotify)
        BasePopup.destroy(self)

    def updateSpectrum(self, spectrum=None):

        if not spectrum:
            spectrum = self.spectrum

        spectra = self.parent.getSpectra()
        if spectra:
            if spectrum not in spectra:
                spectrum = spectra[0]
            index = spectra.index(spectrum)
            names = ['%s:%s' % (x.experiment.name, x.name) for x in spectra]
        else:
            index = 0
            names = []

        self.expt_spectrum.setup(names, spectra, index)

        self.setSpectrumProperties(spectrum)

    def updateNotifier(self, *extra):

        self.updateSpectrum()

    def setLinewidth(self, *event):

        value = self.editLinewidthEntry.get()
        if value is not None:
            PeakFindParams.setPeakFindMinLinewidth(self.dataDim, value)
            self.setSpectrumProperties(self.dataDim.dataSource)

    def getLinewidth(self, dataDim):

        if dataDim:
            self.editLinewidthEntry.set(
                PeakFindParams.getPeakFindMinLinewidth(self.dataDim))

    def setBoxwidth(self, *event):

        value = self.editBoxwidthEntry.get()
        if value is not None:
            PeakFindParams.setPeakFindBoxwidth(self.dataDim, value)
            self.setSpectrumProperties(self.dataDim.dataSource)

    def getBoxwidth(self, dataDim):

        if dataDim:
            self.editBoxwidthEntry.set(
                PeakFindParams.getPeakFindBoxwidth(self.dataDim))

    def selectCell(self, object, row, col):

        self.dataDim = object

    def setExclusion(self, *extra):

        isotope = self.isotopeMatrix.currentObject
        if not isotope:
            return

        value = self.exclusionEntry.get()
        if value is not None:
            setIsotopeExclusion(isotope, value)
            self.setIsotopeProperties()

    def getExclusion(self, isotope):

        value = getIsotopeExclusion(isotope)
        self.exclusionEntry.set(value)

    def setParamsEntries(self):

        project = self.project
        params = PeakFindParams.getPeakFindParams(project)

        self.scale_entry.set(params['scale'])
        self.buffer_entry.set(params['buffer'])
        self.thickness_entry.set(params['thickness'])
        self.drop_entry.set(params['drop'])
        volumeMethod = params['volumeMethod']
        if volumeMethod == 'parabolic fit':
            volumeMethod = PeakBasic.PEAK_VOLUME_METHODS[0]
        self.method_menu.set(params['volumeMethod'])

        if (params['nonadjacent']):
            n = 1
        else:
            n = 0
        self.adjacent_buttons.setIndex(n)

        have_high = params['haveHigh']
        have_low = params['haveLow']
        if (have_high and have_low):
            n = 0
        elif (have_high):
            n = 1
        else:
            n = 2
        self.extrema_buttons.setIndex(n)

    def apply(self, *extra):

        params = {}
        params['scale'] = self.scale_entry.get()
        params['buffer'] = self.buffer_entry.get()
        params['thickness'] = self.thickness_entry.get()
        params['drop'] = self.drop_entry.get()
        params['volumeMethod'] = self.method_menu.getText()

        n = self.adjacent_buttons.getIndex()
        if (n == 0):
            nonadjacent = False
        else:
            nonadjacent = True
        params['nonadjacent'] = nonadjacent

        n = self.extrema_buttons.getIndex()
        if (n == 0):
            have_high = True
            have_low = True
        elif (n == 1):
            have_high = True
            have_low = False
        elif (n == 2):
            have_high = False
            have_low = True
        params['haveHigh'] = have_high
        params['haveLow'] = have_low

        project = self.project
        try:
            PeakFindParams.setPeakFindParams(project, params)
        except Implementation.ApiError, e:
            showError('Parameter error', e.error_msg, parent=self)
Exemplo n.º 22
0
class RepositoryFrame(Frame):
    def __init__(self, guiParent, basePopup):

        # Base popup required to handle notification of data model changes
        # e.g. new peak lists, so that the GUI can update to the latest
        # state
        self.basePopup = basePopup
        self.guiParent = guiParent

        # should the screen autorefresh
        self.autoRefresh = False

        # add this to shortcuts to ease navigation
        self.basePopup.frameShortcuts['Repository'] = self

        # get a port proxy instance
        # this should probably belong to the repository directly
        # or else should belong in a dictionary in the main gui
        # layer when it can be picked up easily

        # FIXME JMCI
        # need to work out how to get a number of these!

        loc = SharedBeanServiceLocator()
        self.port = loc.getSharedBean()

        self.registerNotify = basePopup.registerNotify
        self.unregisterNotify = basePopup.unregisterNotify

        Frame.__init__(self, guiParent)

        # set up the grid

        self.grid_columnconfigure(0, weight=0, minsize=20)
        self.grid_columnconfigure(1, weight=1, minsize=10)
        self.grid_columnconfigure(2, weight=0, minsize=20)

        self.grid_rowconfigure(0, weight=0, minsize=5)
        self.grid_rowconfigure(1, weight=0, minsize=0)
        self.grid_rowconfigure(2, weight=0, minsize=10)
        self.grid_rowconfigure(3, weight=0, minsize=10)
        self.grid_rowconfigure(4, weight=0, minsize=10)
        self.grid_rowconfigure(5, weight=1, minsize=10)
        self.grid_rowconfigure(6, weight=0, minsize=10)
        self.grid_rowconfigure(7, weight=0, minsize=10)

        # widgets for view when no data

        self.noDataWidgets = []

        self.noRepLabel = Label(self, text='No repository currently selected.')
        self.noDataWidgets.append(self.noRepLabel)

        # widgets for view when current repository set

        self.dataWidgets = []

        self.repTitle = Label(self, text='Repository:', font='Helvetica16')
        self.dataWidgets.append(self.repTitle)

        #self.repLabel = Label(self,text='All Projects in Repository')
        #self.dataWidgets.append(self.repLabel)

        self.repTree = Tree(self, doubleCallback=self.goto_project_tab)
        self.dataWidgets.append(self.repTree)

        sel = 1
        if self.autoRefresh:
            sel = 0
        self.autoRefreshSwitchLabel = Label(self, text='Auto Refresh')
        self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'],
                                              select_callback=self.set_refresh,
                                              selected_index=sel)

        # need to decide whether this is static or not
        r_button_texts = [
            'Add to Basket', '  Import  ', '  Export  ', '  Refresh ',
            'Properties'
        ]
        r_button_cmds = [
            self.tmpCall, self.import_project, self.export_project,
            self.drawFrame, self.goto_project_tab
        ]

        self.rep_button_list = ButtonList(self, r_button_texts, r_button_cmds)
        self.dataWidgets.append(self.rep_button_list)

        self.filterFrame = FilterFrame(self, self.basePopup, text='Filter')
        self.dataWidgets.append(self.filterFrame)

        baskets = ('basket1', 'basket2', 'basket3')
        self.basketSelect = PulldownList(self, self.tmpCall, baskets)
        self.dataWidgets.append(self.basketSelect)

        basketElements = ('1ay3', '1ay7')
        self.basketList = ScrolledListbox(self, basketElements, 25, 18)
        self.dataWidgets.append(self.basketList)

        b_button_texts = ['Remove from Basket', 'New Basket']
        b_button_cmds = [self.tmpCall, self.tmpCall]

        self.b_button_list = ButtonList(self, b_button_texts, b_button_cmds)
        self.dataWidgets.append(self.b_button_list)

        # draw if not automatically refreshing
        if sel == 1:
            self.drawFrame()

        # set up a loop
        self.refresh()

    def drawFrame(self):

        if self.basePopup.repList.currentRepository == None:

            for widget in self.dataWidgets:
                widget.grid_remove()

            self.noRepLabel.grid(row=1, column=1, sticky='n')

        else:

            self.repository = self.basePopup.repList.currentRepository

            for widget in self.noDataWidgets:
                widget.grid_remove()

            # Column headers
            # want to have a general admin panel; current repository, button to change, info
            # about login and so on

            self.repTitle.set('Repository: ' + self.repository.user + '@' +
                              self.repository.name + '  ( ' +
                              self.repository.connect + ' )')

            self.repTitle.grid(row=1, column=1, sticky='w')

            # self.repLabel.grid(row=2, column=1, sticky='w')

            # Repository block

            #grid and update
            self.repTree.grid(row=3, column=1, rowspan=3, sticky='nsew')
            self.updateRepTree()

            self.autoRefreshSwitchLabel.grid(row=6,
                                             column=1,
                                             padx=10,
                                             sticky='w')
            self.autoRefreshSwitch.grid(row=6, column=1, padx=10, sticky='e')

            # the buttons for functionality in repository area
            self.rep_button_list.grid(row=7, column=1, padx=3, sticky='ew')

            # filter frame
            self.filterFrame.grid(row=3, column=2, stick='nsew')

            # list of baskest. Will callback to change current basket
            self.basketSelect.grid(row=4, column=2, padx=10, stick='w')

            # lists projects per basket
            self.basketList.grid(row=5,
                                 rowspan=2,
                                 column=2,
                                 padx=10,
                                 stick='nsew')

            self.b_button_list.grid(row=7, column=2, padx=5, stick='ew')

    def openLink(self, node):

        tree = node.tree
        par = node.object

        # this should be associated with the repository object
        request = getList()

        # FIXME JMCI

        # 1. Potentially need to traverse up the node tree
        # 2. Currently there is bug in expansion/contraction
        # 3. Search needs to work off proxy method (not off
        #    generated stubs

        # pass the parent name for now. may need other criteria later
        h1 = {'name': par.__str__()}
        h2 = {'project': h1}
        wsstr_in = WSString(h2)

        request._arg0 = 'org.pimslims.applet.server.ProjectVersionBean'
        request._arg1 = 'getListWithFields'
        request._arg2 = wsstr_in.str

        # get the response
        response = self.port.getList(request)

        # currently we just get a list of numbers. May want to send
        # all the fields for every object too to cut down on db calls
        wsstr_out = WSString(response._return)
        ss = wsstr_out.getStruct()

        for hm in ss:

            print 'handling ', hm, ', ', hm['status'].__str__()
            #if hm['status'].__str__() == 'AVAILABLE':
            icon = 'text-x-generic'
            #else:
            #  icon='emblem-readonly'
            pv = par.__str__() + '::' + hm['versionTag'].__str__()
            obj = pv
            text = hm['versionTag'].__str__()
            callback = None

            tree.add(node, obj, text, icon, callback)

    def set_refresh(self, text):

        print 'setting refresh ', text

        if text == 'on':
            self.autoRefresh = True
        else:
            self.autoRefresh = False

    def refresh(self):

        if self.autoRefresh:
            print 'refreshing frame ', time.time()
            self.drawFrame()

        self.after(5000, self.refresh)

    # FIME JMCI

    # it would probably be a good idea to have a method that allowed
    # a user to unlock a given project version. Would need to check
    # permissions very carefully, though

    def unlock_project_version(self):

        pass

    def goto_project_tab(self, node=None):

        if node is None:
            # get the selected node
            selected_nodes = self.repTree.getSelectedNodes()
            # restrict the choice to one
            node = selected_nodes[0]

        # we really need to traverse the tree a lot more carefully

        pv = node.object.__str__()
        print 'GOTO PROJECT ', pv, ', ', node, ', ', node.object
        pat = re.compile('::')
        matcher = pat.search(pv, 0)
        name = pv[0:matcher.start()]
        versionTag = pv[matcher.end():]

        print 'GOTO PROJECT ', name, ', ', versionTag

        #versionTag = node.object.__str__()
        #name = node.parent.object.__str__()

        #print node.__dict__
        #print node.parent.__dict__

        self.basePopup.repList.currentRepository.currentProjectName = name
        self.basePopup.repList.currentRepository.currentVersionTag = versionTag

        # this is going to have to be keyed on a natural key that then
        # gets set into the criteria of a ws query

        # hack for now. build in later. Essentially, we have to handle two
        # cases; that of a specific projectVersion request and that of a
        # request on a project alone. Probably the best behaviour would be
        # for the project-only request to default to the latest trunk
        # version of the project and the most elegent way of triggering
        # this would probably be to have this as a property of the project
        # returned in the main hash from Project.getFields().

        self.basePopup.tabbedFrame.select(1)
        if self.basePopup.frameShortcuts.has_key('Project'):
            self.basePopup.frameShortcuts['Project'].drawFrame()

    def import_project(self):

        # FIXME JMCI

        # need to preserve the current status. Take default from the
        # Wms layer
        rootDir = self.basePopup.repList.current_import_dir

        fileSelectPopup = FileSelectPopup(self, None, rootDir)

        new_project_dir = fileSelectPopup.getDirectory()
        self.basePopup.repList.current_import_dir = new_project_dir

        print 'in import project with directory', new_project_dir

        idx = new_project_dir.rfind('/')
        new_project_name = new_project_dir[idx + 1:]

        print 'in import project with project', new_project_name

        # FIXME

        # need to set the project version number somewhere. For now set to none
        # and this gets picked up and set to a default 1.1 later

        self.repository.import_project(new_project_name, None, new_project_dir)

        self.drawFrame()

    def export_project(self):

        # get the selected node
        selected_nodes = self.repTree.getSelectedNodes()

        # restrict the choice to one
        node = selected_nodes[0]

        # we really need to traverse the tree a lot more carefully
        name = node.parent.object.__str__()
        versionTag = node.object.__str__()[len(name) + 2:]

        # need to preserve the current status. Take a default from the
        # Wms layer
        rootDir = self.basePopup.repList.current_export_dir

        # This should be obtained from a query box. Hard code for now
        fileSelectPopup = FileSelectPopup(self, None, rootDir)

        exp_project_dir = fileSelectPopup.getDirectory()
        self.basePopup.repList.current_export_dir = exp_project_dir

        self.repository.export_project(name, versionTag, exp_project_dir)

    def disconnectRepository(self):

        # do we need to formally break a connection and destroy the session?
        # yes we probably should.

        # need an "are you sure" dialog box

        # need to protect

        self.repository.repList.repositories.remove(self.repository)
        self.grid_remove()
        for ff in self.guiParent.guiParent.parent.frames[0].children.values():
            ff.drawFrame()

    def tmpCall(self):

        return

    # This will need a separate call to the WS with an additional
    # criterion (picking up the checkout version)

    def updateRepTree(self):

        texts = []
        icons = []
        parents = []
        callbacks = []
        objects = []

        # OK, this would be a good point to access the list

        # this should be associated with the repository object
        loc = SharedBeanServiceLocator()
        port = loc.getSharedBean()
        request = getList()

        # these are actually static
        request._arg0 = 'org.pimslims.applet.server.ProjectBean'
        request._arg1 = 'getList'
        request._arg2 = ''

        # get the response
        response = port.getList(request)

        # this is a hack at present. It needs to be written properly
        wsstr = WSString(response._return)
        ss = wsstr.getStruct()

        for strg in ss:
            texts.append(strg)
            icons.append('folder')
            parents.append(None)
            objects.append(strg)
            callbacks.append(self.openLink)

        print 'UPDATE ', ss
        print 'UPDATE ', len(ss)

        if len(ss) > 0:
            print 'UPDATE: updating '
            self.repTree.update(parents, objects, texts, icons, callbacks)

    def administerNotifiers(self, notifyFunc):

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

    def updateAllAfter(self, obj):

        self.after_idle(self.updateAll)

    def updateAll(self, project=None):

        return

    def quit(self):

        self.guiParent.parent.destroy()

    def destroy(self):

        self.administerNotifiers(self.basePopup.unregisterNotify)
        Frame.destroy(self)
Exemplo n.º 23
0
  def __init__(self, guiParent, basePopup):

    self.guiParent = guiParent
    self.basePopup = basePopup

    # selection hash. This needs to be stored so that we can
    # refresh with the same criteria
    self.select = None

    # should the screen autorefresh
    self.autoRefresh = False
    
    # add this to shortcuts to ease navigation    
    self.basePopup.frameShortcuts['Tasks'] = self

    #self.registerNotify=basePopup.registerNotify
    #self.unregisterNotify=basePopup.unregisterNotify

    #self.frames = []

    # FIXME JMCI

    # This frame is specific for a single repository so we need a
    # method for identifying one from the whole set (or could have
    # subtabs)

    Frame.__init__(self, guiParent)
  
    # set up the grid

    self.grid_columnconfigure(0, weight=0, minsize=20)
    self.grid_columnconfigure(1, weight=1, minsize=30)
    self.grid_columnconfigure(2, weight=0, minsize=40)

    self.grid_rowconfigure(0, weight=0, minsize=20)
    self.grid_rowconfigure(1, weight=0, minsize=10)
    self.grid_rowconfigure(2, weight=0, minsize=0)
    self.grid_rowconfigure(3, weight=0, minsize=0)
    self.grid_rowconfigure(4, weight=0, minsize=0)
    self.grid_rowconfigure(5, weight=1, minsize=0)
    self.grid_rowconfigure(6, weight=0, minsize=10)
    self.grid_rowconfigure(7, weight=0, minsize=10)


    initial_cols = ['ID','Task','User','Status']
    self.task_matrix = ScrolledMatrix(self, headingList=initial_cols, initialRows=15,
                                      doubleCallback=self.goto_task_tab)

    # Filters for narrowing down tasks. should probably code this
    # specifically inside this package    
    #self.filter = FilterFrame(self, self.basePopup, text='Filter')
    self.filter = TaskFilterFrame(self, self.basePopup, text='Filter')

    # Frame for controlling the main client side daemon
    # seems to be a problem. add a simple button for now
    opts = ['Client','Server']
    self.daemonFrame = TabbedFrame(self, options=opts,
                                   toggleOff=False, selected=0)

    self.daemonSwitchLabel = Label(self, text= 'Task Daemon')
    self.daemonSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_daemon, selected_index = 1)

    sel = 1
    if self.autoRefresh:
      sel = 0
    self.autoRefreshSwitchLabel = Label(self, text= 'Auto Refresh')
    self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_refresh, selected_index = sel)

    self.label_rep = Label(self, text='', font='Helvetica16')

    # set up a loop
    self.refresh()
Exemplo n.º 24
0
    def __init__(self, guiParent, basePopup):

        # Base popup required to handle notification of data model changes
        # e.g. new peak lists, so that the GUI can update to the latest
        # state
        self.basePopup = basePopup
        self.guiParent = guiParent

        # should the screen autorefresh
        self.autoRefresh = False

        # add this to shortcuts to ease navigation
        self.basePopup.frameShortcuts['Repository'] = self

        # get a port proxy instance
        # this should probably belong to the repository directly
        # or else should belong in a dictionary in the main gui
        # layer when it can be picked up easily

        # FIXME JMCI
        # need to work out how to get a number of these!

        loc = SharedBeanServiceLocator()
        self.port = loc.getSharedBean()

        self.registerNotify = basePopup.registerNotify
        self.unregisterNotify = basePopup.unregisterNotify

        Frame.__init__(self, guiParent)

        # set up the grid

        self.grid_columnconfigure(0, weight=0, minsize=20)
        self.grid_columnconfigure(1, weight=1, minsize=10)
        self.grid_columnconfigure(2, weight=0, minsize=20)

        self.grid_rowconfigure(0, weight=0, minsize=5)
        self.grid_rowconfigure(1, weight=0, minsize=0)
        self.grid_rowconfigure(2, weight=0, minsize=10)
        self.grid_rowconfigure(3, weight=0, minsize=10)
        self.grid_rowconfigure(4, weight=0, minsize=10)
        self.grid_rowconfigure(5, weight=1, minsize=10)
        self.grid_rowconfigure(6, weight=0, minsize=10)
        self.grid_rowconfigure(7, weight=0, minsize=10)

        # widgets for view when no data

        self.noDataWidgets = []

        self.noRepLabel = Label(self, text='No repository currently selected.')
        self.noDataWidgets.append(self.noRepLabel)

        # widgets for view when current repository set

        self.dataWidgets = []

        self.repTitle = Label(self, text='Repository:', font='Helvetica16')
        self.dataWidgets.append(self.repTitle)

        #self.repLabel = Label(self,text='All Projects in Repository')
        #self.dataWidgets.append(self.repLabel)

        self.repTree = Tree(self, doubleCallback=self.goto_project_tab)
        self.dataWidgets.append(self.repTree)

        sel = 1
        if self.autoRefresh:
            sel = 0
        self.autoRefreshSwitchLabel = Label(self, text='Auto Refresh')
        self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'],
                                              select_callback=self.set_refresh,
                                              selected_index=sel)

        # need to decide whether this is static or not
        r_button_texts = [
            'Add to Basket', '  Import  ', '  Export  ', '  Refresh ',
            'Properties'
        ]
        r_button_cmds = [
            self.tmpCall, self.import_project, self.export_project,
            self.drawFrame, self.goto_project_tab
        ]

        self.rep_button_list = ButtonList(self, r_button_texts, r_button_cmds)
        self.dataWidgets.append(self.rep_button_list)

        self.filterFrame = FilterFrame(self, self.basePopup, text='Filter')
        self.dataWidgets.append(self.filterFrame)

        baskets = ('basket1', 'basket2', 'basket3')
        self.basketSelect = PulldownList(self, self.tmpCall, baskets)
        self.dataWidgets.append(self.basketSelect)

        basketElements = ('1ay3', '1ay7')
        self.basketList = ScrolledListbox(self, basketElements, 25, 18)
        self.dataWidgets.append(self.basketList)

        b_button_texts = ['Remove from Basket', 'New Basket']
        b_button_cmds = [self.tmpCall, self.tmpCall]

        self.b_button_list = ButtonList(self, b_button_texts, b_button_cmds)
        self.dataWidgets.append(self.b_button_list)

        # draw if not automatically refreshing
        if sel == 1:
            self.drawFrame()

        # set up a loop
        self.refresh()
Exemplo n.º 25
0
class PopupTemplate(BasePopup):

  def __init__(self, parent, project=None, *args, **kw):

    self.project = project
    self.parent  = parent
    self.objects = self.getObjects()
    self.object  = None
    
    BasePopup.__init__(self, parent=parent, title='Popup Template', **kw)
                       
    self.updateObjects()

  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)

  def floatEntryReturn(self, event):
  
    value = self.floatEntry.get()
    self.textWindow.setText('%s\n' % value)

  def selectObject(self, object, row, col):
  
    self.object = object

  def getKeywords(self, object):
  
    if object :
      values = object.keywords
      self.multiWidget.set(values)
  
  def setKeywords(self, event):
  
    values = self.multiWidget.get()
    self.object.keywords = values
    self.updateObjects()

  def getNumber(self, object):

    if object :
      self.intEntry.set(object.quantity)

  def setNumber(self, event):

    value = self.intEntry.get()
    self.object.quantity = value
    self.updateObjects()

  def toggleFrame1(self, isHidden):
 
    if isHidden:
      self.scrolledMatrix.grid_forget()
      self.toggleFrame.grid_forget()
    else:
      self.scrolledGraph.grid_forget()
      self.scrolledCanvas.grid_forget()
      self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW)
      self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW)
      self.toggleLabel2.arrowOff()
      self.toggleLabel3.arrowOff()


  def toggleFrame2(self, isHidden):
 
    if isHidden:
      self.scrolledGraph.grid_forget()
      self.toggleFrame.grid_forget()
    else:
      self.scrolledMatrix.grid_forget()
      self.scrolledCanvas.grid_forget()
      self.scrolledGraph.grid(row=0, column=0, sticky=Tkinter.NSEW)
      self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW)
      self.toggleLabel1.arrowOff()
      self.toggleLabel3.arrowOff()

  def toggleFrame3(self, isHidden):
 
    if isHidden:
      self.scrolledCanvas.grid_forget()
      self.toggleFrame.grid_forget()
    else:
      self.scrolledMatrix.grid_forget()
      self.scrolledGraph.grid_forget()
      self.scrolledCanvas.grid(row=0, column=0, sticky=Tkinter.NSEW)
      self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW)
      self.toggleLabel1.arrowOff()
      self.toggleLabel2.arrowOff()

 
  def valueRampCallback(self, value):
  
    self.textWindow.setText('%s\n' % value)

  def checkRadioButtons(self, value):
  
    self.textWindow.setText('%s\n' % value)

  def selectPulldown(self, index, name):
  
    self.textWindow.setText('%d, %s\n' % (index, name))

  def toggleSelector(self, value):
  
    self.textWindow.setText('%s\n' % value)

  def changedCheckButtons(self, values):
  
    self.textWindow.setText(','.join(values) + '\n')

  def getObjects(self):
  
    objects = []
    
    objects.append( Fruit('Lemon',   '#FFFF00',1,keywords=['Bitter','Tangy'] ) )
    objects.append( Fruit('Orange',  '#FF8000',4 ) )
    objects.append( Fruit('Banana',  '#FFF000',5 ) )
    objects.append( Fruit('Pinapple','#FFD000',9 ) )
    objects.append( Fruit('Kiwi',    '#008000',12) )
    objects.append( Fruit('Lime',    '#00FF00',2 ) )
    objects.append( Fruit('Apple',   '#800000',5,keywords=['Crunchy'] ) )
    objects.append( Fruit('Pear',    '#408000',6 ) )
    objects.append( Fruit('Peach',   '#FFE0C0',2,keywords=['Sweet','Furry'] ) )
    objects.append( Fruit('Plumb',   '#800080',7 ) )
    
    return objects

  def updateObjects(self, event=None):

    textMatrix = []
    objectList = []
    colorMatrix = []
    
    for object in self.objects:
      datum = []
      datum.append( object.name )
      datum.append( None )
      datum.append( object.quantity )
      datum.append( ','.join(object.keywords) )
    
      colors = [None, object.color, None, None]
    
      textMatrix.append(datum)
      objectList.append(object)
      colorMatrix.append(colors)

    if self.check.get():
      self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList)
    else:
      self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix)

  def selectFile(self):

    fileSelectPopup = FileSelectPopup(self, title = 'Choose file', dismiss_text = 'Cancel',
                                      selected_file_must_exist = True)

    fileName = fileSelectPopup.getFile()

    self.textWindow.setText('File Selected: %s\n' % fileName)

  def showWarning(self, eventObject):
  
    self.textWindow.setText('Text Entry Return Pressed\n')
    showWarning('Warning Title','Warning Message')
    return

  def pressButton(self):
  
    self.textWindow.setText('Button Pressed\n')
    if showYesNo('Title','Prompt: Clear text window?'):
       self.textWindow.clear()
       
    return

  def quit(self):
  
    BasePopup.destroy(self)  
Exemplo n.º 26
0
    def body(self, guiFrame):

        self.geometry('450x500')

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

        options = ['Peak Separator', 'Advanced Settings']

        tabbedFrame = TabbedFrame(guiFrame, options=options)
        tabbedFrame.grid(row=0, column=0, sticky='nsew')

        buttons = UtilityButtonList(tabbedFrame.sideFrame,
                                    helpUrl=self.help_url)
        buttons.grid(row=0, column=0, sticky='e')

        self.tabbedFrame = tabbedFrame
        frameA, frameB = tabbedFrame.frames

        #
        # FrameA : Main Settings
        #

        frameA.grid_columnconfigure(1, weight=1)
        row = 0  # Label row

        row += 1
        div = LabelDivider(frameA, text='Peak Separator Parameters')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameA, text='Min. number of peaks:')
        label.grid(row=row, column=0, sticky='w')
        self.minPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \
              tipText='Minimum number of peaks to find (must be > 0)')
        self.minPeaksEntry.grid(row=row, column=1, sticky='n')
        self.minPeaksEntry.bind('<Leave>', self.applyChange, '+')

        row += 1
        label = Label(frameA, text='Max. number of peaks:')
        label.grid(row=row, column=0, sticky='w')
        self.maxPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \
              tipText='Maximum number of peaks to find (0 is unlimited - not recommended)')
        self.maxPeaksEntry.grid(row=row, column=1, sticky='n')
        self.maxPeaksEntry.bind('<Leave>', self.applyChange, '+')

        row += 1
        label = Label(frameA, text='Only pick positive peaks:')
        label.grid(row=row, column=0, sticky='w')
        entries = ['False', 'True']
        self.posPeaksButtons = RadioButtons(
            frameA,
            entries=entries,
            select_callback=self.applyChange,
            direction='horizontal',
            tipTexts=[
                'Search for both positive and negative intensity peaks',
                'Limit search to only positive peaks'
            ])
        self.posPeaksButtons.grid(row=row, column=1, sticky='n')

        row += 1
        label = Label(frameA, text='Peak Model:')
        label.grid(row=row, column=0, sticky='w')
        ### G/L Mixture works, but volume calculation involves Gamma function
        # entries = ['Gaussian', 'Lorentzian', 'G/L Mixture']
        entries = ['Gaussian', 'Lorentzian']
        self.shapeButtons = RadioButtons(
            frameA,
            entries=entries,
            select_callback=self.applyChange,
            direction='horizontal',
            tipTexts=[
                'Choose a Gaussian model peak shape to fit to peaks',
                'Choose a Lorentzian model peak shape to fit to peaks'
            ])
        self.shapeButtons.grid(row=row, column=1, sticky='n')

        row += 1
        div = LabelDivider(frameA,
                           text='Region',
                           tipText='Region that search will limit itself to')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameA, text='Peak List:')
        label.grid(row=row, column=0, sticky='nw')
        self.peakListPulldown = PulldownList(
            frameA,
            callback=self.setManuallyPickPeakList,
            tipText='Select which peak list new peaks are to be added to')
        self.peakListPulldown.grid(row=row, column=1, sticky='nw')

        # tricky scrolled matrix
        row += 1
        self.regionTable = None
        frameA.grid_rowconfigure(row, weight=1)
        headings = ('dim.', 'start (ppm)', 'end (ppm)', 'actual size')

        self.editDimEntry = IntEntry(self,
                                     returnCallback=self.applyChange,
                                     width=5,
                                     tipText='Dimension number')
        self.editStartEntry = FloatEntry(self,
                                         returnCallback=self.applyChange,
                                         width=5,
                                         tipText='Search area lower bound')
        self.editEndEntry = FloatEntry(self,
                                       returnCallback=self.applyChange,
                                       width=5,
                                       tipText='Search area upper bound')

        editWidgets = [
            self.editDimEntry, self.editStartEntry, self.editEndEntry, None
        ]

        editGetCallbacks = [None, None, None, None]
        editSetCallbacks = [None, None, None, None]

        self.regionTable = ScrolledMatrix(frameA,
                                          headingList=headings,
                                          multiSelect=False,
                                          editWidgets=editWidgets,
                                          editGetCallbacks=editGetCallbacks,
                                          editSetCallbacks=editSetCallbacks,
                                          initialRows=5)

        self.regionTable.grid(row=row, column=0, columnspan=2, sticky='nsew')

        # Run Button
        row += 1
        texts = ['Add Region']
        commands = [self.updateFromRegion]
        self.addResetButtons = ButtonList(
            frameA,
            texts=texts,
            commands=commands,
            tipTexts=['Add selected specrtral region'])
        self.addResetButtons.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        texts = ['Separate Peaks']
        commands = [self.runPeakSeparator]
        self.runButton = ButtonList(frameA,
                                    texts=texts,
                                    commands=commands,
                                    expands=True,
                                    tipTexts=['Run peak search now'])
        self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew')

        #
        # FrameB : Further Settings
        #

        frameB.grid_columnconfigure(0, weight=1)

        row = 0

        div = LabelDivider(frameB, text='Rate:')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')
        row += 1

        label = Label(frameB, text='Rate of MCMC step size change')
        label.grid(row=row, column=0, columnspan=1, sticky='w')

        self.rateEntry = FloatEntry(frameB, returnCallback=self.applyChange, width=10, \
              tipText='Rate effects speed of run, smaller values take longer but may produce better results')
        self.rateEntry.grid(row=row, column=1, sticky='n')
        self.rateEntry.bind('<Leave>', self.applyChange, '+')
        self.rateEntry.set(self.params.rate)

        # tricky scrolled matrix for line width
        row += 2
        div = LabelDivider(frameB, text='Line Width (Hz):')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameB, text="Descr.")
        label.grid(row=row, rowspan=2, column=0, sticky='w')

        row += 1
        self.lineWidthTable = None
        frameB.grid_rowconfigure(row, weight=1)
        lineWidthHeadings = ('dim.', 'min. σ (Hz)', 'max. σ (Hz)')

        self.editMinSigmaEntry = FloatEntry(self,
                                            returnCallback=self.applyChange,
                                            width=5,
                                            tipText='Minimum line width (Hz)')
        self.editMaxSigmaEntry = FloatEntry(self,
                                            returnCallback=self.applyChange,
                                            width=5,
                                            tipText='Maximum line width (Hz)')

        # self.editDimEntry is also from regionTable
        initialWidthRows = 4

        editLineWidthWidgets = [
            None, self.editMinSigmaEntry, self.editMaxSigmaEntry
        ]
        editLineWidthGetCallbacks = [None, self.getSigmaMin, self.getSigmaMax]
        editLineWidthSetCallbacks = [None, self.setSigmaMin, self.setSigmaMax]

        self.lineWidthTable = ScrolledMatrix(
            frameB,
            headingList=lineWidthHeadings,
            multiSelect=False,
            editWidgets=editLineWidthWidgets,
            editGetCallbacks=editLineWidthGetCallbacks,
            editSetCallbacks=editLineWidthSetCallbacks,
            initialRows=initialWidthRows)

        self.lineWidthTable.grid(row=row,
                                 column=0,
                                 columnspan=2,
                                 sticky='nsew')

        # option to 'repick' exisiting peak list
        row += initialWidthRows
        div = LabelDivider(frameB, text='(optional - repick entire peak list)')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')
        row += 1

        self.repickListPulldown = PulldownList(
            frameB,
            callback=self.setRePickPeakList,
            tipText=
            'Select which peak list to repick (new peaks will be put into a new peak list)'
        )
        self.repickListPulldown.grid(row=row, column=0, sticky='nw')

        texts = ['Repick Peak List']
        commands = [self.runRepickPeaks]
        self.runButton = ButtonList(
            frameB,
            texts=texts,
            commands=commands,
            expands=True,
            tipTexts=['Repick selected peak list into a new peak list.'])
        self.runButton.grid(row=row, column=1, columnspan=1, sticky='nsew')

        row += 1
        div = LabelDivider(frameB)
        row += 1
        texts = ['Separate Peaks']
        commands = [self.runPeakSeparator]
        self.runButton = ButtonList(frameB,
                                    texts=texts,
                                    commands=commands,
                                    expands=True,
                                    tipTexts=['Run peak search now'])
        self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew')

        self.setWidgetEntries()

        self.administerNotifiers(self.registerNotify)
Exemplo n.º 27
0
class PrintWindowPopup(BasePopup):

  """
  **Print Window to Output File**

  The purpose of this dialog is to allow the saving of the drawing of
  one of the spectrum windows to a file, in one of the following formats:
  PostScript (PS), Encapsulated PostScript (EPS) or Portable Document
  Format (PDF).

  The one window that is being printed out is specified at the top.
  There are four tabs.  The first one, Options, is the most important.
  In particular, it is used to specify the File name.  At its simplest
  to print out a window you just need to specify the File name, and
  then click "Save Print File".  But it is likely you will at the very
  least want to change some of the settings in the Options tab.

  You can specify a Title and a label for the X axis and/or Y axis.

  This tab is also used to specify the Paper size (default A4), the
  Orientation of the paper (default Portrait), whether the printout
  is Color or Black and white (the Style, default Color), and what
  the Format is (PS, EPS or PDF, default PS).

  The ticks for the rulers can be chosen to be Inside or Outside the
  main frame and can be in any combination of the Top, Bottom, Left
  or Right side of the main frame.  The Tick Font includes the option
  of not printing the tick labels at all.  The Tick spacing between
  the major and minor ticks can be set automatically (so the program
  determines it) or manually.  For the latter the user has to specify
  the Major and Minor spacings in terms of the unit of the display
  (normally ppm), and also the number of decimal places for the Tick
  labels.

  How the main frame fits into the paper is determined by the Scaling
  option.  The Percentage option just means that the main frame is
  scaled by that amount relative to the biggest size it could be and
  still fit on the paper.  The remaining options are if you want to
  specify the cms or inches per unit (normally ppm), or the inverse
  of these.  In this case it could be the case that the main frame
  actually exceeds the size of the paper.

  You can also include the Time and Date and/or the File Name in the
  printout, and you can specify the font used for this.  The same
  font is used for the Title and X and Y axis labels, except that
  the Title font is 6 pts bigger.

  Finally, you can also set the linewidth, in points (the default is 0.1).

  The other three tabs provide fine tuning of what is output.  In many
  cases they can be ignored.

  The Spectra tab lets you choose settings for which of the window's
  spectra are drawn, in terms of both the positive and negative contours.
  This is independent of what is actually drawn on the screen.  But you
  need to check the "Use below settings when printing" checkbutton if you
  want the values specified here to be used rather than the screen settings.
  The values in the table are initially set to be the screen values but
  afterwards can only be changed manually.  Clicking on the "Reset Selected"
  button changes the values in the table to the current screen ones.

  The Peak Lists tab is similar, except it applies to the peak lists in
  the window rather than the spectra.  Again, if you want the values in
  the table to be used then you need to check the "Use below settings
  when printing" checkbutton.

  The Region tab is for specifying the region for the x, y and orthogonal
  axes, if you do not want to use the regions as seen in the window on the
  screen.  Again, you have to check "Use override region when printing"
  checkbutton to actually have the values in the table be used in the
  printout.  By default, the override region is set to the current
  window region if it is not set already, otherwise it is left to the
  previous value unless you click the "Set Region from Window" or the
  "Set Width from Window" or the "Set Center from Window" buttons.
  And the override region can be specified either using the min and max
  values of the region, or the center and width.
"""

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

    self.waiting = False
    
    title='Window : Print Window'
    BasePopup.__init__(self, parent=parent, title=title, **kw)

  def body(self, guiFrame):

    self.geometry('600x350')

    project = self.project
    analysisProject = self.analysisProject

    guiFrame.grid_columnconfigure(1, weight=1)

    row = 0
    frame = Frame(guiFrame, grid=(0,0))
    label = Label(frame, text=' Window:', grid=(0,0))
    self.windowPulldown = PulldownList(frame, grid=(0,1),
                                      tipText='The window that will be printed out',
                                      callback=self.selectWindow)
                                      
    tipTexts = ['For the window pulldown, show all of the spectrum windows in the current project, irrespective of the active group',
                'For the window pulldown, show only spectrum windows that are in the currently active window group']
    self.whichWindows = RadioButtons(frame, grid=(0,2),
                                     entries=ACTIVE_OPTIONS, tipTexts=tipTexts,
                                     select_callback=self.updateWindows)
    
    texts = [ 'Save Print File' ]
    tipTexts = [ 'Save the printout to the specified file' ]
    commands = [ self.saveFile ]
    buttons = UtilityButtonList(guiFrame, helpUrl=self.help_url, grid=(row,2),
                                commands=commands, texts=texts, tipTexts=tipTexts)
    self.buttons = buttons
    buttons.buttons[0].config(bg='#B0FFB0')
    
    row += 1
    guiFrame.grid_rowconfigure(row, weight=1)
    options = ['Options', 'Spectra', 'Peak Lists', 'Region']
    tipTexts = ['Optional settings for spectra', 'Optional settings for peak lists', 'Optional settings for the region']
    tabbedFrame = TabbedFrame(guiFrame, options=options, tipTexts=tipTexts)
    tabbedFrame.grid(row=row, column=0, columnspan=3, sticky='nsew')
    self.tabbedFrame = tabbedFrame

    optionFrame, spectrumFrame, peakListFrame, regionFrame = tabbedFrame.frames

    optionFrame.expandGrid(0, 0)
    getOption = lambda key, defaultValue: PrintBasic.getPrintOption(analysisProject, key, defaultValue)
    setOption = lambda key, value: PrintBasic.setPrintOption(analysisProject, key, value)
    self.printFrame = PrintFrame(optionFrame, getOption=getOption,
                                 grid=(0,0), gridSpan=(1,1),
                                 setOption=setOption, haveTicks=True,
                                 doOutlineBox=False)

    spectrumFrame.expandGrid(0, 0)
    frame = Frame(spectrumFrame, grid=(0,0), gridSpan=(1,1))
    frame.expandGrid(1,0)

    self.overrideSpectrum = CheckButton(frame,
       text='Use below settings when printing',
       tipText='Use below settings when printing instead of the window values',
       grid=(0,0), sticky='w')

    tipText = 'Change the settings of the selected spectra back to their window values'
    button = Button(frame, text='Reset Selected', tipText=tipText,
                    command=self.resetSelected, grid=(0,1), sticky='e')

    self.posColorPulldown = PulldownList(self, callback=self.setPosColor)
    self.negColorPulldown = PulldownList(self, callback=self.setNegColor)
    headings = ['Spectrum', 'Pos. Contours\nDrawn', 'Neg. Contours\nDrawn', 'Positive\nColours', 'Negative\nColours']
    tipTexts = ['Spectrum in window', 'Whether the positive contours should be drawn', 'Whether the negative contours should be drawn',
      'Colour scheme for positive contours (can be a single colour)', 'Colour scheme for negative contours (can be a single colour)']

    editWidgets      = [ None, None, None, self.posColorPulldown, self.negColorPulldown]
    editGetCallbacks = [ None, self.togglePos, self.toggleNeg, self.getPosColor, self.getNegColor]
    editSetCallbacks = [ None, None, None, self.setPosColor, self.setNegColor]
    self.spectrumTable = ScrolledMatrix(frame, headingList=headings,
                                        tipTexts=tipTexts,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        grid=(1,0), gridSpan=(1,2))

    peakListFrame.expandGrid(0, 0)
    frame = Frame(peakListFrame, grid=(0,0), gridSpan=(1,3))
    frame.expandGrid(1,0)

    self.overridePeakList = CheckButton(frame,
       text='Use below settings when printing',
       tipText='Use below settings when printing instead of the window values',
       grid=(0,0))

    tipText = 'Change the settings of the selected peak lists back to their window values'
    button = Button(frame, text='Reset Selected', tipText=tipText,
                    command=self.resetSelected, grid=(0,1), sticky='e')

    colors = Color.standardColors
    self.peakColorPulldown = PulldownList(self, callback=self.setPeakColor,
                                        texts=[c.name for c in colors],
                                        objects=[c.hex for c in colors],
                                        colors=[c.hex for c in colors])
    headings = [ 'Peak List', 'Symbols Drawn', 'Peak Font', 'Peak Colour']
    self.fontMenu = FontList(self, mode='Print', extraTexts=[no_peak_text])
    editWidgets      = [ None, None, self.fontMenu, self.peakColorPulldown]
    editGetCallbacks = [ None, self.togglePeaks, self.getPeakFont, self.getPeakColor ]
    editSetCallbacks = [ None, None, self.setPeakFont, self.setPeakColor ]
    self.peakListTable = ScrolledMatrix(frame, headingList=headings,
                                        multiSelect=True,
                                        editWidgets=editWidgets,
                                        editGetCallbacks=editGetCallbacks,
                                        editSetCallbacks=editSetCallbacks,
                                        grid=(1,0), gridSpan=(1,2))

    regionFrame.expandGrid(0, 0)
    frame = Frame(regionFrame, grid=(0,0), gridSpan=(1,3))
    frame.expandGrid(3,0)
    tipText = 'Use the specified override region when printing rather than the window values'
    self.overrideButton = CheckButton(frame, text='Use override region when printing',
                                      tipText=tipText,
                                      callback=self.toggledOverride, grid=(0,0))

    tipTexts = ('Use min and max to specify override region', 'Use center and width to specify override region')
    self.use_entry = USE_ENTRIES[0]
    self.useButtons = RadioButtons(frame, entries=USE_ENTRIES,
                                      tipTexts=tipTexts,
                                      select_callback=self.changedUseEntry,
                                      grid=(1,0))

    texts = ('Set Region from Window', 'Set Center from Window', 'Set Width from Window')
    tipTexts = ('Set the override region to be the current window region',
                'Set the center of the override region to be the center of the current window region',
                'Set the width of the override region to be the width of the current window region')
    commands = (self.setRegionFromWindow, self.setCenterFromWindow, self.setWidthFromWindow)
    self.setRegionButton = ButtonList(frame, texts=texts,
                                      tipTexts=tipTexts,
                                      commands=commands, grid=(2,0))

    self.minRegionWidget = FloatEntry(self, returnCallback=self.setMinRegion, width=10)
    self.maxRegionWidget = FloatEntry(self, returnCallback=self.setMaxRegion, width=10)
    headings = MIN_MAX_HEADINGS
    editWidgets      = [ None, None, self.minRegionWidget, self.maxRegionWidget ]
    editGetCallbacks = [ None, None, self.getMinRegion,    self.getMaxRegion ]
    editSetCallbacks = [ None, None, self.setMinRegion,    self.setMaxRegion ]
    self.regionTable = RegionScrolledMatrix(frame, headingList=headings,
                                            editWidgets=editWidgets,
                                            editGetCallbacks=editGetCallbacks,
                                            editSetCallbacks=editSetCallbacks,
                                            grid=(3,0))

    self.updateWindows()
    self.updateAfter()
    
    self.administerNotifiers(self.registerNotify)
    
  def administerNotifiers(self, notifyFunc):
  
    for func in ('__init__', 'delete', 'setOverrideRegion'):
      notifyFunc(self.updateAfter, 'ccpnmr.Analysis.AxisRegion', func)

    notifyFunc(self.updateAfter, 'ccpnmr.Analysis.SpectrumWindow', 'setUseOverrideRegion')

    for func in ('__init__', 'delete', 'setName'):
      notifyFunc(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindow', func)
      notifyFunc(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindowPane', func)
      
    for func in ('addSpectrumWindow', 'removeSpectrumWindow'):
      notifyFunc(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindowGroup', func)

  def destroy(self):

    self.administerNotifiers(self.unregisterNotify)

    BasePopup.destroy(self)

  def changedUseEntry(self, entry):

    self.use_entry = entry
    self.updateRegionTable()

  def resetSpectrum(self):

    spectrumWindowViews = self.spectrumTable.currentObjects
    analysisSpectra = set()
    for spectrumWindowView in spectrumWindowViews:
      PrintBasic.setPrintOption(spectrumWindowView, 'PositiveOn', spectrumWindowView.isPosVisible)
      PrintBasic.setPrintOption(spectrumWindowView, 'NegativeOn', spectrumWindowView.isNegVisible)
      analysisSpectra.add(spectrumWindowView.analysisSpectrum)
    for analysisSpectrum in analysisSpectra:
      PrintBasic.setPrintOption(analysisSpectrum, 'PositiveColors', analysisSpectrum.posColors)
      PrintBasic.setPrintOption(analysisSpectrum, 'NegativeColors', analysisSpectrum.negColors)

    self.updateAfter()

  def resetPeakList(self):

    windowPeakLists = self.peakListTable.currentObjects
    analysisPeakLists = set()
    for windowPeakList in windowPeakLists:
      PrintBasic.setPrintOption(windowPeakList, 'PeaksOn', windowPeakList.isSymbolDrawn)
      PrintBasic.setPrintOption(windowPeakList, 'PeakFont', windowPeakList.spectrumWindowView.analysisSpectrum.font)
      analysisPeakLists.add(windowPeakList.analysisPeakList)
    for analysisPeakList in analysisPeakLists:
      PrintBasic.setPrintOption(analysisPeakList, 'PeakColor', analysisPeakList.symbolColor)

    self.updateAfter()

  def resetSelected(self):

    n = self.tabbedFrame.selected
    if n == 0:
      self.resetSpectrum()
    elif n == 1:
      self.resetPeakList()

  def togglePos(self, spectrumWindowView):

    PrintBasic.setPrintOption(spectrumWindowView, 'PositiveOn',
      not PrintBasic.getPrintOption(spectrumWindowView, 'PositiveOn', defaultValue=spectrumWindowView.isPosVisible))

    self.updateAfter()

  def toggleNeg(self, spectrumWindowView):

    PrintBasic.setPrintOption(spectrumWindowView, 'NegativeOn',
      not PrintBasic.getPrintOption(spectrumWindowView, 'NegativeOn', defaultValue=spectrumWindowView.isNegVisible))

    self.updateAfter()

  def getPosColor(self, spectrumWindowView):

    schemes = getHueSortedColorSchemes(self.analysisProfile)
    names = [s.name for s in schemes]
    colors = [list(s.colors) for s in schemes]
    index = 0
    
    analysisSpec = spectrumWindowView.analysisSpectrum
    posColors = list(PrintBasic.getPrintOption(analysisSpec, 'PositiveColors', defaultValue=analysisSpec.posColors))
    
    if posColors in colors:
      index = colors.index(posColors)
      
    self.posColorPulldown.setup(names, schemes, index, colors)

  def setPosColor(self, *extra):

    spectrumWindowView = self.spectrumTable.currentObject
    if spectrumWindowView:
      analysisSpec = spectrumWindowView.analysisSpectrum
      PrintBasic.setPrintOption(analysisSpec, 'PositiveColors', self.posColorPulldown.getObject().colors)
      self.updateSpectrumTable()
    
  def getNegColor(self, spectrumWindowView):

    schemes = getHueSortedColorSchemes(self.analysisProfile)
    names = [s.name for s in schemes]
    colors = [list(s.colors) for s in schemes]
    index = 0
    
    analysisSpec = spectrumWindowView.analysisSpectrum
    negColors = list(PrintBasic.getPrintOption(analysisSpec, 'NegativeColors', defaultValue=analysisSpec.negColors))
    
    if negColors in colors:
      index = colors.index(negColors)
      
    self.negColorPulldown.setup(names, schemes, index, colors)

  def setNegColor(self, *extra):

    spectrumWindowView = self.spectrumTable.currentObject
    if spectrumWindowView:
      analysisSpec = spectrumWindowView.analysisSpectrum
      PrintBasic.setPrintOption(analysisSpec, 'NegativeColors', self.negColorPulldown.getObject().colors)
      self.updateSpectrumTable()
    
  def getPeakColor(self, windowPeakList):
 
    color = windowPeakList.analysisPeakList.symbolColor
    self.peakColorPulldown.set(color)
 
  def setPeakColor(self, *extra):

    windowPeakList = self.peakListTable.currentObject
    if windowPeakList:
      color = self.peakColorPulldown.getObject()
      scheme = self.analysisProfile.findFirstColorScheme(colors=(color,))
      if scheme:
        color = scheme.name
      analysisPeakList = windowPeakList.analysisPeakList
      PrintBasic.setPrintOption(analysisPeakList, 'PeakColor', color)
      self.updatePeakListTable()
  
  def togglePeaks(self, windowPeakList):

    PrintBasic.setPrintOption(windowPeakList, 'PeaksOn',
      not PrintBasic.getPrintOption(windowPeakList, 'PeaksOn', defaultValue=windowPeakList.isSymbolDrawn))

    self.updateAfter()

  def getPeakFont(self, windowPeakList):

    if windowPeakList.isAnnotationDrawn:
      default = windowPeakList.analysisPeakList.analysisSpectrum.font
    else:
      default = no_peak_text
    font = PrintBasic.getPrintOption(windowPeakList, 'PeakFont', defaultValue=default)

    self.fontMenu.set(font)

  def setPeakFont(self, windowPeakList):

    PrintBasic.setPrintOption(windowPeakList, 'PeakFont', self.fontMenu.getText())

    self.updateAfter()

  def updateWindows(self, obj=None):

    useAll = (self.whichWindows.get() == ACTIVE_OPTIONS[0])
    
    index = 0
    windowPane = self.windowPulldown.getObject()
    windowPanes = []
    names = []
    
    if not windowPane:
      application = self.project.application
      name = application.getValue(self.analysisProject, keyword='printWindowWindow')
      if useAll:
        window = self.analysisProject.findFirstSpectrumWindow(name=name)
        if window:
          windowPane = window.findFirstSpectrumWindowPane()
      else:
        for window in self.analysisProject.sortedSpectrumWindows():
          if isActiveWindow(window):
            windowPane = window.findFirstSpectrumWindowPane()
            break
        else:
          window = None

    for window in self.analysisProject.sortedSpectrumWindows():
      if useAll or isActiveWindow(window):
        for windowPane0 in window.sortedSpectrumWindowPanes():
          windowPanes.append(windowPane0)
          names.append(getWindowPaneName(windowPane0))
    
    if windowPanes:
      if windowPane not in windowPanes:
        windowPane = windowPanes[0]
      
      index = windowPanes.index(windowPane)  
    
    else:
      windowPane = None
      
    self.selectWindow(windowPane)
        
    self.windowPulldown.setup(names, windowPanes, index)

  def saveFile(self):

    windowPane = self.windowPulldown.getObject()

    if not windowPane:
      return

    axisPanels = windowPane.sortedAxisPanels()
    aspectRatio = self.getPrintAspectRatio()
    pixelWidth = self.totalSize(axisPanels[0])
    pixelHeight = aspectRatio*self.totalSize(axisPanels[1])
    unitWidth = self.totalOverrideRegion(axisPanels[0])
    unitHeight = self.totalOverrideRegion(axisPanels[1])

    printFrame = self.printFrame

    isOverrideSpectrumSelected = self.overrideSpectrum.isSelected()
    if isOverrideSpectrumSelected:
      spectrumWindowViews = self.spectrumTable.objectList
      # alternatively, spectrumWindowViews = windowPane.spectrumWindowViews
      analysisSpectra = set()
      for spectrumWindowView in spectrumWindowViews:
        spectrumWindowView.printPositive = PrintBasic.getPrintOption(spectrumWindowView, 'PositiveOn', spectrumWindowView.isPosVisible)
        spectrumWindowView.printNegative = PrintBasic.getPrintOption(spectrumWindowView, 'NegativeOn', spectrumWindowView.isNegVisible)
        analysisSpectra.add(spectrumWindowView.analysisSpectrum)
        
      for analysisSpectrum in analysisSpectra:
        analysisSpectrum.printPositiveColors = PrintBasic.getPrintOption(analysisSpectrum, 'PositiveColors', analysisSpectrum.posColors)
        analysisSpectrum.printNegativeColors = PrintBasic.getPrintOption(analysisSpectrum, 'NegativeColors', analysisSpectrum.negColors)

    isOverridePeakListSelected = self.overridePeakList.isSelected()
    if isOverridePeakListSelected:
      windowPeakLists = self.peakListTable.objectList
      analysisPeakLists = set()
      for windowPeakList in windowPeakLists:
        windowPeakList.printPeaks = PrintBasic.getPrintOption(windowPeakList, 'PeaksOn', windowPeakList.isSymbolDrawn)
        if windowPeakList.isAnnotationDrawn:
          default = windowPeakList.analysisPeakList.analysisSpectrum.font
        else:
          default = no_peak_text
        windowPeakList.printFont = PrintBasic.getPrintOption(windowPeakList, 'PeakFont', default)
        analysisPeakLists.add(windowPeakList.analysisPeakList)
      for analysisPeakList in analysisPeakLists:
        analysisPeakList.printColor = PrintBasic.getPrintOption(analysisPeakList, 'PeakColor', analysisPeakList.symbolColor)

    xrr = axisPanels[0].findFirstAxisRegion().region
    dxx = abs(xrr[0]-xrr[1])
    yrr = axisPanels[1].findFirstAxisRegion().region
    dyy = abs(yrr[0]-yrr[1])
    try:
      outputHandler = printFrame.getOutputHandler(pixelWidth, pixelHeight, unitWidth, unitHeight, fonts=printNames)
      if not outputHandler:
        return
      
      analysisProject = self.analysisProject
      major_minor_dict = {}
      spacing_choice = PrintBasic.getPrintOption(analysisProject, 'SpacingChoice', spacing_choices[0])
      if spacing_choice != spacing_choices[0]:
        for attr in ('XMajor', 'XMinor', 'XDecimal',
                     'YMajor', 'YMinor', 'YDecimal',):
          val = PrintBasic.getPrintOption(analysisProject, attr, None)
          if val is not None:
            major_minor_dict[attr] = val

      tick_length_choice = PrintBasic.getPrintOption(analysisProject, 'TickLengthChoice', tick_length_choices[0])
      if tick_length_choice != tick_length_choices[0]:
        for attr in ('TickMajor', 'TickMinor'):
          val = PrintBasic.getPrintOption(analysisProject, attr, None)
          if val is not None:
            major_minor_dict[attr] = val

      windowDraw = WindowDraw(self.parent, windowPane)

      PrintBasic.printWindow(windowDraw,
                             outputHandler,
                             printFrame.tick_location,
                             printFrame.tick_placement,
                             aspectRatio,
                             printFrame.tick_font,
                             major_minor_dict)
      
      msg = 'Saved to file "%s"' % printFrame.file_name                        
      showInfo('Success', msg, parent=self)
      
    except IOError, e:
      showError('IO Error', str(e), parent=self)

    if isOverrideSpectrumSelected:
      analysisSpectra = set()
      for spectrumWindowView in spectrumWindowViews:
        del spectrumWindowView.printPositive
        del spectrumWindowView.printNegative
        analysisSpectra.add(spectrumWindowView.analysisSpectrum)
      for analysisSpectrum in analysisSpectra:
        del analysisSpectrum.printPositiveColors
        del analysisSpectrum.printNegativeColors

    if isOverridePeakListSelected:
      analysisPeakLists = set()
      for windowPeakList in windowPeakLists:
        del windowPeakList.printPeaks
        del windowPeakList.printFont
        analysisPeakLists.add(windowPeakList.analysisPeakList)
      for analysisPeakList in analysisPeakLists:
        del analysisPeakList.printColor
Exemplo n.º 28
0
class PeakSeparatorGui(BasePopup):
    """
  **Separate Merged Peaks Using Peak Models**

  The Peak Separator code uses a Markov Chain Monte Carlo search which, using
  idealised peak shapes, attempts to deconvolve overlapped peak regions into 
  their separate constituent peaks.
  
  This routine is also suitable for accurately fitting model shapes to single
  peaks in order to calculate precise intensities.
  
  **Options Peak Separator Parameters**
  *Min. Number of peaks* is by default set to one, it is not possible to set 
  this to a value less than one.
  *Max. Number of peaks* is by default set to one, increasing this value allows
  the search routine to fit more models. The best fit may be found with fewer than
  the maximum number models. Higher numbers slow the routine, and setting this
  value to 0 allows the routine to (effectively) fit unlimited peaks.
  *Only pick positive peaks*. If you are not interested in negative peaks, removing
  the possibility of fitting negative peaks can reduce search time.
  *Peak Model* fits the spectra with either a Gaussian peak model or a Lorentzian
  peak model.

  **Options Region**
  *Peak List* choose which peak list newly picked peaks should be added to. Peaks
  picked using this method will have their details appended with 'PeakSepartor' 
  so you know where they came from.
  *Region Table* shows which area of the current spectrum is about to be searched.
  *Add Region*. Once an area of spectra has been highlighted clicking this button
  will pass it's details on to the Peak Separator.
  *Reset All* will reset all search parameters.
  *Separate Peaks* will run the Peak Separator code with your current settings. This
  may take a few minutes to run, depending on the size of the spectral region being
  searched, the number of peaks being fitted and the speed of your machine. Please
  wait while this completes.
  
  After a successful Peak Separation run, the found peaks will be added to the 
  selected peak list. These peaks intensties (volume) have been found using the
  peak model selected.

  **Advanced Settings Tab**
  *Rate* affects the speed of the Markov Chain Monte Carlo routine. A smaller value
  results in longer execution, but possibly higher quality results. The default 
  setting is deemed sensible for the majority of runs.
  *Line Width* offers a finer degree of control over maximum and minimum peak widths
  for each dimension. The default values are *very* stupid and could do with 
  re-checking for each experiment.
  *Re-Pick Entire Peak List* if you would like to use the Peak Separator to repick
  *every* peak in your peak list, try this option - but note that this may take
  a very long time!

  """
    def __init__(self, parent, programName='Peak Separator', **kw):

        self.parent = parent
        self.programName = programName
        self.versionInfo = 'Version 0.2'
        self.help_url = 'http://www.ccpn.ac.uk/'

        self.window = None
        self.waiting = False
        self.rootWindow = None

        # just used for display - PeakSeparator will not see this
        self._minSigmaHz = None
        self._maxSigmaHz = None

        self.customSigma = False
        self.rePickPeakList = False

        self._sampleStartPpm = None
        self._sampleEndPpm = None

        try:
            self.project = parent.project
        except:
            pass

        self.params = PeakSeparatorParams()

        BasePopup.__init__(self,
                           parent=parent,
                           title=programName,
                           location='+100+100',
                           **kw)

        if not self.analysisProject:
            print '&&& init: No analysis project found ...'
        try:
            if parent.argumentServer:
                self.argServer = parent.argumentServer
            else:
                print '&&& init: No argument server found...'
        except:
            print '&&& init: Test'

    ###########################################################################

    def body(self, guiFrame):

        self.geometry('450x500')

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

        options = ['Peak Separator', 'Advanced Settings']

        tabbedFrame = TabbedFrame(guiFrame, options=options)
        tabbedFrame.grid(row=0, column=0, sticky='nsew')

        buttons = UtilityButtonList(tabbedFrame.sideFrame,
                                    helpUrl=self.help_url)
        buttons.grid(row=0, column=0, sticky='e')

        self.tabbedFrame = tabbedFrame
        frameA, frameB = tabbedFrame.frames

        #
        # FrameA : Main Settings
        #

        frameA.grid_columnconfigure(1, weight=1)
        row = 0  # Label row

        row += 1
        div = LabelDivider(frameA, text='Peak Separator Parameters')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameA, text='Min. number of peaks:')
        label.grid(row=row, column=0, sticky='w')
        self.minPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \
              tipText='Minimum number of peaks to find (must be > 0)')
        self.minPeaksEntry.grid(row=row, column=1, sticky='n')
        self.minPeaksEntry.bind('<Leave>', self.applyChange, '+')

        row += 1
        label = Label(frameA, text='Max. number of peaks:')
        label.grid(row=row, column=0, sticky='w')
        self.maxPeaksEntry = IntEntry(frameA, returnCallback=self.applyChange, width=10, \
              tipText='Maximum number of peaks to find (0 is unlimited - not recommended)')
        self.maxPeaksEntry.grid(row=row, column=1, sticky='n')
        self.maxPeaksEntry.bind('<Leave>', self.applyChange, '+')

        row += 1
        label = Label(frameA, text='Only pick positive peaks:')
        label.grid(row=row, column=0, sticky='w')
        entries = ['False', 'True']
        self.posPeaksButtons = RadioButtons(
            frameA,
            entries=entries,
            select_callback=self.applyChange,
            direction='horizontal',
            tipTexts=[
                'Search for both positive and negative intensity peaks',
                'Limit search to only positive peaks'
            ])
        self.posPeaksButtons.grid(row=row, column=1, sticky='n')

        row += 1
        label = Label(frameA, text='Peak Model:')
        label.grid(row=row, column=0, sticky='w')
        ### G/L Mixture works, but volume calculation involves Gamma function
        # entries = ['Gaussian', 'Lorentzian', 'G/L Mixture']
        entries = ['Gaussian', 'Lorentzian']
        self.shapeButtons = RadioButtons(
            frameA,
            entries=entries,
            select_callback=self.applyChange,
            direction='horizontal',
            tipTexts=[
                'Choose a Gaussian model peak shape to fit to peaks',
                'Choose a Lorentzian model peak shape to fit to peaks'
            ])
        self.shapeButtons.grid(row=row, column=1, sticky='n')

        row += 1
        div = LabelDivider(frameA,
                           text='Region',
                           tipText='Region that search will limit itself to')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameA, text='Peak List:')
        label.grid(row=row, column=0, sticky='nw')
        self.peakListPulldown = PulldownList(
            frameA,
            callback=self.setManuallyPickPeakList,
            tipText='Select which peak list new peaks are to be added to')
        self.peakListPulldown.grid(row=row, column=1, sticky='nw')

        # tricky scrolled matrix
        row += 1
        self.regionTable = None
        frameA.grid_rowconfigure(row, weight=1)
        headings = ('dim.', 'start (ppm)', 'end (ppm)', 'actual size')

        self.editDimEntry = IntEntry(self,
                                     returnCallback=self.applyChange,
                                     width=5,
                                     tipText='Dimension number')
        self.editStartEntry = FloatEntry(self,
                                         returnCallback=self.applyChange,
                                         width=5,
                                         tipText='Search area lower bound')
        self.editEndEntry = FloatEntry(self,
                                       returnCallback=self.applyChange,
                                       width=5,
                                       tipText='Search area upper bound')

        editWidgets = [
            self.editDimEntry, self.editStartEntry, self.editEndEntry, None
        ]

        editGetCallbacks = [None, None, None, None]
        editSetCallbacks = [None, None, None, None]

        self.regionTable = ScrolledMatrix(frameA,
                                          headingList=headings,
                                          multiSelect=False,
                                          editWidgets=editWidgets,
                                          editGetCallbacks=editGetCallbacks,
                                          editSetCallbacks=editSetCallbacks,
                                          initialRows=5)

        self.regionTable.grid(row=row, column=0, columnspan=2, sticky='nsew')

        # Run Button
        row += 1
        texts = ['Add Region']
        commands = [self.updateFromRegion]
        self.addResetButtons = ButtonList(
            frameA,
            texts=texts,
            commands=commands,
            tipTexts=['Add selected specrtral region'])
        self.addResetButtons.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        texts = ['Separate Peaks']
        commands = [self.runPeakSeparator]
        self.runButton = ButtonList(frameA,
                                    texts=texts,
                                    commands=commands,
                                    expands=True,
                                    tipTexts=['Run peak search now'])
        self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew')

        #
        # FrameB : Further Settings
        #

        frameB.grid_columnconfigure(0, weight=1)

        row = 0

        div = LabelDivider(frameB, text='Rate:')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')
        row += 1

        label = Label(frameB, text='Rate of MCMC step size change')
        label.grid(row=row, column=0, columnspan=1, sticky='w')

        self.rateEntry = FloatEntry(frameB, returnCallback=self.applyChange, width=10, \
              tipText='Rate effects speed of run, smaller values take longer but may produce better results')
        self.rateEntry.grid(row=row, column=1, sticky='n')
        self.rateEntry.bind('<Leave>', self.applyChange, '+')
        self.rateEntry.set(self.params.rate)

        # tricky scrolled matrix for line width
        row += 2
        div = LabelDivider(frameB, text='Line Width (Hz):')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')

        row += 1
        label = Label(frameB, text="Descr.")
        label.grid(row=row, rowspan=2, column=0, sticky='w')

        row += 1
        self.lineWidthTable = None
        frameB.grid_rowconfigure(row, weight=1)
        lineWidthHeadings = ('dim.', 'min. σ (Hz)', 'max. σ (Hz)')

        self.editMinSigmaEntry = FloatEntry(self,
                                            returnCallback=self.applyChange,
                                            width=5,
                                            tipText='Minimum line width (Hz)')
        self.editMaxSigmaEntry = FloatEntry(self,
                                            returnCallback=self.applyChange,
                                            width=5,
                                            tipText='Maximum line width (Hz)')

        # self.editDimEntry is also from regionTable
        initialWidthRows = 4

        editLineWidthWidgets = [
            None, self.editMinSigmaEntry, self.editMaxSigmaEntry
        ]
        editLineWidthGetCallbacks = [None, self.getSigmaMin, self.getSigmaMax]
        editLineWidthSetCallbacks = [None, self.setSigmaMin, self.setSigmaMax]

        self.lineWidthTable = ScrolledMatrix(
            frameB,
            headingList=lineWidthHeadings,
            multiSelect=False,
            editWidgets=editLineWidthWidgets,
            editGetCallbacks=editLineWidthGetCallbacks,
            editSetCallbacks=editLineWidthSetCallbacks,
            initialRows=initialWidthRows)

        self.lineWidthTable.grid(row=row,
                                 column=0,
                                 columnspan=2,
                                 sticky='nsew')

        # option to 'repick' exisiting peak list
        row += initialWidthRows
        div = LabelDivider(frameB, text='(optional - repick entire peak list)')
        div.grid(row=row, column=0, columnspan=2, sticky='ew')
        row += 1

        self.repickListPulldown = PulldownList(
            frameB,
            callback=self.setRePickPeakList,
            tipText=
            'Select which peak list to repick (new peaks will be put into a new peak list)'
        )
        self.repickListPulldown.grid(row=row, column=0, sticky='nw')

        texts = ['Repick Peak List']
        commands = [self.runRepickPeaks]
        self.runButton = ButtonList(
            frameB,
            texts=texts,
            commands=commands,
            expands=True,
            tipTexts=['Repick selected peak list into a new peak list.'])
        self.runButton.grid(row=row, column=1, columnspan=1, sticky='nsew')

        row += 1
        div = LabelDivider(frameB)
        row += 1
        texts = ['Separate Peaks']
        commands = [self.runPeakSeparator]
        self.runButton = ButtonList(frameB,
                                    texts=texts,
                                    commands=commands,
                                    expands=True,
                                    tipTexts=['Run peak search now'])
        self.runButton.grid(row=row, column=0, columnspan=2, sticky='nsew')

        self.setWidgetEntries()

        self.administerNotifiers(self.registerNotify)

    def administerNotifiers(self, notifyFunc):

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

        notifyFunc(self.updateAfter, 'ccp.nmr.Nmr.Experiment', 'setName')
        notifyFunc(self.updateAfter, 'ccp.nmr.Nmr.DataSource', 'setName')

    def destroy(self):

        self.administerNotifiers(self.unregisterNotify)
        BasePopup.destroy(self)

    ###########################################################################
    # update parameters from PS Region

    def updateFromRegion(self):

        if not self.params.peakList:
            print '&&& update from region: Need a peak list'
            return

        if (self.argServer.parent.currentRegion) == None:
            showError('No Region',
                      'Please select a peak region to be separated')
            return

        self.rePickPeakList = False

        getRegionParams(self.params, argServer=self.argServer)

        if not self.customSigma: self.initSigmaParams()

        self.setWidgetEntries()

    ###########################################################################
    # update parameters from PS PeakList

    def updateFromPeakList(self):

        if not self.params.peakList:
            print '&&& update from peakList: Need a peak list'
            return

        getPeakListParams(self.params)

        if not self.customSigma: self.initSigmaParams()

        self.setWidgetEntries()

    ###########################################################################
    # Run the C library!

    def runPeakSeparator(self):
        """ run the peak separator """

        # hack for Macs - focus isn't always lost on mouse move
        # so bind event not always called. Shouldn't affect other OS.
        self.applyChange()

        if not self.params.peakList:
            print '&&& Peak list not yet set'
        else:
            # SeparatePeakRoutine(self.params, self.params.peakList, routine='pymc' )
            SeparatePeakRoutine(self.params,
                                self.params.peakList,
                                routine='bayesys')

    def runRepickPeaks(self):
        """ Run the Peak Separator on entire chosen peak list """
        # hack for Macs - focus isn't always lost on mouse move
        # so bind event not always called. Shouldn't affect other OS.
        self.applyChange()

        if not self.params.peakList:
            print '&&& Peak list not yet set'
        else:
            SeparatePeaksInPeakList(self.params)

    ###########################################################################

    def setWidgetEntries(self):

        ### Page One widgets
        self.minPeaksEntry.set(self.params.minAtoms)
        self.maxPeaksEntry.set(self.params.maxAtoms)

        if self.params.positivePeaks == 1:
            self.posPeaksButtons.set('True')  # only pick pos peaks
        else:
            self.posPeaksButtons.set('False')

        # do something fancy if different shapes for each dim!
        n = self.params.peakShape - 3  # shape is only 3, 4, (5)
        self.shapeButtons.setIndex(n)

        if self.project is not None:
            self.updatePeakListList()
        self.updateSpectrumWindow()

        if self.params.sampleStart and self.params.peakList:

            if not self.rePickPeakList:
                objectList = []
                textMatrix = []

                if len(self.params.samplePpmStart) != self.params.Ndim: return

                for i in range(self.params.Ndim):
                    dim_entry = []
                    dim_entry.append('%2d' % (i + 1))
                    dim_entry.append('%7.3f' % self.params.samplePpmStart[i])
                    dim_entry.append('%7.3f' % self.params.samplePpmEnd[i])
                    dim_entry.append('%3d' % self.params.sampleSize[i])
                    textMatrix.append(dim_entry)

                self.regionTable.update(textMatrix=textMatrix,
                                        objectList=objectList)

        ### Page Two widgets
        self.rateEntry.set(self.params.rate)

        if self.params.peakList and self.params.Ndim:

            textMatrix = []
            objectList = []

            for i in range(self.params.Ndim):
                if self.params.isFreqDim[i]:
                    dim_entry = []
                    objectList.append(i)
                    dim_entry.append('%2d' % (i + 1))
                    dim_entry.append('%7.3f' % self._minSigmaHz[i])
                    dim_entry.append('%7.3f' % self._maxSigmaHz[i])
                    textMatrix.append(dim_entry)

            self.lineWidthTable.update(textMatrix=textMatrix,
                                       objectList=objectList)

    def applyChange(self, *event):
        """ Upon change, add settings to params """

        # Page One apply changes
        self.params.minAtoms = self.minPeaksEntry.get()
        self.params.maxAtoms = self.maxPeaksEntry.get()

        if self.posPeaksButtons.get() == 'True':  # asked only pick pos peaks
            self.params.positivePeaks = 1
        else:
            self.params.positivePeaks = 0

        # do something fancy if different shapes for each dim!
        n = self.shapeButtons.getIndex()  # shape is only 3, 4, (5)
        self.params.peakShape = n + 3

        # Page Two apply changes
        self.params.rate = float(self.rateEntry.get())

        self.updateSigmaParams()

    ###########################################################################
    # Peak list functions provide PeakSeparator some inherited params

    def getPeakListList(self):
        """ given a spectrum, get list of peak lists """
        project = self.project

        peakLists = []
        for experiment in self.nmrProject.experiments:
            for spectrum in experiment.dataSources:
                for peakList in spectrum.peakLists:
                    peakLists.append([
                        '%s:%s:%d' %
                        (experiment.name, spectrum.name, peakList.serial),
                        peakList
                    ])
        peakLists.sort()
        return peakLists

    def updatePeakListList(self):
        """ set the peaklist list in the pulldown menu """
        peakListData = self.getPeakListList()

        index = -1
        names = []
        peakList = self.params.peakList

        if peakListData:
            names = [x[0] for x in peakListData]
            peakLists = [x[1] for x in peakListData]

            if peakList not in peakLists:
                peakList = peakLists[0]

            index = peakLists.index(peakList)

        else:
            peakList = None
            peakLists = []

        if peakList is not self.params.peakList:
            self.params.peakList = peakList

        self.peakListPulldown.setup(names, peakLists, index)
        self.repickListPulldown.setup(names, peakLists, index)

    def setRePickPeakList(self, peakList):
        """ Set the peak list to be repicked (and hit a Flag) """
        self.rePickPeakList = True
        self.setPeakList(peakList)

    def setManuallyPickPeakList(self, peakList):
        """ Set the peak list to add new peaks to (and hit a Flag) """
        self.rePickPeakList = False
        self.setPeakList(peakList)

    def setPeakList(self, peakList):
        """ Sets the Peak List """
        if peakList is not self.params.peakList:
            self.params.peakList = peakList
            # # interrogate the peak list and get all the usefull parameters out
            self.updateFromPeakList()
            self.updateSpectrumWindow()
            self.setWidgetEntries()

    ###########################################################################
    # TBD I suspect this is for matching region with peak list, but may be obsolete now

    def getSpectrumWindowList(self):
        """ get list of windows which spectrum could be in """
        windows = {}
        if self.params.peakList:
            views = getSpectrumViews(self.params.peakList.dataSource)
            for view in views:
                windows[view.spectrumWindowPane.spectrumWindow] = None

        return [[w.name, w] for w in windows.keys()]

    def updateSpectrumWindow(self):
        """ update the spectrum window """
        windowData = self.getSpectrumWindowList()

        index = -1
        names = []
        window = self.rootWindow

        if windowData:
            names = [x[0] for x in windowData]
            windows = [x[1] for x in windowData]

            if window not in windows:
                window = windows[0]

            index = windows.index(window)

        else:
            window = None
            windows = []

        if window is not self.rootWindow:
            self.rootWindow = window

    ###########################################################################
    # get and set sigma stuff
    def setSigmaMin(self, dim):

        value = self.editMinSigmaEntry.get()
        self._minSigmaHz[dim] = value

        # dont go and re-write users settings
        self.customSigma = True

        # make sure changes are in params object
        self.updateSigmaParams(dim)
        self.setWidgetEntries()

    def getSigmaMin(self, dim):

        if dim is not None:
            self.editMinSigmaEntry.set(self._minSigmaHz[dim])

    def setSigmaMax(self, dim):

        value = self.editMaxSigmaEntry.get()
        self._maxSigmaHz[dim] = value

        # dont go and re-write users settings
        self.customSigma = True

        # make sure changes are in params object
        self.updateSigmaParams(dim)
        self.setWidgetEntries()

    def getSigmaMax(self, dim):

        if dim is not None:
            self.editMaxSigmaEntry.set(self._maxSigmaHz[dim])

    def updateSigmaParams(self, dim=None):
        """ updateSigmaParams Just updates the parameters (params obj) for sigma values. 
        If dim is None, do this for each dim
    """

        dataDimRefs = self.params.dataDimRefs

        if not dataDimRefs: return

        if not self.params.minSigma or len(
                self.params.minSigma) != self.params.Ndim:
            self.params.minSigma = [0.] * self.params.Ndim

        if not self.params.maxSigma or len(
                self.params.maxSigma) != self.params.Ndim:
            self.params.maxSigma = [0.] * self.params.Ndim

        def updateSigmaParam(dim, dataDimRefs):
            """ Convert and update sigma for dim """

            if self.params.isFreqDim[dim]:
                # note factor of two!
                self.params.minSigma[dim] = self.rHz2pnt(
                    self._minSigmaHz[dim], dataDimRefs[dim]) / 2.
                self.params.maxSigma[dim] = self.rHz2pnt(
                    self._maxSigmaHz[dim], dataDimRefs[dim]) / 2.
            else:
                self.params.minSigma[dim] = 1.0
                self.params.maxSigma[dim] = 1.0

        if dim:
            updateSigmaParam(dim, dataDimRefs)
        else:
            for dim in range(self.params.Ndim):
                updateSigmaParam(dim, dataDimRefs)

    # utility functions for sigma values
    def pnt2rHz(self, point, dataDimRef):
        """ Point to relative Hz frequency relative to frequency at Zeroeth point
        Necessary when (for example) looking for width of peak in Hz
    """
        assert point, dataDimRef

        sigmaBase = pnt2hz(0, dataDimRef)
        sigmaHz = pnt2hz(point, dataDimRef)

        return abs(sigmaHz - sigmaBase)

    def rHz2pnt(self, freq, dataDimRef):
        """ Relative Hz to point frequency relative to frequency at Zeroeth point
        Necessary when (for example) looking for width of peak in Hz
    """
        assert freq, dataDimRef

        sigmaBase = hz2pnt(0, dataDimRef)
        sigmaPoint = hz2pnt(freq, dataDimRef)

        return abs(sigmaPoint - sigmaBase)

    def initSigmaParams(self):
        """ Set some initial default values for sigma """

        self._minSigmaHz = []
        self._maxSigmaHz = []

        if self.params.Ndim:
            for dim in range(self.params.Ndim):
                self._minSigmaHz.append(6.)
                self._maxSigmaHz.append(28.)

    ###########################################################################

    def updateAll(self):

        self.updateSpectrumWindow()
        self.updatePeakListList()

        self.waiting = False

    def updateAfter(self, obj=None):

        if self.waiting:
            return
        else:
            self.waiting = True
            self.after_idle(self.updateAll)
Exemplo n.º 29
0
class AssignMentTransferTab(object):
    '''the tab in the GUI where assignments
       can be transferred in bulk to the ccpn analysis
       project. A difference is made between two types
       of assignments:
           1) spin systems to residues, which also
              implies resonanceSets to atomSets.
           2) resonances to peak dimensions.
       The user is able to configure which assignments
       should be transferred to the project.

      Attributes:

          guiParent: gui object this tab is part of.

          frame: the frame in which this element lives.

          dataModel(src.cython.malandro.DataModel): dataModel
              object describing the assignment proposed by
              the algorithm.

          selectedSolution (int): The index of the solution/run
              that is used asa the template to make the assignments.

          resonanceToDimension (bool): True if resonances should
              be assigned to peak dimensions. False if not.

          spinSystemToResidue (bool): True if spin system to
              residue assignment should be carried out.

          minScore (float): The minimal score of a spin system
              assignment to a residue to be allowed
              to transfer this assignment to the project

          intra (bool): True if intra-residual peaks should be
              assigned.

          sequential (bool): True if sequential peaks should be
              assigned.

          noDiagonal (bool): If True, purely diagonal peaks are
              ignored during the transfer of assignments.

          allSpectra (bool): If True, all spectra will be assigned.
              If False, one specified spectrum will be assigned.

          spectrum (src.cython.malandro.Spectrum): The spectrum
              that should be assigned.
    '''

    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

        # Buttons and fields,
        # will be set in body():
        self.peaksCheckButton = None
        self.residuesCheckButton = None
        self.intraCheckButton = None
        self.sequentialCheckButton = None
        self.noDiagonalCheckButton = None
        self.spinSystemTypeSelect = None
        self.minScoreEntry = None
        self.solutionNumberEntry = None
        self.spectrumSelect = None
        self.spectraPullDown = None
        self.assignedResidueStrategySelect = None
        self.transferButton = None

        # Settings that determine how assignments
        # are transferred to the analysis project:
        self.minScore = 80.0
        self.dataModel = None
        self.spectrum = None
        self.selectedSolution = 1
        self.body()
        self.resonanceToDimension = True
        self.spinSystemToResidue = True
        self.intra = True
        self.sequential = True
        self.noDiagonal = True
        self.allSpectra = True
        self.spinSystemType = 0
        self.strategy = 0


    def body(self):
        '''Describes the body of this tab. It consists
           out of a number of radio buttons, check buttons
           and number entries that allow the user to
           indicate which assignments should be transferred.
        '''

        # self.frame.expandColumn(0)
        self.frame.expandGrid(8, 0)
        self.frame.expandGrid(8, 1)

        typeOfAssignmentFrame = LabelFrame(
            self.frame, text='type of assignment')
        typeOfAssignmentFrame.grid(row=0, column=0, sticky='nesw')
        # typeOfAssignmentFrame.expandGrid(0,5)

        peakSelectionFrame = LabelFrame(
            self.frame, text='which peaks to assign')
        peakSelectionFrame.grid(row=0, column=1, sticky='nesw', rowspan=2)

        spinSystemSelectionFrame = LabelFrame(self.frame,
                                              text='Which spin-systems to use')
        spinSystemSelectionFrame.grid(row=2, column=0, sticky='nesw')

        tipText = 'What to do when a residue has already a spin system assigned to it.'
        assignedResidueFrame = LabelFrame(self.frame,
                                          text='if residue already has spin-system',
                                          tipText=tipText)
        assignedResidueFrame.grid(row=2, column=1, sticky='nesw')

        spectrumSelectionFrame = LabelFrame(self.frame, text='spectra')
        spectrumSelectionFrame.grid(row=1, column=0, sticky='nesw')

        row = 0

        Label(typeOfAssignmentFrame,
              text='Resonances to Peak Dimensions',
              grid=(row, 0))
        self.peaksCheckButton = CheckButton(typeOfAssignmentFrame,
                                            selected=True,
                                            grid=(row, 1))

        row += 1

        Label(typeOfAssignmentFrame,
              text='SpinSystems to Residues',
              grid=(row, 0))
        self.residuesCheckButton = CheckButton(
            typeOfAssignmentFrame, selected=True, grid=(row, 1))

        row = 0

        Label(peakSelectionFrame, text='Intra-Residual', grid=(row, 0))
        self.intraCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        row += 1

        Label(peakSelectionFrame, text='Sequential', grid=(row, 0))
        self.sequentialCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        row += 1

        Label(peakSelectionFrame,
              text='Do not assign diagonal peaks',
              grid=(row, 0))
        self.noDiagonalCheckButton = CheckButton(
            peakSelectionFrame, selected=True, grid=(row, 1))

        entries = ['Only assigned spin systems',
                   'All that have a score of at least: ',
                   'User Defined',
                   'Solution number:']
        tipTexts = ['Only assign resonances of spin systems that already have a sequential assignment for the assignment of peak dimensions. Spin system to residue assignment is not relevant in this case.',
                    'Assign all spin systems that have a score of at least a given percentage. 50% or lower is not possible, because than spin systems might have to be assigned to more than 1 residue, which is impossible.',
                    "As defined in the lower row of buttons in the 'results' tab.",
                    'One of the single solutions of the annealing.']
        self.spinSystemTypeSelect = RadioButtons(spinSystemSelectionFrame,
                                                 entries=entries, grid=(0, 0),
                                                 select_callback=None,
                                                 direction=VERTICAL,
                                                 gridSpan=(4, 1),
                                                 tipTexts=tipTexts)

        tipText = 'The minimal amount of colabelling the different nuclei should have in order to still give rise to a peak.'
        self.minScoreEntry = FloatEntry(spinSystemSelectionFrame,
                                        grid=(1, 1), width=7,
                                        text=str(self.minScore),
                                        returnCallback=self.changeMinScore,
                                        tipText=tipText)
        self.minScoreEntry.bind('<Leave>', self.changeMinScore, '+')

        self.solutionNumberEntry = IntEntry(spinSystemSelectionFrame,
                                            grid=(3, 1), width=7, text=1,
                                            returnCallback=self.solutionUpdate,
                                            tipText=tipText)
        self.solutionNumberEntry.bind('<Leave>', self.solutionUpdate, '+')

        #self.solutionPullDown = PulldownList(spinSystemSelectionFrame, None, grid=(3,1), sticky='w')

        entries = ['all spectra', 'only:']
        tipTexts = ['Assign peaks in all the spectra that where selected before the annealing ran.',
                    'Only assign peaks in one particular spectrum. You can of course repeat this multiple times for different spectra.']
        self.spectrumSelect = RadioButtons(spectrumSelectionFrame,
                                           entries=entries,
                                           grid=(0, 0),
                                           select_callback=None,
                                           direction=VERTICAL,
                                           gridSpan=(2, 1), tipTexts=tipTexts)

        self.spectraPullDown = PulldownList(spectrumSelectionFrame,
                                            self.changeSpectrum,
                                            grid=(1, 1), sticky='w')

        entries = ['skip this residue',
                   'de-assign old spin system from residue',
                   'assign, but never merge',
                   'warn to merge']
        tipTexts = ["Don't assign the new spin system to the residue. The residue is not skipped when the old spin system does not contain any resonances",
                    "De-assign old spin system from residue, unless the old spin system is a spin system without any resonances.",
                    "Don't merge any spin systems, merging can be performed later if nescesary in the Resonance --> SpinSystems window.",
                    "Ask to merge individually for each spin system, this might result in clicking on a lot of popups."]
        self.assignedResidueStrategySelect = RadioButtons(assignedResidueFrame,
                                                          entries=entries,
                                                          grid=(0, 0),
                                                          select_callback=None,
                                                          direction=VERTICAL,
                                                          gridSpan=(2, 1),
                                                          tipTexts=tipTexts)

        texts = ['Transfer Assignments']
        commands = [self.transferAssignments]
        self.transferButton = ButtonList(
            self.frame, commands=commands, texts=texts)
        self.transferButton.grid(row=5, column=0, sticky='nsew', columnspan=2)

    def update(self):
        '''Update the nescesary elements in the
           tab. Is called when the algorithm
           has produced possible assignments.
           The only thing that has to be updated
           in practice in this tab is the pulldown
           with spectra.
        '''

        self.dataModel = self.guiParent.connector.results
        self.updateSpectra()

    def setDataModel(self, dataModel):
        '''Here the dataModel, which is the dataModel
           containing the suggested assignments body
           the algorithm, can be set.
        '''

        self.dataModel = dataModel
        self.update()

    def updateSpectra(self, *opt):
        '''Updates the spectra shown in the spectra
           pulldown. These are only the spectra that
           were used by the algorithm. All other spectra
           in the project are not relevant since for those
           no simulated peaks have been matched to real
           peaks.
        '''

        if not self.dataModel:

            return

        spectrum = self.spectrum

        spectra = self.dataModel.getSpectra()

        if spectra:

            names = [spectrum.name for spectrum in spectra]
            index = 0

            if self.spectrum not in spectra:

                self.spectrum = spectra[0]

            else:

                index = spectra.index(self.spectrum)

        self.spectraPullDown.setup(names, spectra, index)

    def changeSpectrum(self, spectrum):
        '''Select a spectum to be assigned.'''

        self.spectrum = spectrum

    def solutionUpdate(self, event=None, value=None):
        '''Select a solution. A solution is a
           one to one mapping of spin systems
           to residues produced by one run of
           the algorithm.
               args: event: event object, this is
                            one of the values the number
                            entry calls his callback
                            function with.
                     value: the index of the solution/run.
        '''

        if not self.dataModel:

            return

        Nsolutions = len(self.dataModel.chain.residues[0].solutions)

        if value is None:

            value = self.solutionNumberEntry.get()

        if value == self.selectedSolution:
            return
        else:
            self.selectedSolution = value
        if value < 1:
            self.solutionNumberEntry.set(1)
            self.selectedSolution = 1
        elif value > Nsolutions:
            self.selectedSolution = Nsolutions
            self.solutionNumberEntry.set(self.selectedSolution)
        else:
            self.solutionNumberEntry.set(self.selectedSolution)

    def fetchOptions(self):
        '''Fetches user set options from the gui in
           one go and stores them in their corresponding
           instance variables.
        '''

        self.resonanceToDimension = self.peaksCheckButton.get()
        self.spinSystemToResidue = self.residuesCheckButton.get()
        self.intra = self.intraCheckButton.get()
        self.sequential = self.sequentialCheckButton.get()
        self.noDiagonal = self.noDiagonalCheckButton.get()
        self.spinSystemType = self.spinSystemTypeSelect.getIndex()
        self.strategy = ['skip', 'remove', 'noMerge', None][
            self.assignedResidueStrategySelect.getIndex()]
        self.allSpectra = [True, False][self.spectrumSelect.getIndex()]

    def changeMinScore(self, event=None):
        '''Set the minimal score for which a spin system
           to residue assignment gets transferred to the
           ccpn analysis project.
        '''

        newMinScore = self.minScoreEntry.get()

        if self.minScore != newMinScore:

            if newMinScore <= 50.0:

                self.minScore = 51.0
                self.minScoreEntry.set(51.0)

            elif newMinScore > 100.0:

                self.minScore = 100.0
                self.minScoreEntry.set(100.0)

            else:

                self.minScore = newMinScore

    def transferAssignments(self):
        '''Transfer assignments to project depending
           on the settings from the GUI.
        '''

        self.fetchOptions()

        if not self.dataModel or (not self.resonanceToDimension and not self.spinSystemToResidue):

            return

        strategy = self.strategy

        lookupSpinSystem = [self.getAssignedSpinSystem,
                            self.getBestScoringSpinSystem,
                            self.getUserDefinedSpinSystem,
                            self.getSelectedSolutionSpinSystem][self.spinSystemType]

        residues = self.dataModel.chain.residues

        spinSystemSequence = [lookupSpinSystem(res) for res in residues]

        ccpnSpinSystems = []
        ccpnResidues = []

        # if self.spinSystemType == 0 it means that it for sure already
        # assigned like this
        if self.spinSystemToResidue and not self.spinSystemType == 0:

            for spinSys, res in zip(spinSystemSequence, residues):

                if spinSys and res:

                    ccpnSpinSystems.append(spinSys.getCcpnResonanceGroup())
                    ccpnResidues.append(res.getCcpnResidue())

            assignSpinSystemstoResidues(ccpnSpinSystems,
                                        ccpnResidues,
                                        strategy=strategy,
                                        guiParent=self.guiParent)

        if self.resonanceToDimension:

            allSpectra = self.allSpectra

            if self.intra:

                for residue, spinSystem in zip(residues, spinSystemSequence):

                    if not spinSystem:

                        continue

                    intraLink = residue.getIntraLink(spinSystem)

                    for pl in intraLink.getPeakLinks():

                        peak = pl.getPeak()

                        if not allSpectra and peak.getSpectrum() is not self.spectrum:

                            continue

                        if not peak:

                            continue

                        resonances = pl.getResonances()

                        if self.noDiagonal and len(set(resonances)) < len(resonances):

                            continue

                        for resonance, dimension in zip(resonances, peak.getDimensions()):

                            ccpnResonance = resonance.getCcpnResonance()
                            ccpnDimension = dimension.getCcpnDimension()
                            assignResToDim(ccpnDimension, ccpnResonance)

            if self.sequential:

                for residue, spinSystemA, spinSystemB in zip(residues,
                                                             spinSystemSequence,
                                                             spinSystemSequence[1:]):

                    if not spinSystemA or not spinSystemB:

                        continue

                    link = residue.getLink(spinSystemA, spinSystemB)

                    for pl in link.getPeakLinks():

                        peak = pl.getPeak()

                        if not allSpectra and peak.getSpectrum() is not self.spectrum:

                            continue

                        if not peak:

                            continue

                        resonances = pl.getResonances()

                        if self.noDiagonal and len(set(resonances)) < len(resonances):

                            continue

                        for resonance, dimension in zip(resonances, peak.getDimensions()):

                            ccpnResonance = resonance.getCcpnResonance()
                            ccpnDimension = dimension.getCcpnDimension()

                            assignResToDim(ccpnDimension, ccpnResonance)

        self.guiParent.resultsTab.update()

    def getAssignedSpinSystem(self, residue):
        '''Get the spinSystem that is assigned in the project
           to a residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        ccpCode = residue.ccpCode
        seqCode = residue.getSeqCode()
        spinSystems = self.dataModel.getSpinSystems()[ccpCode]

        ccpnResidue = residue.getCcpnResidue()
        if ccpnResidue:
            assignedResonanceGroups = ccpnResidue.getResonanceGroups()
            if len(assignedResonanceGroups) > 1:
                print 'There is more than one spin system assigned to residue %s, did not know which one to use to assign peaks. Therefor this residue is skipped.' % (seqCode)
                return

            assignedResonanceGroup = ccpnResidue.findFirstResonanceGroup()

            if assignedResonanceGroup:

                for spinSystem in spinSystems:

                    if spinSystem.getSerial() == assignedResonanceGroup.serial:
                        # Just checking to make sure, analysis project could
                        # have changed
                        if not self.skipResidue(residue, spinSystem):

                            return spinSystem

    def getBestScoringSpinSystem(self, residue):
        '''Get the spinSystem that scores the highest,
           i.e. is assigned in most of the runs to the
           given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        solutions = residue.solutions
        weigth = 1.0 / len(solutions)
        score, bestSpinSystem = max([(solutions.count(solution) * weigth * 100.0, solution) for solution in solutions])

        if score >= self.minScore and not bestSpinSystem.getIsJoker() and not self.skipResidue(residue, bestSpinSystem):

            return bestSpinSystem

        return None

    def getUserDefinedSpinSystem(self, residue):
        '''Get the spinSystem that is defined by the user
           (probably in the resultsTab) as the correct
           assignment of the given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        userDefinedSpinSystem = residue.userDefinedSolution

        if userDefinedSpinSystem and not userDefinedSpinSystem.getIsJoker() and not self.skipResidue(residue, userDefinedSpinSystem):

            return userDefinedSpinSystem

        return None

    def getSelectedSolutionSpinSystem(self, residue):
        '''I a solution corresponding to one specific run
           of the algorithm is defined, return which spinSystem
           in that run got assigned to the given residue.
           args:  residue (src.cython.malandro.Residue)
           return: spinSystem (src.cython.malandro.SpinSystem)
        '''

        solutions = residue.solutions

        spinSystem = solutions[self.selectedSolution - 1]

        if not spinSystem.getIsJoker() and not self.skipResidue(residue, spinSystem):

            return spinSystem

        return None

    def skipResidue(self, residue, spinSystem):
        '''One strategy is to skip all residues that
           already have a spin system assignment.
           If that is the case determine whether to
           skip the given residue.
           args: residue (src.cython.malandro.Residue)
                 spinSystem (src.cython.malandro.SpinSystem)
           return: boolean, True if residue should be skipped.
        '''

        if self.strategy == 0:

            assignedGroups = residue.getCcpnResidue().getResonanceGroups()
            assignedSerials = set([spinSys.serial for spinSys in assignedGroups])

            if assignedSerials and spinSystem.getSerial() not in assignedSerials:

                return True

        return False
Exemplo n.º 30
0
class WidgetCountPopup(BasePopup):

    on_off_entries = ['on', 'off']

    def __init__(self, parent, help_msg='', help_url='', *args, **kw):

        self.help_msg = help_msg
        self.help_url = help_url

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

    def body(self, master):

        self.alarm_id = None
        self.root_widget = getRoot(self)

        row = 0
        label = Label(master, text='Widget count:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.count_label = Label(master,
                                 text='',
                                 tipText='Number of Tkinter widget objects')
        self.count_label.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1
        ind = 1
        label = Label(master, text='Auto count:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.on_off_buttons = RadioButtons(master,
                                           entries=self.on_off_entries,
                                           select_callback=self.applyAuto,
                                           selected_index=ind)
        self.on_off_buttons.grid(row=row, column=1, sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text='Auto frequency:')
        label.grid(row=row, column=0, sticky=Tkinter.W)
        self.freq_entry = IntEntry(master,
                                   text=60,
                                   returnCallback=self.applyAuto)
        self.freq_entry.grid(row=row, column=1, sticky=Tkinter.EW)
        label = Label(master, text='seconds')
        label.grid(row=row, column=2, sticky=Tkinter.W)

        row = row + 1
        texts = ['Do Immediate Count']
        commands = [self.applyManual]
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              help_msg=self.help_msg,
                                              help_url=self.help_url)
        buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW)

        self.doCount()

    def applyAuto(self, *event):

        on_off = self.on_off_buttons.get()
        if on_off == 'on':
            self.setCountOn()
        else:
            self.setCountOff()

    def applyManual(self):

        self.doCount()

    def setCountOn(self):

        self.setCountOff()

        freq = self.freq_entry.get()
        if freq is not None and freq > 0:
            freq *= 1000  # convert from sec to msec
            self.alarm_id = self.after(freq, self.doCountAuto)

    def setCountOff(self):

        if self.alarm_id:
            self.after_cancel(self.alarm_id)
            self.alarm_id = None

    def doCountAuto(self):

        if self.on_off_buttons.get() == 'on':
            self.doCount()
            freq = self.freq_entry.get()
            if freq is not None and freq > 0:
                freq *= 1000  # convert from sec to msec
                self.alarm_id = self.after(freq, self.doCountAuto)

    def doCount(self):

        count = getWidgetCount(self.root_widget)
        self.count_label.set('%d' % count)