- Timestamp:
- Apr 5, 2015 3:15:33 PM (10 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 439420f9
- Parents:
- 0fa825c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/perspectives/calculator/model_editor.py
r49ab5d7 r7b1f4e3 1 ''' 2 This module provides three model editor classes: the composite model editor, 3 the easy editor which provides a simple interface with tooltip help to enter 4 the parameters of the model and their default value and a panel to input a 5 function of y (usually the intensity). It also provides a drop down of 6 standard available math functions. Finally a full python editor panel for 7 complete customizatin is provided. 8 9 :TODO the writiong of the file and name checking (and maybe some other 10 funtions?) should be moved to a computational module which could be called 11 fropm a python script. Basically one just needs to pass the name, 12 description text and function text (or in the case of the composite editor 13 the names of the first and second model and the operator to be used). 14 ''' 15 1 16 ################################################################################ 2 17 #This software was developed by the University of Tennessee as part of the … … 12 27 import os 13 28 import math 29 import re 14 30 from wx.py.editwindow import EditWindow 15 31 … … 53 69 class TextDialog(wx.Dialog): 54 70 """ 55 Dialog for easy custom sum models 71 Dialog for easy custom composite models. Provides a wx.Dialog panel 72 to choose two existing models (including pre-existing custom models which 73 may themselves be sum models) as well as an operation on those models (add 74 or multiply) the resulting model will add a scale parameter for summed 75 models and a background parameter for a multiplied model. 76 77 The user also gives a brief help for the model in a description box and 78 must provide a unique name which is verified as unique before the new 79 model is saved. 80 81 This Dialog pops up for the user when they press 'Sum|Multi(p1,p2)' under 82 'Edit Custom Model' under 'Fitting' menu. This is currently called as 83 a Modal Dialog. 84 85 :TODO the build in compiler currently balks at when it tries to import 86 a model whose name contains spaces or symbols (such as + ... underscore 87 should be fine) need to either alter how the model file is written on add 88 checking method to look for non-approved characters. - PDB:April 5, 2015 56 89 """ 57 90 def __init__(self, parent=None, base=None, id=None, title='', 58 91 model_list=[], plugin_dir=None): 59 92 """ 60 Dialog window popup when selecting 'Easy Custom Sum/Multiply' 61 on the menu 93 This class is run when instatiated. The __init__ intializes and 94 calls the internal methods necessary. On exiting the wx.Dialog 95 window should be destroyed. 96 62 97 """ 63 98 wx.Dialog.__init__(self, parent=parent, id=id, … … 67 102 self.SetWindowVariant(variant=FONT_VARIANT) 68 103 # default 69 self.font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)70 self.font.SetPointSize(10)71 104 self.overwrite_name = False 72 105 self.plugin_dir = plugin_dir … … 77 110 self.factor = 'scale_factor' 78 111 self._notes = '' 79 self. operator = '+'80 self. operator_cbox= None112 self._operator = '+' 113 self._operator_choice = None 81 114 self.explanation = '' 82 115 self.explanationctr = None 83 self. sizer= None116 self.type = None 84 117 self.name_sizer = None 85 self.name_ hsizer= None118 self.name_tcl = None 86 119 self.desc_sizer = None 87 120 self.desc_tcl = None 121 self._selection_box= None 88 122 self.model1 = None 89 123 self.model2 = None … … 107 141 Do the layout for file/function name related widgets 108 142 """ 109 self.name_sizer = wx.BoxSizer(wx.VERTICAL) 110 self.name_hsizer = wx.BoxSizer(wx.HORIZONTAL) 111 #title name [string] 112 name_txt = wx.StaticText(self, -1, 'Function Name : ') 113 self.name_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1)) 143 #container for new model name input 144 self.name_sizer = wx.BoxSizer(wx.HORIZONTAL) 145 146 #set up label and input box with tool tip and event handling 147 self.name_txt = wx.StaticText(self, -1, 'Function Name : ') 148 self.name_tcl = wx.TextCtrl(self, -1, value = 'MySumFunction') 114 149 self.name_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_name) 115 self.name_tcl.SetValue('')116 self.name_tcl.SetFont(self.font)117 150 hint_name = "Unique Sum/Multiply Model Function Name." 118 151 self.name_tcl.SetToolTipString(hint_name) 119 self.name_hsizer.AddMany([(name_txt, 0, wx.LEFT | wx.TOP, 10), 152 153 self.name_sizer.AddMany([(self.name_txt, 0, wx.LEFT | wx.TOP, 10), 120 154 (self.name_tcl, -1, 121 155 wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 122 self.name_sizer.AddMany([(self.name_hsizer, -1,123 wx.LEFT | wx.TOP, 10)])124 156 125 157 … … 128 160 Do the layout for description related widgets 129 161 """ 162 #container for new model description input 130 163 self.desc_sizer = wx.BoxSizer(wx.HORIZONTAL) 131 #title name [string] 164 165 #set up description label and input box with tool tip and event handling 132 166 desc_txt = wx.StaticText(self, -1, 'Description (optional) : ') 133 self.desc_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1)) 134 self.desc_tcl.SetValue('') 135 #self.name_tcl.SetFont(self.font) 167 self.desc_tcl = wx.TextCtrl(self, -1) 136 168 hint_desc = "Write a short description of this model function." 137 169 self.desc_tcl.SetToolTipString(hint_desc) 170 138 171 self.desc_sizer.AddMany([(desc_txt, 0, wx.LEFT | wx.TOP, 10), 139 172 (self.desc_tcl, -1, 140 173 wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 141 174 142 def _build_sizer(self): 143 """ 144 Build gui 175 176 def _layout_model_selection(self): 177 """ 178 Do the layout for model selection related widgets 145 179 """ 146 180 box_width = 195 # combobox width 147 vbox = wx.BoxSizer(wx.VERTICAL) 148 self.sizer = wx.GridBagSizer(1, 3) 149 self._layout_name() 150 self._layout_description() 151 152 153 sum_description = wx.StaticBox(self, -1, 'Select', 181 182 #First set up main sizer for the selection 183 selection_box_title = wx.StaticBox(self, -1, 'Select', 154 184 size=(PNL_WIDTH - 30, 70)) 155 sum_box = wx.StaticBoxSizer(sum_description, wx.VERTICAL) 156 model1_box = wx.BoxSizer(wx.HORIZONTAL) 157 model2_box = wx.BoxSizer(wx.HORIZONTAL) 158 model_vbox = wx.BoxSizer(wx.VERTICAL) 185 self._selection_box = wx.StaticBoxSizer(selection_box_title, wx.VERTICAL) 186 187 #Next create the help labels for the model selection 188 select_help_box = wx.BoxSizer(wx.HORIZONTAL) 189 model_string = " Model%s (p%s):" 190 select_help_box.Add(wx.StaticText(self, -1, model_string % (1, 1)), 0, 0) 191 select_help_box.Add((box_width - 25, 10),0,0) 192 select_help_box.Add(wx.StaticText(self, -1, model_string % (2, 2)), 0, 0) 193 self._selection_box.Add(select_help_box, 0, 0) 194 195 #Next create the actual selection box with 3 combo boxes 196 selection_box_choose = wx.BoxSizer(wx.HORIZONTAL) 197 159 198 self.model1 = wx.ComboBox(self, -1, style=wx.CB_READONLY) 160 199 wx.EVT_COMBOBOX(self.model1, -1, self.on_model1) … … 162 201 self.model1.SetToolTipString("model1") 163 202 164 self.operator_cbox = wx.ComboBox(self, -1, size=(50, -1), 165 style=wx.CB_READONLY) 166 wx.EVT_COMBOBOX(self.operator_cbox, -1, self.on_select_operator) 203 self._operator_choice = wx.ComboBox(self, -1, size=(50, -1), style=wx.CB_READONLY) 204 wx.EVT_COMBOBOX(self._operator_choice, -1, self.on_select_operator) 167 205 operation_tip = "Add: +, Multiply: * " 168 self. operator_cbox.SetToolTipString(operation_tip)206 self._operator_choice.SetToolTipString(operation_tip) 169 207 170 208 self.model2 = wx.ComboBox(self, -1, style=wx.CB_READONLY) … … 174 212 self._set_model_list() 175 213 176 # Buttons on the bottom 214 selection_box_choose.Add(self.model1, 0, 0) 215 selection_box_choose.Add((15, 10)) 216 selection_box_choose.Add(self._operator_choice, 0, 0) 217 selection_box_choose.Add((15, 10)) 218 selection_box_choose.Add(self.model2, 0, 0) 219 self._selection_box.Add((20,5), 0, 0) # add some space between labels and selection 220 self._selection_box.Add(selection_box_choose, 0, 0) 221 222 def _build_sizer(self): 223 """ 224 Build GUI with calls to _layout_name, _layout Description 225 and _layout_model_selection which each build a their portion of the 226 GUI. 227 """ 228 mainsizer = wx.BoxSizer(wx.VERTICAL) # create main sizer for dialog 229 230 # build fromm top by calling _layout_name and _layout_description 231 # and adding to main sizer 232 self._layout_name() 233 mainsizer.Add(self.name_sizer,0, wx.EXPAND) 234 self._layout_description() 235 mainsizer.Add(self.desc_sizer,0, wx.EXPAND) 236 237 # Add an explanation of dialog (short help) 238 self.explanationctr = wx.StaticText(self, -1, self.explanation) 239 self.fill_explanation_helpstring(self._operator) 240 mainsizer.Add(self.explanationctr,0, wx.LEFT | wx.EXPAND, 15) 241 242 # Add the selection box stuff with border and labels built 243 # by _layout_model_selection 244 self._layout_model_selection() 245 mainsizer.Add(self._selection_box, 0, wx.LEFT, 15) 246 247 # Add a space and horizontal line before the notification 248 #messages and the buttons at the bottom 249 mainsizer.Add((10, 10)) 177 250 self.static_line_1 = wx.StaticLine(self, -1) 178 self.okButton = wx.Button(self, wx.ID_OK, 'Apply', size=(box_width / 2, 25)) 179 self.okButton.Bind(wx.EVT_BUTTON, self.check_name) 180 self.closeButton = wx.Button(self, wx.ID_CANCEL, 'Close', 181 size=(box_width / 2, 25)) 182 # Intro 183 self.explanation = " custom model = %s %s " % (self.factor, '*') 184 self.explanation += "(model1 %s model2)\n" % self.operator 185 #explanation += " Note: This will overwrite the previous sum model.\n" 186 model_string = " Model%s (p%s):" 187 # msg 251 mainsizer.Add(self.static_line_1, 0, wx.EXPAND, 10) 252 253 # Add action status notification line (null at startup) 188 254 self._msg_box = wx.StaticText(self, -1, self._notes) 189 255 self.msg_sizer = wx.BoxSizer(wx.HORIZONTAL) 190 256 self.msg_sizer.Add(self._msg_box, 0, wx.LEFT, 0) 191 vbox.Add(self.name_hsizer) 192 vbox.Add(self.desc_sizer) 193 vbox.Add(self.sizer) 194 ix = 0 195 iy = 1 196 self.explanationctr = wx.StaticText(self, -1, self.explanation) 197 self.sizer.Add(self.explanationctr , (iy, ix), 198 (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 199 model1_box.Add(wx.StaticText(self, -1, model_string % (1, 1)), -1, 0) 200 model1_box.Add((box_width - 15, 10)) 201 model1_box.Add(wx.StaticText(self, -1, model_string % (2, 2)), -1, 0) 202 model2_box.Add(self.model1, -1, 0) 203 model2_box.Add((15, 10)) 204 model2_box.Add(self.operator_cbox, 0, 0) 205 model2_box.Add((15, 10)) 206 model2_box.Add(self.model2, -1, 0) 207 model_vbox.Add(model1_box, -1, 0) 208 model_vbox.Add(model2_box, -1, 0) 209 sum_box.Add(model_vbox, -1, 10) 210 iy += 1 211 ix = 0 212 self.sizer.Add(sum_box, (iy, ix), 213 (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 214 vbox.Add((10, 10)) 215 vbox.Add(self.static_line_1, 0, wx.EXPAND, 10) 216 vbox.Add(self.msg_sizer, 0, 257 mainsizer.Add(self.msg_sizer, 0, 217 258 wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE | wx.BOTTOM, 10) 259 260 # Finally add the buttons (apply and close) on the bottom 261 # TODO: need help added here 262 self.okButton = wx.Button(self, wx.ID_OK, 'Apply') 263 self.okButton.Bind(wx.EVT_BUTTON, self.check_name) 264 self.closeButton = wx.Button(self, wx.ID_CANCEL, 'Close') 218 265 sizer_button = wx.BoxSizer(wx.HORIZONTAL) 219 sizer_button.Add((20, 20), 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0) 220 sizer_button.Add(self.okButton, 0, 221 wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 0) 222 sizer_button.Add(self.closeButton, 0, 223 wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10) 224 vbox.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10) 225 226 self.SetSizer(vbox) 266 sizer_button.AddMany([((20, 20), 1, 0), 267 (self.okButton, 0, 0), 268 (self.closeButton, 0, wx.LEFT | wx.RIGHT, 10)]) 269 mainsizer.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10) 270 271 self.SetSizer(mainsizer) 227 272 self.Centre() 228 273 … … 249 294 title = self.name_tcl.GetValue().lstrip().rstrip() 250 295 if title == '': 251 text = self. operator296 text = self._operator 252 297 if text.count('+') > 0: 253 298 mname = 'Sum' … … 283 328 On Apply 284 329 """ 330 self.name_tcl.SetBackgroundColour('white') 285 331 try: 286 332 label = self.getText() … … 379 425 if event != None: 380 426 event.Skip() 381 name = ''382 427 item = event.GetEventObject() 383 428 text = item.GetValue() 384 if text.count('*') > 0: 429 self.fill_explanation_helpstring(text) 430 431 def fill_explanation_helpstring(self, type): 432 """ 433 Choose the equation to use depending on whether we now have 434 a sum or multiply model then create the appropriate string 435 """ 436 437 self._type = type 438 name = '' 439 440 if self._type == '*': 385 441 name = 'Multi' 386 442 factor = 'BackGround' … … 392 448 393 449 self.factor = factor 394 self. operator = text450 self._operator = self._type 395 451 self.explanation = " Custom Model = %s %s (model1 %s model2)\n" % \ 396 (self.factor, f_oper, self. operator)452 (self.factor, f_oper, self._operator) 397 453 self.explanationctr.SetLabel(self.explanation) 398 454 self.name = name + M_NAME 399 self.sizer.Layout() 455 400 456 401 457 def fill_oprator_combox(self): … … 405 461 operator_list = [' +', ' *'] 406 462 for oper in operator_list: 407 pos = self. operator_cbox.Append(str(oper))408 self. operator_cbox.SetClientData(pos, str(oper.strip()))409 self. operator_cbox.SetSelection(0)463 pos = self._operator_choice.Append(str(oper)) 464 self._operator_choice.SetClientData(pos, str(oper.strip())) 465 self._operator_choice.SetSelection(0) 410 466 411 467 def getText(self): … … 422 478 description = self.desc_tcl.GetValue().lstrip().rstrip() 423 479 if description == '': 424 description = name1 + self. operator + name2480 description = name1 + self._operator + name2 425 481 name = self.name_tcl.GetValue().lstrip().rstrip() 426 text = self. operator_cbox.GetValue()482 text = self._operator_choice.GetValue() 427 483 if text.count('+') > 0: 428 484 factor = 'scale_factor' … … 473 529 out_f.write(line % description + "\n") 474 530 #elif line.count("run") and line.count("%s"): 475 # out_f.write(line % self. operator + "\n")531 # out_f.write(line % self._operator + "\n") 476 532 #elif line.count("evalDistribution") and line.count("%s"): 477 # out_f.write(line % self. operator + "\n")533 # out_f.write(line % self._operator + "\n") 478 534 elif line.count("return") and line.count("%s") == 2: 479 535 #print "line return", line 480 out_f.write(line % (f_oper, self. operator) + "\n")536 out_f.write(line % (f_oper, self._operator) + "\n") 481 537 elif line.count("out2")and line.count("%s"): 482 out_f.write(line % self. operator + "\n")538 out_f.write(line % self._operator + "\n") 483 539 else: 484 540 out_f.write(line + "\n") … … 523 579 self.is_2d = False 524 580 self.fname = None 581 self.main_sizer = None 582 self.name_sizer = None 583 self.name_hsizer = None 584 self.desc_sizer = None 585 self.param_sizer = None 586 self.function_sizer = None 587 self.func_horizon_sizer = None 588 self.button_sizer = None 525 589 self.param_strings = '' 526 590 self.function_strings = '' … … 1402 1466 """ 1403 1467 1404 #if __name__ == "__main__":1468 if __name__ == "__main__": 1405 1469 # app = wx.PySimpleApp() 1406 # frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"]) 1470 app = wx.App() 1471 frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"],plugin_dir='../fitting/plugin_models') 1472 # frame = wx.Dialog() 1473 frame.ShowModal() 1407 1474 # frame.Show(True) 1408 #app.MainLoop()1409 1410 if __name__ == "__main__":1411 from sas.perspectives.fitting import models1412 dir_path = models.find_plugins_dir()1413 app = wx.App()1414 window = EditorWindow(parent=None, base=None, path=dir_path, title="Editor")1415 app.MainLoop()1475 app.MainLoop() 1476 1477 #if __name__ == "__main__": 1478 # from sas.perspectives.fitting import models 1479 # dir_path = models.find_plugins_dir() 1480 # app = wx.App() 1481 # window = EditorWindow(parent=None, base=None, path=dir_path, title="Editor") 1482 # app.MainLoop()
Note: See TracChangeset
for help on using the changeset viewer.