"Fossies" - the Fresh Open Source Software Archive

Member "relax-5.0.0/gui/components/spectrum.py" (2 Dec 2019, 31347 Bytes) of package /linux/privat/relax-5.0.0.src.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "spectrum.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.1.3_vs_5.0.0.

    1 ###############################################################################
    2 #                                                                             #
    3 # Copyright (C) 2009-2010 Michael Bieri                                       #
    4 # Copyright (C) 2009-2014,2019 Edward d'Auvergne                              #
    5 #                                                                             #
    6 # This file is part of the program relax (http://www.nmr-relax.com).          #
    7 #                                                                             #
    8 # This program is free software: you can redistribute it and/or modify        #
    9 # it under the terms of the GNU General Public License as published by        #
   10 # the Free Software Foundation, either version 3 of the License, or           #
   11 # (at your option) any later version.                                         #
   12 #                                                                             #
   13 # This program is distributed in the hope that it will be useful,             #
   14 # but WITHOUT ANY WARRANTY; without even the implied warranty of              #
   15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
   16 # GNU General Public License for more details.                                #
   17 #                                                                             #
   18 # You should have received a copy of the GNU General Public License           #
   19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
   20 #                                                                             #
   21 ###############################################################################
   22 
   23 # Module docstring.
   24 """Module containing the classes for GUI components involving spectral data."""
   25 
   26 # Python module imports.
   27 import wx
   28 import wx.lib.buttons
   29 
   30 # relax module imports.
   31 import dep_check
   32 from graphics import fetch_icon
   33 from gui.components.base_list import Base_list
   34 from gui.string_conv import float_to_gui, gui_to_str, str_to_gui
   35 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
   36 from lib.compat import u
   37 from pipe_control.spectrum import replicated_flags, replicated_ids
   38 from status import Status; status = Status()
   39 from specific_analyses.relax_disp.data import is_cpmg_exp_type, is_r1rho_exp_type
   40 from user_functions.data import Uf_info; uf_info = Uf_info()
   41 
   42 
   43 # Some IDs for the menu entries.
   44 MENU_SPECTRUM_BASEPLANE_RMSD = wx.NewId()
   45 MENU_SPECTRUM_DELETE = wx.NewId()
   46 MENU_SPECTRUM_INTEGRATION_POINTS = wx.NewId()
   47 MENU_SPECTRUM_REPLICATED = wx.NewId()
   48 MENU_RELAX_DISP_EXP_TYPE = wx.NewId()
   49 MENU_RELAX_FIT_RELAX_TIME = wx.NewId()
   50 MENU_RELAX_DISP_RELAX_TIME = wx.NewId()
   51 MENU_SPECTROMETER_FRQ = wx.NewId()
   52 MENU_RELAX_DISP_SPIN_LOCK_FIELD = wx.NewId()
   53 MENU_RELAX_DISP_SPIN_LOCK_OFFSET = wx.NewId()
   54 MENU_RELAX_DISP_CPMG_SETUP = wx.NewId()
   55 
   56 
   57 class Spectra_list(Base_list):
   58     """The GUI element for listing loaded spectral data."""
   59 
   60     def __init__(self, gui=None, parent=None, box=None, id=None, fn_add=None, proportion=0, button_placement='default', noe_flag=False, relax_fit_flag=False, relax_disp_flag=False):
   61         """Build the spectral list GUI element.
   62 
   63         @keyword gui:               The main GUI object.
   64         @type gui:                  wx.Frame instance
   65         @keyword parent:            The parent GUI element that this is to be attached to (the panel object).
   66         @type parent:               wx object
   67         @keyword data:              The data storage container.
   68         @type data:                 class instance
   69         @keyword box:               The vertical box sizer to pack this GUI component into.
   70         @type box:                  wx.BoxSizer instance
   71         @keyword id:                A unique identification string.  This is used to register the update method with the GUI user function observer object.
   72         @type id:                   str
   73         @keyword fn_add:            The function to execute when clicking on the 'Add' button.
   74         @type fn_add:               func
   75         @keyword proportion:        The window proportion parameter.
   76         @type proportion:           bool
   77         @keyword button_placement:  Override the button visibility and placement.  The value of 'default' will leave the buttons at the default setting.  The value of 'top' will place the buttons at the top, 'bottom' will place them at the bottom, and None will turn off the buttons.
   78         @type button_placement:     str or None
   79         @keyword noe_flag:          A flag which when True will enable the steady-state NOE portions of the wizard.
   80         @type noe_flag:             bool
   81         @keyword relax_fit_flag:    A flag which when True will enable the relaxation curve-fitting portions of the wizard.
   82         @type relax_fit_flag:       bool
   83         @keyword relax_disp_flag:   A flag which when True will enable the relaxation dispersion portions of the wizard.
   84         @type relax_disp_flag:      bool
   85         """
   86 
   87         # Store the arguments.
   88         self.fn_add = fn_add
   89         self.noe_flag = noe_flag
   90         self.relax_fit_flag = relax_fit_flag
   91         self.relax_disp_flag = relax_disp_flag
   92 
   93         # Initialise the base class.
   94         super(Spectra_list, self).__init__(gui=gui, parent=parent, box=box, id=id, proportion=proportion, button_placement=button_placement)
   95 
   96 
   97     def action_relax_disp_cpmg_setup(self, event=None, item=None):
   98         """Launch the relax_disp.cpmg_setup user function.
   99 
  100         @keyword event: The wx event.
  101         @type event:    wx event
  102         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  103         @type item:     None or int
  104         """
  105 
  106         # The current selection.
  107         if item == None:
  108             item = self.element.GetFirstSelected()
  109 
  110         # The spectrum ID.
  111         id = gui_to_str(self.element.GetItemText(item))
  112 
  113         # The current frequency.
  114         frq = None
  115         frq_flag = False
  116         if hasattr(cdp, 'cpmg_frqs') and id in cdp.cpmg_frqs:
  117             frq = cdp.cpmg_frqs[id]
  118             frq_flag = True
  119 
  120         # The current ncyc_even flag.
  121         even = True
  122         even_flag = False
  123         if hasattr(cdp, 'ncyc_even') and id in cdp.ncyc_even:
  124             even = cdp.ncyc_even[id]
  125             even_flag = True
  126 
  127         # Launch the dialog.
  128         if frq_flag:
  129             uf_store['relax_disp.cpmg_setup'](spectrum_id=id, cpmg_frq=frq, ncyc_even=even)
  130         else:
  131             uf_store['relax_disp.cpmg_setup'](spectrum_id=id, ncyc_even=even)
  132 
  133 
  134     def action_relax_disp_exp_type(self, event=None, item=None):
  135         """Launch the relax_disp.exp_type user function.
  136 
  137         @keyword event: The wx event.
  138         @type event:    wx event
  139         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  140         @type item:     None or int
  141         """
  142 
  143         # The current selection.
  144         if item == None:
  145             item = self.element.GetFirstSelected()
  146 
  147         # The spectrum ID.
  148         id = gui_to_str(self.element.GetItemText(item))
  149 
  150         # The current type.
  151         exp_type = None
  152         if hasattr(cdp, 'exp_type') and id in cdp.exp_type:
  153             exp_type = cdp.exp_type[id]
  154 
  155         # Launch the dialog.
  156         if exp_type == None:
  157             uf_store['relax_disp.exp_type'](spectrum_id=id)
  158         else:
  159             uf_store['relax_disp.exp_type'](spectrum_id=id, exp_type=exp_type)
  160 
  161 
  162     def action_relax_disp_relax_time(self, event=None, item=None):
  163         """Launch the relax_disp.relax_time user function.
  164 
  165         @keyword event: The wx event.
  166         @type event:    wx event
  167         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  168         @type item:     None or int
  169         """
  170 
  171         # The current selection.
  172         if item == None:
  173             item = self.element.GetFirstSelected()
  174 
  175         # The spectrum ID.
  176         id = gui_to_str(self.element.GetItemText(item))
  177 
  178         # The current time.
  179         time = None
  180         if hasattr(cdp, 'relax_times') and id in cdp.relax_times:
  181             time = cdp.relax_times[id]
  182 
  183         # Launch the dialog.
  184         if time == None:
  185             uf_store['relax_disp.relax_time'](spectrum_id=id)
  186         else:
  187             uf_store['relax_disp.relax_time'](time=time, spectrum_id=id)
  188 
  189 
  190     def action_relax_disp_spin_lock_field(self, event=None, item=None):
  191         """Launch the relax_disp.spin_lock_field user function.
  192 
  193         @keyword event: The wx event.
  194         @type event:    wx event
  195         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  196         @type item:     None or int
  197         """
  198 
  199         # The current selection.
  200         if item == None:
  201             item = self.element.GetFirstSelected()
  202 
  203         # The spectrum ID.
  204         id = gui_to_str(self.element.GetItemText(item))
  205 
  206         # The spin-lock.
  207         nu1 = None
  208         nu1_flag = False
  209         if hasattr(cdp, 'spin_lock_nu1') and id in cdp.spin_lock_nu1:
  210             nu1 = cdp.spin_lock_nu1[id]
  211             nu1_flag = True
  212 
  213         # Launch the dialog.
  214         if nu1_flag:
  215             uf_store['relax_disp.spin_lock_field'](field=nu1, spectrum_id=id)
  216         else:
  217             uf_store['relax_disp.spin_lock_field'](spectrum_id=id)
  218 
  219 
  220     def action_relax_disp_spin_lock_offset(self, event=None, item=None):
  221         """Launch the relax_disp.spin_lock_offset user function.
  222 
  223         @keyword event: The wx event.
  224         @type event:    wx event
  225         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  226         @type item:     None or int
  227         """
  228 
  229         # The current selection.
  230         if item == None:
  231             item = self.element.GetFirstSelected()
  232 
  233         # The spectrum ID.
  234         id = gui_to_str(self.element.GetItemText(item))
  235 
  236         # The offset.
  237         offset = None
  238         offset_flag = False
  239         if hasattr(cdp, 'spin_lock_offset') and id in cdp.spin_lock_offset:
  240             offset = cdp.spin_lock_offset[id]
  241             offset_flag = True
  242 
  243         # Launch the dialog.
  244         if offset_flag:
  245             uf_store['relax_disp.spin_lock_offset'](offset=offset, spectrum_id=id)
  246         else:
  247             uf_store['relax_disp.spin_lock_offset'](spectrum_id=id)
  248 
  249 
  250     def action_relax_fit_relax_time(self, event=None, item=None):
  251         """Launch the relax_fit.relax_time user function.
  252 
  253         @keyword event: The wx event.
  254         @type event:    wx event
  255         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  256         @type item:     None or int
  257         """
  258 
  259         # The current selection.
  260         if item == None:
  261             item = self.element.GetFirstSelected()
  262 
  263         # The spectrum ID.
  264         id = gui_to_str(self.element.GetItemText(item))
  265 
  266         # The current time.
  267         time = None
  268         if hasattr(cdp, 'relax_times') and id in cdp.relax_times:
  269             time = cdp.relax_times[id]
  270 
  271         # Launch the dialog.
  272         if time == None:
  273             uf_store['relax_fit.relax_time'](spectrum_id=id)
  274         else:
  275             uf_store['relax_fit.relax_time'](time=time, spectrum_id=id)
  276 
  277 
  278     def action_spectrometer_frq(self, event=None, item=None):
  279         """Launch the spectrometer.frequency user function.
  280 
  281         @keyword event: The wx event.
  282         @type event:    wx event
  283         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  284         @type item:     None or int
  285         """
  286 
  287         # The current selection.
  288         if item == None:
  289             item = self.element.GetFirstSelected()
  290 
  291         # The spectrum ID.
  292         id = gui_to_str(self.element.GetItemText(item))
  293 
  294         # The current frequency.
  295         frq = None
  296         if hasattr(cdp, 'spectrometer_frq') and id in cdp.spectrometer_frq:
  297             frq = cdp.spectrometer_frq[id]
  298 
  299         # Launch the dialog.
  300         if frq == None:
  301             uf_store['spectrometer.frequency'](id=id)
  302         else:
  303             uf_store['spectrometer.frequency'](frq=frq, id=id)
  304 
  305 
  306     def action_spectrum_baseplane_rmsd(self, event):
  307         """Launch the spectrum.baseplane_rmsd user function.
  308 
  309         @param event:   The wx event.
  310         @type event:    wx event
  311         """
  312 
  313         # The current selection.
  314         item = self.element.GetFirstSelected()
  315 
  316         # The spectrum ID.
  317         id = gui_to_str(self.element.GetItemText(item))
  318 
  319         # Launch the dialog.
  320         uf_store['spectrum.baseplane_rmsd'](spectrum_id=id)
  321 
  322 
  323     def action_spectrum_delete(self, event):
  324         """Launch the spectrum.delete user function.
  325 
  326         @param event:   The wx event.
  327         @type event:    wx event
  328         """
  329 
  330         # The current selection.
  331         item = self.element.GetFirstSelected()
  332 
  333         # No selection.
  334         if item == -1:
  335             id = None
  336 
  337         # Selected item.
  338         else:
  339             # The spectrum ID.
  340             id = gui_to_str(self.element.GetItemText(item))
  341 
  342         # Launch the dialog.
  343         uf_store['spectrum.delete'](spectrum_id=id)
  344 
  345 
  346     def action_spectrum_error_analysis(self, event):
  347         """Launch the spectrum.error_analysis user function.
  348 
  349         @param event:   The wx event.
  350         @type event:    wx event
  351         """
  352 
  353         # The first item selected.
  354         item = self.element.GetFirstSelected()
  355 
  356         # Loop over the additional selections.
  357         ids = []
  358         while True:
  359             # No selection.
  360             if item == -1:
  361                 break
  362 
  363             # Add the ID string to the list.
  364             ids.append(gui_to_str(self.element.GetItemText(item)))
  365 
  366             # Get the next selected item.
  367             item = self.element.GetNextSelected(item)
  368 
  369         # No selected items.
  370         if not len(ids):
  371             ids = None
  372 
  373         # Launch the dialog.
  374         uf_store['spectrum.error_analysis'](subset=ids, wx_wizard_modal=True)
  375 
  376         # Display the relax controller, and go to the end of the log window.
  377         self.gui.show_controller(None)
  378         self.gui.controller.log_panel.on_goto_end(None)
  379 
  380 
  381     def action_spectrum_integration_points(self, event):
  382         """Launch the spectrum.integration_points user function.
  383 
  384         @param event:   The wx event.
  385         @type event:    wx event
  386         """
  387 
  388         # The current selection.
  389         item = self.element.GetFirstSelected()
  390 
  391         # The spectrum ID.
  392         id = gui_to_str(self.element.GetItemText(item))
  393 
  394         # Launch the dialog.
  395         uf_store['spectrum.integration_points'](spectrum_id=id)
  396 
  397 
  398     def action_spectrum_replicated(self, event=None, item=None):
  399         """Launch the spectrum.replicated user function.
  400 
  401         @keyword event: The wx event.
  402         @type event:    wx event
  403         @keyword item:  This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
  404         @type item:     None or int
  405         """
  406 
  407         # No elements in the list.
  408         if not self.element.GetItemCount():
  409             return
  410 
  411         # The current selection.
  412         if item == None:
  413             item = self.element.GetFirstSelected()
  414 
  415         # The spectrum ID.
  416         id = gui_to_str(self.element.GetItemText(item))
  417 
  418         # The current replicates.
  419         replicates = replicated_ids(id)
  420 
  421         # Launch the dialog.
  422         if replicates == []:
  423             uf_store['spectrum.replicated'](spectrum_ids=id)
  424         else:
  425             uf_store['spectrum.replicated'](spectrum_ids=replicates)
  426 
  427 
  428     def add_disp_point(self, index):
  429         """Add the dispersion point info to the element.
  430 
  431         This is either the CPMG pulse frequency or the spin-lock field strength.  Both share the same column.
  432 
  433         @param index:   The column index for the data.
  434         @type index:    int
  435         @return:        True if the data exists, False otherwise.
  436         @rtype:         bool
  437         """
  438 
  439         # Append a column.
  440         self.element.InsertColumn(index, u("\u03BDCPMG (Hz) or Spin-lock \u03BD1 (Hz)"))
  441 
  442         # No data.
  443         if not hasattr(cdp, 'spectrum_ids'):
  444             return True
  445 
  446         # Set the values.
  447         for i in range(len(cdp.spectrum_ids)):
  448             # Set the CPMG frequency.
  449             if hasattr(cdp, 'cpmg_frqs') and cdp.spectrum_ids[i] in cdp.cpmg_frqs:
  450                 if dep_check.wx_classic:
  451                     self.element.SetStringItem(i, index, float_to_gui(cdp.cpmg_frqs[cdp.spectrum_ids[i]]))
  452                 else:
  453                     self.element.SetItem(i, index, float_to_gui(cdp.cpmg_frqs[cdp.spectrum_ids[i]]))
  454 
  455             # Set the spin-lock field strength.
  456             if hasattr(cdp, 'spin_lock_nu1') and cdp.spectrum_ids[i] in cdp.spin_lock_nu1:
  457                 if dep_check.wx_classic:
  458                     self.element.SetStringItem(i, index, float_to_gui(cdp.spin_lock_nu1[cdp.spectrum_ids[i]]))
  459                 else:
  460                     self.element.SetItem(i, index, float_to_gui(cdp.spin_lock_nu1[cdp.spectrum_ids[i]]))
  461 
  462         # Successful.
  463         return True
  464 
  465 
  466     def add_exp_type(self, index):
  467         """Add the experiment type info to the element.
  468 
  469         @param index:   The column index for the data.
  470         @type index:    int
  471         @return:        True if the data exists, False otherwise.
  472         @rtype:         bool
  473         """
  474 
  475         # Append a column.
  476         self.element.InsertColumn(index, u("Experiment type"))
  477 
  478         # No data.
  479         if not hasattr(cdp, 'spectrum_ids') or not hasattr(cdp, 'exp_type'):
  480             return True
  481 
  482         # Set the values.
  483         for i in range(len(cdp.spectrum_ids)):
  484             # No value.
  485             if cdp.spectrum_ids[i] not in cdp.exp_type:
  486                 continue
  487 
  488             # Set the value.
  489             if dep_check.wx_classic:
  490                 self.element.SetStringItem(i, index, float_to_gui(cdp.exp_type[cdp.spectrum_ids[i]]))
  491             else:
  492                 self.element.SetItem(i, index, float_to_gui(cdp.exp_type[cdp.spectrum_ids[i]]))
  493 
  494         # Successful.
  495         return True
  496 
  497 
  498     def add_frqs(self, index):
  499         """Add the spectrometer frequency info to the element.
  500 
  501         @param index:   The column index for the data.
  502         @type index:    int
  503         @return:        True if the frequency data exists, False otherwise.
  504         @rtype:         bool
  505         """
  506 
  507         # Append a column.
  508         self.element.InsertColumn(index, u("\u03C9H (MHz)"))
  509 
  510         # No data.
  511         if not hasattr(cdp, 'spectrum_ids'):
  512             return True
  513         if not hasattr(cdp, 'spectrometer_frq') or not len(cdp.spectrometer_frq):
  514             return True
  515 
  516         # Set the values.
  517         for i in range(len(cdp.spectrum_ids)):
  518             # No value.
  519             if cdp.spectrum_ids[i] not in cdp.spectrometer_frq:
  520                 continue
  521 
  522             # Set the value (in MHz).
  523             if dep_check.wx_classic:
  524                 self.element.SetStringItem(i, index, float_to_gui(cdp.spectrometer_frq[cdp.spectrum_ids[i]]/1e6))
  525             else:
  526                 self.element.SetItem(i, index, float_to_gui(cdp.spectrometer_frq[cdp.spectrum_ids[i]]/1e6))
  527 
  528         # Successful.
  529         return True
  530 
  531 
  532     def add_offset(self, index):
  533         """Add the offset info to the element.
  534 
  535         @param index:   The column index for the data.
  536         @type index:    int
  537         @return:        True if the data exists, False otherwise.
  538         @rtype:         bool
  539         """
  540 
  541         # Append a column.
  542         self.element.InsertColumn(index, u("Offset \u03C9_rf (ppm)"))
  543 
  544         # No data.
  545         if not hasattr(cdp, 'spectrum_ids'):
  546             return True
  547 
  548         # Set the values.
  549         for i in range(len(cdp.spectrum_ids)):
  550             if hasattr(cdp, 'spin_lock_offset') and cdp.spectrum_ids[i] in cdp.spin_lock_offset:
  551                 if dep_check.wx_classic:
  552                     self.element.SetStringItem(i, index, float_to_gui(cdp.spin_lock_offset[cdp.spectrum_ids[i]]))
  553                 else:
  554                     self.element.SetItem(i, index, float_to_gui(cdp.spin_lock_offset[cdp.spectrum_ids[i]]))
  555 
  556         # Successful.
  557         return True
  558 
  559 
  560     def generate_popup_menu(self, id=None):
  561         """Create the popup menu.
  562 
  563         @keyword id:    The spectrum ID string for the row that was clicked on.
  564         @type id:       str
  565         @return:        The popup menu.
  566         @rtype:         list of dict of wxID, str, str, method
  567         """
  568 
  569         # The right click popup menu.
  570         popup_menus = [
  571             {
  572                 'id': MENU_SPECTRUM_BASEPLANE_RMSD,
  573                 'text': "Set the &baseplane RMSD",
  574                 'icon': fetch_icon(uf_info.get_uf('spectrum.baseplane_rmsd').gui_icon),
  575                 'method': self.action_spectrum_baseplane_rmsd
  576             }, {
  577                 'id': MENU_SPECTRUM_DELETE,
  578                 'text': "&Delete the peak intensities",
  579                 'icon': fetch_icon(uf_info.get_uf('spectrum.delete').gui_icon),
  580                 'method': self.action_spectrum_delete
  581             }, {
  582                 'id': MENU_SPECTRUM_INTEGRATION_POINTS,
  583                 'text': "Set the number of integration &points",
  584                 'icon': fetch_icon(uf_info.get_uf('spectrum.integration_points').gui_icon),
  585                 'method': self.action_spectrum_integration_points
  586             }, {
  587                 'id': MENU_SPECTRUM_REPLICATED,
  588                 'text': "Specify which spectra are &replicated",
  589                 'icon': fetch_icon(uf_info.get_uf('spectrum.replicated').gui_icon),
  590                 'method': self.action_spectrum_replicated
  591             }
  592         ]
  593         if self.relax_disp_flag:
  594             popup_menus.append({
  595                 'id': MENU_RELAX_DISP_EXP_TYPE,
  596                 'text': "Set the &experiment type",
  597                 'icon': None,
  598                 'method': self.action_relax_disp_exp_type
  599             })
  600         if self.relax_fit_flag:
  601             popup_menus.append({
  602                 'id': MENU_RELAX_FIT_RELAX_TIME,
  603                 'text': "Set the relaxation &time",
  604                 'icon': fetch_icon(uf_info.get_uf('relax_fit.relax_time').gui_icon),
  605                 'method': self.action_relax_fit_relax_time
  606             })
  607         if self.relax_disp_flag:
  608             popup_menus.append({
  609                 'id': MENU_RELAX_DISP_RELAX_TIME,
  610                 'text': "Set the relaxation &time",
  611                 'icon': fetch_icon(uf_info.get_uf('relax_disp.relax_time').gui_icon),
  612                 'method': self.action_relax_disp_relax_time
  613             })
  614             popup_menus.append({
  615                 'id': MENU_SPECTROMETER_FRQ,
  616                 'text': "Set the spectrometer &frequency",
  617                 'icon': fetch_icon("relax.spectrometer"),
  618                 'method': self.action_spectrometer_frq
  619             })
  620         if self.relax_disp_flag and is_r1rho_exp_type(id):
  621             popup_menus.append({
  622                 'id': MENU_RELAX_DISP_SPIN_LOCK_FIELD,
  623                 'text': u("Set the spin-&lock field strength \u03BD1"),
  624                 'icon': fetch_icon("relax.relax_disp"),
  625                 'method': self.action_relax_disp_spin_lock_field
  626             })
  627             popup_menus.append({
  628                 'id': MENU_RELAX_DISP_SPIN_LOCK_OFFSET,
  629                 'text': u("Set the spin-&lock offset \u03C9_rf"),
  630                 'icon': fetch_icon("relax.relax_disp"),
  631                 'method': self.action_relax_disp_spin_lock_offset
  632             })
  633         if self.relax_disp_flag and is_cpmg_exp_type(id):
  634             popup_menus.append({
  635                 'id': MENU_RELAX_DISP_CPMG_SETUP,
  636                 'text': u("Set the &CPMG pulse sequence information"),
  637                 'icon': fetch_icon("relax.relax_disp"),
  638                 'method': self.action_relax_disp_cpmg_setup
  639             })
  640 
  641         # Return the menu.
  642         return popup_menus
  643 
  644 
  645     def noe_spectrum_type(self, index):
  646         """Add the NOE spectral type info to the element.
  647 
  648         @param index:   The column index for the data.
  649         @type index:    int
  650         @return:        True if a spectrum type exists, False otherwise.
  651         @rtype:         bool
  652         """
  653 
  654         # No type info.
  655         if not hasattr(cdp, 'spectrum_type') or not len(cdp.spectrum_type):
  656             return False
  657 
  658         # Append a column.
  659         self.element.InsertColumn(index, str_to_gui("NOE spectrum type"))
  660 
  661         # Translation table.
  662         table = {
  663             'sat': 'Saturated',
  664             'ref': 'Reference'
  665         }
  666 
  667         # No data.
  668         if not hasattr(cdp, 'spectrum_ids'):
  669             return True
  670 
  671         # Set the values.
  672         for i in range(len(cdp.spectrum_ids)):
  673             # No value.
  674             if cdp.spectrum_ids[i] not in cdp.spectrum_type:
  675                 continue
  676 
  677             # Set the value.
  678             if dep_check.wx_classic:
  679                 self.element.SetStringItem(i, index, str_to_gui(table[cdp.spectrum_type[cdp.spectrum_ids[i]]]))
  680             else:
  681                 self.element.SetItem(i, index, str_to_gui(table[cdp.spectrum_type[cdp.spectrum_ids[i]]]))
  682 
  683         # Successful.
  684         return True
  685 
  686 
  687     def relax_times(self, index):
  688         """Add the relaxation delay time info to the element.
  689 
  690         @param index:   The column index for the data.
  691         @type index:    int
  692         @return:        True if relaxation times exist, False otherwise.
  693         @rtype:         bool
  694         """
  695 
  696         # No type info.
  697         if not hasattr(cdp, 'relax_times') or not len(cdp.relax_times):
  698             return False
  699 
  700         # Append a column.
  701         self.element.InsertColumn(index, str_to_gui("Delay times (s)"))
  702 
  703         # No data.
  704         if not hasattr(cdp, 'spectrum_ids'):
  705             return True
  706 
  707         # Set the values.
  708         for i in range(len(cdp.spectrum_ids)):
  709             # No value.
  710             if cdp.spectrum_ids[i] not in cdp.relax_times:
  711                 continue
  712 
  713             # Set the value.
  714             if dep_check.wx_classic:
  715                 self.element.SetStringItem(i, index, float_to_gui(cdp.relax_times[cdp.spectrum_ids[i]]))
  716             else:
  717                 self.element.SetItem(i, index, float_to_gui(cdp.relax_times[cdp.spectrum_ids[i]]))
  718 
  719         # Successful.
  720         return True
  721 
  722 
  723     def replicates(self, index):
  724         """Add the replicated spectra info to the element.
  725 
  726         @param index:   The column index for the data.
  727         @type index:    int
  728         @return:        True if relaxation times exist, False otherwise.
  729         @rtype:         bool
  730         """
  731 
  732         # No type info.
  733         if not hasattr(cdp, 'replicates') or not len(cdp.replicates):
  734             return False
  735 
  736         # Replicated spectra.
  737         repl = replicated_flags()
  738 
  739         # Append a column.
  740         self.element.InsertColumn(index, str_to_gui("Replicate IDs"))
  741 
  742         # No data.
  743         if not hasattr(cdp, 'spectrum_ids'):
  744             return True
  745 
  746         # Set the values.
  747         for i in range(len(cdp.spectrum_ids)):
  748             # No replicates.
  749             if not repl[cdp.spectrum_ids[i]]:
  750                 continue
  751 
  752             # The replicated spectra.
  753             id_list = replicated_ids(cdp.spectrum_ids[i])
  754 
  755             # Convert to a string.
  756             text = ''
  757             for j in range(len(id_list)):
  758                 # Add the id.
  759                 text = "%s%s" % (text, id_list[j])
  760 
  761                 # Separator.
  762                 if j < len(id_list)-1:
  763                     text = "%s, " % text
  764 
  765             # Set the value.
  766             if dep_check.wx_classic:
  767                 self.element.SetStringItem(i, index, str_to_gui(text))
  768             else:
  769                 self.element.SetItem(i, index, str_to_gui(text))
  770 
  771         # Successful.
  772         return True
  773 
  774 
  775     def setup(self):
  776         """Override the base variables."""
  777 
  778         # GUI variables.
  779         self.title = "Spectra list"
  780         self.observer_base_name = "spectra list"
  781 
  782         # The column titles.
  783         self.columns = []
  784 
  785         # Button set up.
  786         self.button_placement = 'top'
  787         self.button_size = (170, 40)
  788         self.button_info = [
  789             {
  790                 'object': 'button_add',
  791                 'label': ' Add',
  792                 'icon': fetch_icon('oxygen.actions.list-add-relax-blue', "22x22"),
  793                 'method': self.fn_add,
  794                 'tooltip': "Read a spectral data file."
  795             }, {
  796                 'object': 'button_delete',
  797                 'label': ' Delete',
  798                 'icon': fetch_icon('oxygen.actions.list-remove', "22x22"),
  799                 'method': self.action_spectrum_delete,
  800                 'tooltip': "Delete loaded relaxation data from the relax data store."
  801             }, {
  802                 'object': 'button_error_analysis',
  803                 'label': ' Error analysis',
  804                 'icon': fetch_icon('oxygen.categories.applications-education', "22x22"),
  805                 'method': self.action_spectrum_error_analysis,
  806                 'tooltip': "Perform a peak intensity error analysis on the currently loaded data or data subsets.  Select a subset of the spectra below to perform the error analysis only on this subset."
  807             }
  808         ]
  809 
  810 
  811     def update_data(self):
  812         """Method called from self.build_element_safe() to update the list data."""
  813 
  814         # Initialise the column index for the data.
  815         index = 1
  816 
  817         # Delete the rows and columns.
  818         self.element.DeleteAllItems()
  819         for i in reversed(range(self.element.GetColumnCount())):
  820             self.element.DeleteColumn(i)
  821 
  822         # Initialise to a single column.
  823         self.element.InsertColumn(0, str_to_gui("Spectrum ID"))
  824 
  825         # Expand the number of rows to match the number of spectrum IDs, and add the IDs.
  826         n = 0
  827         if hasattr(cdp, 'spectrum_ids'):
  828             # The number of IDs.
  829             n = len(cdp.spectrum_ids)
  830 
  831             # Set the IDs.
  832             for i in range(n):
  833                 if dep_check.wx_classic:
  834                     self.element.InsertStringItem(i, str_to_gui(cdp.spectrum_ids[i]))
  835                 else:
  836                     self.element.InsertItem(i, str_to_gui(cdp.spectrum_ids[i]))
  837 
  838         # The NOE spectrum type.
  839         if self.noe_spectrum_type(index):
  840             index += 1
  841 
  842         # The experiment type.
  843         if self.relax_disp_flag and self.add_exp_type(index):
  844             index += 1
  845 
  846         # The spectrometer frequency.
  847         if self.relax_disp_flag and self.add_frqs(index):
  848             index += 1
  849 
  850         # The spin-lock field strength or CPMG pulse frequency.
  851         if self.relax_disp_flag and self.add_disp_point(index):
  852             index += 1
  853 
  854         # The offset.
  855         if self.relax_disp_flag and self.add_offset(index):
  856             index += 1
  857 
  858         # The relaxation times.
  859         if (self.relax_fit_flag or self.relax_disp_flag) and self.relax_times(index):
  860             index += 1
  861 
  862         # The replicated spectra.
  863         if self.replicates(index):
  864             index += 1