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