Esempio n. 1
0
class RegisterPopup(BasePopup):
    """
  **Register User with CCPN**

  The purpose of this dialog is to allow the user to register with CCPN.
  This is mainly to allow CCPN to keep track of the number of users,
  which is important for grant applications.  This information is saved
  both in a file on your computer but also in a private CCPN server
  database if your computer is connected to the internet.  (So unfortunately
  you will need to register once for each computer you use.)

  The required information: the user name, organisation and email address.
  The other information stored on the CCPN server: the version number, the
  first time and most recent time the server has been notifed.

  If you are registered, then the server is notified every time a project is
  opened or saved (if connected to the internet).

  Click "Register Now" to register, or "Register Later" not to register.
"""
    def __init__(self, parent, isModal=False, *args, **kw):

        title = 'Project : Register with CCPN'
        BasePopup.__init__(self,
                           parent=parent,
                           title=title,
                           modal=isModal,
                           **kw)

    def body(self, guiFrame):

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

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

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

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

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

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

        row += 1

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

        texts = ['Register Now', 'Read License', 'Register Later']
        tipTexts = ['Register now', 'Read License', 'Register later']
        commands = [self.register, self.openLicense, self.close]
        buttons = UtilityButtonList(guiFrame,
                                    helpUrl=self.help_url,
                                    grid=(row, 0),
                                    gridSpan=(1, 2),
                                    commands=commands,
                                    texts=texts,
                                    tipTexts=tipTexts)
        self.buttons = buttons

    def openLicense(self):
        licenseUrl = 'http://www.ccpn.ac.uk/license'
        try:
            import webbrowser
        except ImportError:
            showInfo('License Agreement',
                     'The CCPN License Agreement is available at %s' %
                     licenseUrl,
                     parent=self)
            return

        wb = webbrowser.get()
        wb.open(licenseUrl)

    def register(self):

        if not self.agreeButton.get():
            showError(
                'License Agreement',
                'Please tick the box indicating that you agree to the CCPN licensing terms and conditions.',
                parent=self)
            return

        analysisProfile = self.analysisProfile
        attrs = ('userName', 'userOrganisation', 'userEmail')
        for n, entry in enumerate(self.entryWidgets):
            attr = attrs[n]
            value = entry.get().strip()
            if not value:
                showError('Blank value',
                          '%s is blank, value required' % attr[4:],
                          parent=self)
                return
            if attr == 'userEmail' and '@' not in value:
                showError('Illegal email',
                          'Email must have "@" in it',
                          parent=self)
                return
            try:
                setattr(analysisProfile, attr, value)
            except Exception, e:
                showError('Attribute setting',
                          'Error setting %s: %s' % (attr[4:], e),
                          parent=self)
                return
        analysisProfile.save()
        try:
            result = updateRegister(analysisProfile)
            showInfo('Registering', result, parent=self)
            self.close()
        except Exception, e:
            showError('Registering', str(e), parent=self)
