Changeset 18ac46b in sasview for src/sas


Ignore:
Timestamp:
Apr 6, 2015 1:14:09 AM (10 years ago)
Author:
butler
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:
2d50115
Parents:
439420f9
Message:

fixed error handling on new (easy custom editor) and cleaned up some of
the code therein but could use with refactoring as done for composite
model editor.

Also fixed a number of pyling errors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/perspectives/calculator/model_editor.py

    r439420f9 r18ac46b  
    77complete customizatin is provided. 
    88 
    9 :TODO the writiong of the file and name checking (and maybe some other 
     9..TODO:: the writiong of the file and name checking (and maybe some other 
    1010funtions?) should be moved to a computational module which could be called 
    1111fropm a python script.  Basically one just needs to pass the name, 
     
    1717#This software was developed by the University of Tennessee as part of the 
    1818#Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    19 #project funded by the US National Science Foundation.  
     19#project funded by the US National Science Foundation. 
    2020# 
    2121#See the license text in license.txt 
     
    3333    FONT_VARIANT = 0 
    3434    PNL_WIDTH = 450 
    35     PNL_HITE = 320 
     35    PNL_HEIGHT = 320 
    3636else: 
    3737    FONT_VARIANT = 1 
    3838    PNL_WIDTH = 590 
    39     PNL_HITE = 350 
     39    PNL_HEIGHT = 350 
    4040M_NAME = 'Model' 
    4141EDITOR_WIDTH = 800 
     
    4545 
    4646 
    47 def _compileFile(path): 
     47def _compile_file(path): 
    4848    """ 
    4949    Compile the file in the path 
     
    5757        return value 
    5858 
    59 def _deleteFile(path): 
     59def _delete_file(path): 
    6060    """ 
    6161    Delete file in the path 
     
    7171    Dialog for easy custom composite models.  Provides a wx.Dialog panel 
    7272    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  
     73    may themselves be composite models) as well as an operation on those models 
     74    (add or multiply) the resulting model will add a scale parameter for summed  
    7575    models and a background parameter for a multiplied model. 
    7676     
     
    8383    a Modal Dialog. 
    8484     
    85     :TODO the build in compiler currently balks at when it tries to import 
     85    ..TODO:: the build in compiler currently balks at when it tries to import 
    8686    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 
     87    should be fine).  Have fixed so the editor cannot save such a file name 
     88    but if a file is dropped in the plugin directory from outside this class 
     89    will create a file that cannot be compiled.  Should add the check to 
     90    the write method or to the on_modelx method. 
     91          - PDB:April 5, 2015 
    8992    """ 
    9093    def __init__(self, parent=None, base=None, id=None, title='', 
    9194                 model_list=[], plugin_dir=None): 
    9295        """ 
    93         This class is run when instatiated.  The __init__ intializes and 
     96        This class is run when instatiated.  The __init__ initializes and 
    9497        calls the internal methods necessary.  On exiting the wx.Dialog 
    9598        window should be destroyed. 
    96  
    9799        """ 
    98100        wx.Dialog.__init__(self, parent=parent, id=id, 
    99                            title=title, size=(PNL_WIDTH, PNL_HITE)) 
     101                           title=title, size=(PNL_WIDTH, PNL_HEIGHT)) 
    100102        self.parent = base 
    101103        #Font 
     
    123125        self.model2 = None 
    124126        self.static_line_1 = None 
    125         self.okButton = None 
    126         self.closeButton = None 
     127        self.ok_button = None 
     128        self.close_button = None 
    127129        self._msg_box = None 
    128130        self.msg_sizer = None 
     
    152154 
    153155        self.name_sizer.AddMany([(self.name_txt, 0, wx.LEFT | wx.TOP, 10), 
    154                             (self.name_tcl, -1, 
    155                              wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 
     156                                (self.name_tcl, -1, 
     157                                wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 
    156158 
    157159 
     
    170172 
    171173        self.desc_sizer.AddMany([(desc_txt, 0, wx.LEFT | wx.TOP, 10), 
    172                                 (self.desc_tcl, -1, 
    173                                 wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 
     174                                 (self.desc_tcl, -1, 
     175                                  wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 
     176                                  10)]) 
    174177 
    175178 
     
    183186        selection_box_title = wx.StaticBox(self, -1, 'Select', 
    184187                                       size=(PNL_WIDTH - 30, 70)) 
    185         self._selection_box = wx.StaticBoxSizer(selection_box_title, wx.VERTICAL) 
     188        self._selection_box = wx.StaticBoxSizer(selection_box_title,  
     189                                                wx.VERTICAL) 
    186190 
    187191        #Next create the help labels for the model selection 
    188192        select_help_box = wx.BoxSizer(wx.HORIZONTAL) 
    189193        model_string = " Model%s (p%s):" 
    190         select_help_box.Add(wx.StaticText(self, -1, model_string % (1, 1)), 0, 0) 
     194        select_help_box.Add(wx.StaticText(self, -1, model_string % (1, 1)), 
     195                            0, 0) 
    191196        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) 
     197        select_help_box.Add(wx.StaticText(self, -1, model_string % (2, 2)), 
     198                            0, 0) 
    193199        self._selection_box.Add(select_help_box, 0, 0) 
    194200 
     
    201207        self.model1.SetToolTipString("model1") 
    202208 
    203         self._operator_choice = wx.ComboBox(self, -1, size=(50, -1), style=wx.CB_READONLY) 
     209        self._operator_choice = wx.ComboBox(self, -1, size=(50, -1), 
     210                                            style=wx.CB_READONLY) 
    204211        wx.EVT_COMBOBOX(self._operator_choice, -1, self.on_select_operator) 
    205212        operation_tip = "Add: +, Multiply: * " 
     
    217224        selection_box_choose.Add((15, 10)) 
    218225        selection_box_choose.Add(self.model2, 0, 0) 
    219         self._selection_box.Add((20,5), 0, 0) # add some space between labels and selection 
     226        # add some space between labels and selection 
     227        self._selection_box.Add((20,5), 0, 0) 
    220228        self._selection_box.Add(selection_box_choose, 0, 0) 
    221229 
     
    260268        # Finally add the buttons (apply and close) on the bottom 
    261269        # 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') 
     270        self.ok_button = wx.Button(self, wx.ID_OK, 'Apply') 
     271        self.ok_button.Bind(wx.EVT_BUTTON, self.check_name) 
     272        self.close_button = wx.Button(self, wx.ID_CANCEL, 'Close') 
    265273        sizer_button = wx.BoxSizer(wx.HORIZONTAL) 
    266274        sizer_button.AddMany([((20, 20), 1, 0), 
    267                               (self.okButton, 0, 0), 
    268                               (self.closeButton, 0, wx.LEFT | wx.RIGHT, 10)])         
     275                              (self.ok_button, 0, 0), 
     276                              (self.close_button, 0, wx.LEFT | wx.RIGHT, 10)])         
    269277        mainsizer.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10) 
    270278 
     
    287295        pink background in text box else call on_apply 
    288296         
    289         :TODO this should be separated out from the GUI code.  For that we 
     297        ..TODO:: this should be separated out from the GUI code.  For that we 
    290298        need to pass it the name (or if we want to keep the default name  
    291299        option also need to pass the self._operator attribute) We just need 
     
    317325            self.good_name = False 
    318326            msg = ("%s is not a valid Python name. Only alphanumeric \n" \ 
    319                 "and underscore allowed" % self.name) 
     327                   "and underscore allowed" % self.name) 
    320328  
    321329        #Now check if the name already exists 
     
    350358    def on_apply(self, path): 
    351359        """ 
    352         On Apply 
     360        This method is a misnomer - it is not bound to the apply button 
     361        event.  Instead the apply button event goes to check_name which 
     362        then calls this method if the name of the new file is acceptable. 
     363         
     364        ..todo:: this should be bound to the apply button.  The first line 
     365        should call the check_name method which itself should be in another 
     366        module separated from the the GUI modules.  
    353367        """ 
    354368        self.name_tcl.SetBackgroundColour('white') 
    355369        try: 
    356             label = self.getText() 
     370            label = self.get_textnames() 
    357371            fname = path 
    358372            name1 = label[0] 
     
    373387            from sas.guiframe.events import StatusEvent 
    374388            wx.PostEvent(self.parent.parent, StatusEvent(status=msg, 
    375                                                       info=info)) 
     389                                                         info=info)) 
    376390        else: 
    377391            raise 
     
    382396        """ 
    383397        # list of model names 
    384         cm_list = [] 
    385         # models 
    386         list = self.model_list 
    387         # custom models 
    388         al_list = os.listdir(self.plugin_dir) 
    389         for c_name in al_list: 
    390             if c_name.split('.')[-1] == 'py' and \ 
    391                     c_name.split('.')[0] != '__init__': 
    392                 name = str(c_name.split('.')[0]) 
    393                 cm_list.append(name) 
    394                 if name not in list: 
    395                     list.append(name) 
    396         self.cm_list = cm_list 
    397         if len(list) > 1: 
    398             list.sort() 
    399         for idx in range(len(list)): 
    400             self.model1.Append(str(list[idx]), idx) 
    401             self.model2.Append(str(list[idx]), idx) 
     398        # get regular models 
     399        main_list = self.model_list 
     400        # get custom models 
     401        self.update_cm_list() 
     402        # add custom models to model list 
     403        for name in self.cm_list: 
     404            if name not in main_list: 
     405                main_list.append(name) 
     406 
     407        if len(main_list) > 1: 
     408            main_list.sort() 
     409        for idx in range(len(main_list)): 
     410            self.model1.Append(str(main_list[idx]), idx) 
     411            self.model2.Append(str(main_list[idx]), idx) 
    402412        self.model1.SetStringSelection(self.model1_string) 
    403413        self.model2.SetStringSelection(self.model2_string) 
     
    473483        self._operator = type 
    474484        self.explanation = "  Custom Model = %s %s (model1 %s model2)\n" % \ 
    475                     (self.factor, f_oper, self._operator) 
     485                           (self.factor, f_oper, self._operator) 
    476486        self.explanationctr.SetLabel(self.explanation) 
    477487        self.name = name + M_NAME 
     
    488498        self._operator_choice.SetSelection(0) 
    489499 
    490     def getText(self): 
     500    def get_textnames(self): 
    491501        """ 
    492502        Returns model name string as list 
     
    502512        if description == '': 
    503513            description = name1 + self._operator + name2 
    504         name = self.name_tcl.GetValue().lstrip().rstrip() 
    505514        text = self._operator_choice.GetValue() 
    506515        if text.count('+') > 0: 
     
    573582        """ 
    574583        path = self.fname 
    575         _compileFile(path) 
     584        _compile_file(path) 
    576585 
    577586    def delete_file(self, path): 
     
    579588        Delete file in the path 
    580589        """ 
    581         _deleteFile(path) 
     590        _delete_file(path) 
    582591 
    583592 
     
    588597    def __init__(self, parent, base, path, title, *args, **kwds): 
    589598        kwds['name'] = title 
    590         kwds["size"] = (EDITOR_WIDTH, EDITOR_HEIGTH) 
     599#        kwds["size"] = (EDITOR_WIDTH, EDITOR_HEIGTH) 
    591600        kwds["style"] = wx.FULL_REPAINT_ON_RESIZE 
    592601        wx.ScrolledWindow.__init__(self, parent, *args, **kwds) 
    593         #self.SetupScrolling() 
    594602        self.parent = parent 
    595603        self.base = base 
     
    605613        self.name_sizer = None 
    606614        self.name_hsizer = None 
     615        self.name_tcl = None 
    607616        self.desc_sizer = None 
     617        self.desc_tcl = None 
    608618        self.param_sizer = None 
     619        self.param_tcl = None 
    609620        self.function_sizer = None 
    610621        self.func_horizon_sizer = None 
     
    618629        self._description = "New Custom Model" 
    619630        self.function_tcl = None 
     631        self.math_combo = None 
     632        self.bt_apply = None 
     633        self.bt_close = None 
    620634        #self._default_save_location = os.getcwd() 
    621635        self._do_layout() 
    622         #self.bt_apply.Disable() 
     636 
    623637 
    624638 
     
    656670        self.name_tcl.SetToolTipString(hint_name) 
    657671        self.name_hsizer.AddMany([(self.name_tcl, 0, wx.LEFT | wx.TOP, 0), 
    658                                        (overwrite_cb, 0, wx.LEFT, 20)]) 
     672                                  (overwrite_cb, 0, wx.LEFT, 20)]) 
    659673        self.name_sizer.AddMany([(name_txt, 0, wx.LEFT | wx.TOP, 10), 
    660                                        (self.name_hsizer, 0, 
    661                                         wx.LEFT | wx.TOP | wx.BOTTOM, 10)]) 
     674                                 (self.name_hsizer, 0, 
     675                                  wx.LEFT | wx.TOP | wx.BOTTOM, 10)]) 
    662676 
    663677 
     
    670684        self.desc_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1)) 
    671685        self.desc_tcl.SetValue('') 
    672         #self.name_tcl.SetFont(self.font) 
    673686        hint_desc = "Write a short description of the model function." 
    674687        self.desc_tcl.SetToolTipString(hint_desc) 
    675688        self.desc_sizer.AddMany([(desc_txt, 0, wx.LEFT | wx.TOP, 10), 
    676                                        (self.desc_tcl, 0, 
    677                                         wx.LEFT | wx.TOP | wx.BOTTOM, 10)]) 
     689                                 (self.desc_tcl, 0, 
     690                                  wx.LEFT | wx.TOP | wx.BOTTOM, 10)]) 
    678691    def _layout_param(self): 
    679692        """ 
     
    686699        param_tip += "A = 1\nB = 1" 
    687700        #param_txt.SetToolTipString(param_tip) 
    688         id = wx.NewId() 
    689         self.param_tcl = EditWindow(self, id, wx.DefaultPosition, 
    690                             wx.DefaultSize, wx.CLIP_CHILDREN | wx.SUNKEN_BORDER) 
     701        newid = wx.NewId() 
     702        self.param_tcl = EditWindow(self, newid, wx.DefaultPosition, 
     703                                    wx.DefaultSize, 
     704                                    wx.CLIP_CHILDREN | wx.SUNKEN_BORDER) 
    691705        self.param_tcl.setDisplayLineNumbers(True) 
    692706        self.param_tcl.SetToolTipString(param_tip) 
    693707 
    694708        self.param_sizer.AddMany([(param_txt, 0, wx.LEFT, 10), 
    695                         (self.param_tcl, 1, wx.EXPAND | wx.ALL, 10)]) 
     709                                  (self.param_tcl, 1, wx.EXPAND | wx.ALL, 10)]) 
    696710 
    697711    def _layout_function(self): 
     
    709723        math_combo = self._fill_math_combo() 
    710724 
    711         id = wx.NewId() 
    712         self.function_tcl = EditWindow(self, id, wx.DefaultPosition, 
    713                             wx.DefaultSize, wx.CLIP_CHILDREN | wx.SUNKEN_BORDER) 
     725        newid = wx.NewId() 
     726        self.function_tcl = EditWindow(self, newid, wx.DefaultPosition, 
     727                                       wx.DefaultSize, 
     728                                       wx.CLIP_CHILDREN | wx.SUNKEN_BORDER) 
    714729        self.function_tcl.setDisplayLineNumbers(True) 
    715730        self.function_tcl.SetToolTipString(hint_function) 
     
    758773        self._layout_msg() 
    759774        self._layout_button() 
    760         self.main_sizer.AddMany([(self.name_sizer, 0, 
    761                                         wx.EXPAND | wx.ALL, 5), 
     775        self.main_sizer.AddMany([(self.name_sizer, 0, wx.EXPAND | wx.ALL, 5), 
    762776                                 (wx.StaticLine(self), 0, 
    763                                        wx.ALL | wx.EXPAND, 5), 
    764                                  (self.desc_sizer, 0, 
    765                                         wx.EXPAND | wx.ALL, 5), 
     777                                  wx.ALL | wx.EXPAND, 5), 
     778                                 (self.desc_sizer, 0, wx.EXPAND | wx.ALL, 5), 
    766779                                 (wx.StaticLine(self), 0, 
    767                                        wx.ALL | wx.EXPAND, 5), 
    768                                 (self.param_sizer, 1, 
    769                                          wx.EXPAND | wx.ALL, 5), 
     780                                  wx.ALL | wx.EXPAND, 5), 
     781                                 (self.param_sizer, 1, wx.EXPAND | wx.ALL, 5), 
    770782                                 (wx.StaticLine(self), 0, 
    771                                        wx.ALL | wx.EXPAND, 5), 
    772                                 (self.function_sizer, 2, 
    773                                          wx.EXPAND | wx.ALL, 5), 
     783                                  wx.ALL | wx.EXPAND, 5), 
     784                                 (self.function_sizer, 2, 
     785                                  wx.EXPAND | wx.ALL, 5), 
    774786                                 (wx.StaticLine(self), 0, 
    775                                        wx.ALL | wx.EXPAND, 5), 
    776                                  (self.msg_sizer, 0, 
    777                                         wx.EXPAND | wx.ALL, 5), 
    778                                 (self.button_sizer, 0, 
    779                                          wx.EXPAND | wx.ALL, 5)]) 
     787                                  wx.ALL | wx.EXPAND, 5), 
     788                                 (self.msg_sizer, 0, wx.EXPAND | wx.ALL, 5), 
     789                                 (self.button_sizer, 0, wx.EXPAND | wx.ALL, 5)]) 
    780790        self.SetSizer(self.main_sizer) 
    781791        self.SetAutoLayout(True) 
     
    860870        if event is not None: 
    861871            event.Skip() 
    862         cb = event.GetEventObject() 
    863         self.overwrite_name = cb.GetValue() 
     872        cb_value = event.GetEventObject() 
     873        self.overwrite_name = cb_value.GetValue() 
    864874 
    865875    def on_click_apply(self, event): 
    866876        """ 
    867         Changes are saved in data object imported to edit 
     877        Changes are saved in data object imported to edit. 
     878         
     879        checks firs for valid name, then if it already exists then checks 
     880        that a function was entered and finally that if entered it contains at 
     881        least a return statement.  If all passes writes file then tries to  
     882        compile.  If compile fails or import module fails or run method fails 
     883        tries to remove any .py and pyc files that may have been created and 
     884        sets error message. 
     885         
     886        ..todo:: this code still could do with a careful going over to clean 
     887        up and simplify. the non GUI methods such as this one should be removed 
     888        to computational code of SasView. Most of those computational methods 
     889        would be the same for both the simple editors. 
    868890        """ 
    869891        #must post event here 
    870892        event.Skip() 
     893        name = self.name_tcl.GetValue().lstrip().rstrip() 
    871894        info = 'Info' 
    872895        msg = '' 
    873896        # Sort out the errors if occur 
    874         if self.check_name(): 
    875             name = self.name_tcl.GetValue().lstrip().rstrip() 
     897        # First check for valid python name then if the name already exists 
     898        if not re.match('^[A-Za-z0-9_]*$',name): 
     899            msg = "not a valid python name. Name must include only alpha \n" 
     900            msg += "numeric or underline characters and no spaces" 
     901        elif self.check_name(): 
    876902            description = self.desc_tcl.GetValue() 
    877903            param_str = self.param_tcl.GetText() 
     
    881907                if func_str.count('return') > 0: 
    882908                    self.write_file(self.fname, description, param_str, 
    883                                                                     func_str) 
    884                     tr_msg = _compileFile(self.fname) 
     909                                    func_str) 
     910                    tr_msg = _compile_file(self.fname) 
    885911                    msg = str(tr_msg.__str__()) 
    886912                    # Compile error 
     
    895921        else: 
    896922            msg = "Name exists already." 
    897         # Prepare for the messagebox 
     923        # Prepare the messagebox 
    898924        if self.base != None and not msg: 
    899925            self.base.update_custom_combo() 
    900926            Model = None 
    901             exec "from %s import Model" % name 
     927            try: 
     928                exec "from %s import Model" % name 
     929            except: 
     930                msg = 'new model fails to import in python' 
     931        if self.base != None and not msg: 
    902932            try: 
    903933                Model().run(0.01) 
    904934            except: 
    905                 msg = "Error " 
     935                msg = "new model fails on run method:" 
    906936                _, value, _ = sys.exc_info() 
    907937                msg += "in %s:\n%s\n" % (name, value) 
     938        # Prepare the messagebox 
    908939        if msg: 
    909940            info = 'Error' 
     
    911942            try: 
    912943                # try to remove pyc file if exists 
    913                 _deleteFile(self.fname) 
    914                 _deleteFile(self.fname + "c") 
     944                _delete_file(self.fname) 
     945                _delete_file(self.fname + "c") 
    915946            except: 
    916947                pass 
     
    921952            info = 'Info' 
    922953            color = 'blue' 
    923         # Not to display long error msg 
    924         if info == 'Error': 
    925             mss = info 
    926         else: 
    927             mss = msg 
    928         self._msg_box.SetLabel(mss) 
     954        self._msg_box.SetLabel(msg) 
    929955        self._msg_box.SetForegroundColour(color) 
    930         # Send msg to the top window   
     956        # Send msg to the top window 
    931957        if self.base != None: 
    932                 from sas.guiframe.events import StatusEvent 
    933                 wx.PostEvent(self.base.parent, StatusEvent(status=msg, 
    934                                                       info=info)) 
     958            from sas.guiframe.events import StatusEvent 
     959            wx.PostEvent(self.base.parent, StatusEvent(status=msg, info=info)) 
    935960        self.warning = msg 
    936961 
     
    947972        try: 
    948973            out_f = open(fname, 'w') 
    949         except : 
     974        except: 
    950975            raise 
    951976        # Prepare the content of the function 
     
    962987        # write function here 
    963988        for line in lines: 
    964             # The location where to put the strings is  
     989            # The location where to put the strings is 
    965990            # hard-coded in the template as shown below. 
    966991            if line.count("#self.params here"): 
     
    10171042        :param line: one line of string got from the param_str 
    10181043        """ 
    1019         flag = True 
    10201044        params_str = '' 
    10211045        spaces = '        '#8spaces 
     
    10381062        :param line: one line of string got from the param_str 
    10391063        """ 
    1040         flag = True 
    10411064        params_str = '' 
    10421065        spaces = '        '#8spaces 
     
    10851108        #if self.parent != None: 
    10861109        #    self.parent.new_model_frame = None 
    1087         #self.Destroy()   
     1110        #self.Destroy() 
    10881111 
    10891112## Templates for custom models 
     
    14891512""" 
    14901513 
    1491 if __name__ == "__main__":  
     1514if __name__ == "__main__": 
    14921515#    app = wx.PySimpleApp() 
    14931516    app = wx.App() 
    1494     frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"],plugin_dir='../fitting/plugin_models')    
    1495 #    frame = wx.Dialog() 
     1517    frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"], 
     1518                       plugin_dir='../fitting/plugin_models') 
    14961519    frame.ShowModal() 
    1497 #    frame.Show(True) 
    1498     app.MainLoop()              
     1520    app.MainLoop() 
    14991521 
    15001522#if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.