Package gui :: Package components :: Module spectrum
[hide private]
[frames] | no frames]

Source Code for Module gui.components.spectrum

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-2011 Michael Bieri                                       # 
  4  # Copyright (C) 2010-2013 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  from compat import u 
 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 pipe_control.spectrum import replicated_flags, replicated_ids 
 37  from status import Status; status = Status() 
 38  from specific_analyses.relax_disp.disp_data import is_cpmg_exp_type, is_r1rho_exp_type 
 39  from user_functions.data import Uf_info; uf_info = Uf_info() 
 40   
 41   
42 -class Spectra_list(Base_list):
43 """The GUI element for listing loaded spectral data.""" 44
45 - 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):
46 """Build the spectral list GUI element. 47 48 @keyword gui: The main GUI object. 49 @type gui: wx.Frame instance 50 @keyword parent: The parent GUI element that this is to be attached to (the panel object). 51 @type parent: wx object 52 @keyword data: The data storage container. 53 @type data: class instance 54 @keyword box: The vertical box sizer to pack this GUI component into. 55 @type box: wx.BoxSizer instance 56 @keyword id: A unique identification string. This is used to register the update method with the GUI user function observer object. 57 @type id: str 58 @keyword fn_add: The function to execute when clicking on the 'Add' button. 59 @type fn_add: func 60 @keyword proportion: The window proportion parameter. 61 @type proportion: bool 62 @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. 63 @type button_placement: str or None 64 @keyword noe_flag: A flag which when True will enable the steady-state NOE portions of the wizard. 65 @type noe_flag: bool 66 @keyword relax_fit_flag: A flag which when True will enable the relaxation curve-fitting portions of the wizard. 67 @type relax_fit_flag: bool 68 @keyword relax_disp_flag: A flag which when True will enable the relaxation dispersion portions of the wizard. 69 @type relax_disp_flag: bool 70 """ 71 72 # Store the arguments. 73 self.fn_add = fn_add 74 self.noe_flag = noe_flag 75 self.relax_fit_flag = relax_fit_flag 76 self.relax_disp_flag = relax_disp_flag 77 78 # Initialise the base class. 79 super(Spectra_list, self).__init__(gui=gui, parent=parent, box=box, id=id, proportion=proportion, button_placement=button_placement)
80 81
82 - def action_relax_disp_cpmg_frq(self, event=None, item=None):
83 """Launch the relax_disp.cpmg_frq user function. 84 85 @keyword event: The wx event. 86 @type event: wx event 87 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 88 @type item: None or int 89 """ 90 91 # The current selection. 92 if item == None: 93 item = self.element.GetFirstSelected() 94 95 # The spectrum ID. 96 id = gui_to_str(self.element.GetItemText(item)) 97 98 # The current frequency. 99 frq = None 100 frq_flag = False 101 if hasattr(cdp, 'cpmg_frqs') and id in cdp.cpmg_frqs.keys(): 102 frq = cdp.cpmg_frqs[id] 103 frq_flag = True 104 105 # Launch the dialog. 106 if frq_flag: 107 uf_store['relax_disp.cpmg_frq'](cpmg_frq=frq, spectrum_id=id) 108 else: 109 uf_store['relax_disp.cpmg_frq'](spectrum_id=id)
110 111
112 - def action_relax_disp_exp_type(self, event=None, item=None):
113 """Launch the relax_disp.exp_type user function. 114 115 @keyword event: The wx event. 116 @type event: wx event 117 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 118 @type item: None or int 119 """ 120 121 # The current selection. 122 if item == None: 123 item = self.element.GetFirstSelected() 124 125 # The spectrum ID. 126 id = gui_to_str(self.element.GetItemText(item)) 127 128 # The current type. 129 exp_type = None 130 if hasattr(cdp, 'exp_type') and id in cdp.exp_type.keys(): 131 exp_type = cdp.exp_type[id] 132 133 # Launch the dialog. 134 if exp_type == None: 135 uf_store['relax_disp.exp_type'](spectrum_id=id) 136 else: 137 uf_store['relax_disp.exp_type'](spectrum_id=id, exp_type=exp_type)
138 139
140 - def action_relax_disp_relax_time(self, event=None, item=None):
141 """Launch the relax_disp.relax_time user function. 142 143 @keyword event: The wx event. 144 @type event: wx event 145 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 146 @type item: None or int 147 """ 148 149 # The current selection. 150 if item == None: 151 item = self.element.GetFirstSelected() 152 153 # The spectrum ID. 154 id = gui_to_str(self.element.GetItemText(item)) 155 156 # The current time. 157 time = None 158 if hasattr(cdp, 'relax_times') and id in cdp.relax_times.keys(): 159 time = cdp.relax_times[id] 160 161 # Launch the dialog. 162 if time == None: 163 uf_store['relax_disp.relax_time'](spectrum_id=id) 164 else: 165 uf_store['relax_disp.relax_time'](time=time, spectrum_id=id)
166 167
168 - def action_relax_disp_spin_lock_field(self, event=None, item=None):
169 """Launch the relax_disp.spin_lock_field user function. 170 171 @keyword event: The wx event. 172 @type event: wx event 173 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 174 @type item: None or int 175 """ 176 177 # The current selection. 178 if item == None: 179 item = self.element.GetFirstSelected() 180 181 # The spectrum ID. 182 id = gui_to_str(self.element.GetItemText(item)) 183 184 # The spin-lock. 185 nu1 = None 186 nu1_flag = False 187 if hasattr(cdp, 'spin_lock_nu1') and id in cdp.spin_lock_nu1.keys(): 188 nu1 = cdp.spin_lock_nu1[id] 189 nu1_flag = True 190 191 # Launch the dialog. 192 if nu1_flag: 193 uf_store['relax_disp.spin_lock_field'](field=nu1, spectrum_id=id) 194 else: 195 uf_store['relax_disp.spin_lock_field'](spectrum_id=id)
196 197
198 - def action_relax_fit_relax_time(self, event=None, item=None):
199 """Launch the relax_fit.relax_time user function. 200 201 @keyword event: The wx event. 202 @type event: wx event 203 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 204 @type item: None or int 205 """ 206 207 # The current selection. 208 if item == None: 209 item = self.element.GetFirstSelected() 210 211 # The spectrum ID. 212 id = gui_to_str(self.element.GetItemText(item)) 213 214 # The current time. 215 time = None 216 if hasattr(cdp, 'relax_times') and id in cdp.relax_times.keys(): 217 time = cdp.relax_times[id] 218 219 # Launch the dialog. 220 if time == None: 221 uf_store['relax_fit.relax_time'](spectrum_id=id) 222 else: 223 uf_store['relax_fit.relax_time'](time=time, spectrum_id=id)
224 225
226 - def action_spectrometer_frq(self, event=None, item=None):
227 """Launch the spectrometer.frequency user function. 228 229 @keyword event: The wx event. 230 @type event: wx event 231 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs. 232 @type item: None or int 233 """ 234 235 # The current selection. 236 if item == None: 237 item = self.element.GetFirstSelected() 238 239 # The spectrum ID. 240 id = gui_to_str(self.element.GetItemText(item)) 241 242 # The current frequency. 243 frq = None 244 if hasattr(cdp, 'spectrometer_frq') and id in cdp.spectrometer_frq: 245 frq = cdp.spectrometer_frq[id] 246 247 # Launch the dialog. 248 if frq == None: 249 uf_store['spectrometer.frequency'](id=id) 250 else: 251 uf_store['spectrometer.frequency'](frq=frq, id=id)
252 253
254 - def action_spectrum_baseplane_rmsd(self, event):
255 """Launch the spectrum.baseplane_rmsd user function. 256 257 @param event: The wx event. 258 @type event: wx event 259 """ 260 261 # The current selection. 262 item = self.element.GetFirstSelected() 263 264 # The spectrum ID. 265 id = gui_to_str(self.element.GetItemText(item)) 266 267 # Launch the dialog. 268 uf_store['spectrum.baseplane_rmsd'](spectrum_id=id)
269 270
271 - def action_spectrum_delete(self, event):
272 """Launch the spectrum.delete user function. 273 274 @param event: The wx event. 275 @type event: wx event 276 """ 277 278 # The current selection. 279 item = self.element.GetFirstSelected() 280 281 # No selection. 282 if item == -1: 283 id = None 284 285 # Selected item. 286 else: 287 # The spectrum ID. 288 id = gui_to_str(self.element.GetItemText(item)) 289 290 # Launch the dialog. 291 uf_store['spectrum.delete'](spectrum_id=id)
292 293
294 - def action_spectrum_integration_points(self, event):
295 """Launch the spectrum.integration_points user function. 296 297 @param event: The wx event. 298 @type event: wx event 299 """ 300 301 # The current selection. 302 item = self.element.GetFirstSelected() 303 304 # The spectrum ID. 305 id = gui_to_str(self.element.GetItemText(item)) 306 307 # Launch the dialog. 308 uf_store['spectrum.integration_points'](spectrum_id=id)
309 310
311 - def action_spectrum_replicated(self, event):
312 """Launch the spectrum.replicated user function. 313 314 @param event: The wx event. 315 @type event: wx event 316 """ 317 318 # The current selection. 319 item = self.element.GetFirstSelected() 320 321 # The spectrum ID. 322 id = gui_to_str(self.element.GetItemText(item)) 323 324 # The current replicates. 325 replicates = replicated_ids(id) 326 327 # Launch the dialog. 328 if replicates == []: 329 uf_store['spectrum.replicated'](spectrum_ids=id) 330 else: 331 uf_store['spectrum.replicated'](spectrum_ids=replicates)
332 333
334 - def add_disp_point(self, index):
335 """Add the dispersion point info to the element. 336 337 This is either the CPMG pulse frequency or the spin-lock field strength. Both share the same column. 338 339 @param index: The column index for the data. 340 @type index: int 341 @return: True if the data exists, False otherwise. 342 @rtype: bool 343 """ 344 345 # Append a column. 346 self.element.InsertColumn(index, u("\u03BDCPMG (Hz) or Spin-lock \u03BD1 (Hz)")) 347 348 # No data. 349 if not hasattr(cdp, 'spectrum_ids'): 350 return True 351 352 # Set the values. 353 for i in range(len(cdp.spectrum_ids)): 354 # Set the CPMG frequency. 355 if hasattr(cdp, 'cpmg_frqs') and cdp.spectrum_ids[i] in cdp.cpmg_frqs.keys(): 356 self.element.SetStringItem(i, index, float_to_gui(cdp.cpmg_frqs[cdp.spectrum_ids[i]])) 357 358 # Set the spin-lock field strength. 359 if hasattr(cdp, 'spin_lock_nu1') and cdp.spectrum_ids[i] in cdp.spin_lock_nu1.keys(): 360 self.element.SetStringItem(i, index, float_to_gui(cdp.spin_lock_nu1[cdp.spectrum_ids[i]])) 361 362 # Successful. 363 return True
364 365
366 - def add_exp_type(self, index):
367 """Add the experiment type info to the element. 368 369 @param index: The column index for the data. 370 @type index: int 371 @return: True if the data exists, False otherwise. 372 @rtype: bool 373 """ 374 375 # Append a column. 376 self.element.InsertColumn(index, u("Experiment type")) 377 378 # No data. 379 if not hasattr(cdp, 'spectrum_ids') or not hasattr(cdp, 'exp_type'): 380 return True 381 382 # Set the values. 383 for i in range(len(cdp.spectrum_ids)): 384 # No value. 385 if cdp.spectrum_ids[i] not in cdp.exp_type.keys(): 386 continue 387 388 # Set the value. 389 self.element.SetStringItem(i, index, float_to_gui(cdp.exp_type[cdp.spectrum_ids[i]])) 390 391 # Successful. 392 return True
393 394
395 - def add_frqs(self, index):
396 """Add the spectrometer frequency info to the element. 397 398 @param index: The column index for the data. 399 @type index: int 400 @return: True if the frequency data exists, False otherwise. 401 @rtype: bool 402 """ 403 404 # Append a column. 405 self.element.InsertColumn(index, u("\u03C9H (MHz)")) 406 407 # No data. 408 if not hasattr(cdp, 'spectrum_ids'): 409 return True 410 if not hasattr(cdp, 'spectrometer_frq') or not len(cdp.spectrometer_frq): 411 return True 412 413 # Set the values. 414 for i in range(len(cdp.spectrum_ids)): 415 # No value. 416 if cdp.spectrum_ids[i] not in cdp.spectrometer_frq: 417 continue 418 419 # Set the value (in MHz). 420 self.element.SetStringItem(i, index, float_to_gui(cdp.spectrometer_frq[cdp.spectrum_ids[i]]/1e6)) 421 422 # Successful. 423 return True
424 425
426 - def generate_popup_menu(self, id=None):
427 """Create the popup menu. 428 429 @keyword id: The spectrum ID string for the row that was clicked on. 430 @type id: str 431 @return: The popup menu. 432 @rtype: list of dict of wxID, str, str, method 433 """ 434 435 # The right click popup menu. 436 popup_menus = [ 437 { 438 'id': wx.NewId(), 439 'text': "Set the &baseplane RMSD", 440 'icon': fetch_icon(uf_info.get_uf('spectrum.baseplane_rmsd').gui_icon), 441 'method': self.action_spectrum_baseplane_rmsd 442 }, { 443 'id': wx.NewId(), 444 'text': "&Delete the peak intensities", 445 'icon': fetch_icon(uf_info.get_uf('spectrum.delete').gui_icon), 446 'method': self.action_spectrum_delete 447 }, { 448 'id': wx.NewId(), 449 'text': "Set the number of integration &points", 450 'icon': fetch_icon(uf_info.get_uf('spectrum.integration_points').gui_icon), 451 'method': self.action_spectrum_integration_points 452 }, { 453 'id': wx.NewId(), 454 'text': "Specify which spectra are &replicated", 455 'icon': fetch_icon(uf_info.get_uf('spectrum.replicated').gui_icon), 456 'method': self.action_spectrum_replicated 457 } 458 ] 459 if self.relax_disp_flag: 460 popup_menus.append({ 461 'id': wx.NewId(), 462 'text': "Set the &experiment type", 463 'icon': None, 464 'method': self.action_relax_disp_exp_type 465 }) 466 if self.relax_fit_flag: 467 popup_menus.append({ 468 'id': wx.NewId(), 469 'text': "Set the relaxation &time", 470 'icon': fetch_icon(uf_info.get_uf('relax_fit.relax_time').gui_icon), 471 'method': self.action_relax_fit_relax_time 472 }) 473 if self.relax_disp_flag: 474 popup_menus.append({ 475 'id': wx.NewId(), 476 'text': "Set the relaxation &time", 477 'icon': fetch_icon(uf_info.get_uf('relax_disp.relax_time').gui_icon), 478 'method': self.action_relax_disp_relax_time 479 }) 480 popup_menus.append({ 481 'id': wx.NewId(), 482 'text': "Set the spectrometer &frequency", 483 'icon': fetch_icon("relax.spectrometer"), 484 'method': self.action_spectrometer_frq 485 }) 486 if self.relax_disp_flag and is_r1rho_exp_type(id): 487 popup_menus.append({ 488 'id': wx.NewId(), 489 'text': u("Set the spin-&lock field strength \u03BD1"), 490 'icon': fetch_icon("relax.relax_disp"), 491 'method': self.action_relax_disp_spin_lock_field 492 }) 493 if self.relax_disp_flag and is_cpmg_exp_type(id): 494 popup_menus.append({ 495 'id': wx.NewId(), 496 'text': u("Set the &CPMG pulse frequency \u03BDCPMG"), 497 'icon': fetch_icon("relax.relax_disp"), 498 'method': self.action_relax_disp_cpmg_frq 499 }) 500 501 # Return the menu. 502 return popup_menus
503 504
505 - def noe_spectrum_type(self, index):
506 """Add the NOE spectral type info to the element. 507 508 @param index: The column index for the data. 509 @type index: int 510 @return: True if a spectrum type exists, False otherwise. 511 @rtype: bool 512 """ 513 514 # No type info. 515 if not hasattr(cdp, 'spectrum_type') or not len(cdp.spectrum_type): 516 return False 517 518 # Append a column. 519 self.element.InsertColumn(index, str_to_gui("NOE spectrum type")) 520 521 # Translation table. 522 table = { 523 'sat': 'Saturated', 524 'ref': 'Reference' 525 } 526 527 # No data. 528 if not hasattr(cdp, 'spectrum_ids'): 529 return True 530 531 # Set the values. 532 for i in range(len(cdp.spectrum_ids)): 533 # No value. 534 if cdp.spectrum_ids[i] not in cdp.spectrum_type.keys(): 535 continue 536 537 # Set the value. 538 self.element.SetStringItem(i, index, str_to_gui(table[cdp.spectrum_type[cdp.spectrum_ids[i]]])) 539 540 # Successful. 541 return True
542 543
544 - def relax_times(self, index):
545 """Add the relaxation delay time info to the element. 546 547 @param index: The column index for the data. 548 @type index: int 549 @return: True if relaxation times exist, False otherwise. 550 @rtype: bool 551 """ 552 553 # No type info. 554 if not hasattr(cdp, 'relax_times') or not len(cdp.relax_times): 555 return False 556 557 # Append a column. 558 self.element.InsertColumn(index, str_to_gui("Delay times (s)")) 559 560 # No data. 561 if not hasattr(cdp, 'spectrum_ids'): 562 return True 563 564 # Set the values. 565 for i in range(len(cdp.spectrum_ids)): 566 # No value. 567 if cdp.spectrum_ids[i] not in cdp.relax_times.keys(): 568 continue 569 570 # Set the value. 571 self.element.SetStringItem(i, index, float_to_gui(cdp.relax_times[cdp.spectrum_ids[i]])) 572 573 # Successful. 574 return True
575 576
577 - def replicates(self, index):
578 """Add the replicated spectra info to the element. 579 580 @param index: The column index for the data. 581 @type index: int 582 @return: True if relaxation times exist, False otherwise. 583 @rtype: bool 584 """ 585 586 # No type info. 587 if not hasattr(cdp, 'replicates') or not len(cdp.replicates): 588 return False 589 590 # Replicated spectra. 591 repl = replicated_flags() 592 593 # Append a column. 594 self.element.InsertColumn(index, str_to_gui("Replicate IDs")) 595 596 # No data. 597 if not hasattr(cdp, 'spectrum_ids'): 598 return True 599 600 # Set the values. 601 for i in range(len(cdp.spectrum_ids)): 602 # No replicates. 603 if not repl[cdp.spectrum_ids[i]]: 604 continue 605 606 # The replicated spectra. 607 id_list = replicated_ids(cdp.spectrum_ids[i]) 608 609 # Convert to a string. 610 text = '' 611 for j in range(len(id_list)): 612 # Add the id. 613 text = "%s%s" % (text, id_list[j]) 614 615 # Separator. 616 if j < len(id_list)-1: 617 text = "%s, " % text 618 619 # Set the value. 620 self.element.SetStringItem(i, index, str_to_gui(text)) 621 622 # Successful. 623 return True
624 625
626 - def setup(self):
627 """Override the base variables.""" 628 629 # GUI variables. 630 self.title = "Spectra list" 631 self.observer_base_name = "spectra list" 632 633 # The column titles. 634 self.columns = [] 635 636 # Button set up. 637 self.button_placement = 'top' 638 self.button_info = [ 639 { 640 'object': 'button_add', 641 'label': ' Add', 642 'icon': fetch_icon('oxygen.actions.list-add-relax-blue', "22x22"), 643 'method': self.fn_add, 644 'tooltip': "Read a spectral data file." 645 }, { 646 'object': 'button_delete', 647 'label': ' Delete', 648 'icon': fetch_icon('oxygen.actions.list-remove', "22x22"), 649 'method': self.action_spectrum_delete, 650 'tooltip': "Delete loaded relaxation data from the relax data store." 651 } 652 ]
653 654
655 - def update_data(self):
656 """Method called from self.build_element_safe() to update the list data.""" 657 658 # Initialise the column index for the data. 659 index = 1 660 661 # Delete the rows and columns. 662 self.element.DeleteAllItems() 663 self.element.DeleteAllColumns() 664 665 # Initialise to a single column. 666 self.element.InsertColumn(0, str_to_gui("Spectrum ID")) 667 668 # Expand the number of rows to match the number of spectrum IDs, and add the IDs. 669 n = 0 670 if hasattr(cdp, 'spectrum_ids'): 671 # The number of IDs. 672 n = len(cdp.spectrum_ids) 673 674 # Set the IDs. 675 for i in range(n): 676 self.element.InsertStringItem(i, str_to_gui(cdp.spectrum_ids[i])) 677 678 # The NOE spectrum type. 679 if self.noe_spectrum_type(index): 680 index += 1 681 682 # The experiment type. 683 if self.relax_disp_flag and self.add_exp_type(index): 684 index += 1 685 686 # The spectrometer frequency. 687 if self.relax_disp_flag and self.add_frqs(index): 688 index += 1 689 690 # The spin-lock field strength or CPMG pulse frequency. 691 if self.relax_disp_flag and self.add_disp_point(index): 692 index += 1 693 694 # The relaxation times. 695 if (self.relax_fit_flag or self.relax_disp_flag) and self.relax_times(index): 696 index += 1 697 698 # The replicated spectra. 699 if self.replicates(index): 700 index += 1
701