Esempio n. 2
0
class CalcHeteroNoePopup(BasePopup):
  """
  **Calculate Heteronuclear NOE Values From Peak Intensities**
  
  The purpose of this popup window is to calculate the heteronuclear NOE for
  amide resonances based upon a comparison of the peak intensities in spectra
  that derive from an NOE saturated experiment and an unsaturated (reference)
  experiment. The basic idea of this tool is that three peak lists are chosen,
  two of which are for heteronuclear NOE experiments (H,N axes); unsaturated
  reference and saturated, and one which is the source of assignments and peak
  locations. This last "Assignment" peak list may be the same as one of the NOE
  peak lists, but may also be entirely separate.

  The "Assignment" peak list is used to specify which peak assignments and
  locations should be used for the calculation of the heteronuclear NOE values,
  and thus can be used to specify only a subset of the resonances for
  measurement. For example, it is common to copy an HQSC peak list for use as
  the "Assignment" peak list but remove overlapped and NH2 peaks so that the NOE
  values are only calculated for separated backbone amides. The calculation
  process involves taking each of these assigned peaks and finding peaks with
  the same assignment in the NOE peak lists, or if that fails finding peaks with
  a similar position (within the stated tolerances); new peaks may be picked if
  the "Pick new peaks?" option is set.

  The first "Peak Lists & Settings" tab allows the user to choose the peak lists
  and various options that will be used in the peak-finding and NOE calculation.
  The "Peaks" table allows the peaks from each of the three peak list selections
  to be displayed when one of the "Show" buttons is clicked. The [Separate Peak
  Table] function allows these peaks to be displayed in the main, separate `Peak
  Lists`_ table, which has many more peak manipulation options. The options
  below the table may be used to locate selected peaks within the spectrum
  window displays.

  The second "Peak Intensity Comparison" tab is where the heteronuclear NOE
  values are actually calculated. Assuming that two NOE experiment peak lists
  have been chosen and that some of their peaks match the assigned peak
  positions then the peak intensities are extracted and NOE values automatically
  calculated when the tab is opened. Although, a refresh of the table can be
  forced with [Find Matching Peaks] at the bottom

  If pairs of NOE saturated and reference peaks are found then the actual
  heteronuclear NOE value is displayed as the "Intensity Ratio" in the last,
  rightmost, column of the table. To store these values as a NOE measurement
  list; so that the data can be saved in the CCPN project without need for
  recalculation, the [Create Hetero NOE List] function can be used. The results
  are then available to view at any time via the `Measurement Lists`_ table.

  **Caveats & Tips**

  Erroneous peak intensity comparisons may be removed with the [Remove Pairs]
  function, but its is common to curate the "Assign" peak list first and
  avoid tidying afterwards.

  The "Closeness score" can be used to find peak positions where the compared
  NOE peaks are unexpectedly far from one another.

  .. _`Peak Lists`: EditPeakListsPopup.html
  .. _`Measurement Lists`: EditMeasurementListsPopup.html
  
  """

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

    self.guiParent      = parent
    self.peakPairs      = []
    self.intensityType  = 'height'
    self.selectedPair   = None
    self.assignPeakList = None
    self.refPeakList    = None
    self.satPeakList    = None
    self.displayPeakList = None
    self.waiting        = 0
  
    BasePopup.__init__(self, parent, title="Data Analysis : Heteronuclear NOE", **kw)

  def body(self, guiFrame):

    self.geometry('700x700')
   
    guiFrame.expandGrid(0,0)
    
    options = ['Peak Lists & Settings','Peak Intensity Comparison']
    tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.changeTab)
    tabbedFrame.grid(row=0, column=0, sticky='nsew')
    self.tabbedFrame = tabbedFrame
    frameA, frameB = tabbedFrame.frames

    row = 0
    frameA.grid_columnconfigure(1, weight=1)
    frameA.grid_columnconfigure(3, weight=1)
    frameA.grid_columnconfigure(5, weight=1)
    frameA.grid_rowconfigure(5, weight=1)

    tipText = 'Number of reference peaks (no saturation)'
    self.peaksALabel = Label(frameA, text='Number of Ref Peaks: ', tipText=tipText)
    self.peaksALabel.grid(row=1,column=0,columnspan=2,sticky='w')

    tipText = 'Number of NOE saturation peaks'
    self.peaksBLabel = Label(frameA, text='Number of Sat Peaks: ', tipText=tipText)
    self.peaksBLabel.grid(row=1,column=2,columnspan=2,sticky='w')

    tipText = 'Number of peaks in assigned list'
    self.peaksCLabel = Label(frameA, text='Number of Assign Peaks: ', tipText=tipText)
    self.peaksCLabel.grid(row=1,column=4,columnspan=2,sticky='w')
    
    tipText = 'Selects which peak list is considered the NOE intensity reference (no saturation)'
    specALabel = Label(frameA, text='Ref Peak List: ')
    specALabel.grid(row=0,column=0,sticky='w')
    self.specAPulldown = PulldownList(frameA, callback=self.setRefPeakList, tipText=tipText)
    self.specAPulldown.grid(row=0,column=1,sticky='w')

    tipText = 'Selects which peak list is considered as NOE saturated.'
    specBLabel = Label(frameA, text='Sat Peak List: ')
    specBLabel.grid(row=0,column=2,sticky='w')
    self.specBPulldown = PulldownList(frameA, callback=self.setSatPeakList, tipText=tipText)
    self.specBPulldown.grid(row=0,column=3,sticky='w')

    tipText = 'Selects a peak list with assignments to use as a positional reference'
    specCLabel = Label(frameA, text='Assignment Peak List: ')
    specCLabel.grid(row=0,column=4,sticky='w')
    self.specCPulldown = PulldownList(frameA, callback=self.setAssignPeakList, tipText=tipText)
    self.specCPulldown.grid(row=0,column=5,sticky='w')

    frame0a = Frame(frameA)
    frame0a.grid(row=2,column=0,columnspan=6,sticky='nsew')
    frame0a.grid_columnconfigure(9, weight=1)
    
    tipText = '1H ppm tolerance for matching assigned peaks to reference & NOE saturation peaks'
    tolHLabel   = Label(frame0a, text='Tolerances: 1H')
    tolHLabel.grid(row=0,column=0,sticky='w')
    self.tolHEntry = FloatEntry(frame0a,text='0.02', width=6, tipText=tipText)
    self.tolHEntry .grid(row=0,column=1,sticky='w')  

    tipText = '15N ppm tolerance for matching assigned peaks to reference & NOE saturation peaks'
    tolNLabel   = Label(frame0a, text=' 15N')
    tolNLabel .grid(row=0,column=2,sticky='w')   
    self.tolNEntry = FloatEntry(frame0a,text='0.1', width=6, tipText=tipText)
    self.tolNEntry .grid(row=0,column=3,sticky='w')   

    tipText = 'Whether to peak new peaks in reference & NOE saturated lists (at assignment locations)'
    label = Label(frame0a, text=' Pick new peaks?', grid=(0,4)) 
    self.pickPeaksSelect = CheckButton(frame0a, tipText=tipText,
                                       grid=(0,5), selected=True)

    tipText = 'Whether to assign peaks in the peaks in the reference & NOE saturation lists, if not already assigned'
    label = Label(frame0a, text=' Assign peaks?')
    label.grid(row=0,column=6,sticky='w')   
    self.assignSelect = CheckButton(frame0a, tipText=tipText)
    self.assignSelect.set(1)
    self.assignSelect.grid(row=0,column=7,sticky='w')    

    tipText = 'Whether to consider peak height or volume in the heteronuclear NOE calculation'
    intensLabel = Label(frame0a, text=' Intensity Type:')
    intensLabel .grid(row=0,column=8,sticky='w')   
    self.intensPulldown = PulldownList(frame0a, texts=['height','volume'],
                                       callback=self.setIntensityType,
                                       tipText=tipText)
    self.intensPulldown.grid(row=0,column=9,sticky='w')    

    divider = LabelDivider(frameA, text='Peaks', grid=(3,0),
                           gridSpan=(1,6))

    tipTexts = ['Show the selected intensity reference peaks in the below table',
                'Show the selected NOE saturation peaks in the below table',
                'Show the selected assigned peak list in the below table',
                'Show the displayed peaks in a separate peak table, where assignments etc. may be adjusted']
    texts    = ['Show Ref Peaks','Show Sat Peaks',
                'Show Assign Peaks', 'Separate Peak Table']
    commands = [self.viewRefPeakList, self.viewSatPeakList,
                self.viewAssignPeakList, self.viewSeparatePeakTable]
    self.viewPeaksButtons = ButtonList(frameA, expands=True, tipTexts=tipTexts,
                                       texts=texts, commands=commands)
    self.viewPeaksButtons.grid(row=4,column=0,columnspan=6,sticky='nsew')

    self.peakTable = PeakTableFrame(frameA, self.guiParent, grid=(5,0),
                                    gridSpan=(1,6))
    self.peakTable.bottomButtons1.grid_forget()
    self.peakTable.bottomButtons2.grid_forget()
    #self.peakTable.topFrame.grid_forget()
    self.peakTable.topFrame.grid(row=2, column=0, sticky='ew')
    # Next tab

    frameB.expandGrid(0,0)
    
    tipTexts = ['Row number',
                'Assignment annotation for NOE saturation peak',
                'Assignment annotation for reference peak (no saturation)',
                '1H chemical shift of NOE saturation peak',
                '1H chemical shift of reference peak',
                '15N chemical shift of NOE saturation peak',
                '15N chemical shift of reference peak',
                'The separation between compared peaks: square root of the sum of ppm differences squared',
                'The intensity if the NOE saturation peak',
                'The intensity of the reference peak (no saturation)',
                'Ratio of peak intensities: saturated over reference',
                'Residue(s) for reference peak']
    colHeadings      = ['#','Sat Peak','Ref Peak','1H shift A',
                        '1H shift B','15N shift A','15N shift B',
                        'Closeness\nScore','Intensity A','Intensity B',
                        'Intensity\nRatio','Residue']
    self.scrolledMatrix = ScrolledMatrix(frameB, multiSelect=True, 
                                         headingList=colHeadings,
                                         callback=self.selectCell,
                                         tipTexts=tipTexts,
                                         grid=(0,0),
                                         deleteFunc=self.removePair)

    tipTexts = ['Force a manual update of the table; pair-up NOE saturation and reference peaks according to assigned peak positions',
                'Remove the selected rows of peak pairs',
                'Show peaks corresponding to the selected row in a table',
                'Save the Heteronuclear NOE values in the CCPN project as a data list']
    texts    = ['Refresh Table','Remove Pairs',
                'Show Peak Pair','Create Hetero NOE List']
    commands = [self.matchPeaks,self.removePair,
                self.showPeakPair,self.makeNoeList]
    self.pairButtons = ButtonList(frameB, tipTexts=tipTexts, grid=(1,0),
                                  texts=texts, commands=commands)


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

    self.administerNotifiers(self.registerNotify)

  def administerNotifiers(self, notifyFunc):

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

    for func in ('__init__', 'delete','setAnnotation','setFigOfMerit'):
      notifyFunc(self.updatePeaks, 'ccp.nmr.Nmr.Peak', func)
    for func in ('setAnnotation','setPosition','setNumAliasing'):
      notifyFunc(self.updatePeakChild, 'ccp.nmr.Nmr.PeakDim', func)
    for func in ('__init__', 'delete', 'setValue'):
      notifyFunc(self.updatePeakChild, 'ccp.nmr.Nmr.PeakIntensity', func)

  def changeTab(self, index):
  
    if index == 1:
      self.matchPeaks()

  def open(self):
  
    self.updatePulldowns()
    self.updateAfter()
    BasePopup.open(self)
    
    
  def destroy(self):
  
    self.administerNotifiers(self.unregisterNotify)

    BasePopup.destroy(self)
 
  def updatePulldowns(self, *obj):

    index0 = 0
    index1 = 0
    index2 = 0
    names, peakLists = self.getPeakLists()
    
    if names:

      if self.refPeakList not in peakLists:
        self.refPeakList = peakLists[0]

      if  self.satPeakList not in peakLists:
        self.satPeakList = peakLists[0]

      if self.assignPeakList not in peakLists:
        self.assignPeakList = peakLists[0]

      index0 = peakLists.index(self.refPeakList)
      index1 = peakLists.index(self.satPeakList)
      index2 = peakLists.index(self.assignPeakList)
    
    self.specAPulldown.setup(names, peakLists, index0)
    self.specBPulldown.setup(names, peakLists, index1)
    self.specCPulldown.setup(names, peakLists, index2)

  def updatePeakChild(self,peakChild):
  
    if self.waiting:
      return
    
    self.updatePeaks(peakChild.peak)
  
  def updatePeaks(self, peak):
  
    if self.waiting:
      return
    
    if peak.peakList in (self.refPeakList,self.satPeakList,self.assignPeakList):
      if peak.isDeleted and (peak.peakList in (self.refPeakList,self.satPeakList) ):
        for peaks in self.peakPairs:
          if peak in peaks:
            self.peakPairs.remove(peaks)
            if self.selectedPair is peaks:
              self.selectedPair = None
            self.updateAfter()
            return
            
      self.updateAfter()
 
  def setIntensityType(self, intensityType):
    
    self.intensityType = intensityType
    self.updateAfter()
  
  def viewRefPeakList(self):
  
    if self.refPeakList:
      self.updatePeakTable(self.refPeakList)
   
  def viewSatPeakList(self):
  
    if self.satPeakList:
      self.updatePeakTable(self.satPeakList)
  
  def viewAssignPeakList(self):
  
    if self.assignPeakList:
      self.updatePeakTable(self.assignPeakList)
  
  def viewSeparatePeakTable(self):
  
    if self.displayPeakList:
      self.guiParent.editPeakList(peakList=self.displayPeakList)
  
  def setRefPeakList(self, refPeakList):
  
    if self.displayPeakList is self.refPeakList:
      self.updatePeakTable(refPeakList)

    self.refPeakList = refPeakList
    self.updateViewButtons()
    self.updateAfter()
  
  def setSatPeakList(self, satPeakList):
  
    if self.displayPeakList is self.satPeakList:
      self.updatePeakTable(satPeakList)
      
    self.satPeakList = satPeakList
    self.updateViewButtons()
    self.updateAfter()
  
  def setAssignPeakList(self, assignPeakList):
  
    if self.displayPeakList is self.assignPeakList:
      self.updatePeakTable(assignPeakList)
      
    self.assignPeakList = assignPeakList
    self.updateViewButtons()
    self.updateAfter()
  
  def getPeakListName(self, peakList):
  
    if peakList:
      spectrum = peakList.dataSource
      experiment = spectrum.experiment
      name = '%s:%s:%d' % (experiment.name, spectrum.name, peakList.serial)
    else:
      name = '<None>'
  
    return name
  
  def getPeakLists(self):
  
    names = []
    peakLists = []
    
    for experiment in self.nmrProject.sortedExperiments():
      for dataSource in experiment.sortedDataSources():
        if dataSource.numDim == 2:
          dimsN = findSpectrumDimsByIsotope(dataSource,'15N')
          dimsH = findSpectrumDimsByIsotope(dataSource,'1H')
          if len(dimsN) == 1 and len(dimsH) == 1:
            for peakList in dataSource.sortedPeakLists():
              name = self.getPeakListName(peakList)
              names.append( name )
              peakLists.append(peakList)
    
    return names, peakLists
  
  def showPeakPair(self):
  
    if self.selectedPair:
      self.guiParent.viewPeaks(self.selectedPair)
          
  def selectCell(self, object, row, col):
  
    self.selectedPair = object

    if self.selectedPair:
      self.pairButtons.buttons[1].enable()
      self.pairButtons.buttons[2].enable()
    else:
      self.pairButtons.buttons[1].disable()
      self.pairButtons.buttons[2].disable()
  
  def removePair(self, *event):
  
    pairs = self.scrolledMatrix.currentObjects
    
    if pairs:
      for pair in pairs:
        self.peakPairs.remove(pair)
        
      self.selectedPair = None
      self.updateAfter()
  
  def matchPeaks(self):
  
    # assign relative to reference
    
    if self.assignPeakList and self.assignPeakList.peaks and self.refPeakList and self.satPeakList:
 
      tolH = float( self.tolHEntry.get() )
      tolN = float( self.tolNEntry.get() )
      pickNewPeaks = self.pickPeaksSelect.get()
      doAssign     = self.assignSelect.get()
 
      dimH  = findSpectrumDimsByIsotope(self.assignPeakList.dataSource,'1H' )[0]
      dimHA = findSpectrumDimsByIsotope(self.refPeakList.dataSource,'1H' )[0]
      dimHB = findSpectrumDimsByIsotope(self.satPeakList.dataSource,'1H' )[0]
      dimN  = 1-dimH
      dimNA = 1-dimHA
      dimNB = 1-dimHB
 
      tolerancesA = [0,0]
      tolerancesA[dimHA] = tolH
      tolerancesA[dimNA] = tolN

      tolerancesB = [0,0]
      tolerancesB[dimHB] = tolH
      tolerancesB[dimNB] = tolN
 
      self.peakPairs = matchHnoePeaks(self.assignPeakList,self.refPeakList,
                                      self.satPeakList,tolerancesA,tolerancesB,
                                      pickNewPeaks,doAssign)
 
      self.updateAfter()
 
  def makeNoeList(self):

    if self.refPeakList is self.satPeakList:
      showWarning('Same Peak List',
                  'Ref Peak List and Sat Peak List cannot be the same',
                  parent=self)
      return

    if self.peakPairs:
      s1 = self.refPeakList.dataSource
      s2 = self.satPeakList.dataSource
      noiseRef = getSpectrumNoise(s1)
      noiseSat = getSpectrumNoise(s2)
      
      es = '%s-%s' % (s1.experiment.name,s2.experiment.name)
      if len(es) > 50:
        es = 'Expt(%d)-Expt(%d)' % (s1.experiment.serial,s2.experiment.serial)

      noeList = self.nmrProject.newNoeList(unit='None',name='Hetero NOE list for %s' % es)
      noeList.setExperiments([s1.experiment,])
      if s1.experiment is not s2.experiment:
        noeList.addExperiment( s2.experiment )
      # TBD: sf, noeValueType, refValue, refDescription
    
      resonancePairsSeen = set()
      for (peakA,peakB) in self.peakPairs: # peakA is sat
        intensA    = getPeakIntensity(peakA,self.intensityType)
        intensB    = getPeakIntensity(peakB,self.intensityType)
        value      = float(intensA)/intensB
        error      = abs(value) * sqrt((noiseSat/intensA)**2 + (noiseRef/intensB)**2)
        resonances = tuple(self.getPeakResonances(peakA))
        frozenResonances = frozenset(resonances)
        if len(resonances) < 2:
          pl = peakA.peakList
          sp = pl.dataSource
          msg = 'Skipping %s:%s:%d peak %d it has too few resonances assigned'
          data = (sp.experiment.name, sp.name, pl.serial, peakA.serial)
          showWarning('Warning',msg % data, parent=self)
        
        elif len(resonances) > 2:
          pl = peakA.peakList
          sp = pl.dataSource
          resonanceText = ' '.join([makeResonanceGuiName(r) for r in resonances])
          msg = 'Skipping %s:%s:%d peak %d it has too many resonances assigned (%s)'
          data = (sp.experiment.name, sp.name, pl.serial, peakA.serial, resonanceText)
          showWarning('Warning', msg % data, parent=self)
        
        elif frozenResonances not in resonancePairsSeen:
          resonancePairsSeen.add(frozenResonances)
          noeList.newNoe(value=value,resonances=resonances,peaks=[peakA,peakB],error=error)
          
        else:
          resonanceText = ' '.join([makeResonanceGuiName(r) for r in resonances])
          msg = 'Skipping duplicate entry for resonances %s' % resonanceText
          showWarning('Warning', msg, parent=self)

      self.parent.editMeasurements(measurementList=noeList)

  def getPeakResonances(self,peak):
  
    resonances = []
    for peakDim in peak.sortedPeakDims():
      for contrib in peakDim.sortedPeakDimContribs():
        resonances.append(contrib.resonance)
    
    return resonances

  def updateAfter(self, *opt):

    if self.waiting:
      return
    else:
      self.waiting = True
      self.after_idle(self.update)
 
  def updateViewButtons(self):
  
    if self.refPeakList:
      self.viewPeaksButtons.buttons[0].enable()
    else:
      self.viewPeaksButtons.buttons[0].disable()
  
    if self.satPeakList:
      self.viewPeaksButtons.buttons[1].enable()
    else:
      self.viewPeaksButtons.buttons[1].disable()
  
    if self.assignPeakList:
      self.viewPeaksButtons.buttons[2].enable()
    else:
      self.viewPeaksButtons.buttons[2].disable()
  
  def updatePeakTable(self, peakList):
    
    if peakList is not self.displayPeakList:
      self.displayPeakList = peakList
      self.peakTable.update(peaks=peakList.sortedPeaks())

  
  def update(self):

    if self.refPeakList:
      self.peaksALabel.set( 'Number of Ref Peaks: %d' % len(self.refPeakList.peaks) )
    else:
      self.peaksALabel.set( 'Number of Ref Peaks: %d' % 0 )
    if self.satPeakList:
      self.peaksBLabel.set( 'Number of Sat Peaks: %d' % len(self.satPeakList.peaks) )
    else:
      self.peaksBLabel.set( 'Number of Sat Peaks: %d' % 0 )
    if self.assignPeakList:
      self.peaksCLabel.set( 'Number of Assign Peaks: %d' % len(self.assignPeakList.peaks) )
    else:
      self.peaksCLabel.set( 'Number of Assign Peaks: %d' % 0 )

    if self.refPeakList and self.satPeakList and self.assignPeakList:
      if self.refPeakList is self.satPeakList:
        self.pairButtons.buttons[0].disable()
      else:
        self.pairButtons.buttons[0].enable()
    else:
      self.pairButtons.buttons[0].disable()
 
    if self.selectedPair:
      self.pairButtons.buttons[1].enable()
      self.pairButtons.buttons[2].enable()
    else:
      self.pairButtons.buttons[1].disable()
      self.pairButtons.buttons[2].disable()

    if self.peakPairs:
      self.pairButtons.buttons[3].enable()
      dsA = self.peakPairs[0][0].peakList.dataSource
      dsB = self.peakPairs[0][1].peakList.dataSource
      dimHA = findSpectrumDimsByIsotope(dsA,'1H')[0]
      dimHB = findSpectrumDimsByIsotope(dsB,'1H')[0]
      dimNA = findSpectrumDimsByIsotope(dsA,'15N')[0]
      dimNB = findSpectrumDimsByIsotope(dsB,'15N')[0]
    else:
      self.pairButtons.buttons[3].disable()
    
    objectList  = []
    textMatrix  = []

    i = 0
    for (peakA,peakB) in self.peakPairs:
      i += 1

      peakDimsA = peakA.sortedPeakDims()
      peakDimsB = peakB.sortedPeakDims()

      ppm0 = peakDimsA[dimHA].value
      ppm1 = peakDimsB[dimHB].value
      ppm2 = peakDimsA[dimNA].value
      ppm3 = peakDimsB[dimNB].value
      d0 = abs(ppm0-ppm1)
      d1 = abs(ppm2-ppm3)
      intensA = getPeakIntensity(peakA,self.intensityType)
      intensB = getPeakIntensity(peakB,self.intensityType)
      datum = []
      datum.append( i )
      datum.append( getPeakAnnotation(peakA, doPeakDims=False) )
      datum.append( getPeakAnnotation(peakB, doPeakDims=False) )
      datum.append( ppm0 )
      datum.append( ppm1 )
      datum.append( ppm2 )
      datum.append( ppm3 )
      datum.append( sqrt((d0*d0)+(d1*d1)) )
      datum.append( intensA )
      datum.append( intensB )
      if intensB:
        datum.append( float(intensA)/intensB )
      else:
        datum.append( None )
      seqCodes = ','.join(['%s' % seqCode for seqCode in getPeakSeqCodes(peakB)])
      datum.append(seqCodes)
      
      objectList.append( (peakA,peakB) )
      textMatrix.append( datum )
      
    if not objectList:
      textMatrix.append([])

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

    self.waiting = False
