Package gui :: Module export_bmrb
[hide private]
[frames] | no frames]

Source Code for Module gui.export_bmrb

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2012 Edward d'Auvergne                                        # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The BMRB export wizard.""" 
 24   
 25  # Python module imports. 
 26  import wx 
 27   
 28  # relax module imports. 
 29  from generic_fns.mol_res_spin import molecule_loop 
 30  from generic_fns.pipes import cdp_name, pipe_names, switch 
 31  from graphics import IMAGE_PATH, fetch_icon 
 32  from status import Status; status = Status() 
 33   
 34  # relax GUI module imports. 
 35  from gui.components.citations import Citations 
 36  from gui.components.molecule import Molecule 
 37  from gui.components.relax_data_meta import Relax_data_meta_list 
 38  from gui.components.scripts import Scripts 
 39  from gui.components.software import Software 
 40  from gui.message import Missing_data 
 41  from gui.fonts import font 
 42  from gui.icons import relax_icons 
 43  from gui.input_elements.value import Value 
 44  from gui.misc import add_border, bitmap_setup 
 45  from gui.string_conv import gui_to_str, str_to_gui 
 46  from gui.uf_objects import Uf_storage; uf_store = Uf_storage() 
 47   
 48   
49 -class Export_bmrb_window(wx.Frame):
50 """The BMRB export window.""" 51
52 - def __init__(self, gui):
53 """Set up the export window. 54 55 @param gui: The GUI object. 56 @type gui: wx.Frame instance 57 """ 58 59 # The window style. 60 style = wx.DEFAULT_FRAME_STYLE 61 if not status.debug and status.wx_info["os"] != 'darwin': 62 style = style | wx.MAXIMIZE 63 64 # Initialise the base class, setting the main GUI window as the parent. 65 super(Export_bmrb_window, self).__init__(gui, -1, style=style) 66 67 # Some default values. 68 self.size = (1200, 900) 69 self.size_min = (900, 700) 70 self.border = 5 71 self.spacer = 10 72 self.button_size = (200, 40) 73 self.button_spacing = 10 74 self.main_spacing = 20 75 76 # Set up the frame. 77 sizer = self.setup_frame() 78 79 # Add the header. 80 self.add_header(sizer) 81 82 # Top spacing. 83 sizer.AddSpacer(10) 84 85 # Add the data pipe selection element. 86 self.add_pipe(sizer) 87 88 # Spacing. 89 sizer.AddSpacer(self.main_spacing) 90 91 # Add the relaxation data metadata list GUI element. 92 self.relax_data = Relax_data_meta_list(parent=self.main_panel, box=sizer, id='BMRB export', proportion=2) 93 94 # Spacing. 95 sizer.AddSpacer(self.main_spacing) 96 97 # Add the molecule GUI element. 98 self.molecule = Molecule(parent=self.main_panel, box=sizer, id='BMRB export', proportion=1) 99 100 # Spacing. 101 sizer.AddSpacer(self.main_spacing) 102 103 # Create a horizontal layout for the software, script and citations GUI elements. 104 sub_sizer = wx.BoxSizer(wx.HORIZONTAL) 105 106 # Add the software GUI element. 107 self.software = Software(parent=self.main_panel, box=sub_sizer, id='BMRB export', proportion=1) 108 109 # Vertical spacing. 110 sub_sizer.AddSpacer(self.main_spacing) 111 112 # Add the scripts GUI element. 113 self.scripts = Scripts(parent=self.main_panel, box=sub_sizer, id='BMRB export', proportion=1) 114 115 # Vertical spacing. 116 sub_sizer.AddSpacer(self.main_spacing) 117 118 # Add the citation GUI element. 119 self.citation = Citations(parent=self.main_panel, box=sub_sizer, id='BMRB export', proportion=1) 120 121 # Add the sizer. 122 sizer.Add(sub_sizer, 2, wx.ALL|wx.EXPAND, 0) 123 124 # Bottom spacing. 125 sizer.AddSpacer(10) 126 127 # Add the buttons. 128 self.add_buttons(sizer) 129 130 # Open the window. 131 if status.show_gui: 132 self.Show()
133 134
135 - def action_cancel(self, event=None):
136 """Cancel the export. 137 138 @keyword event: The wx event. 139 @type event: wx event 140 """ 141 142 # Close the window. 143 self.Close()
144 145
146 - def action_export(self, event=None):
147 """Write out the NMR-STAR formatted data. 148 149 @keyword event: The wx event. 150 @type event: wx event 151 """ 152 153 # Checks. 154 missing = self.is_complete() 155 156 # Missing data. 157 if len(missing): 158 Missing_data(missing, parent=self) 159 return 160 161 # Execute the user function. 162 uf_store['bmrb.write'](wx_parent=self, wx_wizard_sync=True, wx_wizard_modal=True) 163 164 # Close the window. 165 self.Close()
166 167
168 - def action_preview(self, event=None):
169 """Preview the NMR-STAR formatted data. 170 171 @keyword event: The wx event. 172 @type event: wx event 173 """ 174 175 # Execute the user function. 176 uf_store['bmrb.display'](wx_parent=self)
177 178
179 - def add_buttons(self, sizer):
180 """Build and add the bottom buttons. 181 182 @param sizer: The sizer element to pack the buttons into. 183 @type sizer: wx.Sizer instance 184 """ 185 186 # Button sizer. 187 button_sizer = wx.BoxSizer(wx.HORIZONTAL) 188 sizer.Add(button_sizer, 0, wx.ALIGN_RIGHT, 0) 189 190 # Preview button. 191 button = wx.lib.buttons.ThemedGenBitmapTextButton(self.main_panel, -1, None, " Preview") 192 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.document-preview', "32x32"), wx.BITMAP_TYPE_ANY)) 193 button.SetFont(font.normal) 194 button.SetMinSize(self.button_size) 195 button_sizer.Add(button, 0, 0, 0) 196 self.Bind(wx.EVT_BUTTON, self.action_preview, button) 197 button.SetToolTipString("Preview the NMR-STAR formatted data.") 198 199 # Spacing. 200 button_sizer.AddSpacer(self.button_spacing) 201 202 # Export button. 203 button = wx.lib.buttons.ThemedGenBitmapTextButton(self.main_panel, -1, None, " Export") 204 button.SetBitmapLabel(wx.Bitmap(fetch_icon('relax.bmrb', "32x32"), wx.BITMAP_TYPE_ANY)) 205 button.SetFont(font.normal) 206 button.SetMinSize(self.button_size) 207 button_sizer.Add(button, 0, 0, 0) 208 self.Bind(wx.EVT_BUTTON, self.action_export, button) 209 button.SetToolTipString("Create the NMR-STAR formatted file for BMRB deposition.") 210 211 # Spacing. 212 button_sizer.AddSpacer(self.button_spacing) 213 214 # Cancel button. 215 button = wx.lib.buttons.ThemedGenBitmapTextButton(self.main_panel, -1, None, " Cancel") 216 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.dialog-cancel', "32x32"), wx.BITMAP_TYPE_ANY)) 217 button.SetFont(font.normal) 218 button.SetMinSize(self.button_size) 219 button_sizer.Add(button, 0, 0, 0) 220 self.Bind(wx.EVT_BUTTON, self.action_cancel, button) 221 button.SetToolTipString("Cancel the BMRB export.")
222 223
224 - def add_header(self, sizer):
225 """Build and add the header to the sizer. 226 227 @param sizer: The sizer element to pack the header into. 228 @type sizer: wx.Sizer instance 229 """ 230 231 # Create a horizontal layout. 232 sub_sizer = wx.BoxSizer(wx.HORIZONTAL) 233 234 # Left spacing. 235 sub_sizer.AddStretchSpacer(3) 236 237 # Add the BMRB logo (left side). 238 logo = wx.StaticBitmap(self.main_panel, -1, bitmap_setup(IMAGE_PATH+"bmrb_100x100.png")) 239 sub_sizer.Add(logo, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 0) 240 241 # Spacing. 242 sub_sizer.AddStretchSpacer() 243 244 # The text sizer. 245 text_sizer = wx.BoxSizer(wx.VERTICAL) 246 247 # The title. 248 text = wx.StaticText(self.main_panel, -1, 'Data export for BMRB deposition', style=wx.ALIGN_LEFT) 249 text.SetFont(font.title) 250 text_sizer.Add(text, 0, wx.ALIGN_CENTER_HORIZONTAL, 0) 251 252 # Spacing. 253 text_sizer.AddSpacer(15) 254 255 # The text. 256 main_text = 'This wizard will help in executing all of the relevant user functions required to convert the contents of the selected data pipe to the NMR-STAR format for deposition within the BioMagResBank. Note that this is currently only for the deposition of model-free analysis results or simple NMR relaxation data.' 257 text = wx.StaticText(self.main_panel, -1, main_text, style=wx.ALIGN_LEFT) 258 text.Wrap(600) 259 text.SetFont(font.normal) 260 text_sizer.Add(text, 0, 0, 0) 261 262 # Add the text sizer. 263 sub_sizer.Add(text_sizer, 0, 0, 0) 264 265 # Spacing. 266 sub_sizer.AddStretchSpacer() 267 268 # Add the BMRB logo (right side). 269 logo = wx.StaticBitmap(self.main_panel, -1, bitmap_setup(IMAGE_PATH+"bmrb_100x100.png")) 270 sub_sizer.Add(logo, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 0) 271 272 # Right spacing. 273 sub_sizer.AddStretchSpacer(3) 274 275 # Add the sizer. 276 sizer.Add(sub_sizer, 0, wx.ALL|wx.EXPAND, 0) 277 278 # A line with spacing. 279 sizer.AddSpacer(10) 280 sizer.Add(wx.StaticLine(self.main_panel, -1), 0, wx.EXPAND|wx.ALL, 0) 281 sizer.AddSpacer(10)
282 283
284 - def add_pipe(self, sizer):
285 """Build and add the data pipe selection element. 286 287 @param sizer: The sizer element to pack the buttons into. 288 @type sizer: wx.Sizer instance 289 """ 290 291 # A sizer for the element. 292 pipe_sizer = wx.BoxSizer(wx.HORIZONTAL) 293 sizer.Add(pipe_sizer, 0, wx.ALIGN_LEFT, 0) 294 295 # The pipe text. 296 text = wx.StaticText(self.main_panel, -1, ' The data pipe to export: ', style=wx.ALIGN_LEFT) 297 tooltip = "The name of the data pipe to export to NMR-STAR format for BMRB export." 298 text.SetFont(font.normal) 299 text.SetToolTipString(tooltip) 300 pipe_sizer.Add(text, 0, wx.ALIGN_CENTER_VERTICAL, 0) 301 302 # Spacing. 303 pipe_sizer.AddSpacer(20) 304 305 # The pipe selection. 306 self.pipe_name = wx.ComboBox(self.main_panel, -1, "", style=wx.CB_DROPDOWN|wx.CB_READONLY, choices=[]) 307 self.pipe_name.SetToolTipString(tooltip) 308 self.Bind(wx.EVT_COMBOBOX, self.update_pipes, self.pipe_name) 309 pipe_sizer.Add(self.pipe_name, 0, wx.ALIGN_CENTER_VERTICAL, 0) 310 311 # Update the pipe selection. 312 self.update_pipes()
313 314
315 - def handler_close(self, event):
316 """Event handler for the close window action. 317 318 @param event: The wx event. 319 @type event: wx event 320 """ 321 322 # Unregister the observers. 323 self.observer_register(remove=True) 324 325 # Close the window. 326 event.Skip()
327 328
329 - def is_complete(self):
330 """Determine if the data input is complete. 331 332 @return: A list of all the missing components. 333 @rtype: list of str 334 """ 335 336 # Initialise. 337 missing = [] 338 339 # Relaxation data metadata. 340 if hasattr(cdp, 'ri_ids'): 341 # Loop over the data. 342 for i in range(len(cdp.ri_ids)): 343 # Check the peak intensity types. 344 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'peak_intensity_type') or not cdp.ri_ids[i] in cdp.exp_info.peak_intensity_type.keys(): 345 missing.append("The peak intensity type for the relaxation data ID '%s'." % cdp.ri_ids[i]) 346 347 # Check the temperature calibration methods. 348 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_calibration') or not cdp.ri_ids[i] in cdp.exp_info.temp_calibration.keys(): 349 missing.append("The temperature calibration method for the relaxation data ID '%s'." % cdp.ri_ids[i]) 350 351 # Check the temperature control methods. 352 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_control') or not cdp.ri_ids[i] in cdp.exp_info.temp_control.keys(): 353 missing.append("The temperature control method for the relaxation data ID '%s'." % cdp.ri_ids[i]) 354 355 356 # Loop over the molecules. 357 for mol, mol_id in molecule_loop(return_id=True): 358 # No name. 359 if mol.name == None: 360 missing.append("The name of the molecule for %s." % mol_id) 361 continue 362 363 # No molecule type. 364 if not hasattr(mol, 'type') or mol.type == None: 365 missing.append("The type of the molecule %s." % mol_id) 366 367 # No thiol state. 368 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'thiol_state'): 369 missing.append("The thiol state of the molecule %s." % mol_id) 370 371 # Return the list of missing data. 372 return missing
373 374
375 - def observer_register(self, remove=False):
376 """Register and unregister methods with the observer objects. 377 378 @keyword remove: If set to True, then the methods will be unregistered. 379 @type remove: False 380 """ 381 382 # Register. 383 if not remove: 384 status.observers.pipe_alteration.register('BMRB export', self.update_pipes, method_name='update_pipes') 385 386 # Unregister. 387 else: 388 # The class methods. 389 status.observers.pipe_alteration.unregister('BMRB export') 390 391 # The embedded objects methods. 392 self.relax_data.observer_register(remove=True) 393 self.molecule.observer_register(remove=True) 394 self.software.observer_register(remove=True) 395 self.scripts.observer_register(remove=True) 396 self.citation.observer_register(remove=True)
397 398
399 - def setup_frame(self):
400 """Set up the relax controller frame. 401 @return: The sizer object. 402 @rtype: wx.Sizer instance 403 """ 404 405 # Set the frame title. 406 self.SetTitle("BMRB export window") 407 408 # Set up the window icon. 409 self.SetIcons(relax_icons) 410 411 # Place all elements within a panel (to remove the dark grey in MS Windows). 412 self.main_panel = wx.Panel(self, -1) 413 414 # Use a grid sizer for packing the main elements. 415 main_sizer = wx.BoxSizer(wx.VERTICAL) 416 self.main_panel.SetSizer(main_sizer) 417 418 # Build the central sizer, with borders. 419 sizer = add_border(main_sizer, border=self.border, packing=wx.VERTICAL) 420 421 # Close the window cleanly (unregistering observers). 422 self.Bind(wx.EVT_CLOSE, self.handler_close) 423 424 # Set the default size of the controller. 425 self.SetSize(self.size) 426 self.SetMinSize(self.size_min) 427 428 # Centre the frame. 429 self.Centre() 430 431 # Return the central sizer. 432 return sizer
433 434
435 - def update_pipes(self, event=None):
436 """Update the spin view data pipe selector. 437 438 @keyword event: The wx event. 439 @type event: wx event 440 """ 441 442 # Change the cursor to busy. 443 wx.BeginBusyCursor() 444 445 # Init. 446 pipe_switch = False 447 448 # The selected pipe. 449 if event: 450 # The name of the selected pipe. 451 pipe = gui_to_str(self.pipe_name.GetString(event.GetSelection())) 452 453 # A pipe change. 454 if pipe != cdp_name(): 455 pipe_switch = True 456 else: 457 pipe = cdp_name() 458 if not pipe: 459 pipe = '' 460 461 # Clear the previous data. 462 self.pipe_name.Clear() 463 464 # The list of pipe names. 465 for name in pipe_names(): 466 self.pipe_name.Append(str_to_gui(name)) 467 468 # Switch data pipes. 469 if pipe_switch: 470 switch(pipe) 471 472 # Set the pipe name to the cdp. 473 self.pipe_name.SetValue(str_to_gui(pipe)) 474 475 # Reset the cursor. 476 if wx.IsBusy(): 477 wx.EndBusyCursor()
478