Esempio n. 3
0
class MeccanoPopup(BasePopup):

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

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

    self.curateNotifiers(self.registerNotify)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Sequence

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

    # Media, RDCs & Dihedrals

    rdcLists = []
    dihedralLists = []

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  def selectShiftList(self, shiftList):
  
    if shiftList is not self.shiftList:
      if self.run:
        self.run.setInputMeasurementLists([shiftList])
      
      self.shiftList = shiftList                   
Esempio n. 4
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)  
Esempio n. 5
0
class CreateShiftListPopup(BasePopup):

    help_url = joinPath(getHelpUrlDir(), 'CreateShiftList.html')

    def __init__(self, parent, project):

        self.project = project
        self.peakLists = []

        BasePopup.__init__(self,
                           parent=parent,
                           title="Project '%s': " % project.name +
                           'Create shift list from peak lists',
                           modal=False,
                           transient=True)

    def body(self, master):

        #
        # Peaklist setup
        #

        self.peakListDict = {}

        for experiment in self.project.currentNmrProject.sortedExperiments():
            for dataSource in experiment.sortedDataSources():
                for peakList in dataSource.sortedPeakLists():

                    peakListLabel = "%s:%s:%d:%s" % (
                        experiment.name, dataSource.name, peakList.serial,
                        peakList.name)

                    self.peakListDict[peakListLabel] = peakList

        peakListLabels = self.peakListDict.keys()
        peakListLabels.sort()

        #
        # chemical shift list setup
        #

        self.shiftListDict = {}
        self.shiftListDict['None'] = None

        for shiftList in self.project.currentNmrProject.findAllMeasurementLists(
                className='ShiftList'):

            shiftListLabel = "%d:%s" % (shiftList.serial, shiftList.name)

            self.shiftListDict[shiftListLabel] = shiftList

        shiftListLabels = self.shiftListDict.keys()
        shiftListLabels.sort()

        row = 0

        label = Label(master, text="Generation of chemical shift list")
        label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W)

        row += 1

        label = Label(master, text="Peak lists:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.peakListBox = ScrolledListbox(master,
                                           width=50,
                                           height=5,
                                           selectmode=Tkinter.MULTIPLE,
                                           initial_list=peakListLabels)
        self.peakListBox.grid(row=row, column=1, sticky=Tkinter.EW)

        row += 1

        label = Label(master, text="Use existing shift list:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.shiftListSelect = PulldownMenu(master, entries=shiftListLabels)
        self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW)

        row += 1

        label = Label(master, text="Use multiple assignments:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.useAllContribs = CheckButton(master)
        self.useAllContribs.grid(row=row, column=1, sticky=Tkinter.W)

        #
        # Setup the default shift error per nucleus
        #

        self.defaultShiftError = {}

        for (nucl, text, defValue) in [('1H', 'proton', '0.002'),
                                       ('13C', 'carbon', '0.1'),
                                       ('15N', 'nitrogen', '0.1')]:

            row += 1

            label = Label(master, text="Default %s shift error:" % text)
            label.grid(row=row, column=0, sticky=Tkinter.W)

            self.defaultShiftError[nucl] = Entry(master, text=defValue)
            self.defaultShiftError[nucl].grid(row=row,
                                              column=1,
                                              sticky=Tkinter.W)

        row += 1

        texts = ['Create shift list']
        commands = [
            self.ok
        ]  # This calls 'ok' in BasePopup, this then calls 'apply' in here
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              help_url=self.help_url)
        buttons.grid(row=row, columnspan=2, column=0)

    def apply(self):

        selectedPeakLists = self.peakListBox.getSelectedItems()

        for peakListLabel in selectedPeakLists:

            self.peakLists.append(self.peakListDict[peakListLabel])

        chemShiftList = self.shiftListDict[self.shiftListSelect.getSelected()]

        if not chemShiftList:

            chemShiftListName = askString("Enter chemical shift list name",
                                          "New chemical shift list name", '',
                                          self)

        else:

            chemShiftListName = chemShiftList.name

        useAllContribs = self.useAllContribs.isSelected()

        defaultShiftError = {}
        for nucl in self.defaultShiftError.keys():
            defaultShiftError[nucl] = returnFloat(
                self.defaultShiftError[nucl].get())

        listCreated = createChemShifts(self.peakLists,
                                       guiParent=self.parent,
                                       multiDialog=self.parent.multiDialog,
                                       shiftList=chemShiftList,
                                       useAllContribs=useAllContribs,
                                       defaultShiftError=defaultShiftError,
                                       shiftListName=chemShiftListName)

        if listCreated:
            showInfo(
                "Success",
                "Succesfully created a chemical shift list from peaklist(s)")

        return True
Esempio n. 6
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
Esempio n. 7
0
class ArchiveProjectPopup(BasePopup):
    """
  **Archive the Project**

  This popup window enables the user to archive the CCPN Project into a gzipped
  tar file.  By default it only includes the *.xml files which reside in the
  project directory.  If the "Include *.xml.bak files" check button is checked
  then it will also include the *.xml.bak files which reside in the project
  directory.  If the "Include data files which are in the project directory"
  check button is checked then it will also include the binary data files
  which reside in the project directory.

  **Caveats & Tips**

  The archive excludes the reference data *.xml files (quite sensibly).
"""
    def __init__(self,
                 parent,
                 project,
                 title='Project : Archive',
                 callback=None,
                 help_msg='',
                 help_url='',
                 dismiss_text='',
                 *args,
                 **kw):

        self.callback = callback
        self.help_msg = help_msg
        self.help_url = help_url
        self.dismiss_text = dismiss_text
        BasePopup.__init__(self,
                           parent=parent,
                           project=project,
                           title=title,
                           *args,
                           **kw)

    def body(self, guiParent):

        now = datetime.date.today().strftime('%y%m%d')
        filePrefix = '%s_%s' % (self.project.name, now)
        projDir = getUserDataPath(self.project)
        directory = os.path.dirname(projDir)

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

        row = 0
        label = Label(guiParent, text='Archive File:')
        label.grid(row=row, column=0, sticky=Tkinter.E)
        tipText = 'File name (excluding .tgz ending) for archive'
        self.fileEntry = Entry(guiParent, text=filePrefix, tipText=tipText)
        self.fileEntry.grid(row=row, column=1, sticky=Tkinter.EW)
        label = Label(guiParent, text='.tgz (automatically appended)')
        label.grid(row=row, column=2, sticky=Tkinter.W)

        row = row + 1
        self.backupCheck = CheckButton(
            guiParent,
            text='Include *.xml.bak files',
            tipText='If checked include *.xml.bak files')
        self.backupCheck.grid(row=row,
                              column=1,
                              columnspan=2,
                              sticky=Tkinter.W)

        row = row + 1
        self.dataCheck = CheckButton(
            guiParent,
            text='Include data files which are in project directory',
            tipText=
            'If checked include data files if they are located in project directory'
        )
        self.dataCheck.grid(row=row, column=1, columnspan=2, sticky=Tkinter.W)

        row = row + 1
        labelFrame = LabelFrame(guiParent, text='Archive Location')
        labelFrame.grid(row=row, column=0, columnspan=3, sticky=Tkinter.NSEW)
        labelFrame.grid_rowconfigure(0, weight=1)
        labelFrame.grid_columnconfigure(0, weight=1)

        self.dirSelect = FileSelect(labelFrame,
                                    directory=directory,
                                    show_file=False)
        self.dirSelect.grid(row=0, column=0, sticky=Tkinter.NSEW)

        guiParent.grid_rowconfigure(row, weight=1)

        row = row + 1
        texts = ['Save']
        tipTexts = ['Create archive file']
        commands = [self.save]
        buttons = createDismissHelpButtonList(guiParent,
                                              texts=texts,
                                              tipTexts=tipTexts,
                                              commands=commands,
                                              help_msg=self.help_msg,
                                              help_url=self.help_url,
                                              dismiss_text=self.dismiss_text,
                                              expands=True)
        buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW)

    def save(self):

        filePrefix = self.fileEntry.get()
        directory = self.dirSelect.getDirectory()
        filePrefix = joinPath(directory, filePrefix)
        fileName = filePrefix + '.tgz'

        if os.path.exists(fileName):
            if not showYesNo('File exists',
                             'File "%s" exists, overwrite?' % fileName,
                             parent=self):
                return

        includeBackups = self.backupCheck.isSelected()
        includeData = self.dataCheck.isSelected()
        packageProject(self.project, filePrefix, includeBackups, includeData)
Esempio n. 8
0
    def __init__(self,
                 parent,
                 entries,
                 select_callback=None,
                 selected=None,
                 direction=Tkinter.HORIZONTAL,
                 docKeys=None,
                 tipTexts=None,
                 *args,
                 **kw):

        if tipTexts and (len(tipTexts) == 1):
            # for length 1 tooltips just put on frame, rather than individual checkButtons
            tipText = tipTexts[0]
            if docKeys:
                docKey = docKeys[0]
            else:
                docKey = None
            tipTexts = None
            docKeys = None
        else:
            tipText = None
            docKey = None

        Frame.__init__(self,
                       parent,
                       docKey=docKey,
                       tipText=tipText,
                       createToolTip=True,
                       *args,
                       **kw)

        self.entries = entries
        self.select_callback = select_callback
        self.buttons = []

        if selected is None:
            selected = [False] * len(entries)

        nentries = len(entries)
        if not docKeys:
            docKeys = [None] * nentries

        if not tipTexts:
            tipTexts = [None] * nentries

        for n, entry in enumerate(entries):

            if select_callback:
                callback = self.doCallback
            else:
                callback = None

            b = CheckButton(self,
                            text=str(entry),
                            callback=callback,
                            docKey=docKeys[n],
                            tipText=tipTexts[n],
                            selected=selected[n])

            if direction == Tkinter.HORIZONTAL:
                b.grid(row=0, column=n, sticky='nw')
            else:
                b.grid(row=n, sticky='nw')

            self.buttons.append(b)
Esempio n. 9
0
class MidgePopup(BasePopup):
    def __init__(self, parent, *args, **kw):

        self.guiParent = parent
        self.project = parent.getProject()
        self.waiting = 0
        self.specFreq = 800.13
        self.maxIter = 15
        self.mixTime = 60
        self.corrTime = 11.5
        self.leakRate = 2.0
        self.ratioHD = 0.9
        self.peakListDict = {}
        self.peakListDict3d = {}
        self.noesyPeakList = None
        self.noesy3dPeakList = None
        self.carbonLabel = 0
        self.nitrogenLabel = 1
        self.noesyPeakList1 = None
        self.noesyPeakList2 = None
        self.noesyPeakList3 = None
        self.noesyPeakList3d = None

        self.resonances = None
        self.noesyPeaks = None
        self.distanceConstraintList = None
        self.antiDistConstraintList = None
        self.adcAtomTypes = None
        self.structure = None

        BasePopup.__init__(self,
                           parent,
                           title="Relaxation Matrix Optimisation",
                           **kw)

    def body(self, guiFrame):

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

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

        row = 0
        labelFrame0 = LabelFrame(guiFrame, text='Input data')
        labelFrame0.grid(row=row, column=0, sticky=Tkinter.NSEW)
        labelFrame0.grid_columnconfigure(3, weight=1)

        label = Label(labelFrame0, text='Assigned NOESY spectrum')
        label.grid(row=0, column=0, sticky=Tkinter.NW)
        self.noesyPulldown = PulldownMenu(labelFrame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.noesyPulldown.grid(row=0, column=1, sticky=Tkinter.NW)

        label = Label(labelFrame0, text='H/D ratio: ')
        label.grid(row=0, column=2, sticky=Tkinter.NW)
        self.ratioHDEntry = FloatEntry(labelFrame0, text=self.ratioHD, width=6)
        self.ratioHDEntry.grid(row=0, column=3, sticky=Tkinter.NW)

        label = Label(labelFrame0, text='NOESY spectrum 1:')
        label.grid(row=1, column=0, sticky=Tkinter.NW)
        self.tmix1Pulldown = PulldownMenu(labelFrame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy1,
                                          selected_index=-0,
                                          do_initial_callback=0)
        self.tmix1Pulldown.grid(row=1, column=1, sticky=Tkinter.NW)
        label = Label(labelFrame0, text='Tmix (ms): ')
        label.grid(row=1, column=2, sticky=Tkinter.NW)
        self.tmix1Entry = FloatEntry(labelFrame0, text=60, width=6)
        self.tmix1Entry.grid(row=1, column=3, sticky=Tkinter.NW)

        label = Label(labelFrame0, text='NOESY spectrum 2:')
        label.grid(row=2, column=0, sticky=Tkinter.NW)
        self.tmix2Pulldown = PulldownMenu(labelFrame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy2,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.tmix2Pulldown.grid(row=2, column=1, sticky=Tkinter.NW)
        label = Label(labelFrame0, text='Tmix (ms): ')
        label.grid(row=2, column=2, sticky=Tkinter.NW)
        self.tmix2Entry = FloatEntry(labelFrame0, text=120, width=6)
        self.tmix2Entry.grid(row=2, column=3, sticky=Tkinter.NW)

        label = Label(labelFrame0, text='NOESY spectrum 3:')
        label.grid(row=3, column=0, sticky=Tkinter.NW)
        self.tmix3Pulldown = PulldownMenu(labelFrame0,
                                          entries=self.getNoesys(),
                                          callback=self.setNoesy3,
                                          selected_index=0,
                                          do_initial_callback=0)
        self.tmix3Pulldown.grid(row=3, column=1, sticky=Tkinter.NW)
        label = Label(labelFrame0, text='Tmix (ms): ')
        label.grid(row=3, column=2, sticky=Tkinter.NW)
        self.tmix3Entry = FloatEntry(labelFrame0, text=200, width=6)
        self.tmix3Entry.grid(row=3, column=3, sticky=Tkinter.NW)

        label = Label(labelFrame0, text='3D NOESY:')
        label.grid(row=4, column=0, sticky=Tkinter.NW)
        self.noesy3dPulldown = PulldownMenu(labelFrame0,
                                            entries=self.getNoesys3d(),
                                            callback=self.setNoesy3d,
                                            selected_index=0,
                                            do_initial_callback=0)
        self.noesy3dPulldown.grid(row=4, column=1, sticky=Tkinter.NW)

        label10 = Label(labelFrame0, text='Num peaks:')
        label10.grid(row=5, column=0, sticky=Tkinter.NW)
        self.numPeaksLabel = Label(labelFrame0, text='0')
        self.numPeaksLabel.grid(row=5, column=1, sticky=Tkinter.NW)

        label11 = Label(labelFrame0, text='Num resonances:')
        label11.grid(row=5, column=2, sticky=Tkinter.NW)
        self.numResonancesLabel = Label(labelFrame0, text='0')
        self.numResonancesLabel.grid(row=5, column=3, sticky=Tkinter.NW)

        row += 1
        labelFrame1 = LabelFrame(guiFrame, text='Parameters')
        labelFrame1.grid(row=row, column=0, sticky=Tkinter.NSEW)
        labelFrame1.grid_columnconfigure(3, weight=1)

        label = Label(labelFrame1, text='15N labelled sample:')
        label.grid(row=0, column=0, sticky=Tkinter.NW)
        self.nitrogenSelect = CheckButton(labelFrame1,
                                          callback=self.setNitrogenLabel)
        self.nitrogenSelect.grid(row=0, column=1, sticky=Tkinter.W)
        self.nitrogenSelect.set(1)

        label = Label(labelFrame1, text='13C labelled sample:')
        label.grid(row=0, column=2, sticky=Tkinter.NW)
        self.carbonSelect = CheckButton(labelFrame1,
                                        callback=self.setCarbonLabel)
        self.carbonSelect.grid(row=0, column=3, sticky=Tkinter.W)
        self.carbonSelect.set(0)

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

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

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

        row += 1
        labelFrame2 = LabelFrame(guiFrame, text='Output')
        labelFrame2.grid(row=row, column=0, sticky=Tkinter.NSEW)
        labelFrame2.grid_columnconfigure(3, weight=1)

        label20 = Label(labelFrame2, text='Distance constraints:')
        label20.grid(row=0, column=0, sticky=Tkinter.NW)
        self.distConstrLabel = Label(labelFrame2, text='0')
        self.distConstrLabel.grid(row=0, column=1, sticky=Tkinter.NW)

        label21 = Label(labelFrame2, text='Anti-distance constraints:')
        label21.grid(row=0, column=2, sticky=Tkinter.NW)
        self.antiConstrLabel = Label(labelFrame2, text='0')
        self.antiConstrLabel.grid(row=0, column=3, sticky=Tkinter.NW)

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

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

        self.getPeaks()
        self.getResonances()
        self.update()

        self.geometry('600x400')

    def setCarbonLabel(self, boolean):

        self.carbonLabel = boolean

    def setNitrogenLabel(self, boolean):

        self.nitrogenLabel = boolean

    def update(self):

        if self.resonances and (
            (self.noesyPeaks and self.noesyPeakList1 and self.noesyPeakList2
             and self.noesyPeakList3) or self.noesyPeakList3d):
            self.midgeButtons.buttons[0].enable()
        else:
            self.midgeButtons.buttons[0].disable()

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

        if self.antiDistConstraintList:
            self.antiConstrLabel.set(
                str(len(self.antiDistConstraintList.constraints)))
            self.midgeButtons.buttons[2].enable()
        else:
            self.antiConstrLabel.set('')
            self.midgeButtons.buttons[2].disable()

        if self.resonances:
            self.numResonancesLabel.set(str(len(self.resonances)))
        else:
            self.numResonancesLabel.set('')

        if self.noesyPeaks:
            self.numPeaksLabel.set(str(len(self.noesyPeaks)))
        else:
            self.numPeaksLabel.set('')

    def getStructures(self):

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

        return names

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

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

            self.structure = structures[index - 1]

    def getAdcAtomTypes(self):

        return ['<None>', 'HN', 'HN HA', 'HN HA HB']

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

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

        if name == '<None>':
            name = None

        self.adcAtomTypes = name

    def getResonances(self):

        resonanceDict = {}
        if self.noesyPeaks:
            for peak in self.noesyPeaks:
                for peakDim in peak.peakDims:
                    for contrib in peakDim.peakDimContribs:
                        resonanceDict[contrib.resonance] = 1
                        # TBD: Set resonance.name for typing

        self.resonances = resonanceDict.keys()

    def getPeaks(self):

        if self.noesyPeakList:
            self.noesyPeaks = self.noesyPeakList.sortedPeaks()

    def calculateDistances(self):

        resonances = list(self.resonances)

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

        ratioHD = self.ratioHDEntry.get() or self.ratioHD

        tmix1 = self.tmix1Entry.get() or 60
        tmix2 = self.tmix2Entry.get() or 120
        tmix3 = self.tmix3Entry.get() or 200

        data = [(tmix1, self.noesyPeakList1), (tmix2, self.noesyPeakList2),
                (tmix3, self.noesyPeakList3)]
        data.sort()

        mixingTimes = [x[0] for x in data]
        peakLists = [x[1] for x in data]

        # get a clean, symmetric and normalised NOE matrix
        noeMatrix = getNoeMatrixFromPeaks(self.noesyPeaks,
                                          resonances,
                                          peakLists,
                                          mixingTimes,
                                          ratioHD=ratioHD,
                                          analysis=self.guiParent)

        # optimiseRelaxation will remove unconstrained resonances
        self.distanceConstraintList, resonances = optimiseRelaxation(
            resonances,
            noeMatrix,
            self.mixTime,
            self.specFreq,
            self.corrTime,
            self.leakRate,
            self.carbonLabel,
            self.nitrogenLabel,
            maxIter=self.maxIter)

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

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

        if self.distanceConstraintList and self.noesyPeakList:
            constraintHead = self.distanceConstraintList.nmrConstraintStore

            if self.adcAtomTypes:
                adcDict = {
                    'HN': ['H'],
                    'HN HA': ['H', 'HA', 'HA1', 'HA2'],
                    'HN HA HB': ['H', 'HA', 'HA1', 'HA2', 'HB', 'HB2', 'HB3']
                }

                allowedAtomTypes = adcDict[self.adcAtomTypes]

                print "Making ADCs"
                self.antiDistConstraintList = makeNoeAdcs(
                    resonances[:],
                    self.noesyPeakList.dataSource,
                    constraintHead,
                    allowedAtomTypes=allowedAtomTypes)
                print "Done ADCs"

            if self.structure:

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

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

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

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

                    constraint.setOrigData(distance)

        self.update()

    def showConstraints(self):

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

    def showAntiConstraints(self):

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

    def getNoesys3d(self):

        peakLists = getThroughSpacePeakLists(self.project)

        names = [
            '<None>',
        ]
        for peakList in peakLists:
            spectrum = peakList.dataSource
            if spectrum.numDim != 3:
                continue

            name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                 peakList.serial)
            names.append(name)
            self.peakListDict3d[name] = peakList
            if not self.noesyPeakList:
                self.noesyPeakList = peakList

        return names

    def getNoesys(self):

        peakLists = getThroughSpacePeakLists(self.project)

        names = [
            '<None>',
        ]
        for peakList in peakLists:
            spectrum = peakList.dataSource
            name = '%s:%s:%s' % (spectrum.experiment.name, spectrum.name,
                                 peakList.serial)
            names.append(name)
            self.peakListDict[name] = peakList

            if not self.noesyPeakList:
                self.noesyPeakList = peakList

        return names

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

        if not name:
            name = self.noesyPulldown.getSelected()

        if name == '<None>':
            self.noesyPeakList = None

        else:
            self.noesyPeakList = self.peakListDict[name]

        self.getPeaks()
        self.getResonances()
        self.update()

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

        if not name:
            name = self.tmix1Pulldown.getSelected()

        if name != '<None>':
            self.noesyPeakList1 = self.peakListDict[name]
        else:
            self.noesyPeakList1 = None

        self.update()

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

        if not name:
            name = self.tmix2Pulldown.getSelected()

        if name != '<None>':
            self.noesyPeakList2 = self.peakListDict[name]
        else:
            self.noesyPeakList2 = None

        self.update()

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

        if not name:
            name = self.tmix3Pulldown.getSelected()

        if name != '<None>':
            self.noesyPeakList3 = self.peakListDict[name]
        else:
            self.noesyPeakList3 = None

        self.update()

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

        if not name:
            name = self.noesy3dPulldown.getSelected()

        if name != '<None>':
            self.noesyPeakList3d = self.peakListDict3d[name]
            self.noesyPeaks = self.noesyPeakList3d.sortedPeaks()

        else:
            self.noesyPeakList3d = None
            self.noesyPeaks = []

        self.getResonances()
        self.update()

    def updateMidgeParams(self):

        data = [
            self.specFreq, self.maxIter, self.mixTime, self.corrTime,
            self.leakRate
        ]

        self.midgeParamsMatrix.update(textMatrix=[
            data,
        ])

    def getSpecFreq(self, obj):

        self.specFreqEntry.set(self.specFreq)

    def getMaxIter(self, obj):

        self.maxIterEntry.set(self.maxIter)

    def getMixTime(self, obj):

        self.mixTimeEntry.set(self.mixTime)

    def getCorrTime(self, obj):

        self.corrTimeEntry.set(self.corrTime)

    def getLeakRate(self, obj):

        self.leakRateEntry.set(self.leakRate)

    def setSpecFreq(self, event):

        value = self.specFreqEntry.get()
        if value is not None:
            self.specFreq = value

        self.updateMidgeParams()

    def setMaxIter(self, event):

        value = self.maxIterEntry.get()
        if value is not None:
            self.maxIter = value

        self.updateMidgeParams()

    def setMixTime(self, event):

        value = self.mixTimeEntry.get()
        if value is not None:
            self.mixTime = value

        self.updateMidgeParams()

    def setCorrTime(self, event):

        value = self.corrTimeEntry.get()
        if value is not None:
            self.corrTime = value

        self.updateMidgeParams()

    def setLeakRate(self, event):

        value = self.leakRateEntry.get()
        if value is not None:
            self.leakRate = value

        self.updateMidgeParams()

    def destroy(self):

        BasePopup.destroy(self)
Esempio n. 10
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
Esempio n. 11
0
class SaveProjectFrame(Frame):
    def __init__(self,
                 guiParent,
                 project,
                 callback=None,
                 help_msg='',
                 help_url='',
                 dismiss_text='',
                 modal=False,
                 *args,
                 **kw):

        self.project = project
        self.callback = callback
        self.help_msg = help_msg
        self.help_url = help_url
        self.dismiss_text = dismiss_text
        self.modal = modal

        self.did_save = False

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

        projDir = Io.getUserDataPath(self.project)

        guiParent.grid_columnconfigure(1, weight=1)

        row = 0

        label = Label(guiParent, text='Project Name:')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.proj_name_entry = Entry(
            guiParent,
            text=self.project.name,
            returnCallback=self.updateInfo,
            leaveCallback=self.updateInfo,
            tipText='The name used for the project save directory')
        self.proj_name_entry.grid(row=row, column=1, sticky=Tkinter.EW)

        row = row + 1
        label = Label(guiParent, text='Project Directory:')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        label = self.proj_dir_label = Label(guiParent, text=projDir)
        label.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1
        label = Label(
            guiParent,
            text='Note: Project Directory = Save Location + Project Name')
        label.grid(row=row, column=1, sticky=Tkinter.W)

        text = 'Save binary data with project'
        tipText = 'Copy data files (e.g. for spectra) into new project directory if not already in current project directory: careful, this can take some time'
        row = row + 1
        self.dataCheckButton = CheckButton(guiParent,
                                           text=text,
                                           tipText=tipText)
        self.dataCheckButton.grid(row=row,
                                  column=0,
                                  columnspan=2,
                                  sticky=Tkinter.W)

        row = row + 1
        guiParent.grid_rowconfigure(row, weight=1)
        labelFrame = LabelFrame(guiParent, text='Save Location')
        labelFrame.grid(row=row, column=0, columnspan=2, sticky=Tkinter.NSEW)
        labelFrame.grid_rowconfigure(0, weight=1)
        labelFrame.grid_columnconfigure(0, weight=1)

        directory = os.path.dirname(projDir)
        self.proj_dir_select = FileSelect(
            labelFrame,
            directory=directory,
            select_dir_callback=self.selectDir,
            change_dir_callback=self.updateInfo,
            should_change_dir_callback=self.shouldChangeDir,
            getRowColor=self.getEntryColor,
            show_file=False)
        self.proj_dir_select.grid(row=0, column=0, sticky=Tkinter.NSEW)

        row = row + 1
        texts = ['Save']
        tipTexts = ['Save project with specified name in specified directory']
        commands = [self.save]
        buttons = createDismissHelpButtonList(guiParent,
                                              texts=texts,
                                              tipTexts=tipTexts,
                                              commands=commands,
                                              help_msg=self.help_msg,
                                              help_url=self.help_url,
                                              dismiss_text=self.dismiss_text,
                                              expands=True)
        buttons.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW)

    def save(self):

        projName = self.proj_name_entry.get()
        directory = self.proj_dir_select.getDirectory()
        directory = joinPath(directory, projName)
        if self.isProjectDirectory(directory):
            if not showOkCancel('Overwrite directory',
                                'Overwrite existing project directory?',
                                parent=self):
                return

        self.updateInfo()

        self.did_save = False
        changeDataLocations = self.dataCheckButton.isSelected()
        done = False
        try:
            done = Io.saveProject(self.project,
                                  newPath=directory,
                                  newProjectName=projName,
                                  createFallback=True,
                                  showYesNo=showYesNo,
                                  changeDataLocations=changeDataLocations,
                                  showWarning=showWarning)

            if done:
                showInfo('Project saved', 'Project saved successfully')
                self.did_save = True
                if self.callback:
                    self.callback(self.project)
            elif self.modal:
                return  # give another chance
        except Implementation.ApiError, e:
            showError('Save project', e.error_msg)
        except IOError, e:
            showError('Save project', str(e))
Esempio n. 12
0
class EditSymmetryPopup(BasePopup):
    def __init__(self, parent, project):

        self.parent = parent
        self.project = project
        self.singleMolecule = True
        self.molSystem = None
        self.molecules = []
        self.symmetrySet = None
        self.symmetryOp = None
        self.waiting = False

        BasePopup.__init__(self, parent=parent, title='Symmetry Operations')

    def body(self, guiFrame):

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

        frame = LabelFrame(guiFrame, text='Options')
        frame.grid(row=0, column=0, sticky='ew')
        frame.grid_columnconfigure(5, weight=1)

        label = Label(frame, text='MolSystem:')
        label.grid(row=0, column=0, sticky='w')
        self.molSystemPulldown = PulldownMenu(frame,
                                              callback=self.selectMolSystem)
        self.molSystemPulldown.grid(row=0, column=1, sticky='w')

        self.molLabel = Label(frame, text='Molecule:')
        self.molLabel.grid(row=0, column=2, sticky='w')
        self.moleculePulldown = PulldownMenu(frame,
                                             callback=self.selectMolecule)
        self.moleculePulldown.grid(row=0, column=3, sticky='w')

        label = Label(frame, text='Same Molecule Symmetry:')
        label.grid(row=0, column=4, sticky='w')
        self.molSelect = CheckButton(frame, callback=self.toggleSingleMolecule)
        self.molSelect.grid(row=0, column=5, sticky='w')
        self.molSelect.set(self.singleMolecule)

        frame = LabelFrame(guiFrame, text='Symmetry Operations')
        frame.grid(row=1, column=0, sticky='nsew')
        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(0, weight=1)

        self.symmCodePulldown = PulldownMenu(self,
                                             callback=self.setSymmCode,
                                             do_initial_callback=False)
        self.segLengthEntry = IntEntry(self,
                                       returnCallback=self.setSegLength,
                                       width=6)
        self.setChainMulti = MultiWidget(self,
                                         CheckButton,
                                         callback=self.setChains,
                                         minRows=0,
                                         useImages=False)
        self.setSegmentMulti = MultiWidget(self,
                                           IntEntry,
                                           callback=self.setSegments,
                                           minRows=0,
                                           useImages=False)

        editWidgets = [
            None, self.symmCodePulldown, self.segLengthEntry,
            self.setChainMulti, self.setSegmentMulti
        ]
        editGetCallbacks = [
            None, self.getSymmCode, self.getSegLength, self.getChains,
            self.getSegments
        ]
        editSetCallbacks = [
            None, self.setSymmCode, self.setSegLength, self.setChains,
            self.setSegments
        ]

        headings = [
            '#', 'Symmetry\nType', 'Segment\nLength', 'Chains',
            'Segment\nPositions'
        ]
        self.symmetryMatrix = ScrolledMatrix(frame,
                                             headingList=headings,
                                             callback=self.selectSymmetry,
                                             editWidgets=editWidgets,
                                             editGetCallbacks=editGetCallbacks,
                                             editSetCallbacks=editSetCallbacks)
        self.symmetryMatrix.grid(row=0, column=0, sticky='nsew')

        texts = ['Add Symmetry Op', 'Remove Symmetrey Op']
        commands = [self.addSymmOp, self.removeSymmOp]
        buttonList = createDismissHelpButtonList(guiFrame,
                                                 texts=texts,
                                                 commands=commands,
                                                 expands=True)
        buttonList.grid(row=2, column=0, sticky='ew')

        self.updateMolSystems()
        self.updateMolecules()
        self.updateSymmetriesAfter()

        self.notify(self.registerNotify)

    def open(self):

        self.updateMolSystems()
        self.updateMolecules()
        self.updateSymmetriesAfter()

        BasePopup.open(self)

    def notify(self, notifyFunc):

        for func in ('__init__', 'delete', 'setSymmetryCode',
                     'setSegmentLength'):
            notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Symmetry',
                       func)

        for func in ('__init__', 'delete', 'setfirstSeqId'):
            notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Segment',
                       func)

    def getSymmCode(self, symmetryOp):
        """Get allowed symmetry operators from the model"""

        symmetryOpCodes = symmetryOp.parent.metaclass.container.getElement(
            'SymmetryOpCode').enumeration
        index = 0

        if symmetryOp.symmetryCode in symmetryOpCodes:
            index = symmetryOpCodes.index(symmetryOp.symmetryCode)

        self.symmCodePulldown.setup(symmetryOpCodes, index)

    def getSegLength(self, symmetryOp):

        if symmetryOp and symmetryOp.segmentLength:
            self.segLengthEntry.set(symmetryOp.segmentLength)

    def getChains(self, symmetryOp):

        chains = []
        for chain in self.molSystem.chains:
            if chain.residues:
                if chain.molecule in self.molecules: chains.append(chain.code)
        chains.sort()

        values = []
        for chain in chains:
            if symmetryOp.findFirstSegment(chainCode=chain):
                values.append(True)
            else:
                values.append(False)

        self.setChainMulti.set(values=values, options=chains)

    def getSegments(self, symmetryOp):

        values = []
        names = []

        if symmetryOp:
            for segment in symmetryOp.sortedSegments():
                names.append(segment.chainCode)
                values.append(segment.firstSeqId)

        n = len(values)
        self.setSegmentMulti.maxRows = n
        self.setSegmentMulti.minRows = n
        self.setSegmentMulti.set(values=values, options=names)

    def setSymmCode(self, index, name=None):
        """Set the symmetry code as NCS,C2,C3,C4,C5,C6"""

        if self.symmetryOp:
            symmCode = self.symmCodePulldown.getSelected()
            self.symmetryOp.symmetryCode = symmCode

    def setSegLength(self, event):

        value = self.segLengthEntry.get() or 1
        self.symmetryOp.segmentLength = value

    def setChains(self, obj):

        if self.symmetryOp and obj:
            codes = self.setChainMulti.options
            segment = self.symmetryOp.findFirstSegment()
            values = self.setChainMulti.get()

            if segment: seqId0 = segment.firstSeqId
            else: seqId0 = 1

            for i in range(len(values)):
                segment = self.symmetryOp.findFirstSegment(chainCode=codes[i])

                if segment and not values[i]: segment.delete()
                elif values[i] and not segment:
                    chain = self.molSystem.findFirstChain(code=codes[i])
                    residue = chain.findFirstResidue(seqid=seqId0)

                    if residue: seqId = seqId0
                    else:
                        residue = chain.sortedResidues()[0]
                        seqId = residue.seqId

                    residue2 = chain.findFirstResidue(
                        seqid=seqId + self.symmetryOp.segmentLength)
                    if not residue2:
                        residue2 = chain.sortedResidues()[-1]
                        self.symmetryOp.segmentLength = (residue2.seqId -
                                                         seqId) + 1

                    segment = self.symmetryOp.newSegment(chainCode=codes[i],
                                                         firstSeqId=seqId)

        self.symmetryMatrix.keyPressEscape()

    def setSegments(self, obj):

        if self.symmetryOp and obj:
            segments = self.symmetryOp.sortedSegments()
            values = self.setSegmentMulti.get()

            for i in range(len(values)):
                seqCode = values[i]
                chain = self.molSystem.findFirstChain(
                    code=segments[i].chainCode)
                residue = chain.findFirstResidue(seqCode=seqCode)

                if residue: seqId = residue.seqId
                if segments[i].firstSeqId != seqId:
                    segments[i].delete()
                    segments[i] = self.symmetryOp.newSegment(
                        chainCode=chain.code, firstSeqId=seqId)

        self.symmetryMatrix.keyPressEscape()

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

        self.symmetryOp = obj

    def addSymmOp(self):

        if self.molSystem:
            if not self.symmetrySet:
                self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet(
                )

            if not self.symmetrySet:
                objGen = self.project.newMolSystemSymmetrySet
                self.symmetrySet = objGen(symmetrySetId=1,
                                          molSystem=self.molSystem)

            segLen = len(self.molSystem.findFirstChain().residues)
            symmetry = self.symmetrySet.newSymmetry(segmentLength=segLen)

    def removeSymmOp(self):

        if self.symmetryOp: self.symmetryOp.delete()

    def toggleSingleMolecule(self, boolean):

        self.singleMolecule = not boolean
        self.updateMolSystems()
        self.updateMolecules()

    def setMolecules(self, molecules):

        self.molecules = molecules
        if self.symmetrySet:
            for symmetryOp in self.symmetrySet.symmetries:
                for segment in symmetryOp.segments:
                    chain = self.molSystem.findFirstChain(
                        code=segment.chainCode)
                if chain and (chain.molecule not in molecules):
                    segment.delete()

    def selectMolecule(self, index, name):

        self.setMolecules(self.getMolecules()[index])
        self.updateSymmetries()

    def getMolecules(self):

        counts = {}
        moleculesList = []

        for chain in self.molSystem.chains:
            molecule = chain.molecule
            counts[molecule] = counts.get(molecule, 0) + 1

        molecules = counts.keys()
        if self.singleMolecule:
            for molecule in counts:
                if counts[molecule] > 1: moleculesList.append([
                        molecule,
                ])

        elif molecules:
            molecules = counts.keys()
            n = len(molecules)
            moleculesList.append([
                molecules[0],
            ])

            if n > 1:
                moleculesList.append([
                    molecules[1],
                ])
                moleculesList.append([molecules[0], molecules[1]])

            if n > 2:
                moleculesList.append([
                    molecules[2],
                ])
                moleculesList.append([molecules[1], molecules[2]])
                moleculesList.append(
                    [molecules[0], molecules[1], molecules[2]])

            if n > 3:
                moleculesList.append([
                    molecules[3],
                ])
                moleculesList.append([molecules[0], molecules[3]])
                moleculesList.append([molecules[1], molecules[3]])
                moleculesList.append([molecules[2], molecules[3]])
                moleculesList.append(
                    [molecules[0], molecules[1], molecules[3]])
                moleculesList.append(
                    [molecules[0], molecules[2], molecules[3]])
                moleculesList.append(
                    [molecules[1], molecules[2], molecules[3]])
                moleculesList.append(
                    [molecules[0], molecules[1], molecules[2], molecules[3]])

        return moleculesList

    def updateMolecules(self):

        names = []
        index = -1
        moleculesList = self.getMolecules()
        if moleculesList:
            if self.molecules not in moleculesList:
                self.setMolecules(moleculesList[0])
                self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet(
                )

            index = moleculesList.index(self.molecules)

            names = []
            for molecules in moleculesList:
                names.append(','.join([mol.name for mol in molecules]))

        else:
            self.molecules = []

        self.moleculePulldown.setup(names, index)

    def selectMolSystem(self, index, name):

        self.molSystem = self.getMolSystems()[index]
        self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet()
        self.updateSymmetries()

    def getMolSystems(self):

        molSystems = []
        for molSystem in self.project.sortedMolSystems():
            n = len(molSystem.chains)

            if self.singleMolecule and (n > 1): molSystems.append(molSystem)
            elif n > 0: molSystems.append(molSystem)

        return molSystems

    def updateMolSystems(self):

        names = []
        index = -1
        molSystems = self.getMolSystems()

        if molSystems:
            if self.molSystem not in molSystems: self.molSystem = molSystems[0]

            index = molSystems.index(self.molSystem)
            names = [ms.code for ms in molSystems]
        else:
            self.molSystem = None

        self.molSystemPulldown.setup(names, index)

    def updateSymmetriesAfter(self, obj=None):

        if self.waiting: return
        else:
            self.waiting = True
            self.after_idle(self.updateSymmetries)

    def updateSymmetries(self):

        textMatrix = []
        objectList = []
        if self.symmetrySet:
            for symmetryOp in self.symmetrySet.symmetries:
                chains = []
                segments = []
                length = symmetryOp.segmentLength

                for segment in symmetryOp.sortedSegments():
                    code = segment.chainCode
                    chain = self.molSystem.findFirstChain(code=code)

                    if chain:
                        chains.append(code)
                        seqId = segment.firstSeqId
                        residue1 = chain.findFirstResidue(seqId=seqId)
                        residue2 = chain.findFirstResidue(seqId=seqId +
                                                          length - 1)
                        segments.append(
                            '%s:%d-%d' %
                            (code, residue1.seqCode, residue2.seqCode))

                datum = [
                    symmetryOp.serial, symmetryOp.symmetryCode, length,
                    '\n'.join(chains), '\n'.join(segments)
                ]
                objectList.append(symmetryOp)
                textMatrix.append(datum)

        self.symmetryMatrix.update(objectList=objectList,
                                   textMatrix=textMatrix)
        self.waiting = False

    def destroy(self):

        self.notify(self.unregisterNotify)
        BasePopup.destroy(self)
Esempio n. 13
0
    def setupProchiralList(self, listIndex, chainLabel):

        chain = self.resParentChainLabelDict[self.resParent][chainLabel]
        self.chain = chain

        self.prochiralListFrame.destroy()
        self.prochiralListFrame = ScrolledFrame(self.prochiralListFrameMaster,
                                                width=200,
                                                doExtraConfig=False)
        self.prochiralListFrame.grid(row=self.prochiralListFrameRow,
                                     column=0,
                                     columnspan=2,
                                     sticky=Tkinter.NSEW)

        #
        # TODO: also handle case one resonance, two atomSets!?!?
        #

        frameRow = 0
        x = y = 0

        frame = self.prochiralListFrame.frame

        self.resonanceObjects = {}
        self.resonanceLabelDict = {}

        #
        # Reuse previous settings...
        #

        if len(self.chainResonancesDict[self.resParent][chain]) == len(
                self.chainAtomSetsDict[self.resParent][chain]):
            usePreviousSettings = True
        else:
            usePreviousSettings = False

        for i in range(0, len(self.chainAtomSetsDict[self.resParent][chain])):
            atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i]

            isStereo = False
            hasResonances = False
            isValidCase = False

            resonances = []

            if usePreviousSettings and self.chainResonancesDict[
                    self.resParent][chain][i]:

                resonances = self.chainResonancesDict[
                    self.resParent][chain][i][3]
                isStereo = self.chainResonancesDict[
                    self.resParent][chain][i][0]
                hasResonances = True
                isValidCase = True

            else:

                for atomSet in atomSetGroup:
                    resonanceSets = atomSet.sortedResonanceSets()

                    if resonanceSets:
                        hasResonances = True

                        for resonanceSet in resonanceSets:
                            for resonance in resonanceSet.sortedResonances():
                                if resonance not in resonances:
                                    resonances.append(resonance)

                        if len(resonanceSets) == 1:
                            isValidCase = True
                            if len(resonanceSet.atomSets) == 1:
                                isStereo = True

                    else:
                        # Case only one resonance but stereo assigned
                        resonances.append(0)

                if len(resonances) == 1:
                    # Case only one resonance, not stereo assigned
                    resonances.append(None)

            #
            # Set up only for valid cases
            #

            if hasResonances and isValidCase:

                if not usePreviousSettings:
                    self.chainResonancesDict[self.resParent][chain].append(
                        [isStereo, False, False, resonances])

                residue = atomSetGroup[0].findFirstAtom().residue
                ccpCode = residue.molResidue.ccpCode
                seqCode = residue.seqCode

                rowspan = 2

                checkButton = CheckButton(
                    frame,
                    selected=isStereo,
                    callback=lambda status=isStereo, fr=frameRow, item=i, setup
                    =False: self.toggleResonances(status, fr, item, setup))
                checkButton.grid(row=frameRow,
                                 rowspan=rowspan,
                                 column=0,
                                 sticky=Tkinter.EW)

                label = Label(frame, text=ccpCode, width=5)
                label.grid(row=frameRow,
                           rowspan=rowspan,
                           column=1,
                           sticky=Tkinter.E)
                label = Label(frame, text=str(seqCode), width=5)
                label.grid(row=frameRow,
                           rowspan=rowspan,
                           column=2,
                           sticky=Tkinter.W)

                #
                # Set up the atom names
                #

                for j in range(0, len(atomSetGroup)):
                    atomSet = atomSetGroup[j]
                    label = Label(frame, text=atomSet.name)
                    label.grid(row=frameRow + j,
                               column=3,
                               sticky=Tkinter.E,
                               ipadx=4)

                #
                # Set up the resonances
                #

                self.resonanceObjects[frameRow] = {
                    True: [[], []],
                    False: [[], []]
                }

                resonanceLabelList = []

                for resonance in resonances:

                    if not resonance:

                        resonanceLabel = 'unknown'

                    else:

                        if hasattr(resonance, 'shifts') and resonance.shifts:
                            shiftLabel = " (shifts: "

                            for shift in resonance.sortedShifts():
                                shiftLabel += "%.2f, " % shift.value

                            shiftLabel = shiftLabel[:-2] + ")"

                        else:
                            shiftLabel = ""

                        resonanceLabel = "'%d.%s'%s" % (
                            seqCode, resonance.name, shiftLabel)
                        self.resonanceLabelDict[resonanceLabel] = resonance

                    resonanceLabelList.append(resonanceLabel)

                separator = Separator(frame, height=1, width=30)
                separator.setColor('black', bgColor='black')
                separator.grid(row=frameRow, column=4, sticky=Tkinter.EW)
                self.resonanceObjects[frameRow][True][0].append(separator)

                separator = CrossLine(frame,
                                      height=20,
                                      width=30,
                                      canvas_bg=frame['bg'],
                                      color='dimgray')
                self.resonanceObjects[frameRow][False][0].append(separator)

                resonanceList = PulldownMenu(
                    frame,
                    entries=resonanceLabelList,
                    callback=lambda selInd=x, selItem=y, fr=frameRow, item=i:
                    self.setProchiralLabels(selInd, selItem, fr, item),
                    do_initial_callback=False,
                    label_color='red')
                resonanceList.grid(row=frameRow, column=5, sticky=Tkinter.EW)
                self.resonanceObjects[frameRow][True][0].append(resonanceList)

                resonanceLabel = Label(frame,
                                       text="%s" % resonanceLabelList[0],
                                       fg='dimgray')
                self.resonanceObjects[frameRow][False][0].append(
                    resonanceLabel)

                separator = Separator(frame, height=1, width=30)
                separator.setColor('black', bgColor='black')
                separator.grid(row=frameRow + 1, column=4)
                self.resonanceObjects[frameRow][True][1].append(separator)

                self.resonanceObjects[frameRow][False][1].append(None)

                resonanceLabel = Label(frame,
                                       text="%s" % resonanceLabelList[1],
                                       fg='red')
                resonanceLabel.grid(row=frameRow + 1,
                                    column=5,
                                    sticky=Tkinter.EW)
                self.resonanceObjects[frameRow][True][1].append(resonanceLabel)

                resonanceLabel = Label(frame,
                                       text="%s" % resonanceLabelList[1],
                                       fg='dimgray')
                self.resonanceObjects[frameRow][False][1].append(
                    resonanceLabel)

                if not isStereo:
                    checkButton.callback(isStereo, setup=True)

                separator = Separator(frame, height=1)
                separator.setColor('black', bgColor='black')
                separator.grid(row=frameRow + rowspan,
                               columnspan=6,
                               sticky=Tkinter.EW)

                frameRow += rowspan + 1

            elif not usePreviousSettings:
                self.chainResonancesDict[self.resParent][chain].append(None)

        return True
Esempio n. 14
0
class LinkResonancesPopup(TemporaryBasePopup):

    help_url = joinPath(getHelpUrlDir(), 'LinkResonances.html')

    def __init__(self,
                 parent,
                 formatNamesList,
                 formatNamesDict,
                 title='Link resonances setup'):

        self.guiParent = parent
        self.formatNamesList = formatNamesList
        self.formatNamesDict = formatNamesDict
        self.status = False

        TemporaryBasePopup.__init__(self,
                                    parent=parent,
                                    title=title,
                                    modal=False,
                                    transient=False)

    def body(self, master):

        row = 0

        label = Label(master, text='File format reference:')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.menu = PulldownMenu(master, entries=self.formatNamesList)
        self.menu.grid(row=row, column=1, sticky=Tkinter.E, ipadx=20)

        row = row + 1

        label = Label(master, text='Try to link unrecognized atom names')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.linkRes = CheckButton(master, selected=True)
        self.linkRes.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Try IUPAC names (as backup)')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.iupacNames = CheckButton(master)
        self.iupacNames.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Use ambiguous name information')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.useAmb = CheckButton(master)
        self.useAmb.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Complete stereospecific assignment')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.allStereo = CheckButton(master)
        self.allStereo.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Force shift merges')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.shiftMerge = CheckButton(master)
        self.shiftMerge.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master,
                      text='Status other atom for all single prochiral atoms')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.allSingleProchiral = PulldownMenu(
            master, entries=['Unknown', 'Same information', 'Always ignore'])
        self.allSingleProchiral.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(
            master,
            text='Status other atom for all possibly equivalent single atoms')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.allSinglePossEquiv = PulldownMenu(
            master, entries=['Unknown', 'Always equivalent', 'Always ignore'])
        self.allSinglePossEquiv.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(
            master,
            text=
            'Automatically connect ambiguous resonances to stereospecific ones'
        )
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.connStereo = CheckButton(master)
        self.connStereo.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Use minimal number of popups')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.minimalPopups = CheckButton(master)
        self.minimalPopups.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(master, text='Verbose output')
        label.grid(row=row, column=0, sticky=Tkinter.E)

        self.verbose = CheckButton(master, selected=True)
        self.verbose.grid(row=row, column=1, sticky=Tkinter.W)

        row = row + 1

        label = Label(
            master,
            text=
            'Warning: it is recommended you save your project first,\nin case linkResonances is interrupted (this might corrupt the data).',
            fg='red')
        label.grid(row=row,
                   column=0,
                   columnspan=2,
                   ipady=15,
                   sticky=Tkinter.EW)

        row = row + 1

        texts = ['Link resonances to atoms']
        commands = [
            self.ok
        ]  # This calls 'ok' in BasePopup, this then calls 'apply' in here
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              help_url=self.help_url)
        buttons.grid(row=row, column=0, columnspan=3)

    def apply(self):

        self.assignFormat = self.formatNamesDict[self.menu.getSelected()]

        self.globalStereoAssign = self.allStereo.isSelected()
        self.useIupacMatching = self.iupacNames.isSelected()
        self.useLinkResonancePopup = self.linkRes.isSelected()
        self.minimalPrompts = self.minimalPopups.isSelected()
        self.verbose = self.verbose.isSelected()
        self.forceShiftMerge = self.shiftMerge.isSelected()
        self.useAmbiguity = self.useAmb.isSelected()
        self.autoConnectStereo = self.connStereo.isSelected()

        self.setSingleProchiral = self.allSingleProchiral.getSelected()
        self.setSinglePossEquiv = self.allSinglePossEquiv.getSelected()

        self.status = True

        return True
Esempio n. 15
0
class OpenSpectrumPopup(BasePopup):
    r"""
  **Locate Spectrum Data for Use in CCPN Project**
  
  This popup window enables the user to locate spectrum data within a file
  system and associate the files (typically binary) with an experiment and
  spectrum name so that it may be visualised and accessed within the current
  CCPN project. Spectra of many different origins and file formats may be
  loaded, which currently includes Bruker, Varian, Felix, NMRPipe, NmrView,
  SPARKY/UCSF, Azara and the factorised shape format "USF3". Depending upon the
  file format of the spectrum, data loaded the user may be required to either
  select a parameter file which then refers to the actual spectrum intensity
  data; this is true for Bruker "procs" and AZARA ".par" files, or alternatively
  a spectrum data file itself that contains referencing information; this is
  the case for SPARKY/UCSF, NmrView and NMRPipe spectra.

  The layout of the popup involved two sections; the upper of which is for
  navigating to and selecting the spectrum or parameter files within the
  file-system, and the lower is for specifying how each spectrum is loaded into
  the CCPN project. It should be noted that when spectrum parameters are read
  the first time, the relevant information is copied into the CCPN project,
  where it may be adjusted independently of the original file information. No
  copies of the spectrum intensity data are made, the CCPN project merely refers
  to the spectrum data on disk, although the data file for a loaded spectrum may
  subsequently be moved or replaced.

  In normal operation the user first selects the kind of spectrum file format
  that will be loaded via the upper "File format" pulldown menu and then checks
  that the "File type" pulldown (toward the bottom of the file browser) is set
  to detect the appropriate kinds of filename; if a helpful file name filter is
  not available the user can add one via the "Manual Select" field, taking care
  to add any wild-card symbols, like the asterisk in "\*.ft3". Next the spectrum
  data or parameter files, appropriate to the selected format, are located by
  navigating within the file-system browser. When the required spectrum files are
  visible the user selects one *or more* to load. Multiple file selections may
  be made using left-click with <Ctrl> (toggle selection) or <Shift> (select
  range). It should be noted that when selecting Bruker files, when using the
  standard Bruker directory structure, the user only needs to navigate to the
  numbered spectrum directory; by default the "procs" file two levels down is
  searched for, e.g. "123/pdata/1/procs" is shown in the directory containing
  the "123" directory.

  When spectrum or parameter files are selected in the file table, the lower
  "Spectra To Open" table is filled to reflect the selection. The user should
  then be mindful of the settings within this table and may choose to edit
  various things by double-clicking on the appropriate cell. Typically the user
  just adjusts the name of the independent "Experiment" and "Spectrum" records.
  These names are usually concatenated like "expName:specName" in CCPN graphical
  displays so there is no need to repeat a name in both fields; this only takes
  up more space. The Experiment, which is a record of *what was done
  experimentally*, commonly has a short name like "HNCA" or "HSQC_298K" so the
  user readily knows how to interpret the experimental data. The Spectrum, which
  is a record of *the data that was collected*, commonly has a short name to
  identify the spectrum number or file name. An Experiment record may contain
  several Spectrum records, so the spectrum's name need minimally only identify
  it amongst others from the same experiment. The Shift List value may be
  changed if the user knows that the experiment represents a distinct set of
  conditions, with different spectrum peak/resonance positions, to existing or
  other experiments being entered. Each shift list will be curated separately,
  to give separate chemical shift values for assignments made under different
  conditions (even when relating to the same atoms). The shift list that an
  experiment uses may also be changed at any time after loading.

  When all spectra and options are specified the [Open Spectrum] button will
  load the relevant data into the CCPN project. If the "Skip verification
  dialogs" option is set it is assumed that all of the spectrum point to
  frequency referencing information, and any data file references, are correct.
  Otherwise, the user will be prompted to confirm the file details and
  referencing information for each spectrum in turn. Finally, after loading the
  user is asked to set the type of NMR experiment, in terms of general
  magnetisation transfer pathway, that was performed.

  **Caveats & Tips**

  If the name of an Experiment that is *already within the CCPN project* is
  used, then the loaded spectrum will (assuming it is compatible) be entered
  under that existing experiment record; no new experiment entity will be
  defined. The user may legitimately use this feature to load several spectra
  that relate to the same experiment; typically where spectra are different
  projections. To facilitate this the "Use shared experiment" option can be
  selected.

  Although experiments and spectra may be renamed after loading, a spectrum
  record may not be placed under a different experiment once created; deletion
  and re-loading is the only mans of achieving this, and care must be taken in
  transferring any assignments.

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

        self.experiment = None
        self.currentObject = None
        #self.currentObjects = [] # looks obsolete

        BasePopup.__init__(self,
                           parent=parent,
                           title='Experiment : Open Spectra',
                           **kw)

    def open(self):

        self.message()
        BasePopup.open(self)

    def body(self, guiFrame):

        self.fileSelect = None
        names, objects = self.getShiftLists()
        self.shiftListPulldown = PulldownList(self,
                                              callback=self.setShiftList,
                                              texts=names,
                                              objects=objects)
        self.windowPulldown = PulldownList(self,
                                           texts=WINDOW_OPTS,
                                           callback=self.setWindow)
        self.experimentEntry = Entry(self,
                                     width=16,
                                     returnCallback=self.setExperiment)
        self.spectrumEntry = Entry(self,
                                   width=16,
                                   returnCallback=self.setSpectrum)

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

        leftFrame = LabelFrame(guiFrame, text='File Selection')
        leftFrame.grid(row=0, column=0, sticky='nsew')
        leftFrame.grid_columnconfigure(3, weight=1)

        row = 0

        label = Label(leftFrame, text='File format:')
        label.grid(row=row, column=0, sticky='w')
        tipText = 'Selects which kind of spectrum file is being loaded; what its data matrix format is'
        self.formatPulldown = PulldownList(leftFrame,
                                           callback=self.chooseFormat,
                                           texts=file_formats,
                                           tipText=tipText,
                                           grid=(row, 1))

        self.detailsLabel = Label(leftFrame, text='Show details:')
        tipText = 'Whether to show an annotation that describes the spectrum in the file selection; currently only uses comment fields from Bruker spectra'
        self.detailsSelect = CheckButton(leftFrame,
                                         selected=False,
                                         callback=self.showDetails,
                                         tipText=tipText)
        self.titleRow = row
        self.detailsSelected = False

        row = row + 1
        leftFrame.grid_rowconfigure(row, weight=1)
        file_types = [FileType('All', ['*'])]
        self.fileSelect = FileSelect(leftFrame,
                                     multiSelect=True,
                                     file_types=file_types,
                                     single_callback=self.chooseFiles,
                                     extraHeadings=('Details', ),
                                     extraJustifies=('left', ),
                                     displayExtra=False,
                                     getExtraCell=self.getDetails,
                                     manualFileFilter=True)
        self.fileSelect.grid(row=row, column=0, columnspan=6, sticky='nsew')

        rightFrame = LabelFrame(guiFrame, text='Spectra To Open')
        rightFrame.grid(row=1, column=0, sticky='nsew')
        rightFrame.grid_columnconfigure(3, weight=1)

        row = 0
        label = Label(rightFrame,
                      text='Skip verification dialogs:',
                      grid=(row, 0))
        tipText = 'Whether to allow the user to check file interpretation and referencing information before the spectrum is loaded'
        self.verifySelect = CheckButton(rightFrame,
                                        selected=False,
                                        grid=(row, 1),
                                        tipText=tipText)

        label = Label(rightFrame, text='Use shared experiment:', grid=(row, 2))
        tipText = 'When selecting multiple spectrum files, whether the loaded spectra will all belong to (derive from) the same experiment; useful for projection spectra etc.'
        self.sharedExpSelect = CheckButton(rightFrame,
                                           selected=False,
                                           tipText=tipText,
                                           callback=self.useShared,
                                           grid=(row, 3))

        row = row + 1
        rightFrame.grid_rowconfigure(row, weight=1)
        tipTexts = [
            'A short textual name for the experiment record that the loaded spectrum will belong to; may be a new experiment or the name of an existing one',
            'A short textual name to identify the spectrum within its experiment; typically a few characters or spectrum number, rather than a repeat of the experiment name',
            'The location of the file, relative to the current directory, that the spectrum data will be loaded from',
            'Sets which window or windows the spectrum will initially appear within once loaded',
            'Sets which shift list the experiment (and hence loaded spectrum) will use to curate chemical shift information; can be changed after load time'
        ]
        headingList = [
            'Experiment', 'Spectrum', 'File', 'Windows', 'Shift List'
        ]
        editWidgets = [
            self.experimentEntry, self.spectrumEntry, None,
            self.windowPulldown, self.shiftListPulldown
        ]
        editGetCallbacks = [
            self.getExperiment, self.getSpectrum, None, self.getWindow,
            self.getShiftList
        ]
        editSetCallbacks = [
            self.setExperiment, self.setSpectrum, None, self.setWindow,
            self.setShiftList
        ]
        self.scrolledMatrix = ScrolledMatrix(rightFrame,
                                             headingList=headingList,
                                             callback=self.selectCell,
                                             editWidgets=editWidgets,
                                             multiSelect=True,
                                             editGetCallbacks=editGetCallbacks,
                                             editSetCallbacks=editSetCallbacks,
                                             tipTexts=tipTexts,
                                             grid=(row, 0),
                                             gridSpan=(1, 4))

        row = row + 1
        tipTexts = [
            'Load spectrum or spectra into the CCPN project using the selected file(s)',
        ]
        texts = ['Open Spectrum']
        commands = [self.openSpectra]
        bottomButtons = UtilityButtonList(guiFrame,
                                          texts=texts,
                                          tipTexts=tipTexts,
                                          doClone=False,
                                          commands=commands,
                                          helpUrl=self.help_url)
        bottomButtons.grid(row=row, column=0, columnspan=1, sticky='ew')
        self.openButton = bottomButtons.buttons[0]

        self.chooseFormat('Azara')
        self.message()

    def message(self):

        if not self.project or len(self.nmrProject.experiments) < 1:
            pass
            #self.parent.ticker.setMessage('Choose spectrum files to open....     ')

    def showDetails(self, isSelected):

        self.detailsSelected = isSelected
        self.fileSelect.updateDisplayExtra(isSelected)
        # below is so that when Details column is toggled on it will actually
        # be seen without having to use the scrollbar
        self.fileSelect.fileList.refreshSize()

    def useShared(self, isSelected):

        self.chooseFiles(forceUpdate=True)

        #if isSelected:

        #objects = self.scrolledMatrix.objectList
        #if len(objects) > 1:
        #  self.currentObject = objects[0]
        #  text = objects[0][0]
        #  self.chooseFiles()
        #  for oo in objects[1:]:
        #    oo[0] = text
        #  if self.project:
        #    self.experiment = self.nmrProject.findFirstExperiment(name=text)
        #self.update()

    def gridDetails(self, bool):

        if bool:
            self.detailsLabel.grid(row=self.titleRow, column=2, sticky='w')
            self.detailsSelect.grid(row=self.titleRow, column=3, sticky='w')
            self.fileSelect.updateDisplayExtra(self.detailsSelected)
        else:
            self.detailsLabel.grid_forget()
            self.detailsSelect.grid_forget()
            self.fileSelect.updateDisplayExtra(False)

    def openSpectra(self):

        noVerify = self.verifySelect.getSelected()

        # tracks if 'add to existing experiment' has already ben OK'ed
        self.okExpSet = set()

        directory = self.fileSelect.getDirectory()
        spectra = []
        specIndex = 0
        for obj in self.scrolledMatrix.objectList:
            fileName = uniIo.joinPath(directory, obj.fileName)
            spectrum = self.openSpectrum(obj.exptName, obj.specName, fileName,
                                         obj.window, obj.shiftListName)
            specIndex += 1

            if (spectrum):
                # check endianness if we are not verifying
                spectra.append(spectrum)
                if noVerify:
                    isBigEndian = isSpectrumBigEndian(
                        spectrum)  # according to data in file
                    if isBigEndian is not None:
                        isBigEndianCurr = getIsSpectrumBigEndian(
                            spectrum)  # according to data model
                        setIsSpectrumBigEndian(spectrum, isBigEndian)
                        if isBigEndian != isBigEndianCurr:
                            if isBigEndian:
                                s = 'big'
                            else:
                                s = 'little'
                            print 'WARNING: swapped endianess of spectrum to %s endian' % s
        #
        del self.okExpSet

        if noVerify and len(spectra) > 1 and self.sharedExpSelect.getSelected(
        ):
            # if we are using a shared experiment and not verifying,
            # set referencing to match first spectrum for all

            # get reference spectrum and set up data structure
            # use most recent pre-existing spectrum, otherwise first new one
            refSpec = spectra[0]
            for spec in spectra[0].experiment.sortedDataSources():
                if spec in spectra:
                    break
                else:
                    refSpec = spec

            ddrLists = {}
            refDdrs = []
            for dataDim in refSpec.sortedDataDims():
                for ddr in dataDim.dataDimRefs:
                    ddrLists[ddr.expDimRef] = []
                    refDdrs.append(ddr)

            # get dataDimRefs, store by ExpDimRef,
            # checking that all spectra have data dim refs for same set of xdr
            nTotal = len(ddrLists)
            for spec in spectra:
                nFound = 0
                for dataDim in spec.sortedDataDims():
                    for ddr in dataDim.dataDimRefs:
                        xdr = ddr.expDimRef
                        ll = ddrLists.get(xdr)
                        if ll is None:
                            # something did not match - do nothing
                            break
                        else:
                            ll.append(ddr)
                            nFound += 1
                else:
                    if nFound == nTotal:
                        # we are OK. Do next spectrum
                        continue
                # something did not match - do nothing
                break
            else:

                # all spectra matched. Now reset O1 references to match reference
                if refSpec is spectra[0]:
                    startAt = 1
                else:
                    startAt = 0

                for refDdr in refDdrs:
                    dataDim = refDdr.dataDim
                    centrePoint = dataDim.numPointsOrig / 2 - dataDim.pointOffset + 1
                    refValue = refDdr.pointToValue(centrePoint)

                    xdr = refDdr.expDimRef
                    for ddr in ddrLists[xdr][startAt:]:
                        dataDim = ddr.dataDim
                        centrePoint = dataDim.numPointsOrig / 2 - dataDim.pointOffset + 1
                        ddr.refPoint = centrePoint
                        ddr.refValue = refValue

        # set refExperiment if there is only one possibility
        experiments = []
        ignoreSet = set()
        showPopup = False
        for spectrum in spectra:
            experiment = spectrum.experiment
            if experiment not in ignoreSet:
                ignoreSet.add(experiment)
                if not experiment.refExperiment:
                    experiments.append(spectrum.experiment)
                    if noVerify:
                        resetCategory = False
                        if not hasattr(experiment, 'category'):
                            if (hasattr(experiment, 'pulProgName')
                                    and hasattr(experiment, 'pulProgType')):
                                # this is first time we get here, and we have external name and source
                                # use external source to set fullType
                                experiment.category = 'use external'
                                resetCategory = True
                        refExperiments = getRefExperiments(experiment)
                        if resetCategory and not refExperiments:
                            # no refExperiments match external source.
                            # unset 'use external' category
                            del experiment.category

                        if len(refExperiments) == 1:
                            # only one possibility, just set it
                            setRefExperiment(experiment, refExperiments[0])

                        # wb104: 20 Oct 2014: do not popup Experiment types dialog if noVerify
                        #else:
                        #  showPopup = True

        # Pop up refExperiment verification
        if experiments and (showPopup or not noVerify):
            self.parent.initRefExperiments(experiments)

        # set up internal Analysis data
        for spectrum in spectra:
            self.parent.finishInitSpectrum(spectrum)
            print 'finished opening spectrum', spectrum.experiment.name, spectrum.name

    def chooseFiles(self, forceUpdate=False, *file):

        directory = self.fileSelect.getDirectory()

        fileNames = self.fileSelect.fileList.currentObjects
        fullFileNames1 = [uniIo.joinPath(directory, x) for x in fileNames]

        fullFileNames2 = [x.fileName for x in self.scrolledMatrix.objectList]
        fullFileNames2 = [uniIo.joinPath(directory, x) for x in fullFileNames2]

        if fullFileNames1 == fullFileNames2 and not forceUpdate:
            return

        objectList = []
        textMatrix = []

        format = self.formatPulldown.getText()

        shiftListName = self.getShiftLists()[0][0]
        windowOpt = WINDOW_OPTS[1]
        oneUp = os.path.dirname

        if format == 'Bruker':
            if self.sharedExpSelect.getSelected():
                nameTemplate = 'Bruker_%d'
                next = self.getNextExpNum(nfiles=len(fileNames),
                                          nameTemplate=nameTemplate)

                exptName = nameTemplate % (next)
                for i, fileName in enumerate(fileNames):
                    fullFileName = fullFileNames1[i]
                    specName = os.path.basename(
                        oneUp(oneUp(oneUp(fullFileName))))
                    datum = (exptName, specName, fileName, windowOpt,
                             shiftListName)
                    dataObj = RowObject(*datum)
                    textMatrix.append(datum)
                    objectList.append(dataObj)

            else:
                for i, fileName in enumerate(fileNames):
                    fullFileName = fullFileNames1[i]
                    try:  # below should not fail
                        ss1 = oneUp(fullFileName)
                        specName = os.path.basename(ss1)
                        ss2 = os.path.basename(oneUp(oneUp(ss1)))
                        exptName = 'Bruker_' + ss2
                    except:  # just put in something
                        ss = os.path.basename(fullFileName)
                        exptName = 'Bruker_' + ss
                        specName = ss

                    datum = (exptName, specName, fileName, windowOpt,
                             shiftListName)
                    dataObj = RowObject(*datum)
                    textMatrix.append(datum)
                    objectList.append(dataObj)

        else:
            next = self.getNextExpNum(nfiles=len(fileNames))
            if self.sharedExpSelect.getSelected():
                exptName = 'Expt_%d' % (next)
                for i, fileName in enumerate(fileNames):
                    specName = re.sub('\.\w+$', '', fileName)

                    datum = (exptName, specName, fileName, windowOpt,
                             shiftListName)
                    dataObj = RowObject(*datum)
                    textMatrix.append(datum)
                    objectList.append(dataObj)

            else:
                for i, fileName in enumerate(fileNames):
                    exptName = 'Expt_%d' % (next + i)
                    specName = re.sub('\.\w+$', '', fileName)

                    datum = (exptName, specName, fileName, windowOpt,
                             shiftListName)
                    dataObj = RowObject(*datum)
                    textMatrix.append(datum)
                    objectList.append(dataObj)

        if len(fileNames) > 1:
            self.openButton.config(text='Open Spectra')

        else:
            self.openButton.config(text='Open Spectrum')

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

    def getNextExpNum(self, nfiles=0, nameTemplate='Expt_%d'):
        """ get suitable free integer to use for exp names 
    """
        next = 1
        if self.project:
            nmrProject = self.nmrProject
            ii = len(nmrProject.experiments)

            # find first exp number that is not taken
            # NBNB TBD could consider expname = specname, specname = proc dir
            next = ii + 1
            if nfiles:
                while ii < next + nfiles:
                    ii += 1
                    if nmrProject.findFirstExperiment(name=nameTemplate % ii):
                        next = ii + 1
        #
        return next

    def getDetails(self, fullfile):

        details = ''
        if os.path.isfile(fullfile):
            format = self.formatPulldown.getText()
            detailsDir = os.path.dirname(fullfile)
            detailsFile = uniIo.joinPath(detailsDir, details_file_dict[format])
            if os.path.exists(detailsFile):
                fp = open(detailsFile)
                details = fp.read().strip().replace('\n',
                                                    ' ').replace('\r', ' ')
                fp.close()

        return (details, )

    def update(self):

        objectList = self.scrolledMatrix.objectList
        textMatrix = [(obj.exptName, obj.specName, obj.fileName, obj.window,
                       obj.shiftListName) for obj in objectList]

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

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

        self.currentObject = obj

        if self.project:
            self.experiment = self.nmrProject.findFirstExperiment(
                name=obj.exptName)
        else:
            self.experiment = None

    def getWindow(self, obj):

        if obj:
            self.windowPulldown.set(obj.window)

    def setWindow(self, opt):

        if isinstance(opt, RowObject):
            self.currentObject.window = opt.window
        else:
            self.currentObject.window = opt
        self.update()

    def setShiftList(self, obj=None):

        if self.project:
            project = self.project
            shiftList = self.shiftListPulldown.getObject()
            if shiftList is None:
                shiftList = newShiftList(project, unit='ppm')

            if self.experiment and shiftList and (
                    shiftList is not self.experiment.shiftList):
                setExperimentShiftList(self.experiment, shiftList)

            self.currentObject.shiftListName = shiftList.name

        self.update()

    def getShiftList(self, object):

        names, shiftLists = self.getShiftLists()
        if names:
            self.shiftListPulldown.setup(names, shiftLists, 0)
            if self.experiment and self.experiment.shiftList:
                name = self.experiment.shiftList.name
            else:
                name = object.shiftListName

            if name is not None:
                self.shiftListPulldown.set(name)

    def getShiftLists(self):

        if self.project:
            names = []
            objects = getShiftLists(self.nmrProject)
            for shiftList in objects:
                if not shiftList.name:
                    shiftList.name = 'ShiftList %d' % shiftList.serial
                names.append(shiftList.name)

            objects.append(None)
            names.append('<New>')

        else:
            objects = [
                None,
            ]
            names = [
                'ShiftList 1',
            ]

        return names, objects

    def chooseFormat(self, format):

        if format in ('Bruker', 'Varian'):
            self.gridDetails(True)
        else:
            self.gridDetails(False)

        file_types = []
        file_type = file_type_dict.get(format)
        if (file_type):
            file_types.extend([file_type])
        file_types.append(FileType('All', ['*']))
        file_types.append(self.fileSelect.manualFilter)
        self.fileSelect.setFileTypes(file_types)

    def getSpectrum(self, obj):

        if obj:
            self.spectrumEntry.set(obj.specName)

    def setSpectrum(self, *event):

        if self.currentObject:
            text = self.spectrumEntry.get()
            if text and text != ' ':
                for data in self.scrolledMatrix.objectList:
                    if data is self.currentObject:
                        continue
                    if (data.specName
                            == text) and (data.exptName
                                          == self.currentObject.exptName):
                        showWarning(
                            'Repeated name',
                            'Spectrum name (%s) already in use for experiment (%s)'
                            % (data.specName, data.exptName),
                            parent=self)
                        return
                    elif (self.experiment) and (
                            self.experiment.findFirstDataSource(name=text)):
                        showWarning(
                            'Repeated name',
                            'Spectrum name (%s) already in use for experiment (%s)'
                            % (data.specName, data.exptName),
                            parent=self)
                        return

                self.currentObject.specName = text
            self.update()

    def getExperiment(self, obj):

        if obj:
            self.experimentEntry.set(obj.exptName)

    def setExperiment(self, *event):

        if self.currentObject:
            text = self.experimentEntry.get()
            if text and text != ' ':
                if self.sharedExpSelect.getSelected():
                    # share one experiment for all rows
                    for oo in self.scrolledMatrix.objectList:
                        oo.exptName = text
                else:
                    #separate experiments
                    self.currentObject.exptName = text
                if self.project:
                    self.experiment = self.nmrProject.findFirstExperiment(
                        name=text)
            self.update()

    def updateShiftLists(self):

        if self.project:
            name = self.expt_entry.get()
            e = self.nmrProject.findFirstExperiment(name=name)

        else:
            e = None

        names, objects = self.getShiftLists()
        if e and e.shiftList:
            index = objects.index(e.shiftList)
        else:
            index = 0

        self.shiftListPulldown.setup(names, objects, index)

    def openSpectrum(self,
                     exptName,
                     specName,
                     file,
                     windowOpt=WINDOW_OPTS[2],
                     shiftListName='<New>',
                     extraData=None):

        # input checks
        if not file:
            showError('No file', 'Need to enter file', parent=self)
            return None

        if not exptName:
            showError('Experiment',
                      'Need to enter experiment name',
                      parent=self)
            return None

        if not specName:
            showError('Spectrum', 'Need to enter spectrum name', parent=self)
            return None

        # get or set up project
        project = self.project
        if not project:
            self.project = project = defaultProject()
            self.parent.initProject(project)
            self.nmrProject = self.parent.nmrProject
            self.analysisProject = self.parent.analysisProject
            #Default ShiftList with name 'ShiftList 1' created

        # set up shift list
        if shiftListName == '<New>':
            shiftList = None
        else:
            shiftList = self.nmrProject.findFirstMeasurementList(
                className='ShiftList', name=shiftListName)

        # read params

        format = self.formatPulldown.getText()
        clazz = params_class_dict[format]
        try:
            params = clazz(file, extraData=extraData)
        except Implementation.ApiError, e:
            showError('Reading params file',
                      'Fatal error: ' + e.error_msg,
                      parent=self)
            return None

        dim = params.pseudoDataDim()
        if dim is not None:
            if format == 'NMRPipe':
                popup = NmrPipePseudoPopup(self, params, dim, file)
                popup.destroy()
            elif format == 'Bruker':
                popup = BrukerPseudoPopup(self, params, dim)
                popup.destroy()

        # get or set up experiment

        experiment = self.nmrProject.findFirstExperiment(name=exptName)
        if experiment:
            expIsNew = False
            if experiment.findFirstDataSource(name=specName):
                showError('Duplicate name',
                          'Duplicate spectrum name "%s" in experiment %s' %
                          (specName, experiment.name),
                          parent=self)
                return None
            elif (experiment.dataSources and experiment not in self.okExpSet):
                if showOkCancel('Multiple Spectra Warning',
                                'Really put multiple '
                                'spectra into existing experiment %s?' %
                                experiment.name,
                                parent=self):
                    self.okExpSet.add(experiment)
                else:
                    return

        else:
            expIsNew = True
            try:
                # Will also work for shiftList == None
                experiment = Nmr.Experiment(self.nmrProject,
                                            name=exptName,
                                            numDim=params.ndim,
                                            shiftList=shiftList)

            except Implementation.ApiError, experiment:
                showError('Experiment', experiment.error_msg, parent=self)
                return None