Changeset dceff6e in sasview for src/sas/sasgui


Ignore:
Timestamp:
Aug 31, 2016 11:21:55 AM (8 years ago)
Author:
Gonzalez, Miguel <gonzalez@…>
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.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
ce94504
Parents:
ec30905 (diff), 4036cb0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of https://github.com/SasView/sasview

Location:
src/sas/sasgui
Files:
1 added
31 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/guiframe/data_panel.py

    rd85c194 re767897  
    22#This software was developed by the University of Tennessee as part of the 
    33#Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    4 #project funded by the US National Science Foundation.  
     4#project funded by the US National Science Foundation. 
    55# 
    66#See the license text in license.txt 
     
    1313import wx 
    1414from wx.build import build_options 
     15 
    1516# Check version 
    1617toks = str(wx.__version__).split('.') 
     
    4041        as QucikPlotDialog 
    4142import sas.sasgui.guiframe.config as config 
    42   
     43 
    4344extension_list = [] 
    4445if config.APPLICATION_STATE_EXTENSION is not None: 
    4546    extension_list.append(config.APPLICATION_STATE_EXTENSION) 
    46 EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list    
     47EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list 
    4748PLUGINS_WLIST = config.PLUGINS_WLIST 
    4849APPLICATION_WLIST = config.APPLICATION_WLIST 
    4950 
    50 #Control panel width  
     51#Control panel width 
    5152if sys.platform.count("win32") > 0: 
    5253    PANEL_WIDTH = 235 
     
    6667STYLE_FLAG = wx.RAISED_BORDER|CT.TR_HAS_BUTTONS| CT.TR_HIDE_ROOT|\ 
    6768                    wx.WANTS_CHARS|CT.TR_HAS_VARIABLE_ROW_HEIGHT 
    68                      
    69                      
     69 
     70 
    7071class DataTreeCtrl(CT.CustomTreeCtrl): 
    7172    """ 
     
    9697                    CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds) 
    9798        self.root = self.AddRoot("Available Data") 
    98                     
     99 
    99100    def OnCompareItems(self, item1, item2): 
    100         """  
    101         Overrides OnCompareItems in wx.TreeCtrl.  
    102         Used by the SortChildren method.  
     101        """ 
     102        Overrides OnCompareItems in wx.TreeCtrl. 
     103        Used by the SortChildren method. 
    103104        """ 
    104105        # Get the item data 
     
    112113        else: 
    113114            return 0 
    114          
     115 
    115116class DataPanel(ScrolledPanel, PanelBase): 
    116117    """ 
    117     This panel displays data available in the application and widgets to  
     118    This panel displays data available in the application and widgets to 
    118119    interact with data. 
    119120    """ 
     
    122123    ## Title to appear on top of the window 
    123124    window_caption = "Data Explorer" 
    124     #type of window  
     125    #type of window 
    125126    window_type = "Data Panel" 
    126127    ## Flag to tell the GUI manager that this panel is not 
    127128    #  tied to any perspective 
    128129    #ALWAYS_ON = True 
    129     def __init__(self, parent,  
     130    def __init__(self, parent, 
    130131                 list=None, 
    131132                 size=(PANEL_WIDTH, PANEL_HEIGHT), 
     
    137138        PanelBase.__init__(self, parent) 
    138139        self.SetupScrolling() 
    139         #Set window's font size  
     140        #Set window's font size 
    140141        self.SetWindowVariant(variant=FONT_VARIANT) 
    141         self.loader = Loader()   
     142        self.loader = Loader() 
    142143        #Default location 
    143         self._default_save_location = None   
     144        self._default_save_location = None 
    144145        self.all_data1d = True 
    145146        self.parent = parent.parent 
     
    187188        if self.parent is not None: 
    188189            self.parent.Bind(EVT_DELETE_PLOTPANEL, self._on_delete_plot_panel) 
    189       
     190 
    190191    def do_layout(self): 
    191192        """ 
     
    197198        self.layout_batch() 
    198199        self.layout_button() 
    199          
     200 
    200201    def disable_app_combo(self, enable): 
    201202        """ 
     
    203204        """ 
    204205        self.perspective_cbox.Enable(enable) 
    205          
     206 
    206207    def define_panel_structure(self): 
    207208        """ 
     
    212213        self.sizer1 = wx.BoxSizer(wx.VERTICAL) 
    213214        self.sizer1.SetMinSize(wx.Size(w/13, h*2/5)) 
    214        
     215 
    215216        self.sizer2 = wx.BoxSizer(wx.VERTICAL) 
    216217        self.sizer3 = wx.FlexGridSizer(9, 2, 4, 1) 
    217218        self.sizer4 = wx.BoxSizer(wx.VERTICAL) 
    218219        self.sizer5 = wx.BoxSizer(wx.VERTICAL) 
    219         
     220 
    220221        self.vbox.Add(self.sizer5, 0, wx.EXPAND|wx.ALL, 1) 
    221222        self.vbox.Add(self.sizer1, 1, wx.EXPAND|wx.ALL, 0) 
     
    223224        self.vbox.Add(self.sizer3, 0, wx.EXPAND|wx.ALL, 10) 
    224225        #self.vbox.Add(self.sizer4, 0, wx.EXPAND|wx.ALL,5) 
    225          
     226 
    226227        self.SetSizer(self.vbox) 
    227          
     228 
    228229    def layout_selection(self): 
    229230        """ 
     
    243244        self.selection_cbox.SetValue('Select all Data') 
    244245        wx.EVT_COMBOBOX(self.selection_cbox, -1, self._on_selection_type) 
    245         self.sizer5.AddMany([(select_txt, 0, wx.ALL, 5),  
     246        self.sizer5.AddMany([(select_txt, 0, wx.ALL, 5), 
    246247                            (self.selection_cbox, 0, wx.ALL,5)]) 
    247248        self.enable_selection() 
    248          
    249      
     249 
     250 
    250251    def _on_selection_type(self, event): 
    251252        """ 
     
    253254            :param event: UI event 
    254255        """ 
     256        def check_item_and_children(control, check_value=True): 
     257            self.tree_ctrl.CheckItem(data_ctrl, check_value) 
     258            if data_ctrl.HasChildren(): 
     259                if check_value == True and not control.IsExpanded(): 
     260                    # Only select children if control is expanded 
     261                    # Always deselect children, regardless (see ticket #259) 
     262                    return 
     263                for child_ctrl in data_ctrl.GetChildren(): 
     264                    self.tree_ctrl.CheckItem(child_ctrl, check_value) 
     265 
    255266        option = self.selection_cbox.GetValue() 
    256          
     267 
    257268        pos = self.selection_cbox.GetSelection() 
    258269        if pos == wx.NOT_FOUND: 
    259             return  
     270            return 
    260271        option = self.selection_cbox.GetString(pos) 
    261272        for item in self.list_cb_data.values(): 
    262273            data_ctrl, _, _, _, _, _, _, _ = item 
    263             _, data_class, _ = self.tree_ctrl.GetItemPyData(data_ctrl)  
     274            _, data_class, _ = self.tree_ctrl.GetItemPyData(data_ctrl) 
    264275            if option == 'Select all Data': 
    265                 self.tree_ctrl.CheckItem(data_ctrl, True)  
     276                check_item_and_children(data_ctrl, check_value=True) 
    266277            elif option == 'Unselect all Data': 
    267                 self.tree_ctrl.CheckItem(data_ctrl, False) 
     278                check_item_and_children(data_ctrl, check_value=False) 
    268279            elif option == 'Select all Data 1D': 
    269280                if data_class == 'Data1D': 
    270                     self.tree_ctrl.CheckItem(data_ctrl, True)  
     281                    check_item_and_children(data_ctrl, check_value=True) 
    271282            elif option == 'Unselect all Data 1D': 
    272283                if data_class == 'Data1D': 
    273                     self.tree_ctrl.CheckItem(data_ctrl, False)  
    274             elif option == 'Select all Data 1D': 
    275                 if data_class == 'Data1D': 
    276                     self.tree_ctrl.CheckItem(data_ctrl, True)  
     284                    check_item_and_children(data_ctrl, check_value=False) 
    277285            elif option == 'Select all Data 2D': 
    278286                if data_class == 'Data2D': 
    279                     self.tree_ctrl.CheckItem(data_ctrl, True)  
     287                    check_item_and_children(data_ctrl, check_value=True) 
    280288            elif option == 'Unselect all Data 2D': 
    281289                if data_class == 'Data2D': 
    282                     self.tree_ctrl.CheckItem(data_ctrl, False)  
     290                    check_item_and_children(data_ctrl, check_value=False) 
    283291        self.enable_append() 
    284292        self.enable_freeze() 
     
    286294        self.enable_import() 
    287295        self.enable_remove() 
    288                 
     296 
    289297    def layout_button(self): 
    290298        """ 
    291299        Layout widgets related to buttons 
    292300        """ 
    293         self.bt_add = wx.Button(self, wx.NewId(), "Load Data",  
     301        #Load Data Button 
     302        self.bt_add = wx.Button(self, wx.NewId(), "Load Data", 
    294303                                size=(BUTTON_WIDTH, -1)) 
    295304        self.bt_add.SetToolTipString("Load data files") 
    296305        wx.EVT_BUTTON(self, self.bt_add.GetId(), self._load_data) 
     306 
     307        #Delete Data Button 
    297308        self.bt_remove = wx.Button(self, wx.NewId(), "Delete Data", 
    298309         size=(BUTTON_WIDTH, -1)) 
    299310        self.bt_remove.SetToolTipString("Delete data from the application") 
    300311        wx.EVT_BUTTON(self, self.bt_remove.GetId(), self.on_remove) 
     312 
     313        #Send data to perspective button 
    301314        self.bt_import = wx.Button(self, wx.NewId(), "Send To", 
    302315                                    size=(BUTTON_WIDTH, -1)) 
    303316        self.bt_import.SetToolTipString("Send Data set to active perspective") 
    304317        wx.EVT_BUTTON(self, self.bt_import.GetId(), self.on_import) 
     318 
     319        #Choose perspective to be send data to combo box 
    305320        self.perspective_cbox = wx.ComboBox(self, -1, 
    306321                                style=wx.CB_READONLY) 
    307322        if not IS_MAC: 
    308323            self.perspective_cbox.SetMinSize((BUTTON_WIDTH*1.6, -1)) 
    309         wx.EVT_COMBOBOX(self.perspective_cbox, -1,  
     324        wx.EVT_COMBOBOX(self.perspective_cbox, -1, 
    310325                        self._on_perspective_selection) 
    311      
     326 
     327        #Append data to current Graph Button 
    312328        self.bt_append_plot = wx.Button(self, wx.NewId(), "Append Plot To", 
    313329                                        size=(BUTTON_WIDTH, -1)) 
     
    315331                                "Plot the selected data in the active panel") 
    316332        wx.EVT_BUTTON(self, self.bt_append_plot.GetId(), self.on_append_plot) 
    317          
    318         self.bt_plot = wx.Button(self, wx.NewId(), "New Plot",  
     333 
     334        #Create a new graph and send data to that new graph button 
     335        self.bt_plot = wx.Button(self, wx.NewId(), "New Plot", 
    319336                                 size=(BUTTON_WIDTH, -1)) 
    320337        self.bt_plot.SetToolTipString("To trigger plotting") 
    321338        wx.EVT_BUTTON(self, self.bt_plot.GetId(), self.on_plot) 
    322          
    323         self.bt_freeze = wx.Button(self, wx.NewId(), "Freeze Theory",  
     339 
     340        #Freeze current theory button - becomes a data set and stays on graph 
     341        self.bt_freeze = wx.Button(self, wx.NewId(), "Freeze Theory", 
    324342                                   size=(BUTTON_WIDTH, -1)) 
    325343        freeze_tip = "To trigger freeze a theory: making a copy\n" 
     
    328346        self.bt_freeze.SetToolTipString(freeze_tip) 
    329347        wx.EVT_BUTTON(self, self.bt_freeze.GetId(), self.on_freeze) 
    330         
     348 
     349        #select plot to send to combo box (blank if no data) 
    331350        if sys.platform == 'darwin': 
    332             self.cb_plotpanel = wx.ComboBox(self, -1,  
     351            self.cb_plotpanel = wx.ComboBox(self, -1, 
    333352                                            style=wx.CB_READONLY) 
    334353        else: 
    335             self.cb_plotpanel = wx.ComboBox(self, -1,  
     354            self.cb_plotpanel = wx.ComboBox(self, -1, 
    336355                                            style=wx.CB_READONLY|wx.CB_SORT) 
    337356        wx.EVT_COMBOBOX(self.cb_plotpanel, -1, self._on_plot_selection) 
    338357        self.cb_plotpanel.Disable() 
     358 
     359        #Help button 
     360        self.bt_help = wx.Button(self, wx.NewId(), "HELP", 
     361                                 size=(BUTTON_WIDTH, -1)) 
     362        self.bt_help.SetToolTipString("Help for the Data Explorer.") 
     363        wx.EVT_BUTTON(self,self.bt_help.GetId(), self.on_help) 
    339364 
    340365        self.sizer3.AddMany([(self.bt_add), 
     
    347372                             ((10, 10)), 
    348373                             (self.bt_append_plot), 
    349                              (self.cb_plotpanel,  
     374                             (self.cb_plotpanel, 
    350375                              wx.EXPAND|wx.ADJUST_MINSIZE, 5), 
    351376                             ((5, 5)), 
    352377                             ((5, 5)), 
    353378                             (self.bt_import, 0, wx.EXPAND|wx.RIGHT, 5), 
    354                              (self.perspective_cbox,  
     379                             (self.perspective_cbox, 
    355380                              wx.EXPAND|wx.ADJUST_MINSIZE, 5), 
    356381                             ((10, 10)), 
    357382                             (self.sizer4), 
    358                              ((10, 40)), 
    359                              ((10, 40))]) 
     383                             ((10, 10)), 
     384                             (self.bt_help, 0, wx.RIGHT, 5)]) 
    360385 
    361386        self.sizer3.AddGrowableCol(1, 1) 
     
    367392        self.enable_freeze() 
    368393        self.enable_remove_plot() 
    369          
     394 
    370395    def layout_batch(self): 
    371396        """ 
     
    379404        self.Bind(wx.EVT_RADIOBUTTON, self.on_batch_mode, 
    380405                   id=self.rb_batch_mode.GetId()) 
    381          
     406 
    382407        self.rb_single_mode.SetValue(not self.parent.batch_on) 
    383408        self.rb_batch_mode.SetValue(self.parent.batch_on) 
    384409        self.sizer4.AddMany([(self.rb_single_mode, 0, wx.ALL, 4), 
    385410                             (self.rb_batch_mode, 0, wx.ALL, 4)]) 
    386          
     411 
    387412    def on_single_mode(self, event): 
    388413        """ 
     
    392417        if self.parent is not None: 
    393418            wx.PostEvent(self.parent, NewBatchEvent(enable=False)) 
    394         
     419 
    395420    def on_batch_mode(self, event): 
    396421        """ 
     
    399424        """ 
    400425        if self.parent is not None: 
    401             wx.PostEvent(self.parent,  
     426            wx.PostEvent(self.parent, 
    402427                         NewBatchEvent(enable=True)) 
    403      
    404     def _get_data_selection(self, event):   
     428 
     429    def _get_data_selection(self, event): 
    405430        """ 
    406431            Get data selection from the right click 
     
    417442            data = theory_list.values()[0][0] 
    418443        return data 
    419      
     444 
    420445    def on_edit_data(self, event): 
    421446        """ 
     
    425450        from sas.sasgui.guiframe.local_perspectives.plotting.masking \ 
    426451            import MaskPanel as MaskDialog 
    427          
    428         panel = MaskDialog(parent=self.parent, base=self,  
     452 
     453        panel = MaskDialog(parent=self.parent, base=self, 
    429454                           data=data, id=wx.NewId()) 
    430455        panel.ShowModal() 
    431      
     456 
    432457    def on_plot_3d(self, event): 
    433458        """ 
     
    437462        from sas.sasgui.guiframe.local_perspectives.plotting.masking \ 
    438463        import FloatPanel as Float3dDialog 
    439          
    440         panel = Float3dDialog(base=self, data=data,  
     464 
     465        panel = Float3dDialog(base=self, data=data, 
    441466                              dimension=3, id=wx.NewId()) 
    442         panel.ShowModal()    
    443      
     467        panel.ShowModal() 
     468 
    444469    def on_quick_plot(self, event): 
    445470        """ 
     
    450475            dimension = 2 
    451476        else: 
    452             dimension = 1  
    453         #panel = QucikPlotDialog(base=self, data=data,  
     477            dimension = 1 
     478        #panel = QucikPlotDialog(base=self, data=data, 
    454479        #                        dimension=dimension, id=wx.NewId()) 
    455480        frame = QucikPlotDialog(self, -1, "Plot " + data.name, 'log_{10}') 
     
    459484        frame.Show(True) 
    460485        frame.SetFocus() 
    461         #panel.ShowModal()     
    462      
     486        #panel.ShowModal() 
     487 
    463488    def on_data_info(self, event): 
    464489        """ 
     
    470495        else: 
    471496            self.parent.show_data1d(data, data.name) 
    472          
     497 
    473498    def on_save_as(self, event): 
    474499        """ 
     
    488513            else: 
    489514                print "unable to save this type of data" 
    490          
     515 
    491516    def layout_data_list(self): 
    492517        """ 
     
    505530        self.data_menu.Append(id, name, msg) 
    506531        wx.EVT_MENU(self, id, self.on_data_info) 
    507          
     532 
    508533        id = wx.NewId() 
    509534        name = "Save As" 
     
    511536        self.data_menu.Append(id, name, msg) 
    512537        wx.EVT_MENU(self, id, self.on_save_as) 
    513      
     538 
    514539        quickplot_id = wx.NewId() 
    515540        name = "Quick Plot" 
     
    517542        self.data_menu.Append(quickplot_id, name, msg) 
    518543        wx.EVT_MENU(self, quickplot_id, self.on_quick_plot) 
    519          
     544 
    520545        self.plot3d_id = wx.NewId() 
    521546        name = "Quick 3DPlot (Slow)" 
     
    523548        self.data_menu.Append(self.plot3d_id, name, msg) 
    524549        wx.EVT_MENU(self, self.plot3d_id, self.on_plot_3d) 
    525              
     550 
    526551        self.editmask_id = wx.NewId() 
    527552        name = "Edit Mask" 
     
    529554        self.data_menu.Append(self.editmask_id, name, msg) 
    530555        wx.EVT_MENU(self, self.editmask_id, self.on_edit_data) 
    531          
     556 
    532557        tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory") 
    533558        tree_ctrl_theory_label.SetForegroundColour('blue') 
    534         self.tree_ctrl_theory = DataTreeCtrl(parent=self,  
     559        self.tree_ctrl_theory = DataTreeCtrl(parent=self, 
    535560                                                    style=wx.SUNKEN_BORDER) 
    536         self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING,  
     561        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING, 
    537562                                                    self.on_check_item) 
    538         self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU,  
     563        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU, 
    539564                                   self.on_right_click_theory) 
    540565        self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10) 
     
    542567        self.sizer1.Add(tree_ctrl_theory_label, 0,  wx.LEFT, 10) 
    543568        self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND|wx.ALL, 10) 
    544             
     569 
    545570    def on_right_click_theory(self, event): 
    546571        """ 
     
    557582            self.data_menu.Enable(self.editmask_id, False) 
    558583            self.data_menu.Enable(self.plot3d_id, menu_enable) 
    559             self.PopupMenu(self.data_menu)  
    560                     
     584            self.PopupMenu(self.data_menu) 
     585 
    561586    def on_right_click_data(self, event): 
    562587        """ 
     
    578603            self.data_menu.Enable(self.editmask_id, maskmenu_enable) 
    579604            self.data_menu.Enable(self.plot3d_id, menu_enable) 
    580             self.PopupMenu(self.data_menu)  
    581          
    582     def onContextMenu(self, event):  
     605            self.PopupMenu(self.data_menu) 
     606 
     607    def onContextMenu(self, event): 
    583608        """ 
    584609        Retrieve the state selected state 
     
    588613        pos = event.GetPosition() 
    589614        pos = self.ScreenToClient(pos) 
    590         self.PopupMenu(self.popUpMenu, pos)  
    591        
    592    
     615        self.PopupMenu(self.popUpMenu, pos) 
     616 
     617 
    593618    def on_check_item(self, event): 
    594619        """ 
     
    596621        """ 
    597622        item = event.GetItem() 
    598         item.Check(not item.IsChecked())  
     623        item.Check(not item.IsChecked()) 
    599624        self.enable_append() 
    600625        self.enable_freeze() 
     
    603628        self.enable_remove() 
    604629        event.Skip() 
    605          
     630 
    606631    def fill_cbox_analysis(self, plugin): 
    607632        """ 
     
    617642                if plug.get_perspective(): 
    618643                    self.perspective_cbox.Append(plug.sub_menu, plug) 
    619              
     644 
    620645            curr_pers = self.parent.get_current_perspective() 
    621646            if curr_pers: 
    622647                self.perspective_cbox.SetStringSelection(curr_pers.sub_menu) 
    623648                self.enable_import() 
    624                          
     649 
    625650    def load_data_list(self, list): 
    626651        """ 
     
    636661                    data_run = str(data.run) 
    637662                    data_class = data.__class__.__name__ 
    638                     path = dstate.get_path()  
     663                    path = dstate.get_path() 
    639664                    process_list = data.process 
    640665                    data_id = data.id 
     
    643668                        #new state 
    644669                        data_c = self.tree_ctrl.InsertItem(self.tree_ctrl.root, 
    645                                         0, data_name, ct_type=1,  
     670                                        0, data_name, ct_type=1, 
    646671                                        data=(data_id, data_class, state_id)) 
    647672                        data_c.Check(True) 
    648673                        d_i_c = self.tree_ctrl.AppendItem(data_c, 'Info') 
    649                         d_t_c = self.tree_ctrl.AppendItem(d_i_c,  
     674                        d_t_c = self.tree_ctrl.AppendItem(d_i_c, 
    650675                                                      'Title: %s' % data_title) 
    651                         r_n_c = self.tree_ctrl.AppendItem(d_i_c,  
     676                        r_n_c = self.tree_ctrl.AppendItem(d_i_c, 
    652677                                                      'Run: %s' % data_run) 
    653                         i_c_c = self.tree_ctrl.AppendItem(d_i_c,  
     678                        i_c_c = self.tree_ctrl.AppendItem(d_i_c, 
    654679                                                      'Type: %s' % data_class) 
    655680                        p_c_c = self.tree_ctrl.AppendItem(d_i_c, 
    656681                                                      "Path: '%s'" % s_path) 
    657682                        d_p_c = self.tree_ctrl.AppendItem(d_i_c, 'Process') 
    658                          
     683 
    659684                        for process in process_list: 
    660685                            process_str = str(process).replace('\n',' ') 
     
    662687                                process_str = process_str[:20]+' [...]' 
    663688                            self.tree_ctrl.AppendItem(d_p_c, process_str) 
    664                         theory_child = self.tree_ctrl.AppendItem(data_c,  
     689                        theory_child = self.tree_ctrl.AppendItem(data_c, 
    665690                                                                 "THEORIES") 
    666                         self.list_cb_data[state_id] = [data_c,  
     691                        self.list_cb_data[state_id] = [data_c, 
    667692                                                       d_i_c, 
    668693                                                       d_t_c, 
     
    677702                        data_c, d_i_c, d_t_c, r_n_c,  i_c_c, p_c_c, d_p_c, _ \ 
    678703                                = data_ctrl_list 
    679                         self.tree_ctrl.SetItemText(data_c, data_name)  
     704                        self.tree_ctrl.SetItemText(data_c, data_name) 
    680705                        temp = (data_id, data_class, state_id) 
    681                         self.tree_ctrl.SetItemPyData(data_c, temp)  
    682                         self.tree_ctrl.SetItemText(i_c_c,  
     706                        self.tree_ctrl.SetItemPyData(data_c, temp) 
     707                        self.tree_ctrl.SetItemText(i_c_c, 
    683708                                                   'Type: %s' % data_class) 
    684                         self.tree_ctrl.SetItemText(p_c_c,  
    685                                                    'Path: %s' % s_path)  
    686                         self.tree_ctrl.DeleteChildren(d_p_c)  
     709                        self.tree_ctrl.SetItemText(p_c_c, 
     710                                                   'Path: %s' % s_path) 
     711                        self.tree_ctrl.DeleteChildren(d_p_c) 
    687712                        for process in process_list: 
    688713                            if not process.is_empty(): 
     
    692717            # Sort by data name 
    693718            if self.tree_ctrl.root: 
    694                 self.tree_ctrl.SortChildren(self.tree_ctrl.root)     
     719                self.tree_ctrl.SortChildren(self.tree_ctrl.root) 
    695720        self.enable_remove() 
    696721        self.enable_import() 
     
    698723        self.enable_freeze() 
    699724        self.enable_selection() 
    700          
     725 
    701726    def _uncheck_all(self): 
    702727        """ 
     
    705730        for item in self.list_cb_data.values(): 
    706731            data_ctrl, _, _, _, _, _, _, _ = item 
    707             self.tree_ctrl.CheckItem(data_ctrl, False)  
     732            self.tree_ctrl.CheckItem(data_ctrl, False) 
    708733        self.enable_append() 
    709734        self.enable_freeze() 
     
    711736        self.enable_import() 
    712737        self.enable_remove() 
    713     
     738 
    714739    def append_theory(self, state_id, theory_list): 
    715740        """ 
     
    718743        """ 
    719744        if not theory_list: 
    720             return  
     745            return 
    721746        if state_id not in self.list_cb_data.keys(): 
    722747            root = self.tree_ctrl_theory.root 
     
    728753            tree = self.tree_ctrl 
    729754        if root is not None: 
    730             wx.CallAfter(self.append_theory_helper, tree=tree, root=root,  
    731                                        state_id=state_id,  
     755            wx.CallAfter(self.append_theory_helper, tree=tree, root=root, 
     756                                       state_id=state_id, 
    732757                                       theory_list=theory_list) 
    733        
    734        
     758 
     759 
    735760    def append_theory_helper(self, tree, root, state_id, theory_list): 
    736761        """ 
     
    760785                                                    name, ct_type=1, data=temp) 
    761786                    t_i_c = tree.AppendItem(t_child, 'Info') 
    762                     i_c_c = tree.AppendItem(t_i_c,  
     787                    i_c_c = tree.AppendItem(t_i_c, 
    763788                                                  'Type: %s' % theory_class) 
    764789                    t_p_c = tree.AppendItem(t_i_c, 'Process') 
    765                      
     790 
    766791                    for process in theory_data.process: 
    767792                        tree.AppendItem(t_p_c, process.__str__()) 
    768                     theory_list_ctrl[theory_id] = [t_child,  
    769                                                    i_c_c,  
     793                    theory_list_ctrl[theory_id] = [t_child, 
     794                                                   i_c_c, 
    770795                                                   t_p_c] 
    771796                else: 
    772797                    #replace theory 
    773798                    t_child, i_c_c, t_p_c = theory_list_ctrl[theory_id] 
    774                     tree.SetItemText(t_child, name)  
    775                     tree.SetItemPyData(t_child, temp)  
    776                     tree.SetItemText(i_c_c, 'Type: %s' % theory_class)  
    777                     tree.DeleteChildren(t_p_c)  
     799                    tree.SetItemText(t_child, name) 
     800                    tree.SetItemPyData(t_child, temp) 
     801                    tree.SetItemText(i_c_c, 'Type: %s' % theory_class) 
     802                    tree.DeleteChildren(t_p_c) 
    778803                    for process in theory_data.process: 
    779804                        tree.AppendItem(t_p_c, process.__str__()) 
    780                
     805 
    781806        else: 
    782807            #data didn't have a theory associated it before 
     
    789814                    theory_id = theory_data.id 
    790815                    #if theory_state is not None: 
    791                     #    name = theory_state.model.name  
     816                    #    name = theory_state.model.name 
    792817                    temp = (theory_id, theory_class, state_id) 
    793818                    t_child = tree.AppendItem(root, 
    794                             name, ct_type=1,  
     819                            name, ct_type=1, 
    795820                            data=(theory_data.id, theory_class, state_id)) 
    796821                    t_i_c = tree.AppendItem(t_child, 'Info') 
    797                     i_c_c = tree.AppendItem(t_i_c,  
     822                    i_c_c = tree.AppendItem(t_i_c, 
    798823                                                  'Type: %s' % theory_class) 
    799824                    t_p_c = tree.AppendItem(t_i_c, 'Process') 
    800                      
     825 
    801826                    for process in theory_data.process: 
    802827                        tree.AppendItem(t_p_c, process.__str__()) 
    803              
     828 
    804829                    theory_list_ctrl[theory_id] = [t_child, i_c_c, t_p_c] 
    805830                #self.list_cb_theory[data_id] = theory_list_ctrl 
    806831                self.list_cb_theory[state_id] = theory_list_ctrl 
    807          
    808              
    809     
     832 
     833 
     834 
    810835    def set_data_helper(self): 
    811836        """ 
     
    822847                if state_id not in state_to_plot: 
    823848                    state_to_plot.append(state_id) 
    824             
     849 
    825850        for theory_dict in self.list_cb_theory.values(): 
    826851            for _, value in theory_dict.iteritems(): 
     
    832857                        state_to_plot.append(state_id) 
    833858        return data_to_plot, theory_to_plot, state_to_plot 
    834      
     859 
    835860    def remove_by_id(self, id): 
    836861        """ 
     
    839864        for item in self.list_cb_data.values(): 
    840865            data_c, _, _, _, _, _,  _, _ = item 
    841             data_id, _, state_id = self.tree_ctrl.GetItemPyData(data_c)  
     866            data_id, _, state_id = self.tree_ctrl.GetItemPyData(data_c) 
    842867            if id == data_id: 
    843868                self.tree_ctrl.Delete(data_c) 
    844869                del self.list_cb_data[state_id] 
    845870                del self.list_cb_theory[data_id] 
    846                
     871 
    847872    def load_error(self, error=None): 
    848873        """ 
    849874        Pop up an error message. 
    850          
     875 
    851876        :param error: details error message to be displayed 
    852877        """ 
    853878        if error is not None or str(error).strip() != "": 
    854             dial = wx.MessageDialog(self.parent, str(error),  
     879            dial = wx.MessageDialog(self.parent, str(error), 
    855880                                    'Error Loading File', 
    856881                                    wx.OK | wx.ICON_EXCLAMATION) 
    857             dial.ShowModal()   
    858          
     882            dial.ShowModal() 
     883 
    859884    def _load_data(self, event): 
    860885        """ 
     
    863888        if self.parent is not None: 
    864889            wx.PostEvent(self.parent, NewLoadDataEvent()) 
    865              
     890 
    866891 
    867892    def on_remove(self, event): 
    868893        """ 
    869894        Get a list of item checked and remove them from the treectrl 
    870         Ask the parent to remove reference to this item  
     895        Ask the parent to remove reference to this item 
    871896        """ 
    872897        msg = "This operation will delete the data sets checked " 
     
    875900        if msg_box.ShowModal() != wx.ID_OK: 
    876901            return 
    877          
     902 
    878903        data_to_remove, theory_to_remove, _ = self.set_data_helper() 
    879904        data_key = [] 
     
    888913                    theory_list_ctrl = self.list_cb_theory[d_key] 
    889914                    theory_to_remove += theory_list_ctrl.keys() 
    890         # Remove theory from treectrl        
     915        # Remove theory from treectrl 
    891916        for _, theory_dict in self.list_cb_theory.iteritems(): 
    892917            for  key, value in theory_dict.iteritems(): 
     
    898923                        pass 
    899924                    theory_key.append(key) 
    900                      
     925 
    901926        #Remove data and related theory references 
    902927        for key in data_key: 
     
    916941                                pass 
    917942                    del theory_dict[key] 
    918                      
    919              
     943 
     944 
    920945        self.parent.remove_data(data_id=data_to_remove, 
    921946                                  theory_id=theory_to_remove) 
     
    923948        self.enable_freeze() 
    924949        self.enable_remove_plot() 
    925          
     950 
    926951    def on_import(self, event=None): 
    927952        """ 
     
    933958        temp = data_id + state_id 
    934959        self.parent.set_data(data_id=temp, theory_id=theory_id) 
    935          
     960 
    936961    def on_append_plot(self, event=None): 
    937962        """ 
     
    940965        self._on_plot_selection() 
    941966        data_id, theory_id, state_id = self.set_data_helper() 
    942         self.parent.plot_data(data_id=data_id,   
     967        self.parent.plot_data(data_id=data_id, 
    943968                              state_id=state_id, 
    944969                              theory_id=theory_id, 
    945970                              append=True) 
    946     
     971 
    947972    def on_plot(self, event=None): 
    948973        """ 
     
    950975        """ 
    951976        data_id, theory_id, state_id = self.set_data_helper() 
    952         self.parent.plot_data(data_id=data_id,   
     977        self.parent.plot_data(data_id=data_id, 
    953978                              state_id=state_id, 
    954979                              theory_id=theory_id, 
    955980                              append=False) 
    956981        self.enable_remove_plot() 
    957           
     982 
    958983    def on_close_page(self, event=None): 
    959984        """ 
     
    964989        # send parent to update menu with no show nor hide action 
    965990        self.parent.show_data_panel(action=False) 
    966      
     991 
    967992    def on_freeze(self, event): 
    968993        """ 
     
    9771002            msg = "Freeze Theory: Requires at least one theory checked." 
    9781003        wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    979              
     1004 
    9801005    def set_active_perspective(self, name): 
    9811006        """ 
     
    9841009        self.perspective_cbox.SetStringSelection(name) 
    9851010        self.enable_import() 
    986          
     1011 
    9871012    def _on_delete_plot_panel(self, event): 
    9881013        """ 
    989         get an event with attribute name and caption to delete existing name  
     1014        get an event with attribute name and caption to delete existing name 
    9901015        from the combobox of the current panel 
    9911016        """ 
     
    9931018        caption = event.caption 
    9941019        if self.cb_plotpanel is not None: 
    995             pos = self.cb_plotpanel.FindString(str(caption))  
     1020            pos = self.cb_plotpanel.FindString(str(caption)) 
    9961021            if pos != wx.NOT_FOUND: 
    9971022                self.cb_plotpanel.Delete(pos) 
    9981023        self.enable_append() 
    999          
     1024 
    10001025    def set_panel_on_focus(self, name=None): 
    10011026        """ 
     
    10131038        self.enable_append() 
    10141039        self.enable_remove_plot() 
    1015      
     1040 
    10161041    def set_plot_unfocus(self): 
    10171042        """ 
     
    10191044        """ 
    10201045        return 
    1021      
     1046 
    10221047    def _on_perspective_selection(self, event=None): 
    10231048        """ 
     
    10291054            perspective.on_perspective(event=None) 
    10301055            self.parent.check_multimode(perspective=perspective) 
    1031                  
     1056 
    10321057    def _on_plot_selection(self, event=None): 
    10331058        """ 
     
    10431068        if combo.GetValue() != 'None': 
    10441069            panel = combo.GetClientData(selection) 
    1045             self.parent.on_set_plot_focus(panel)    
    1046              
     1070            self.parent.on_set_plot_focus(panel) 
     1071 
    10471072    def on_close_plot(self, event): 
    10481073        """ 
    10491074        clseo the panel on focus 
    1050         """  
     1075        """ 
    10511076        self.enable_append() 
    10521077        selection = self.cb_plotpanel.GetSelection() 
     
    10541079            panel = self.cb_plotpanel.GetClientData(selection) 
    10551080            if self.parent is not None and panel is not None: 
    1056                 wx.PostEvent(self.parent,  
     1081                wx.PostEvent(self.parent, 
    10571082                             NewPlotEvent(group_id=panel.group_id, 
    10581083                                          action="delete")) 
    10591084        self.enable_remove_plot() 
    1060      
     1085 
    10611086    def set_frame(self, frame): 
    10621087        """ 
    10631088        """ 
    10641089        self.frame = frame 
    1065      
     1090 
    10661091    def get_frame(self): 
    10671092        """ 
    10681093        """ 
    1069         return self.frame  
    1070      
     1094        return self.frame 
     1095 
     1096    def on_help(self, event): 
     1097        """ 
     1098        Bring up the data manager Documentation whenever 
     1099        the HELP button is clicked. 
     1100 
     1101        Calls DocumentationWindow with the path of the location within the 
     1102        documentation tree (after /doc/ ....".  Note that when using old 
     1103        versions of Wx (before 2.9) and thus not the release version of 
     1104        installers, the help comes up at the top level of the file as 
     1105        webbrowser does not pass anything past the # to the browser when it is 
     1106        running "file:///...." 
     1107 
     1108    :param evt: Triggers on clicking the help button 
     1109    """ 
     1110 
     1111        #import documentation window here to avoid circular imports 
     1112        #if put at top of file with rest of imports. 
     1113        from documentation_window import DocumentationWindow 
     1114 
     1115        _TreeLocation = "user/sasgui/guiframe/data_explorer_help.html" 
     1116        _doc_viewer = DocumentationWindow(self, -1, _TreeLocation, "", 
     1117                                          "Data Explorer Help") 
     1118 
    10711119    def on_close(self, event): 
    10721120        """ 
     
    10741122        """ 
    10751123        self.parent.show_data_panel(event) 
    1076                          
     1124 
    10771125    def set_schedule_full_draw(self, panel=None, func='del'): 
    10781126        """ 
     
    10801128        """ 
    10811129        self.parent.set_schedule_full_draw(panel, func) 
    1082          
     1130 
    10831131    def enable_remove_plot(self): 
    10841132        """ 
     
    10901138        #else: 
    10911139        #    self.bt_close_plot.Enable() 
    1092              
     1140 
    10931141    def enable_remove(self): 
    10941142        """ 
     
    11011149        else: 
    11021150            self.bt_remove.Enable() 
    1103              
     1151 
    11041152    def enable_import(self): 
    11051153        """ 
     
    11191167        else: 
    11201168            self.perspective_cbox.Enable() 
    1121              
     1169 
    11221170    def enable_plot(self): 
    11231171        """ 
    11241172        enable or disable plot button 
    11251173        """ 
    1126         n_t = 0  
     1174        n_t = 0 
    11271175        n_t_t = 0 
    11281176        if self.tree_ctrl != None: 
     
    11351183            self.bt_plot.Enable() 
    11361184        self.enable_append() 
    1137         
     1185 
    11381186    def enable_append(self): 
    11391187        """ 
    11401188        enable or disable append button 
    11411189        """ 
    1142         n_t = 0  
     1190        n_t = 0 
    11431191        n_t_t = 0 
    11441192        if self.tree_ctrl != None: 
     
    11461194        if self.tree_ctrl_theory != None: 
    11471195            n_t_t = self.tree_ctrl_theory.GetCount() 
    1148         if n_t + n_t_t <= 0:  
     1196        if n_t + n_t_t <= 0: 
    11491197            self.bt_append_plot.Disable() 
    11501198            self.cb_plotpanel.Disable() 
     
    11551203            self.bt_append_plot.Enable() 
    11561204            self.cb_plotpanel.Enable() 
    1157              
     1205 
    11581206    def check_theory_to_freeze(self): 
    11591207        """ 
     
    11731221        else: 
    11741222            self.bt_freeze.Disable() 
    1175          
     1223 
    11761224    def enable_selection(self): 
    11771225        """ 
     
    11881236        else: 
    11891237            self.selection_cbox.Disable() 
    1190              
     1238 
    11911239    def show_data_button(self): 
    11921240        """ 
    1193         show load data and remove data button if  
     1241        show load data and remove data button if 
    11941242        dataloader on else hide them 
    11951243        """ 
     
    11971245            gui_style = self.parent.get_style() 
    11981246            style = gui_style & GUIFRAME.DATALOADER_ON 
    1199             if style == GUIFRAME.DATALOADER_ON:  
     1247            if style == GUIFRAME.DATALOADER_ON: 
    12001248                #self.bt_remove.Show(True) 
    1201                 self.bt_add.Show(True)  
     1249                self.bt_add.Show(True) 
    12021250            else: 
    12031251                #self.bt_remove.Hide() 
    12041252                self.bt_add.Hide() 
    1205         except:  
     1253        except: 
    12061254            #self.bt_remove.Hide() 
    1207             self.bt_add.Hide()  
    1208      
     1255            self.bt_add.Hide() 
     1256 
    12091257 
    12101258 
     
    12231271        self.list_of_ctrl = [] 
    12241272        if not data_list: 
    1225             return  
     1273            return 
    12261274        self._sizer_main = wx.BoxSizer(wx.VERTICAL) 
    12271275        self._sizer_txt = wx.BoxSizer(wx.VERTICAL) 
     
    12321280        self._panel.SetupScrolling() 
    12331281        self.__do_layout(data_list, text=text) 
    1234          
     1282 
    12351283    def __do_layout(self, data_list, text=''): 
    12361284        """ 
     
    12381286        """ 
    12391287        if not data_list or len(data_list) <= 1: 
    1240             return  
     1288            return 
    12411289        #add text 
    1242          
     1290 
    12431291        text = "Deleting these file reset some panels.\n" 
    12441292        text += "Do you want to proceed?\n" 
     
    12741322                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10) 
    12751323        static_line = wx.StaticLine(self, -1) 
    1276          
     1324 
    12771325        self._sizer_txt.Add(self._panel, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5) 
    12781326        self._sizer_main.Add(self._sizer_txt, 1, wx.EXPAND|wx.ALL, 10) 
    1279         #self._sizer_main.Add(self._data_text_ctrl, 0,  
     1327        #self._sizer_main.Add(self._data_text_ctrl, 0, 
    12801328        #                     wx.EXPAND|wx.LEFT|wx.RIGHT, 10) 
    12811329        self._sizer_main.Add(static_line, 0, wx.EXPAND, 0) 
     
    12831331        self.SetSizer(self._sizer_main) 
    12841332        self.Layout() 
    1285          
     1333 
    12861334    def get_data(self): 
    12871335        """ 
     
    12941342                temp.append(data) 
    12951343        return temp 
    1296                 
     1344 
    12971345class DataFrame(wx.Frame): 
    12981346    """ 
     
    13061354    #  tied to any perspective 
    13071355    ALWAYS_ON = True 
    1308      
     1356 
    13091357    def __init__(self, parent=None, owner=None, manager=None, size=(300, 800), 
    13101358                         list_of_perspective=[], list=[], *args, **kwds): 
     
    13161364        self.owner = owner 
    13171365        self._manager = manager 
    1318         self.panel = DataPanel(parent=self,  
     1366        self.panel = DataPanel(parent=self, 
    13191367                               manager=manager, 
    13201368                               list_of_perspective=list_of_perspective) 
    1321       
     1369 
    13221370    def load_data_list(self, list=[]): 
    13231371        """ 
     
    13251373        """ 
    13261374        self.panel.load_data_list(list=list) 
    1327          
    1328     
    1329      
     1375 
     1376 
     1377 
    13301378from sas.sasgui.guiframe.dataFitting import Theory1D 
    13311379from sas.sasgui.guiframe.data_state import DataState 
     
    13421390        self.msg += "name  value\n" 
    13431391        return self.msg 
    1344      
     1392 
    13451393def set_data_state(data=None, path=None, theory=None, state=None): 
    13461394    """ 
     
    13501398    dstate.set_path(path=path) 
    13511399    dstate.set_theory(theory, state) 
    1352    
     1400 
    13531401    return dstate 
    1354      
     1402 
    13551403if __name__ == "__main__": 
    1356      
     1404 
    13571405    app = wx.App() 
    13581406    try: 
     
    14361484        #raise 
    14371485        print "error", sys.exc_value 
    1438          
    1439     app.MainLoop()   
    1440      
    1441      
     1486 
     1487    app.MainLoop() 
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    rfaa3ae7 ra674d0b  
    162162            logging.error("Loader returned an invalid object:\n %s" % str(item)) 
    163163            data_error = True 
    164          
     164 
    165165        data = self.parent.create_gui_data(item, p_file) 
    166166        output[data.id] = data 
     
    170170        """ 
    171171        """ 
    172         message = "" 
    173         log_msg = '' 
     172        file_errors = {} 
    174173        output = {} 
    175         any_error = False 
    176         data_error = False 
    177         error_message = "" 
     174        exception_occurred = False 
     175 
    178176        for p_file in path: 
    179             info = "info" 
    180177            basename = os.path.basename(p_file) 
    181178            _, extension = os.path.splitext(basename) 
    182179            if extension.lower() in EXTENSIONS: 
    183                 any_error = True 
    184180                log_msg = "Data Loader cannot " 
    185                 log_msg += "load: %s\n" % str(p_file) 
    186                 log_msg += """Please try to open that file from "open project" """ 
    187                 log_msg += """or "open analysis" menu\n""" 
    188                 error_message = log_msg + "\n" 
     181                log_msg += "load: {}\n".format(str(p_file)) 
     182                log_msg += "Please try to open that file from \"open project\"" 
     183                log_msg += "or \"open analysis\" menu." 
    189184                logging.info(log_msg) 
     185                file_errors[basename] = [log_msg] 
    190186                continue 
    191187 
    192188            try: 
    193                 message = "Loading Data... " + str(p_file) + "\n" 
    194                 self.load_update(output=output, message=message, info=info) 
     189                message = "Loading {}...\n".format(p_file) 
     190                self.load_update(output=output, message=message, info="info") 
    195191                temp = self.loader.load(p_file, format) 
    196                 if temp.__class__.__name__ == "list": 
    197                     for item in temp: 
    198                         output, error_message, data_error = \ 
    199                             self._process_data_and_errors(item, 
    200                                                           p_file, 
    201                                                           output, 
    202                                                           error_message) 
    203                 else: 
     192                if not isinstance(temp, list): 
     193                    temp = [temp] 
     194                for item in temp: 
     195                    error_message = "" 
    204196                    output, error_message, data_error = \ 
    205                             self._process_data_and_errors(temp, 
    206                                                           p_file, 
    207                                                           output, 
    208                                                           error_message) 
     197                        self._process_data_and_errors(item, 
     198                                                      p_file, 
     199                                                      output, 
     200                                                      error_message) 
     201                    if data_error: 
     202                        if basename in file_errors.keys(): 
     203                            file_errors[basename] += [error_message] 
     204                        else: 
     205                            file_errors[basename] = [error_message] 
     206                        self.load_update(output=output, 
     207                            message=error_message, info="warning") 
     208 
     209                self.load_update(output=output, 
     210                message="Loaded {}\n".format(p_file), 
     211                info="info") 
     212 
    209213            except: 
    210214                logging.error(sys.exc_value) 
    211                 any_error = True 
    212             if any_error or error_message != "": 
    213                 if error_message == "": 
    214                     error = "Error: " + str(sys.exc_info()[1]) + "\n" 
    215                     error += "while loading Data: \n%s\n" % str(basename) 
    216                     error_message += "The data file you selected could not be loaded.\n" 
    217                     error_message += "Make sure the content of your file" 
    218                     error_message += " is properly formatted.\n\n" 
    219                     error_message += "When contacting the SasView team, mention the" 
    220                     error_message += " following:\n%s" % str(error) 
    221                 elif data_error: 
    222                     base_message = "Errors occurred while loading " 
    223                     base_message += "{0}\n".format(basename) 
    224                     base_message += "The data file loaded but with errors.\n" 
    225                     error_message = base_message + error_message 
    226                 else: 
    227                     error_message += "%s\n" % str(p_file) 
    228                 info = "error" 
    229          
    230         if any_error or error_message: 
    231             self.load_update(output=output, message=error_message, info=info) 
    232         else: 
    233             message = "Loading Data Complete! " 
    234         message += log_msg 
    235         self.load_complete(output=output, error_message=error_message, 
    236                            message=message, path=path, info='info') 
     215 
     216                error_message = "The Data file you selected could not be loaded.\n" 
     217                error_message += "Make sure the content of your file" 
     218                error_message += " is properly formatted.\n" 
     219                error_message += "When contacting the SasView team, mention the" 
     220                error_message += " following:\n" 
     221                error_message += "Error: " + str(sys.exc_info()[1]) 
     222                file_errors[basename] = [error_message] 
     223                self.load_update(output=output, message=error_message, info="warning") 
     224 
     225        if len(file_errors) > 0: 
     226            error_message = "" 
     227            for filename, error_array in file_errors.iteritems(): 
     228                error_message += "The following errors occured whilst " 
     229                error_message += "loading {}:\n".format(filename) 
     230                for message in error_array: 
     231                    error_message += message + "\n" 
     232                error_message += "\n" 
     233            self.load_update(output=output, message=error_message, info="error") 
     234 
     235        self.load_complete(output=output, message="Loading data complete!", 
     236            info="info") 
    237237 
    238238    def load_update(self, output=None, message="", info="warning"): 
     
    254254        #    self.load_error(error_message) 
    255255        self.parent.add_data(data_list=output) 
    256  
    257  
    258  
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py

    rd85c194 r895c9cb  
    527527            self.subplot.set_xlim((xlo, xhi)) 
    528528            self.subplot.set_ylim((ylo, yhi)) 
     529        self.graph.selected_plottable = None 
    529530 
    530531 
     
    555556        self._slicerpop.set_graph(self.graph) 
    556557        ids = iter(self._menu_ids) 
    557         if not self.graph.selected_plottable in self.plots: 
    558             # Various plot options 
    559             wx_id = ids.next() 
    560             self._slicerpop.Append(wx_id, '&Save Image', 'Save image as PNG') 
    561             wx.EVT_MENU(self, wx_id, self.onSaveImage) 
    562             wx_id = ids.next() 
    563             self._slicerpop.Append(wx_id, '&Print Image', 'Print image ') 
    564             wx.EVT_MENU(self, wx_id, self.onPrint) 
    565  
    566             wx_id = ids.next() 
    567             self._slicerpop.Append(wx_id, '&Copy to Clipboard', 
    568                                    'Copy to the clipboard') 
    569             wx.EVT_MENU(self, wx_id, self.OnCopyFigureMenu) 
    570  
    571             self._slicerpop.AppendSeparator() 
     558 
     559        # Various plot options 
     560        wx_id = ids.next() 
     561        self._slicerpop.Append(wx_id, '&Save Image', 'Save image as PNG') 
     562        wx.EVT_MENU(self, wx_id, self.onSaveImage) 
     563        wx_id = ids.next() 
     564        self._slicerpop.Append(wx_id, '&Print Image', 'Print image ') 
     565        wx.EVT_MENU(self, wx_id, self.onPrint) 
     566 
     567        wx_id = ids.next() 
     568        self._slicerpop.Append(wx_id, '&Copy to Clipboard', 
     569                               'Copy to the clipboard') 
     570        wx.EVT_MENU(self, wx_id, self.OnCopyFigureMenu) 
     571 
     572        self._slicerpop.AppendSeparator() 
    572573 
    573574        for plot in self.plots.values(): 
     
    592593            item_list = self.parent.get_current_context_menu(self) 
    593594            if (not item_list == None) and (not len(item_list) == 0): 
    594                 # Note: reusing menu ids in submenu.  This code works because 
    595                 # IdItems is set up as a lazy iterator returning each id in 
    596                 # sequence, creating new ids as needed so it never runs out. 
    597                 # zip() is set up to stop when any iterator is empty, so it 
    598                 # only asks for the number of ids in item_list. 
    599                 for item, wx_id in zip(item_list, self._menu_ids): 
     595                for item, wx_id in zip(item_list, [ids.next() for i in range(len(item_list))]): 
    600596 
    601597                    try: 
     
    609605 
    610606            if self.parent.ClassName.count('wxDialog') == 0: 
    611                 wx_id = ids.next() 
    612                 plot_menu.Append(wx_id, '&Linear Fit', name) 
    613                 wx.EVT_MENU(self, wx_id, self.onFitting) 
    614                 plot_menu.AppendSeparator() 
     607                if plot.id != 'fit': 
     608                    wx_id = ids.next() 
     609                    plot_menu.Append(wx_id, '&Linear Fit', name) 
     610                    wx.EVT_MENU(self, wx_id, self.onFitting) 
     611                    plot_menu.AppendSeparator() 
    615612 
    616613                wx_id = ids.next() 
     
    646643            # Option to hide 
    647644            # TODO: implement functionality to hide a plottable (legend click) 
    648         if not self.graph.selected_plottable in self.plots: 
     645 
     646        self._slicerpop.AppendSeparator() 
     647        loc_menu = wx.Menu() 
     648        for label in self._loc_labels: 
     649            wx_id = ids.next() 
     650            loc_menu.Append(wx_id, str(label), str(label)) 
     651            wx.EVT_MENU(self, wx_id, self.onChangeLegendLoc) 
     652 
     653        wx_id = ids.next() 
     654        self._slicerpop.Append(wx_id, '&Modify Graph Appearance', 
     655                               'Modify graph appearance') 
     656        wx.EVT_MENU(self, wx_id, self.modifyGraphAppearance) 
     657        self._slicerpop.AppendSeparator() 
     658 
     659 
     660        if self.position != None: 
     661            wx_id = ids.next() 
     662            self._slicerpop.Append(wx_id, '&Add Text') 
     663            wx.EVT_MENU(self, wx_id, self._on_addtext) 
     664            wx_id = ids.next() 
     665            self._slicerpop.Append(wx_id, '&Remove Text') 
     666            wx.EVT_MENU(self, wx_id, self._on_removetext) 
    649667            self._slicerpop.AppendSeparator() 
    650             loc_menu = wx.Menu() 
    651             for label in self._loc_labels: 
    652                 wx_id = ids.next() 
    653                 loc_menu.Append(wx_id, str(label), str(label)) 
    654                 wx.EVT_MENU(self, wx_id, self.onChangeLegendLoc) 
    655  
    656             wx_id = ids.next() 
    657             self._slicerpop.Append(wx_id, '&Modify Graph Appearance', 
    658                                    'Modify graph appearance') 
    659             wx.EVT_MENU(self, wx_id, self.modifyGraphAppearance) 
    660             self._slicerpop.AppendSeparator() 
    661  
    662  
    663             if self.position != None: 
    664                 wx_id = ids.next() 
    665                 self._slicerpop.Append(wx_id, '&Add Text') 
    666                 wx.EVT_MENU(self, wx_id, self._on_addtext) 
    667                 wx_id = ids.next() 
    668                 self._slicerpop.Append(wx_id, '&Remove Text') 
    669                 wx.EVT_MENU(self, wx_id, self._on_removetext) 
    670                 self._slicerpop.AppendSeparator() 
    671             wx_id = ids.next() 
    672             self._slicerpop.Append(wx_id, '&Change Scale') 
    673             wx.EVT_MENU(self, wx_id, self._onProperties) 
     668        wx_id = ids.next() 
     669        self._slicerpop.Append(wx_id, '&Change Scale') 
     670        wx.EVT_MENU(self, wx_id, self._onProperties) 
     671        self._slicerpop.AppendSeparator() 
     672        wx_id = ids.next() 
     673        self._slicerpop.Append(wx_id, '&Set Graph Range') 
     674        wx.EVT_MENU(self, wx_id, self.onSetRange) 
     675        wx_id = ids.next() 
     676        self._slicerpop.Append(wx_id, '&Reset Graph Range') 
     677        wx.EVT_MENU(self, wx_id, self.onResetGraph) 
     678 
     679        if self.parent.ClassName.count('wxDialog') == 0: 
    674680            self._slicerpop.AppendSeparator() 
    675681            wx_id = ids.next() 
    676             self._slicerpop.Append(wx_id, '&Reset Graph Range') 
    677             wx.EVT_MENU(self, wx_id, self.onResetGraph) 
    678  
    679             if self.parent.ClassName.count('wxDialog') == 0: 
    680                 self._slicerpop.AppendSeparator() 
    681                 wx_id = ids.next() 
    682                 self._slicerpop.Append(wx_id, '&Window Title') 
    683                 wx.EVT_MENU(self, wx_id, self.onChangeCaption) 
     682            self._slicerpop.Append(wx_id, '&Window Title') 
     683            wx.EVT_MENU(self, wx_id, self.onChangeCaption) 
    684684        try: 
    685685            pos_evt = event.GetPosition() 
     
    689689            pos = (pos_x, pos_y + 5) 
    690690        self.PopupMenu(self._slicerpop, pos) 
     691 
     692    def onSetRange(self, event): 
     693        # Display dialog 
     694        # self.subplot.set_xlim((low, high)) 
     695        # self.subplot.set_ylim((low, high)) 
     696        from sas.sasgui.plottools.RangeDialog import RangeDialog 
     697        d = RangeDialog(self, -1) 
     698        xlim = self.subplot.get_xlim() 
     699        ylim = self.subplot.get_ylim() 
     700        d.SetXRange(xlim) 
     701        d.SetYRange(ylim) 
     702        if d.ShowModal() == wx.ID_OK: 
     703            x_range = d.GetXRange() 
     704            y_range = d.GetYRange() 
     705            if x_range is not None and y_range is not None: 
     706                self.subplot.set_xlim(x_range) 
     707                self.subplot.set_ylim(y_range) 
     708                self.subplot.figure.canvas.draw_idle() 
     709        d.Destroy() 
    691710 
    692711    def onFreeze(self, event): 
     
    776795                                                             int(curr_symbol))), curr_label) 
    777796        self.appD.Bind(wx.EVT_CLOSE, self.on_AppDialog_close) 
     797        self.graph.selected_plottable = None 
    778798 
    779799    def on_AppDialog_close(self, event): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py

    rd85c194 r1a696bf  
    293293 
    294294        wx_id = ids.next() 
    295         slicerpop.Append(wx_id, '&Save Image') 
     295        slicerpop.Append(wx_id, '&Save Image', 'Save image as png') 
    296296        wx.EVT_MENU(self, wx_id, self.onSaveImage) 
    297297 
     
    320320            if (not item_list == None) and (not len(item_list) == 0) and\ 
    321321                self.data2D.name.split(" ")[0] != 'Residuals': 
    322                 # The line above; Not for trunk 
    323                 # Note: reusing menu ids for the sub-menus.  See Plotter1D. 
    324                 for item, wx_id in zip(item_list, self._menu_ids): 
     322                for item, wx_id in zip(item_list, [ids.next() for i in range(len(item_list))]): 
    325323                    try: 
    326324                        slicerpop.Append(wx_id, item[0], item[1]) 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/SimplePlot.py

    rd85c194 r25b9707a  
    188188    """ 
    189189    def __init__(self, parent, id, title, scale='log_{10}', 
    190                  size=wx.Size(550, 470)): 
     190                 size=wx.Size(550, 470), show_menu_icons=True): 
    191191        """ 
    192192        comment 
     
    202202        self._default_save_location = None 
    203203        self.scale = scale 
     204        self._show_menu_icons = show_menu_icons 
    204205        self.plotpanel = SimplePlotPanel(self, -1) 
    205206        self._build_menubar() 
     
    213214        quit_bmp = wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_TOOLBAR, tsize) 
    214215        print_bmp = wx.ArtProvider.GetBitmap(wx.ART_PRINT, wx.ART_TOOLBAR, tsize) 
    215         preview_bmp = wx.ArtProvider.GetBitmap(wx.ART_REPORT_VIEW, wx.ART_TOOLBAR, tsize) 
    216216        copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize) 
    217217        menu_bar = wx.MenuBar() 
     
    219219        menu = wx.Menu() 
    220220        id = wx.NewId() 
    221         item = wx.MenuItem(menu, id, "&Save Image") 
    222         item.SetBitmap(save_bmp) 
    223         menu.AppendItem(item) 
     221        save_item = wx.MenuItem(menu, id, "&Save Image") 
     222        menu.AppendItem(save_item) 
    224223        wx.EVT_MENU(self, id, self.on_save_file) 
    225224 
    226225        id = wx.NewId() 
    227         item = wx.MenuItem(menu, id, "&Print Image") 
    228         item.SetBitmap(print_bmp) 
    229         menu.AppendItem(item) 
     226        print_item = wx.MenuItem(menu, id, "&Print Image") 
     227        menu.AppendItem(print_item) 
    230228        wx.EVT_MENU(self, id, self.on_print_image) 
    231229 
    232230        menu.AppendSeparator() 
    233231        id = wx.NewId() 
    234         item = wx.MenuItem(menu, id, "&Quit") 
    235         item.SetBitmap(quit_bmp) 
    236         menu.AppendItem(item) 
     232        quit_item = wx.MenuItem(menu, id, "&Quit") 
     233        menu.AppendItem(quit_item) 
    237234 
    238235        menu_bar.Append(menu, "&File") 
     
    241238        menu_edit = wx.Menu() 
    242239        id = wx.NewId() 
    243         item = wx.MenuItem(menu_edit, id, "&Copy") 
    244         item.SetBitmap(copy_bmp) 
    245         menu_edit.AppendItem(item) 
     240        copy_item = wx.MenuItem(menu_edit, id, "&Copy") 
     241        menu_edit.AppendItem(copy_item) 
    246242        wx.EVT_MENU(self, id, self.on_copy_image) 
     243 
     244        if self._show_menu_icons: 
     245            save_item.SetBitmap(save_bmp) 
     246            print_item.SetBitmap(print_bmp) 
     247            quit_item.SetBitmap(quit_bmp) 
     248            copy_item.SetBitmap(copy_bmp) 
    247249 
    248250        menu_bar.Append(menu_edit, "&Edit") 
     
    324326        except: 
    325327            self.Destroy() 
    326  
  • src/sas/sasgui/guiframe/local_perspectives/plotting/detector_dialog.py

    rd85c194 r8416a02  
    77from sas.sasgui.guiframe.events import StatusEvent 
    88from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas 
    9 from matplotlib import mpl 
     9import matplotlib as mpl 
    1010from matplotlib import pylab 
    1111# FONT size 
  • src/sas/sasgui/guiframe/media/data_explorer_help.rst

    rd85c194 rb64b87c  
    2020 
    2121*NOTE! When* Data Explorer *is hidden, all data loaded will be sent directly  
    22 to the current active analysis perspective, if possible. When* Data Explorer *is 
     22to the current active analysis, if possible. When* Data Explorer *is 
    2323shown, data go first to the* Data Explorer. 
    2424 
     
    116116 
    117117Click on the *Send To* button to send the currently selected data to one of the 
    118 perspectives (for *Fitting*, *P(r) Inversion*, or *Invariant* calculation). 
     118available types of analysis (*Fitting*, *P(r) Inversion*, or *Invariant* calculation). 
    119119  
    120 The *Single*/*Batch* mode radio buttons only apply to the *Fitting* perspective. 
     120The *Single*/*Batch* mode radio buttons only apply to *Fitting*. 
    121121 
    122122*Batch mode* provides serial (batch) fitting with one model function, that is,  
  • src/sas/sasgui/guiframe/media/graph_help.rst

    rf93b473f re68c9bf  
    2020^^^^^^^^^^^^^^^^^^^^^^^ 
    2121 
    22 To invoke the *Graph Menu* simply right-click on a data/theory plot, or click  
    23 the *Graph Menu* (bullet list) icon in the toolbar at the bottom of the plot.  
     22To invoke the *Graph Menu* simply right-click on a data/theory plot, or click 
     23the *Graph Menu* (bullet list) icon in the toolbar at the bottom of the plot. 
    2424Then select a menu item. 
    2525 
     
    2727^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    2828 
    29 To expand a plot window, click the *Maximise* (square) icon in the top-right  
     29To expand a plot window, click the *Maximise* (square) icon in the top-right 
    3030corner. 
    3131 
    32 To shrink a plot window, click the *Restore down* (square-on-square) icon in  
     32To shrink a plot window, click the *Restore down* (square-on-square) icon in 
    3333the top-right corner. 
    3434 
    35 To hide a plot, click the *Minimise* (-) icon in the top-right corner of the  
     35To hide a plot, click the *Minimise* (-) icon in the top-right corner of the 
    3636plot window. 
    3737 
    38 To show a hidden plot, select the *Restore up* (square-on-square) icon on the  
     38To show a hidden plot, select the *Restore up* (square-on-square) icon on the 
    3939minimised window. 
    4040 
    41 To delete a plot, click the *Close* (x) icon in the top-right corner of the  
     41To delete a plot, click the *Close* (x) icon in the top-right corner of the 
    4242plot window. 
    4343 
    44 *NOTE! If a residuals graph (when fitting data) is hidden, it will not show up  
     44*NOTE! If a residuals graph (when fitting data) is hidden, it will not show up 
    4545after computation.* 
    4646 
     
    4848^^^^^^^^^^^^^^^ 
    4949 
    50 Select the *Pan* (crossed arrows) icon in the toolbar at the bottom of the plot  
    51 to activate this option. Move the mouse pointer to the plot. It will change to  
    52 a hand. Then left-click and drag the plot around. The axis values will adjust  
     50Select the *Pan* (crossed arrows) icon in the toolbar at the bottom of the plot 
     51to activate this option. Move the mouse pointer to the plot. It will change to 
     52a hand. Then left-click and drag the plot around. The axis values will adjust 
    5353accordingly. 
    54   
     54 
    5555To disable dragging mode, unselect the *crossed arrows* icon on the toolbar. 
    5656 
     
    5858^^^^^^^^^^^^^^^^^^^^^^^^ 
    5959 
    60 Select the *Zoom* (magnifying glass) button in the toolbar at the bottom of  
    61 the plot to activate this option. Move the mouse pointer to the plot. It will  
    62 change to a cross-hair. Then left-click and drag the pointer around to generate  
     60Select the *Zoom* (magnifying glass) button in the toolbar at the bottom of 
     61the plot to activate this option. Move the mouse pointer to the plot. It will 
     62change to a cross-hair. Then left-click and drag the pointer around to generate 
    6363a region of interest. Release the mouse button to generate the new view. 
    6464 
    6565To disable zoom mode, unselect the *Zoom* button on the toolbar. 
    6666 
    67 After zooming in on a a region, the *left arrow* or *right arrow* buttons on  
     67After zooming in on a a region, the *left arrow* or *right arrow* buttons on 
    6868the toolbar will switch between recent views. 
    6969 
    70 *NOTE! If a wheel mouse is available scrolling the wheel will zoom in/out  
    71 on the current plot (changing both axes). Alternatively, point at the numbers  
     70*NOTE! If a wheel mouse is available scrolling the wheel will zoom in/out 
     71on the current plot (changing both axes). Alternatively, point at the numbers 
    7272on one axis and scroll the wheel to zoom in/out on just that axis.* 
    7373 
    74 To return to the original view of the data, click the the *Reset* (home) icon  
     74To return to the original view of the data, click the the *Reset* (home) icon 
    7575in the toolbar at the bottom of the plot (see Resetting_the_graph_ for further details). 
    7676 
     
    7878^^^^^^^^^^^^^^^^^^^ 
    7979 
    80 To save the current plot as an image file, right click on the plot to bring up  
     80To save the current plot as an image file, right click on the plot to bring up 
    8181the *Graph Menu* (see Invoking_the_graph_menu_) and select *Save Image*. 
    82 Alternatively, click on the *Save* (floppy disk) icon in the toolbar at the  
     82Alternatively, click on the *Save* (floppy disk) icon in the toolbar at the 
    8383bottom of the plot. 
    84   
    85 A dialog window will open. Select a folder, enter a filename, choose an output  
     84 
     85A dialog window will open. Select a folder, enter a filename, choose an output 
    8686image type, and click *Save*. 
    8787 
     
    9494*  PNG (portable network graphics) 
    9595*  PS (postscript) 
    96 *  RAW/RGBA (bitmap) 
     96*  RAW/RGBA (bitmap, stored as 935x635 pixels of depth 8) 
    9797*  SVG/SVGA (scalable vector graphics) 
    9898*  TIF/TIFF (tagged iamge file) 
     
    101101^^^^^^^^^^^^^^^ 
    102102 
    103 To send the current plot to a printer, click on the *Print* (printer) icon in  
     103To send the current plot to a printer, click on the *Print* (printer) icon in 
    104104the toolbar at the bottom of the plot. 
    105105 
     
    109109^^^^^^^^^^^^^^^^^^^ 
    110110 
    111 To reset the axis range of a graph to its initial values select *Reset Graph  
     111To reset the axis range of a graph to its initial values select *Reset Graph 
    112112Range* on the *Graph Menu* (see Invoking_the_graph_menu_). Alternatively, use 
    113113the *Reset* (home) icon in the toolbar at the bottom of the plot. 
     
    133133 
    134134From the *Graph Menu* (see Invoking_the_graph_menu_) select *Change Scale*. A 
    135 dialog window will appear in which it is possible to choose different  
     135dialog window will appear in which it is possible to choose different 
    136136transformations of the x (usually Q) or y (usually I(Q)) axes, including: 
    137137 
     
    139139*  y, 1/y, ln(y), y^2, y.(x^4), 1/sqrt(y), 
    140140*  log10(y), ln(y.x), ln(y.x^2), ln(y.x^4), log10(y.x^4) 
    141   
     141 
    142142A *View* option includes short-cuts to common SAS transformations, such as: 
    143143 
     
    148148*  Kratky 
    149149 
    150 For properly corrected and scaled data, these SAS transformations can be used  
    151 to estimate, for example, Rg, rod diameter, or SANS incoherent background  
     150For properly corrected and scaled data, these SAS transformations can be used 
     151to estimate, for example, Rg, rod diameter, or SANS incoherent background 
    152152levels, via a linear fit (see Making_a_linear_fit_). 
    153153 
     
    158158 
    159159From the *Graph Menu* (see Invoking_the_graph_menu_) select *Toggle Linear/Log 
    160 Scale* to switch between a linear to log intensity scale. The type of scale  
     160Scale* to switch between a linear to log intensity scale. The type of scale 
    161161selected is written alongside the colour scale. 
    162162 
     
    167167 
    168168From the *Graph Menu* (see Invoking_the_graph_menu_) select *2D Color Map* to 
    169 choose a different color scale for the image and/or change the maximum or  
     169choose a different color scale for the image and/or change the maximum or 
    170170minimum limits of the scale. 
    171171 
     
    173173^^^^^^^^^^^^^^^^^^^^^^^^ 
    174174 
    175 Clicking anywhere in the plot window will cause the current coordinates to be  
     175Clicking anywhere in the plot window will cause the current coordinates to be 
    176176displayed in the status bar at the very bottom-left of the SasView window. 
    177   
     177 
    178178.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    179179 
     
    193193 
    194194In the *Dataset Menu* (see Invoking_the_dataset_menu_), highlight a data set 
    195 and select *DataInfo* to bring up a data information dialog panel for that  
     195and select *DataInfo* to bring up a data information dialog panel for that 
    196196data set. 
    197197 
     
    200200 
    201201In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Save Points as 
    202 a File* (if 1D data) or *Save as a file(DAT)* (if 2D data). A save dialog will  
     202a File* (if 1D data) or *Save as a file(DAT)* (if 2D data). A save dialog will 
    203203appear. 
    204204 
    205 1D data can be saved in either ASCII text (.TXT) or CanSAS/SASXML (.XML)  
     2051D data can be saved in either ASCII text (.TXT) or CanSAS/SASXML (.XML) 
    206206formats (see :ref:`Formats`). 
    207207 
     
    216216 
    217217In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Linear Fit*. A 
    218 fitting dialog will appear. Set some initial parameters and data limits and  
    219 click *Fit*. The fitted parameter values are displayed and the resulting line  
    220 calculated from them is added to the plot.  
     218fitting dialog will appear. Set some initial parameters and data limits and 
     219click *Fit*. The fitted parameter values are displayed and the resulting line 
     220calculated from them is added to the plot. 
    221221 
    222222This option is most useful for performing simple Guinier, XS Guinier, and 
    223 Porod type analyses, for example, to estimate Rg, a rod diameter, or incoherent  
     223Porod type analyses, for example, to estimate Rg, a rod diameter, or incoherent 
    224224background level, respectively. 
    225225 
     
    240240 
    241241In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Show Error Bar* 
    242 or *Hide Error Bar* to switch between showing/hiding the errors associated  
    243 with the chosen dataset.  
     242or *Hide Error Bar* to switch between showing/hiding the errors associated 
     243with the chosen dataset. 
    244244 
    245245Modify plot properties 
     
    247247 
    248248In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Modify Plot 
    249 Property* to change the size, color, or shape of the displayed marker for the  
     249Property* to change the size, color, or shape of the displayed marker for the 
    250250chosen dataset, or to change the dataset label that appears on the plot. 
    251251 
     
    260260This feature is only available with 2D data. 
    261261 
    262 2D data averaging allows you to perform different types of averages on your  
    263 data. The region to be averaged is displayed in the plot window and its limits  
     2622D data averaging allows you to perform different types of averages on your 
     263data. The region to be averaged is displayed in the plot window and its limits 
    264264can be modified by dragging the boundaries around. 
    265265 
     
    277277*  Box averaging on Qy 
    278278 
    279 A 'slicer' will appear (except for *Perform Circular Average*) in the plot that  
    280 you can drag by clicking on a slicer's handle. When the handle is highlighted  
     279A 'slicer' will appear (except for *Perform Circular Average*) in the plot that 
     280you can drag by clicking on a slicer's handle. When the handle is highlighted 
    281281in red, it means that the slicer can move/change size. 
    282282 
    283 *NOTE! The slicer size will reset if you try to select a region greater than  
     283*NOTE! The slicer size will reset if you try to select a region greater than 
    284284the size of the data.* 
    285285 
    286 Alternatively, once a 'slicer' is active you can also select the region to  
    287 average by bringing back the *Dataset Menu* and selecting *Edit Slicer  
    288 Parameters*. A dialog window will appear in which you can enter values to  
     286Alternatively, once a 'slicer' is active you can also select the region to 
     287average by bringing back the *Dataset Menu* and selecting *Edit Slicer 
     288Parameters*. A dialog window will appear in which you can enter values to 
    289289define a region or select the number of points to plot (*nbins*). 
    290290 
    291 A separate plot window will also have appeared, displaying the requested  
     291A separate plot window will also have appeared, displaying the requested 
    292292average. 
    293293 
    294 *NOTE! The displayed average only updates when input focus is moved back to  
     294*NOTE! The displayed average only updates when input focus is moved back to 
    295295that window; ie, when the mouse pointer is moved onto that plot.* 
    296296 
    297 Selecting *Box Sum* automatically brings up the 'Slicer Parameters' dialog in  
     297Selecting *Box Sum* automatically brings up the 'Slicer Parameters' dialog in 
    298298order to display the average numerically, rather than graphically. 
    299299 
     
    303303^^^^^^^^^^^^^^^^^^^^^^^^^ 
    304304 
    305 This operation will perform an average in constant Q-rings around the (x,y)  
     305This operation will perform an average in constant Q-rings around the (x,y) 
    306306pixel location of the beam center. 
    307307 
     
    309309^^^^^^^^^^^^^^^^^^^^^^^ 
    310310 
    311 This operation is the same as 'Unmasked Circular Average' except that any  
     311This operation is the same as 'Unmasked Circular Average' except that any 
    312312masked region is excluded. 
    313313 
     
    317317This operation averages in constant Q-arcs. 
    318318 
    319 The width of the sector is specified in degrees (+/- |delta|\|phi|\) each side  
     319The width of the sector is specified in degrees (+/- |delta|\|phi|\) each side 
    320320of the central angle (|phi|\). 
    321321 
     
    323323^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    324324 
    325 This operation performs an average between two Q-values centered on (0,0),  
     325This operation performs an average between two Q-values centered on (0,0), 
    326326and averaged over a specified number of pixels. 
    327327 
    328 The data is returned as a function of angle (|phi|\) in degrees with zero  
     328The data is returned as a function of angle (|phi|\) in degrees with zero 
    329329degrees at the 3 O'clock position. 
    330330 
     
    334334This operation performs a sum of counts in a 2D region of interest. 
    335335 
    336 When editing the slicer parameters, the user can enter the length and the width  
     336When editing the slicer parameters, the user can enter the length and the width 
    337337the rectangular slicer and the coordinates of the center of the rectangle. 
    338338 
     
    342342This operation computes an average I(Qx) for the region of interest. 
    343343 
    344 When editing the slicer parameters, the user can control the length and the  
    345 width the rectangular slicer. The averaged output is calculated from constant  
    346 bins with rectangular shape. The resultant Q values are nominal values, that  
     344When editing the slicer parameters, the user can control the length and the 
     345width the rectangular slicer. The averaged output is calculated from constant 
     346bins with rectangular shape. The resultant Q values are nominal values, that 
    347347is, the central value of each bin on the x-axis. 
    348348 
     
    352352This operation computes an average I(Qy) for the region of interest. 
    353353 
    354 When editing the slicer parameters, the user can control the length and the  
    355 width the rectangular slicer. The averaged output is calculated from constant  
    356 bins with rectangular shape. The resultant Q values are nominal values, that  
     354When editing the slicer parameters, the user can control the length and the 
     355width the rectangular slicer. The averaged output is calculated from constant 
     356bins with rectangular shape. The resultant Q values are nominal values, that 
    357357is, the central value of each bin on the x-axis. 
    358358 
  • src/sas/sasgui/guiframe/report_dialog.py

    rd85c194 r6dd6e32  
    1515    FONT_VARIANT = 0 
    1616    ISPDF = True 
    17 elif sys.platform == "darwin": 
     17# For OSX and everything else 
     18else: 
    1819    _STATICBOX_WIDTH = 480 
    1920    PANEL_WIDTH = 530 
  • src/sas/sasgui/perspectives/calculator/data_operator.py

    re871a2d r0e760e9  
    1515from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
    1616 
    17 #Control panel width  
     17#Control panel width 
    1818if sys.platform.count("win32") > 0: 
    1919    PANEL_TOP = 0 
     
    156156 
    157157        wx.EVT_TEXT_ENTER(self.data_namectr, -1, self.on_name) 
    158         wx.EVT_TEXT_ENTER(self.numberctr, -1, self.on_number) 
     158        wx.EVT_TEXT(self.numberctr, -1, self.on_number) 
    159159        wx.EVT_COMBOBOX(self.data1_cbox, -1, self.on_select_data1) 
    160160        wx.EVT_COMBOBOX(self.operator_cbox, -1, self.on_select_operator) 
     
    235235        self.name_sizer.Layout() 
    236236 
    237     def on_number(self, event=None): 
     237    def on_number(self, event=None, control=None): 
    238238        """ 
    239239        On selecting Number for Data2 
    240240        """ 
    241241        self.send_warnings('') 
    242         item = event.GetEventObject() 
     242        item = control 
     243        if item is None and event is not None: 
     244            item = event.GetEventObject() 
     245        elif item is None: 
     246            raise ValueError("Event or control must be supplied") 
    243247        text = item.GetValue().strip() 
    244248        if self.numberctr.IsShown(): 
     
    251255                except: 
    252256                    self._set_textctrl_color(self.numberctr, 'pink') 
    253                     msg = "DataOperation: Number requires a float number." 
    254                     self.send_warnings(msg, 'error') 
    255                     return 
     257                    if event is None: 
     258                        msg = "DataOperation: Number requires a float number." 
     259                        self.send_warnings(msg, 'error') 
     260                    return False 
    256261            else: 
    257262                self._set_textctrl_color(self.numberctr, self.color) 
     
    263268        self.draw_output(self.output) 
    264269        self.Refresh() 
     270        return True 
    265271 
    266272    def on_select_data1(self, event=None): 
     
    607613            wx.MessageBox(msg, 'Error') 
    608614            return 
     615        if self.numberctr.IsEnabled() and self.numberctr.IsShown(): 
     616            valid_num = self.on_number(control=self.numberctr) 
     617            if not valid_num: 
     618                return 
    609619        # send data to data manager 
    610620        self.output.name = name 
     
    731741        #add plot 
    732742        self.graph.add(plot) 
    733         #draw         
     743        #draw 
    734744        self.graph.render(self) 
    735745 
     
    985995    window = DataOperatorWindow(parent=None, data=[], title="Data Editor") 
    986996    app.MainLoop() 
    987  
  • src/sas/sasgui/perspectives/calculator/image_viewer.py

    rd0248bd r25b9707a  
    7373                    parent.put_icon(plot_frame) 
    7474            except: 
    75                 print "parent", parent 
    7675                err_msg += "Failed to load '%s'.\n" % basename 
    7776        if err_msg: 
     
    109108        """ 
    110109        # Initialize the Frame object 
    111         PlotFrame.__init__(self, parent, id, title, scale, size) 
     110        PlotFrame.__init__(self, parent, id, title, scale, size, 
     111            show_menu_icons=False) 
    112112        self.parent = parent 
    113113        self.data = image 
     
    437437    ImageView(None).load() 
    438438    app.MainLoop() 
    439  
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    rbb841ef r9501661  
    578578                    else: 
    579579                        out_f.write(line + "\n") 
    580                 elif line.count("P1 = make_class"): 
     580                elif line.count("P1 = find_model"): 
    581581                    out_f.write(line % (name1) + "\n") 
    582                 elif line.count("P2 = make_class"): 
     582                elif line.count("P2 = find_model"): 
    583583                    out_f.write(line % (name2) + "\n") 
    584584 
     
    719719        Do the layout for parameter related widgets 
    720720        """ 
    721         param_txt = wx.StaticText(self, -1, 'Fit Parameters (if any): ') 
    722  
    723         param_tip = "#Set the parameters and initial values.\n" 
     721        param_txt = wx.StaticText(self, -1, 'Fit Parameters NOT requiring' + \ 
     722                                  ' polydispersity (if any): ') 
     723 
     724        param_tip = "#Set the parameters NOT requiring polydispersity " + \ 
     725        "and their initial values.\n" 
    724726        param_tip += "#Example:\n" 
    725727        param_tip += "A = 1\nB = 1" 
     
    736738         
    737739        # Parameters with polydispersity 
    738         pd_param_txt = wx.StaticText(self, -1, 'Fit Parameters requiring polydispersity (if any): ') 
    739  
    740         pd_param_tip = "#Set the parameters and initial values.\n" 
     740        pd_param_txt = wx.StaticText(self, -1, 'Fit Parameters requiring ' + \ 
     741                                     'polydispersity (if any): ') 
     742 
     743        pd_param_tip = "#Set the parameters requiring polydispersity and " + \ 
     744        "their initial values.\n" 
    741745        pd_param_tip += "#Example:\n" 
    742746        pd_param_tip += "C = 2\nD = 2" 
     
    803807        self.bt_close.SetToolTipString("Close this panel.") 
    804808 
    805         self.button_sizer.AddMany([(self.bt_apply, 0, 
    806                                     wx.LEFT, EDITOR_WIDTH * 0.8), 
    807                                    (self.bt_help, 0, 
    808                                     wx.LEFT,15), 
    809                                    (self.bt_close, 0, 
    810                                     wx.LEFT | wx.BOTTOM, 15)]) 
     809        self.button_sizer.AddMany([(self.bt_apply, 0,0), 
     810                                   (self.bt_help, 0, wx.LEFT | wx.BOTTOM,15), 
     811                                   (self.bt_close, 0, wx.LEFT | wx.RIGHT, 15)]) 
    811812 
    812813    def _do_layout(self): 
     
    835836                                  wx.ALL | wx.EXPAND, 5), 
    836837                                 (self.msg_sizer, 0, wx.EXPAND | wx.ALL, 5), 
    837                                  (self.button_sizer, 0, wx.EXPAND | wx.ALL, 5)]) 
     838                                 (self.button_sizer, 0, wx.ALIGN_RIGHT)]) 
    838839        self.SetSizer(self.main_sizer) 
    839840        self.SetAutoLayout(True) 
     
    12371238##import scipy? 
    12381239#class Model(Model1DPlugin): 
    1239 #    name = "" 
     1240#    name = basename without extension of __file__ 
    12401241#    def __init__(self): 
    12411242#        Model1DPlugin.__init__(self, name=self.name) 
    12421243#        #set name same as file name 
    1243 #        self.name = self.get_fname() 
    12441244#        #self.params here 
    12451245#        self.description = "%s" 
     
    13031303""" 
    13041304TEST_TEMPLATE = """ 
    1305     def get_fname(self): 
    1306         path = sys._getframe().f_code.co_filename 
    1307         basename  = os.path.basename(path) 
    1308         name, _ = os.path.splitext(basename) 
    1309         return name 
    13101305###################################################################### 
    13111306## THIS IS FOR TEST. DO NOT MODIFY THE FOLLOWING LINES!!!!!!!!!!!!!!!! 
     
    13301325import sys 
    13311326import copy 
     1327import collections 
    13321328 
    13331329import numpy 
    13341330 
    13351331from sas.sascalc.fit.pluginmodel import Model1DPlugin 
    1336 from sasmodels.sasview_model import make_class 
    1337 from sasmodels.core import load_model_info 
    1338 # User can change the name of the model (only with single functional model) 
    1339 #P1_model: 
    1340 #from %s import Model as P1 
    1341  
    1342 #P2_model: 
    1343 #from %s import Model as P2 
     1332from sasmodels.sasview_model import find_model 
    13441333 
    13451334class Model(Model1DPlugin): 
    1346     name = "" 
    1347     def __init__(self): 
     1335    name = os.path.splitext(os.path.basename(__file__))[0] 
     1336    is_multiplicity_model = False 
     1337    def __init__(self, multiplicity=1): 
    13481338        Model1DPlugin.__init__(self, name='') 
    1349         P1 = make_class('%s') 
    1350         P2 = make_class('%s') 
     1339        P1 = find_model('%s') 
     1340        P2 = find_model('%s') 
    13511341        p_model1 = P1() 
    13521342        p_model2 = P2() 
    13531343        ## Setting  model name model description 
    13541344        self.description = '%s' 
    1355         self.name = self.get_fname() 
    13561345        if self.name.rstrip().lstrip() == '': 
    13571346            self.name = self._get_name(p_model1.name, p_model2.name) 
     
    13621351 
    13631352        ## Define parameters 
    1364         self.params = {} 
     1353        self.params = collections.OrderedDict() 
    13651354 
    13661355        ## Parameter details [units, min, max] 
     
    13911380        #list of parameter that can be fitted 
    13921381        self._set_fixed_params() 
     1382 
    13931383        ## parameters with orientation 
     1384        self.orientation_params = [] 
    13941385        for item in self.p_model1.orientation_params: 
    13951386            new_item = "p1_" + item 
     
    14021393                self.orientation_params.append(new_item) 
    14031394        ## magnetic params 
     1395        self.magnetic_params = [] 
    14041396        for item in self.p_model1.magnetic_params: 
    14051397            new_item = "p1_" + item 
     
    14591451 
    14601452    def _set_dispersion(self): 
     1453        self.dispersion = collections.OrderedDict() 
    14611454        ##set dispersion only from p_model 
    14621455        for name , value in self.p_model1.dispersion.iteritems(): 
     
    15741567 
    15751568    def _set_fixed_params(self): 
     1569        self.fixed = [] 
    15761570        for item in self.p_model1.fixed: 
    15771571            new_item = "p1" + item 
     
    16241618        self.description += description 
    16251619 
    1626     def get_fname(self): 
    1627         path = sys._getframe().f_code.co_filename 
    1628         basename  = os.path.basename(path) 
    1629         name, _ = os.path.splitext(basename) 
    1630         return name 
    1631  
    16321620if __name__ == "__main__": 
    16331621    m1= Model() 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    r26d6e045 r7673ecd  
    2727    """ 
    2828    # try running the model 
    29     from sasmodels.core import load_model, call_kernel 
    30     model = load_model(path) 
    31  
     29    from sasmodels.sasview_model import load_custom_model 
     30    Model = load_custom_model(path) 
     31    model = Model() 
    3232    q =  np.array([0.01, 0.1]) 
    33     kernel = model.make_kernel([q]) 
    34     Iq = call_kernel(kernel, {}) 
    35  
     33    Iq = model.evalDistribution(q) 
    3634    qx, qy =  np.array([0.01, 0.01]), np.array([0.1, 0.1]) 
    37     kernel = model.make_kernel([qx, qy]) 
    38     Iqxy = call_kernel(kernel, {}) 
     35    Iqxy = model.evalDistribution([qx, qy]) 
    3936 
    4037    result = """ 
     
    5653    except Exception: 
    5754        import traceback 
    58         result, errmsg = None, traceback.format_exc(limit=2) 
     55        result, errmsg = None, traceback.format_exc() 
    5956 
    6057    parts = ["Running model '%s'..." % os.path.basename(fname)] 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    rcb4ef58 ree4b3cb  
    1212import json 
    1313import logging 
     14import traceback 
     15 
    1416from collections import defaultdict 
    1517from wx.lib.scrolledpanel import ScrolledPanel 
     18 
     19import sasmodels.sasview_model 
    1620from sas.sasgui.guiframe.panel_base import PanelBase 
    1721from sas.sasgui.guiframe.utils import format_number, check_float, IdList 
     
    198202        self.state_change = False 
    199203        ## save customized array 
    200         self.values = [] 
    201         self.weights = [] 
     204        self.values = {}   # type: Dict[str, List[float, ...]] 
     205        self.weights = {}   # type: Dict[str, List[float, ...]] 
    202206        ## retrieve saved state 
    203207        self.number_saved_state = 0 
     
    852856                    angles.append(angle) 
    853857                    weights.append(weight) 
    854                 except: 
     858                except Exception: 
    855859                    # Skip non-data lines 
    856                     logging.error(sys.exc_info()[1]) 
     860                    logging.error(traceback.format_exc()) 
    857861            return numpy.array(angles), numpy.array(weights) 
    858862        except: 
     
    13931397                self.model._persistency_dict[key] = \ 
    13941398                                 [state.values, state.weights] 
    1395             except: 
    1396                 logging.error(sys.exc_info()[1]) 
     1399            except Exception: 
     1400                logging.error(traceback.format_exc()) 
    13971401            selection = self._find_polyfunc_selection(disp_model) 
    13981402            for list in self.fittable_param: 
     
    14101414                            list[5].Disable() 
    14111415                            list[6].Disable() 
    1412                         except: 
    1413                             logging.error(sys.exc_info()[1]) 
     1416                        except Exception: 
     1417                            logging.error(traceback.format_exc()) 
    14141418            # For array, disable all fixed params 
    14151419            if selection == 1: 
     
    14191423                        try: 
    14201424                            item[2].Disable() 
    1421                         except: 
    1422                             logging.error(sys.exc_info()[1]) 
     1425                        except Exception: 
     1426                            logging.error(traceback.format_exc()) 
    14231427 
    14241428        # Make sure the check box updated when all checked 
     
    15001504            is_2Ddata = True 
    15011505        if self.model != None: 
    1502             try: 
    1503                 is_modified = self._check_value_enter(self.fittable_param, 
    1504                                                       is_modified) 
    1505                 is_modified = self._check_value_enter(self.fixed_param, 
    1506                                                       is_modified) 
    1507                 is_modified = self._check_value_enter(self.parameters, 
    1508                                                       is_modified) 
    1509             except: 
    1510                 logging.error(sys.exc_info()[1]) 
     1506            is_modified = (self._check_value_enter(self.fittable_param) 
     1507                           or self._check_value_enter(self.fixed_param) 
     1508                           or self._check_value_enter(self.parameters)) 
    15111509 
    15121510            # Here we should check whether the boundaries have been modified. 
     
    15571555        flag = True 
    15581556        self.fitrange = True 
    1559         is_modified = False 
    15601557 
    15611558        #wx.PostEvent(self._manager.parent, StatusEvent(status=" \ 
     
    15701567                                                                [self.data]) 
    15711568            ##Check the values 
    1572             self._check_value_enter(self.fittable_param, is_modified) 
    1573             self._check_value_enter(self.fixed_param, is_modified) 
    1574             self._check_value_enter(self.parameters, is_modified) 
     1569            self._check_value_enter(self.fittable_param) 
     1570            self._check_value_enter(self.fixed_param) 
     1571            self._check_value_enter(self.parameters) 
    15751572 
    15761573            # If qmin and qmax have been modified, update qmin and qmax and 
     
    16511648        try: 
    16521649            self.save_current_state() 
    1653         except: 
    1654             logging.error(sys.exc_info()[1]) 
     1650        except Exception: 
     1651            logging.error(traceback.format_exc()) 
    16551652 
    16561653        return flag 
    1657  
    1658     def _is_modified(self, is_modified): 
    1659         """ 
    1660         return to self._is_modified 
    1661         """ 
    1662         return is_modified 
    16631654 
    16641655    def _reset_parameters_state(self, listtorestore, statelist): 
     
    18951886            if mod_cat == custom_model: 
    18961887                for model in self.model_list_box[mod_cat]: 
    1897                     if 'sasmodels.sasview_model.' in str(model): 
    1898                         str_m = model.id 
    1899                     else: 
    1900                         str_m = str(model).split(".")[0] 
    1901                     #self.model_box.Append(str_m) 
     1888                    str_m = model.id if hasattr(model, 'id') else model.name 
    19021889                    m_list.append(self.model_dict[str_m]) 
    19031890            else: 
     
    19101897                    #    wx.PostEvent(self.parent.parent, 
    19111898                    #                 StatusEvent(status=msg, info="error")) 
    1912         except: 
    1913             msg = "%s\n" % (sys.exc_info()[1]) 
     1899        except Exception: 
     1900            msg = traceback.format_exc() 
    19141901            wx.PostEvent(self._manager.parent, 
    19151902                         StatusEvent(status=msg, info="error")) 
     
    19641951        wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    19651952        # Flag to register when a parameter has changed. 
    1966         #is_modified = False 
    19671953        if tcrtl.GetValue().lstrip().rstrip() != "": 
    19681954            try: 
     
    19941980                    if temp_npts != self.num_points: 
    19951981                        self.num_points = temp_npts 
    1996                         #is_modified = True 
    19971982                else: 
    19981983                    msg = "Cannot plot: No points in Q range!!!  " 
     
    21462131                self.temp_multi_functional = True 
    21472132        elif form_factor != None: 
    2148             self.model = form_factor(self.multi_factor) 
     2133            if self.multi_factor is not None: 
     2134                self.model = form_factor(self.multi_factor) 
     2135            else: 
     2136                # old style plugin models do not accept a multiplicity argument 
     2137                self.model = form_factor() 
    21492138        else: 
    21502139            self.model = None 
     
    21652154        self.on_set_focus(None) 
    21662155        self.Layout() 
     2156 
    21672157 
    21682158    def _validate_qrange(self, qmin_ctrl, qmax_ctrl): 
     
    22722262        return flag 
    22732263 
    2274     def _check_value_enter(self, list, modified): 
     2264    def _check_value_enter(self, list): 
    22752265        """ 
    22762266        :param list: model parameter and panel info 
     
    22822272                parameter's maximum value , 
    22832273                parameter's units] 
    2284         """ 
    2285         is_modified = modified 
    2286         if len(list) == 0: 
    2287             return is_modified 
     2274 
     2275        Returns True if the model parameters have changed. 
     2276        """ 
     2277        is_modified = False 
    22882278        for item in list: 
    22892279            #skip angle parameters for 1D 
    2290             if not self.enable2D: 
    2291                 if item in self.orientation_params: 
    2292                     continue 
    2293             #try: 
     2280            if not self.enable2D and item in self.orientation_params: 
     2281                continue 
     2282 
    22942283            name = str(item[1]) 
    2295  
    2296             if string.find(name, ".npts") == -1 and \ 
    2297                                         string.find(name, ".nsigmas") == -1: 
    2298                 ## check model parameters range 
    2299                 param_min = None 
    2300                 param_max = None 
    2301  
    2302                 ## check minimun value 
    2303                 if item[5] != None and item[5] != "": 
    2304                     if item[5].GetValue().lstrip().rstrip() != "": 
    2305                         try: 
    2306                             param_min = float(item[5].GetValue()) 
    2307                             if not self._validate_qrange(item[5], item[2]): 
    2308                                 if numpy.isfinite(param_min): 
    2309                                     item[2].SetValue(format_number(param_min)) 
    2310  
    2311                             item[5].SetBackgroundColour(wx.WHITE) 
    2312                             item[2].SetBackgroundColour(wx.WHITE) 
    2313  
    2314                         except: 
    2315                             msg = "Wrong fit parameter range entered" 
    2316                             wx.PostEvent(self._manager.parent, 
    2317                                          StatusEvent(status=msg)) 
    2318                             raise ValueError, msg 
    2319                         is_modified = True 
    2320                 ## check maximum value 
    2321                 if item[6] != None and item[6] != "": 
    2322                     if item[6].GetValue().lstrip().rstrip() != "": 
    2323                         try: 
    2324                             param_max = float(item[6].GetValue()) 
    2325                             if not self._validate_qrange(item[2], item[6]): 
    2326                                 if numpy.isfinite(param_max): 
    2327                                     item[2].SetValue(format_number(param_max)) 
    2328  
    2329                             item[6].SetBackgroundColour(wx.WHITE) 
    2330                             item[2].SetBackgroundColour(wx.WHITE) 
    2331                         except: 
    2332                             msg = "Wrong Fit parameter range entered " 
    2333                             wx.PostEvent(self._manager.parent, 
    2334                                          StatusEvent(status=msg)) 
    2335                             raise ValueError, msg 
    2336                         is_modified = True 
    2337  
    2338                 if param_min != None and param_max != None: 
    2339                     if not self._validate_qrange(item[5], item[6]): 
    2340                         msg = "Wrong Fit range entered for parameter " 
    2341                         msg += "name %s of model %s " % (name, self.model.name) 
    2342                         wx.PostEvent(self._manager.parent, 
    2343                                      StatusEvent(status=msg)) 
    2344  
    2345                 if name in self.model.details.keys(): 
    2346                     self.model.details[name][1:3] = param_min, param_max 
    2347                     is_modified = True 
    2348                 else: 
    2349                     self.model.details[name] = ["", param_min, param_max] 
    2350                     is_modified = True 
    2351             try: 
    2352                 # Check if the textctr is enabled 
    2353                 if item[2].IsEnabled(): 
    2354                     value = float(item[2].GetValue()) 
    2355                     item[2].SetBackgroundColour("white") 
    2356                     # If the value of the parameter has changed, 
    2357                     # +update the model and set the is_modified flag 
    2358                     if value != self.model.getParam(name) and \ 
    2359                                                 numpy.isfinite(value): 
    2360                         self.model.setParam(name, value) 
    2361             except: 
    2362                 item[2].SetBackgroundColour("pink") 
    2363                 msg = "Wrong Fit parameter value entered " 
    2364                 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2284            if name.endswith(".npts") or name.endswith(".nsigmas"): 
     2285                continue 
     2286 
     2287            # Check that min, max and value are floats 
     2288            value_ctrl, min_ctrl, max_ctrl = item[2], item[5], item[6] 
     2289            min_str = min_ctrl.GetValue().strip() 
     2290            max_str = max_ctrl.GetValue().strip() 
     2291            value_str = value_ctrl.GetValue().strip() 
     2292            validity = check_float(value_ctrl) 
     2293            if min_str != "": 
     2294                validity = validity and check_float(min_ctrl) 
     2295            if max_str != "": 
     2296                validity = validity and check_float(max_ctrl) 
     2297            if not validity: 
     2298                continue 
     2299 
     2300            # Check that min is less than max 
     2301            low = -numpy.inf if min_str == "" else float(min_str) 
     2302            high = numpy.inf if max_str == "" else float(max_str) 
     2303            if high < low: 
     2304                min_ctrl.SetBackgroundColour("pink") 
     2305                min_ctrl.Refresh() 
     2306                max_ctrl.SetBackgroundColour("pink") 
     2307                max_ctrl.Refresh() 
     2308                #msg = "Invalid fit range for %s: min must be smaller than max"%name 
     2309                #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2310                continue 
     2311 
     2312            # Force value between min and max 
     2313            value = float(value_str) 
     2314            if value < low: 
     2315                value = low 
     2316                value_ctrl.SetValue(format_number(value)) 
     2317            elif value > high: 
     2318                value = high 
     2319                value_ctrl.SetValue(format_number(value)) 
     2320 
     2321            # Update value in model if it has changed 
     2322            if value != self.model.getParam(name): 
     2323                self.model.setParam(name, value) 
     2324                is_modified = True 
     2325 
     2326            if name not in self.model.details.keys(): 
     2327                self.model.details[name] = ["", None, None] 
     2328            old_low, old_high = self.model.details[name][1:3] 
     2329            if old_low != low or old_high != high: 
     2330                # The configuration has changed but it won't change the 
     2331                # computed curve so no need to set is_modified to True 
     2332                #is_modified = True 
     2333                self.model.details[name][1:3] = low, high 
    23652334 
    23662335        return is_modified 
     
    24742443                try: 
    24752444                    self.model.set_dispersion(p, disp_model) 
    2476                 except: 
    2477                     logging.error(sys.exc_info()[1]) 
     2445                except Exception: 
     2446                    logging.error(traceback.format_exc()) 
    24782447 
    24792448        ## save state into 
     
    25882557            self._draw_model() 
    25892558            self.Refresh() 
    2590         except: 
     2559        except Exception: 
     2560            logging.error(traceback.format_exc()) 
    25912561            # Error msg 
    25922562            msg = "Error occurred:" 
     
    26802650        # Try to delete values and weight of the names array dic if exists 
    26812651        try: 
    2682             del self.values[name] 
    2683             del self.weights[name] 
    2684             # delete all other dic 
    2685             del self.state.values[name] 
    2686             del self.state.weights[name] 
    2687             del self.model._persistency_dict[name.split('.')[0]] 
    2688             del self.state.model._persistency_dict[name.split('.')[0]] 
    2689         except: 
    2690             logging.error(sys.exc_info()[1]) 
     2652            if name in self.values: 
     2653                del self.values[name] 
     2654                del self.weights[name] 
     2655                # delete all other dic 
     2656                del self.state.values[name] 
     2657                del self.state.weights[name] 
     2658                del self.model._persistency_dict[name.split('.')[0]] 
     2659                del self.state.model._persistency_dict[name.split('.')[0]] 
     2660        except Exception: 
     2661            logging.error(traceback.format_exc()) 
    26912662 
    26922663    def _lay_out(self): 
     
    28322803                        graphs.append(item2.figure) 
    28332804                        canvases.append(item2.canvas) 
    2834             except: 
     2805            except Exception: 
    28352806                # Not for control panels 
    2836                 logging.error(sys.exc_info()[1]) 
     2807                logging.error(traceback.format_exc()) 
    28372808        # Make sure the resduals plot goes to the last 
    28382809        if res_item != None: 
     
    29362907        """ 
    29372908 
    2938         _TreeLocation = "user/sasgui/perspectives/fitting/mag_help.html" 
     2909        _TreeLocation = "user/magnetism.html" 
    29392910        _doc_viewer = DocumentationWindow(self, wx.ID_ANY, _TreeLocation, "", 
    29402911                                          "Polarized Beam/Magnetc Help") 
     
    31673138                if item[7].__class__.__name__ == 'ComboBox': 
    31683139                    disfunc = str(item[7].GetValue()) 
    3169             except: 
    3170                 logging.error(sys.exc_info()[1]) 
     3140            except Exception: 
     3141                logging.error(traceback.format_exc()) 
    31713142 
    31723143            # 2D 
     
    31743145                try: 
    31753146                    check = item[0].GetValue() 
    3176                 except: 
     3147                except Exception: 
    31773148                    check = None 
    31783149                name = item[1] 
     
    32023173                    for weight in self.weights[name]: 
    32033174                        disfunc += ' ' + str(weight) 
    3204             except: 
    3205                 logging.error(sys.exc_info()[1]) 
     3175            except Exception: 
     3176                logging.error(traceback.format_exc()) 
    32063177            content += name + ',' + str(check) + ',' + value + disfunc + ':' 
    32073178 
     
    34033374                                                       weights=pd_weights) 
    34043375                            is_array = True 
    3405                 except: 
    3406                     logging.error(sys.exc_info()[1]) 
     3376                except Exception: 
     3377                    logging.error(traceback.format_exc()) 
    34073378                if not is_array: 
    34083379                    self._disp_obj_dict[name] = disp_model 
     
    34183389                                             self.state.weights] 
    34193390 
    3420             except: 
    3421                 logging.error(sys.exc_info()[1]) 
     3391            except Exception: 
     3392                logging.error(traceback.format_exc()) 
    34223393                print "Error in BasePage._paste_poly_help: %s" % \ 
    34233394                                        sys.exc_info()[1] 
  • src/sas/sasgui/perspectives/fitting/batchfitpage.py

    rfc18690 ree4b3cb  
    256256#         if self.model != None:            
    257257#             ##Check the values 
    258 #             self._check_value_enter( self.fittable_param, is_modified) 
    259 #             self._check_value_enter( self.fixed_param, is_modified) 
    260 #             self._check_value_enter( self.parameters, is_modified) 
     258#             self._check_value_enter( self.fittable_param) 
     259#             self._check_value_enter( self.fixed_param) 
     260#             self._check_value_enter( self.parameters) 
    261261#  
    262262#             # If qmin and qmax have been modified, update qmin and qmax and  
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r934ce649 ree4b3cb  
    13651365            try: 
    13661366                tcrtl.SetBackgroundColour(wx.WHITE) 
    1367                 self._check_value_enter(self.fittable_param, is_modified) 
    1368                 self._check_value_enter(self.parameters, is_modified) 
     1367                self._check_value_enter(self.fittable_param) 
     1368                self._check_value_enter(self.parameters) 
    13691369            except: 
    13701370                tcrtl.SetBackgroundColour("pink") 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r934ce649 r7673ecd  
    273273                        wx.PostEvent(self.parent, evt) 
    274274                        break 
    275         except: 
     275        except Exception: 
     276            import traceback; traceback.print_exc() 
    276277            msg = 'Delete Error: \nCould not delete the file; Check if in use.' 
    277278            wx.MessageBox(msg, 'Error') 
     
    579580                _, theory_state = item 
    580581                self.fit_panel.set_model_state(theory_state) 
    581             except: 
     582            except Exception: 
    582583                msg = "Fitting: cannot deal with the theory received" 
    583584                evt = StatusEvent(status=msg, info="error") 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r20846be rb64b87c  
    1515 
    1616 
    17 Fitting Perspective 
    18 =================== 
     17Fitting 
     18======= 
    1919 
    2020.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    2424 
    2525To fit some data you must first load some data, activate one or more data sets, 
    26 send those data sets to the fitting perspective, and select a model to fit to 
    27 each data set. 
     26send those data sets to fitting, and select a model to fit to each data set. 
    2827 
    2928Instructions on how to load and activate data are in the section :ref:`Loading_data`. 
     
    331330This mode fits one data set. 
    332331 
    333 When data is sent to the fitting perspective it is plotted in a graph window as 
    334 markers. 
     332When data is sent to the fitting it is plotted in a graph window as markers. 
    335333 
    336334If a graph does not appear, or a graph window appears but is empty, then the data 
  • src/sas/sasgui/perspectives/fitting/media/pd_help.rst

    r7805458 rb64b87c  
    105105 
    106106The median value for the distribution will be the value given for the respective 
    107 size parameter in the *Fitting Perspective*, for example, radius = 60. 
     107size parameter in the *FitPage*, for example, radius = 60. 
    108108 
    109109The polydispersity is given by |sigma| 
     
    172172 
    173173SasView only uses these array values during the computation, therefore any mean 
    174 value of the parameter represented by *x* present in the *Fitting Perspective* 
     174value of the parameter represented by *x* present in the *FitPage* 
    175175will be ignored. 
    176176 
  • src/sas/sasgui/perspectives/fitting/models.py

    r6afc14b rdceff6e  
    22    Utilities to manage models 
    33""" 
    4 import imp 
     4import traceback 
    55import os 
    66import sys 
     
    88# Time is needed by the log method 
    99import time 
     10import datetime 
    1011import logging 
    1112import py_compile 
     
    2021 
    2122PLUGIN_DIR = 'plugin_models' 
     23PLUGIN_LOG = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR, 
     24                          "plugins.log") 
    2225 
    2326def get_model_python_path(): 
     
    2831 
    2932 
    30 def log(message): 
     33def plugin_log(message): 
    3134    """ 
    3235    Log a message in a file located in the user's home directory 
    3336    """ 
    34     dir = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR) 
    35     out = open(os.path.join(dir, "plugins.log"), 'a') 
    36     out.write("%10g:  %s\n" % (time.clock(), message)) 
     37    out = open(PLUGIN_LOG, 'a') 
     38    now = time.time() 
     39    stamp = datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S') 
     40    out.write("%s: %s\n" % (stamp, message)) 
    3741    out.close() 
    3842 
     
    5155    if not issubclass(model, Model1DPlugin): 
    5256        msg = "Plugin %s must be of type Model1DPlugin \n" % str(name) 
    53         log(msg) 
     57        plugin_log(msg) 
    5458        return None 
    5559    if model.__name__ != "Model": 
    5660        msg = "Plugin %s class name must be Model \n" % str(name) 
    57         log(msg) 
     61        plugin_log(msg) 
    5862        return None 
    5963    try: 
     
    6367                                                             str(sys.exc_type), 
    6468                                                             sys.exc_info()[1]) 
    65         log(msg) 
     69        plugin_log(msg) 
    6670        return None 
    6771 
     
    7276            msg = "Plugin %s: error writing function \n\t :%s %s\n " % \ 
    7377                    (str(name), str(sys.exc_type), sys.exc_info()[1]) 
    74             log(msg) 
     78            plugin_log(msg) 
    7579            return None 
    7680    else: 
    7781        msg = "Plugin  %s needs a method called function \n" % str(name) 
    78         log(msg) 
     82        plugin_log(msg) 
    7983        return None 
    8084    return model 
     
    132136    """ 
    133137    def __nonzero__(self): 
    134         type, value, traceback = sys.exc_info() 
     138        type, value, tb = sys.exc_info() 
    135139        if type is not None and issubclass(type, py_compile.PyCompileError): 
    136140            print "Problem with", repr(value) 
    137             raise type, value, traceback 
     141            raise type, value, tb 
    138142        return 1 
    139143 
     
    155159 
    156160def _findModels(dir): 
     161    """ 
     162    Find custom models 
     163    """ 
    157164    # List of plugin objects 
    158     plugins = {} 
    159165    dir = find_plugins_dir() 
    160166    # Go through files in plug-in directory 
    161     #always recompile the folder plugin 
    162167    if not os.path.isdir(dir): 
    163         msg = "SasView couldn't locate Model plugin folder." 
    164         msg += """ "%s" does not exist""" % dir 
     168        msg = "SasView couldn't locate Model plugin folder %r." % dir 
    165169        logging.warning(msg) 
    166         return plugins 
    167     else: 
    168         log("looking for models in: %s" % str(dir)) 
    169         compile_file(dir) 
    170         logging.info("plugin model dir: %s" % str(dir)) 
    171     try: 
    172         list = os.listdir(dir) 
    173         for item in list: 
    174             toks = os.path.splitext(os.path.basename(item)) 
    175             if toks[1] == '.py' and not toks[0] == '__init__': 
    176                 name = toks[0] 
    177                 path = [os.path.abspath(dir)] 
    178                 file = None 
    179                 try: 
    180                     (file, path, info) = imp.find_module(name, path) 
    181                     module = imp.load_module(name, file, item, info) 
    182                     if hasattr(module, "Model"): 
    183                         try: 
    184                             if _check_plugin(module.Model, name) != None: 
    185                                 plugins[name] = module.Model 
    186                         except: 
    187                             msg = "Error accessing Model" 
    188                             msg += "in %s\n  %s %s\n" % (name, 
    189                                                          str(sys.exc_type), 
    190                                                          sys.exc_info()[1]) 
    191                             log(msg) 
    192                     else: 
    193                         filename = os.path.join(dir, item) 
    194                         plugins[name] = load_custom_model(filename) 
    195  
    196                 except: 
    197                     msg = "Error accessing Model" 
    198                     msg += " in %s\n  %s %s \n" % (name, 
    199                                                    str(sys.exc_type), 
    200                                                    sys.exc_info()[1]) 
    201                     log(msg) 
    202                 finally: 
    203  
    204                     if not file == None: 
    205                         file.close() 
    206     except: 
    207         # Don't deal with bad plug-in imports. Just skip. 
    208         msg = "Could not import model plugin: %s" % sys.exc_info()[1] 
    209         log(msg) 
    210  
     170        return {} 
     171 
     172    plugin_log("looking for models in: %s" % str(dir)) 
     173    #compile_file(dir)  #always recompile the folder plugin 
     174    logging.info("plugin model dir: %s" % str(dir)) 
     175 
     176    plugins = {} 
     177    for filename in os.listdir(dir): 
     178        name, ext = os.path.splitext(filename) 
     179        if ext == '.py' and not name == '__init__': 
     180            path = os.path.abspath(os.path.join(dir, filename)) 
     181            try: 
     182                model = load_custom_model(path) 
     183                plugins[model.name] = model 
     184            except Exception: 
     185                msg = traceback.format_exc() 
     186                msg += "\nwhile accessing model in %r" % path 
     187                plugin_log(msg) 
     188                logging.warning("Failed to load plugin %r. See %s for details" 
     189                                % (path, PLUGIN_LOG)) 
     190             
    211191    return plugins 
    212192 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    rc10d9d6c r7673ecd  
    1919import logging 
    2020import numpy 
    21 import string 
     21import traceback 
    2222 
    2323import xml.dom.minidom 
     
    473473            try: 
    474474                value = content[1] 
    475             except: 
    476                 logging.error(sys.exc_value) 
     475            except Exception: 
     476                logging.error(traceback.format_exc()) 
    477477            if name.count("State created"): 
    478478                repo_time = "" + value 
     
    515515                        title = content[2] + " [" + repo_time + "]" 
    516516                        title_name = HEADER % title 
    517                 except: 
    518                     logging.error(sys.exc_value) 
     517                except Exception: 
     518                    logging.error(traceback.format_exc()) 
    519519            if name == "model name ": 
    520520                try: 
     
    530530                    q_name = ("Q Range:    " + q_range) 
    531531                    q_range = CENTRE % q_name 
    532                 except: 
    533                     logging.error(sys.exc_value) 
     532                except Exception: 
     533                    logging.error(traceback.format_exc()) 
    534534        paramval = "" 
    535535        for lines in param_string.split(":"): 
     
    864864                            attribute = getattr(self, item[1]) 
    865865                            attribute[name] = com_name 
    866                         except: 
    867                             logging.error(sys.exc_value) 
     866                        except Exception: 
     867                            logging.error(traceback.format_exc()) 
    868868 
    869869                # get self.values and self.weights dic. if exists 
     
    880880                                val = float(line) 
    881881                                value_list.append(val) 
    882                             except: 
     882                            except Exception: 
    883883                                # pass if line is empty (it happens) 
    884                                 logging.error(sys.exc_value) 
     884                                logging.error(traceback.format_exc()) 
    885885                        dic[name] = numpy.array(value_list) 
    886886                    setattr(self, item[1], dic) 
     
    12931293                    if len(note_value) > 0: 
    12941294                        data_info.notes.append(note_value) 
    1295             except: 
     1295            except Exception: 
    12961296                err_mess = "cansas_reader.read: error processing entry notes\n  %s" % sys.exc_value 
    12971297                self.errors.append(err_mess) 
     
    13151315                    if len(detail_value) > 0: 
    13161316                        data_info.sample.details.append(detail_value) 
    1317             except: 
     1317            except Exception: 
    13181318                err_mess = "cansas_reader.read: error processing sample details\n  %s" % sys.exc_value 
    13191319                self.errors.append(err_mess) 
  • src/sas/sasgui/perspectives/invariant/invariant_panel.py

    rc12f9b4 rcb93b40  
    250250 
    251251            num = self.state.saved_state['state_num'] 
    252             if num > 0: 
     252            if int(num) > 0: 
    253253                self._set_undo_flag(True) 
    254             if num < len(state.state_list) - 1: 
     254            if int(num) < len(state.state_list) - 1: 
    255255                self._set_redo_flag(True) 
    256256 
     
    18601860                                   (self.button_calculate, 0, 
    18611861                                    wx.RIGHT | wx.TOP | wx.BOTTOM, 10), 
    1862                                    (self.button_help, 0,  
     1862                                   (self.button_help, 0, 
    18631863                                    wx.RIGHT | wx.TOP | wx.BOTTOM, 10),]) 
    18641864    def _do_layout(self): 
     
    18821882        self.SetSizer(self.main_sizer) 
    18831883        self.SetAutoLayout(True) 
    1884          
     1884 
    18851885    def on_help(self, event): 
    18861886        """ 
    1887         Bring up the Invariant Documentation whenever the HELP button is  
     1887        Bring up the Invariant Documentation whenever the HELP button is 
    18881888        clicked. 
    18891889 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rc10d9d6c rcb93b40  
    426426                        if input_field is not None: 
    427427                            temp_state[item] = val 
    428                             self.state_list[ind] = temp_state 
     428                            self.state_list[str(ind)] = temp_state 
    429429 
    430430            # Parse current state (ie, saved_state) 
     
    790790            doc = state.toXML(datainfo.name, doc=doc, entry_node=sasentry) 
    791791        return doc 
    792  
  • src/sas/sasgui/perspectives/invariant/media/invariant_help.rst

    r70305bd2 rb64b87c  
    44.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
    55 
    6 Invariant Calculation Perspective 
    7 ================================= 
     6Invariant Calculation 
     7===================== 
    88 
    99Description 
     
    4545.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    4646 
    47 Using the perspective 
    48 --------------------- 
     47Using invariant analysis 
     48------------------------ 
    4949 
    50501) Select *Invariant* from the *Analysis* menu on the SasView toolbar. 
     
    5353 
    54543) Select a dataset and use the *Send To* button on the *Data Explorer* to load  
    55    the dataset into the *Invariant* perspective. 
     55   the dataset into the *Invariant* panel. 
    5656 
    57 4) Use the *Customised Input* boxes on the *Invariant* perspective to subtract  
     574) Use the *Customised Input* boxes on the *Invariant* panel to subtract  
    5858   any background, specify the contrast (i.e. difference in SLDs - this must be  
    5959   specified for the eventual value of Q*\  to be on an absolute scale), or to  
     
    7373 
    74748) If the value of Q*\  calculated with the extrapolated regions is invalid, a  
    75    red warning will appear at the top of the *Invariant* perspective panel. 
     75   red warning will appear at the top of the *Invariant* panel. 
    7676 
    7777   The details of the calculation are available by clicking the *Details*  
  • src/sas/sasgui/perspectives/pr/media/pr_help.rst

    r7805458 rb64b87c  
    44.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
    55 
    6 P(r) Inversion Perspective 
    7 ========================== 
     6P(r) Calculation 
     7================ 
    88 
    99Description 
     
    3232.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    3333 
    34 Using the perspective 
    35 --------------------- 
     34Using P(r) inversion 
     35-------------------- 
    3636 
    3737The user must enter 
  • src/sas/sasgui/plottools/LineModel.py

    rd7bb526 rdd5bf63  
    11#!/usr/bin/env python 
    22""" 
    3 Provide Line function (y= A + Bx) 
     3Provide Line function (y= Ax + B). Until July 10, 2016 this function provided 
     4(y= A + Bx).  This however was contrary to all the other code using it which  
     5assumed (y= mx+b) or in this nomenclature (y=Ax + B). This lead to some 
     6contortions in the code and worse incorrect calculations until now for at least 
     7some of the functions.  This seemed the easiest to fix particularly since this 
     8function should disappear in a future iteration (see notes in fitDialog) 
     9 
     10                -PDB   July 10, 2016 
    411""" 
    512 
     
    1017    Class that evaluates a linear model. 
    1118 
    12     f(x) = A + Bx 
     19    f(x) = Ax + B 
    1320 
    1421    List of default parameters: 
    15     A = 0.0 
    16     B = 0.0 
     22    A = 1.0 
     23    B = 1.0 
    1724    """ 
    1825 
     
    5360 
    5461        """ 
    55         return  self.params['A'] + (x * self.params['B']) 
     62        return  (self.params['A'] * x) + self.params['B'] 
    5663 
    5764    def run(self, x=0.0): 
    5865        """ 
    5966        Evaluate the model 
     67 
     68        :note: This is the function called by fitDialog to calculate the 
     69        the y(xmin) and y(xmax), but the only difference between this and 
     70        runXY is when the if statement is true. I however cannot see what that 
     71        function is for.  It needs to be documented here or removed. 
     72        -PDB 7/10/16  
    6073 
    6174        :param x: simple value 
     
    7487    def runXY(self, x=0.0): 
    7588        """ 
    76         Evaluate the model 
     89        Evaluate the model. 
     90         
     91        :note: This is to be what is called by fitDialog for the actual fit 
     92        but the only difference between this and run is when the if  
     93        statement is true. I however cannot see what that function 
     94        is for.  It needs to be documented here or removed. -PDB 7/10/16  
    7795 
    7896        :param x: simple value 
  • src/sas/sasgui/plottools/PlotPanel.py

    r16b769b r1a8e2e8e  
    1515import os 
    1616import transform 
    17 from plottables import Data1D 
    1817#TODO: make the plottables interactive 
    1918from binder import BindArtist 
     
    151150        #List of texts currently on the plot 
    152151        self.textList = [] 
     152        self.selectedText = None 
    153153        #User scale 
    154154        if xtransform != None: 
     
    190190 
    191191        # new data for the fit 
     192        from sas.sasgui.guiframe.dataFitting import Data1D 
    192193        self.fit_result = Data1D(x=[], y=[], dy=None) 
    193194        self.fit_result.symbol = 13 
     
    352353            self.leftdown = True 
    353354            ax = event.inaxes 
     355            for text in self.textList: 
     356                if text.contains(event)[0]: # If user has clicked on text 
     357                    self.selectedText = text 
     358                    return 
     359 
    354360            if ax != None: 
    355361                self.xInit, self.yInit = event.xdata, event.ydata 
     
    373379            self.mousemotion = False 
    374380            self.leftup = True 
     381            self.selectedText = None 
    375382 
    376383        #release the legend 
     
    448455            self._on_legend_motion(event) 
    449456            return 
     457 
     458        if self.leftdown and self.selectedText is not None: 
     459            # User has clicked on text and is dragging 
     460            ax = event.inaxes 
     461            if ax != None: 
     462                # Only move text if mouse is within axes 
     463                self.selectedText.set_position((event.xdata, event.ydata)) 
     464                self._dragHelper(0, 0) 
     465            else: 
     466                # User has dragged outside of axes 
     467                self.selectedText = None 
     468            return 
     469 
    450470        if self.enable_toolbar: 
    451471            #Disable dragging without the toolbar to allow zooming with toolbar 
     
    646666                dlg.setFitRange(self.xminView, self.xmaxView, 
    647667                                self.xmin, self.xmax) 
     668            else: 
     669                xlim = self.subplot.get_xlim() 
     670                ylim = self.subplot.get_ylim() 
     671                dlg.setFitRange(xlim[0], xlim[1], ylim[0], ylim[1]) 
     672            # It would be nice for this to NOT be modal (i.e. Show). 
     673            # Not sure about other ramifications - for example 
     674            # if a second linear fit is started before the first is closed. 
     675            # consider for future - being able to work on the plot while 
     676            # seing the fit values would be very nice  -- PDB 7/10/16 
    648677            dlg.ShowModal() 
    649678 
     
    708737                if dial.ShowModal() == wx.ID_OK: 
    709738                    self.xLabel, self.yLabel, self.viewModel = dial.getValues() 
    710                     if self.viewModel == "Linear y vs x": 
    711                         self.xLabel = "x" 
    712                         self.yLabel = "y" 
    713                         self.viewModel = "--" 
    714                         dial.setValues(self.xLabel, self.yLabel, self.viewModel) 
    715                     if self.viewModel == "Guinier lny vs x^(2)": 
    716                         self.xLabel = "x^(2)" 
    717                         self.yLabel = "ln(y)" 
    718                         self.viewModel = "--" 
    719                         dial.setValues(self.xLabel, self.yLabel, self.viewModel) 
    720                     if self.viewModel == "XS Guinier ln(y*x) vs x^(2)": 
    721                         self.xLabel = "x^(2)" 
    722                         self.yLabel = "ln(y*x)" 
    723                         self.viewModel = "--" 
    724                         dial.setValues(self.xLabel, self.yLabel, self.viewModel) 
    725                     if self.viewModel == "Porod y*x^(4) vs x^(4)": 
    726                         self.xLabel = "x^(4)" 
    727                         self.yLabel = "y*x^(4)" 
    728                         self.viewModel = "--" 
    729                         dial.setValues(self.xLabel, self.yLabel, self.viewModel) 
    730739                    self._onEVT_FUNC_PROPERTY() 
    731740                dial.Destroy() 
     
    12061215 
    12071216        # Properties defined by plot 
    1208          
     1217 
    12091218        # Ricardo: 
    1210         # A empty label "$$" will prevent the panel from displaying!  
    1211          
     1219        # A empty label "$$" will prevent the panel from displaying! 
    12121220        if prop["xlabel"]: 
    12131221            self.subplot.set_xlabel(r"$%s$"%prop["xlabel"]) 
     
    12151223            self.subplot.set_ylabel(r"$%s$"%prop["ylabel"]) 
    12161224        self.subplot.set_title(prop["title"]) 
    1217          
     1225 
    12181226 
    12191227    def clear(self): 
     
    15591567                                                  bins=[self.y_bins, self.x_bins], 
    15601568                                                  weights=self.data) 
    1561         # Now, normalize the image by weights only for weights>1:  
     1569        # Now, normalize the image by weights only for weights>1: 
    15621570        # If weight == 1, there is only one data point in the bin so 
    15631571        # that no normalization is required. 
     
    17411749        if remove_fit: 
    17421750            self.graph.delete(self.fit_result) 
     1751            if hasattr(self, 'plots'): 
     1752                if 'fit' in self.plots.keys(): 
     1753                    del self.plots['fit'] 
    17431754        self.ly = None 
    17441755        self.q_ctrl = None 
     
    17541765        _yscale = 'linear' 
    17551766        for item in list: 
     1767            if item.id == 'fit': 
     1768                continue 
    17561769            item.setLabel(self.xLabel, self.yLabel) 
    1757  
    17581770            # control axis labels from the panel itself 
    17591771            yname, yunits = item.get_yaxis() 
     
    17851797            if self.xLabel == "ln(x)": 
    17861798                item.transformX(transform.toLogX, transform.errToLogX) 
    1787                 self.graph._xaxis_transformed("\ln\\ %s" % xname, "%s" % xunits) 
     1799                self.graph._xaxis_transformed("\ln{(%s)}" % xname, "%s" % xunits) 
    17881800            if self.xLabel == "log10(x)": 
    17891801                item.transformX(transform.toX_pos, transform.errToX_pos) 
     
    17971809            if self.yLabel == "ln(y)": 
    17981810                item.transformY(transform.toLogX, transform.errToLogX) 
    1799                 self.graph._yaxis_transformed("\ln\\ %s" % yname, "%s" % yunits) 
     1811                self.graph._yaxis_transformed("\ln{(%s)}" % yname, "%s" % yunits) 
    18001812            if self.yLabel == "y": 
    18011813                item.transformY(transform.toX, transform.errToX) 
     
    18131825                yunits = convert_unit(-1, yunits) 
    18141826                self.graph._yaxis_transformed("1/%s" % yname, "%s" % yunits) 
     1827            if self.yLabel == "y*x^(2)": 
     1828                item.transformY(transform.toYX2, transform.errToYX2) 
     1829                xunits = convert_unit(2, self.xaxis_unit) 
     1830                self.graph._yaxis_transformed("%s \ \ %s^{2}" % (yname, xname), 
     1831                                              "%s%s" % (yunits, xunits)) 
    18151832            if self.yLabel == "y*x^(4)": 
    18161833                item.transformY(transform.toYX4, transform.errToYX4) 
     
    18261843            if self.yLabel == "ln(y*x)": 
    18271844                item.transformY(transform.toLogXY, transform.errToLogXY) 
    1828                 self.graph._yaxis_transformed("\ln (%s \ \ %s)" % (yname, xname), 
     1845                self.graph._yaxis_transformed("\ln{(%s \ \ %s)}" % (yname, xname), 
    18291846                                              "%s%s" % (yunits, self.xaxis_unit)) 
    18301847            if self.yLabel == "ln(y*x^(2))": 
     
    18441861                self.graph._yaxis_transformed("%s \ \ %s^{4}" % (yname, xname), 
    18451862                                              "%s%s" % (yunits, xunits)) 
    1846             if self.viewModel == "Guinier lny vs x^(2)": 
    1847                 item.transformX(transform.toX2, transform.errToX2) 
    1848                 xunits = convert_unit(2, xunits) 
    1849                 self.graph._xaxis_transformed("%s^{2}" % xname, "%s" % xunits) 
    1850                 item.transformY(transform.toLogX, transform.errToLogX) 
    1851                 self.graph._yaxis_transformed("\ln\ \ %s" % yname, "%s" % yunits) 
    1852             if self.viewModel == "Porod y*x^(4) vs x^(4)": 
    1853                 item.transformX(transform.toX4, transform.errToX4) 
    1854                 xunits = convert_unit(4, self.xaxis_unit) 
    1855                 self.graph._xaxis_transformed("%s^{4}" % xname, "%s" % xunits) 
    1856                 item.transformY(transform.toYX4, transform.errToYX4) 
    1857                 self.graph._yaxis_transformed("%s \ \ %s^{4}" % (yname, xname), 
    1858                                               "%s%s" % (yunits, xunits)) 
    18591863            item.transformView() 
    18601864 
     
    18941898 
    18951899        """ 
     1900        xlim = self.subplot.get_xlim() 
     1901        ylim = self.subplot.get_ylim() 
     1902 
    18961903        # Saving value to redisplay in Fit Dialog when it is opened again 
    18971904        self.Avalue, self.Bvalue, self.ErrAvalue, \ 
     
    19171924        self.graph.render(self) 
    19181925        self._offset_graph() 
     1926        if hasattr(self, 'plots'): 
     1927            # Used by Plotter1D 
     1928            fit_id = 'fit' 
     1929            self.fit_result.id = fit_id 
     1930            self.fit_result.title = 'Fit' 
     1931            self.fit_result.name = 'Fit' 
     1932            self.plots[fit_id] = self.fit_result 
     1933        self.subplot.set_xlim(xlim) 
     1934        self.subplot.set_ylim(ylim) 
    19191935        self.subplot.figure.canvas.draw_idle() 
    19201936 
  • src/sas/sasgui/plottools/PropertyDialog.py

    rd7bb526 r5129686  
    2323        iy += 1 
    2424        ix = 1 
    25         self.xvalue = wx.ComboBox(self, -1) 
     25        self.xvalue = wx.ComboBox(self, -1, style=wx.CB_READONLY) 
    2626        x_size += self.xvalue.GetSize()[0] 
    27         sizer.Add(self.xvalue, (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
     27        sizer.Add(self.xvalue, (iy, ix), (1, 1), wx.ADJUST_MINSIZE, 0) 
    2828 
    2929        ix += 2 
    30         self.yvalue = wx.ComboBox(self, -1) 
     30        self.yvalue = wx.ComboBox(self, -1, style=wx.CB_READONLY) 
    3131        x_size += self.yvalue.GetSize()[0] 
    32         sizer.Add(self.yvalue, (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
     32        sizer.Add(self.yvalue, (iy, ix), (1, 1), wx.ADJUST_MINSIZE, 0) 
    3333 
    3434        ix += 2 
    35         self.view = wx.ComboBox(self, -1) 
     35        self.view = wx.ComboBox(self, -1, style=wx.CB_READONLY) 
     36        self.view.Bind(wx.EVT_COMBOBOX, self.viewChanged) 
    3637        x_size += self.view.GetSize()[0] 
    3738        self.view.SetMinSize((160, 30)) 
     
    6465        self.yvalue.Insert("ln(y)", 2) 
    6566        self.yvalue.Insert("y^(2)", 3) 
    66         self.yvalue.Insert("y*x^(4)", 4) 
    67         self.yvalue.Insert("1/sqrt(y)", 5) 
    68         self.yvalue.Insert("log10(y)", 6) 
    69         self.yvalue.Insert("ln(y*x)", 7) 
    70         self.yvalue.Insert("ln(y*x^(2))", 8) 
    71         self.yvalue.Insert("ln(y*x^(4))", 9) 
    72         self.yvalue.Insert("log10(y*x^(4))", 10) 
     67        self.yvalue.Insert("y*x^(2)", 4) 
     68        self.yvalue.Insert("y*x^(4)", 5) 
     69        self.yvalue.Insert("1/sqrt(y)", 6) 
     70        self.yvalue.Insert("log10(y)", 7) 
     71        self.yvalue.Insert("ln(y*x)", 8) 
     72        self.yvalue.Insert("ln(y*x^(2))", 9) 
     73        self.yvalue.Insert("ln(y*x^(4))", 10) 
     74        self.yvalue.Insert("log10(y*x^(4))", 11) 
    7375        # type of view or model used 
    7476        self.view.SetValue("--") 
     
    8385        self.Centre() 
    8486 
     87    def viewChanged(self, event): 
     88        event.Skip() 
     89        view = self.view.GetValue() 
     90        if view == "Linear y vs x": 
     91            self.xvalue.SetValue("x") 
     92            self.yvalue.SetValue("y") 
     93        elif view == "Guinier lny vs x^(2)": 
     94            self.xvalue.SetValue("x^(2)") 
     95            self.yvalue.SetValue("ln(y)") 
     96        elif view == "XS Guinier ln(y*x) vs x^(2)": 
     97            self.xvalue.SetValue("x^(2)") 
     98            self.yvalue.SetValue("ln(y*x)") 
     99        elif view == "Porod y*x^(4) vs x^(4)": 
     100            self.xvalue.SetValue("x^(4)") 
     101            self.yvalue.SetValue("y*x^(4)") 
     102        elif view == "Kratky y*x^(2) vs x": 
     103            self.xvalue.SetValue("x") 
     104            self.yvalue.SetValue("y*x^(2)") 
     105 
    85106    def setValues(self, x, y, view): 
    86107        """ 
  • src/sas/sasgui/plottools/fitDialog.py

    rd7bb526 rdd5bf63  
    2020def format_number(value, high=False): 
    2121    """ 
    22     Return a float in a standardized, human-readable formatted string 
     22    Return a float in a standardized, human-readable formatted string. 
     23    This is used to output readable (e.g. x.xxxe-y) values to the panel. 
    2324    """ 
    2425    try: 
     
    4041        """ 
    4142        Dialog window pops- up when select Linear fit on Context menu 
    42         Displays fitting parameters 
     43        Displays fitting parameters. This class handles the linearized 
     44        fitting and derives and displays specialized output parameters based 
     45        on the scale choice of the plot calling it. 
     46         
     47        :note1: The fitting is currently a bit convoluted as besides using 
     48        plottools.transform.py to handle all the conversions, it uses 
     49        LineModel to define a linear model and calculate a number of 
     50        things like residuals etc as well as the function itself given an x 
     51        value. It also uses fittings.py to set up the defined LineModel for 
     52        fitting and then send it to the SciPy NLLSQ method.  As these are by 
     53        definition "linear nodels" it would make more sense to just call 
     54        a linear solver such as scipy.stats.linregress or bumps.wsolve directly. 
     55        This would considerably simplify the code and remove the need I think 
     56        for LineModel.py and possibly fittins.py altogether.   -PDB 7/10/16 
     57         
     58        :note2: The linearized fits do not take resolution into account. This 
     59        means that for poor resolution such as slit smearing the answers will 
     60        be completely wrong --- Rg would be OK but I0 would be orders of 
     61        magnitude off.  Eventually we should fix this to account properly for 
     62        resolution.   -PDB  7/10/16 
    4363        """ 
    4464        wx.Dialog.__init__(self, parent, title=title, 
     
    5070        # Registered owner for close event 
    5171        self._registered_close = None 
    52  
    5372        # dialog panel self call function to plot the fitting function 
     73        # calls the calling PlotPanel method onFitDisplay 
    5474        self.push_data = push_data 
    55         # dialog self plottable 
     75        # dialog self plottable - basically the plot we are working with 
     76        # passed in by the caller 
    5677        self.plottable = plottable 
     78        # is this a Guinier fit 
    5779        self.rg_on = False 
    58         # Receive transformations of x and y 
     80        # Receive transformations of x and y - basically transform is passed 
     81        # as caller method that returns its current value for these 
    5982        self.xLabel, self.yLabel, self.Avalue, self.Bvalue, \ 
    6083               self.ErrAvalue, self.ErrBvalue, self.Chivalue = self.transform() 
    6184 
    62         # Dialog interface 
     85        # Now set up the dialog interface 
     86        self.layout() 
     87        # Receives the type of model for the fitting 
     88        from LineModel import LineModel 
     89        self.model = LineModel() 
     90        # Display the fittings values 
     91        self.default_A = self.model.getParam('A') 
     92        self.default_B = self.model.getParam('B') 
     93        self.cstA = fittings.Parameter(self.model, 'A', self.default_A) 
     94        self.cstB = fittings.Parameter(self.model, 'B', self.default_B) 
     95 
     96        # Set default value of parameter in the dialog panel 
     97        if self.Avalue == None: 
     98            self.tcA.SetValue(format_number(self.default_A)) 
     99        else: 
     100            self.tcA.SetLabel(format_number(self.Avalue)) 
     101        if self.Bvalue == None: 
     102            self.tcB.SetValue(format_number(self.default_B)) 
     103        else: 
     104            self.tcB.SetLabel(format_number(self.Bvalue)) 
     105        if self.ErrAvalue == None: 
     106            self.tcErrA.SetLabel(format_number(0.0)) 
     107        else: 
     108            self.tcErrA.SetLabel(format_number(self.ErrAvalue)) 
     109        if self.ErrBvalue == None: 
     110            self.tcErrB.SetLabel(format_number(0.0)) 
     111        else: 
     112            self.tcErrB.SetLabel(format_number(self.ErrBvalue)) 
     113        if self.Chivalue == None: 
     114            self.tcChi.SetLabel(format_number(0.0)) 
     115        else: 
     116            self.tcChi.SetLabel(format_number(self.Chivalue)) 
     117        if self.plottable.x != []: 
     118            # store the values of View in self.x,self.y,self.dx,self.dy 
     119            self.x, self.y, self.dx, \ 
     120                     self.dy = self.plottable.returnValuesOfView() 
     121            try: 
     122                self.mini = self.floatForwardTransform(min(self.x)) 
     123            except: 
     124                self.mini = "Invalid" 
     125            try: 
     126                self.maxi = self.floatForwardTransform(max(self.x)) 
     127            except: 
     128                self.maxi = "Invalid" 
     129 
     130            self.initXmin.SetValue(format_number(min(self.plottable.x))) 
     131            self.initXmax.SetValue(format_number(max(self.plottable.x))) 
     132            self.mini = min(self.x) 
     133            self.maxi = max(self.x) 
     134            self.xminFit.SetValue(format_number(self.mini)) 
     135            self.xmaxFit.SetValue(format_number(self.maxi)) 
     136 
     137    def layout(self): 
     138        """ 
     139        Sets up the panel layout for the linear fit including all the 
     140        labels, text entry boxes, and buttons. 
     141 
     142        """ 
     143 
     144        # set up sizers first.  
     145        # vbox is the panel sizer and is a vertical sizer 
     146        # The first element of the panel is sizer which is a gridbagsizer 
     147        # and contains most of the text fields 
     148        # this is followed by a line separator added to vbox 
     149        # and finally the sizer_button (a horizontal sizer) adds the buttons 
    63150        vbox = wx.BoxSizer(wx.VERTICAL) 
    64151        sizer = wx.GridBagSizer(5, 5) 
     152        sizer_button = wx.BoxSizer(wx.HORIZONTAL) 
     153         
     154        #size of string boxes in pixels 
    65155        _BOX_WIDTH = 100 
    66  
    67         self.tcA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     156        _BOX_HEIGHT = 20 
     157        #now set up all the text fields 
     158        self.tcA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    68159        self.tcA.SetToolTipString("Fit value for the slope parameter.") 
    69         self.tcErrA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     160        self.tcErrA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    70161        self.tcErrA.SetToolTipString("Error on the slope parameter.") 
    71         self.tcB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     162        self.tcB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    72163        self.tcA.SetToolTipString("Fit value for the constant parameter.") 
    73         self.tcErrB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     164        self.tcErrB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    74165        self.tcErrB.SetToolTipString("Error on the constant parameter.") 
    75         self.tcChi = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     166        self.tcChi = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    76167        self.tcChi.SetToolTipString("Chi^2 over degrees of freedom.") 
    77         self.xminFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     168        self.xminFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    78169        msg = "Enter the minimum value on " 
    79170        msg += "the x-axis to be included in the fit." 
    80171        self.xminFit.SetToolTipString(msg) 
    81         self.xmaxFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     172        self.xmaxFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    82173        msg = "Enter the maximum value on " 
    83174        msg += " the x-axis to be included in the fit." 
    84175        self.xmaxFit.SetToolTipString(msg) 
    85         self.initXmin = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     176        self.initXmin = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    86177        msg = "Minimum value on the x-axis for the plotted data." 
    87178        self.initXmin.SetToolTipString(msg) 
    88         self.initXmax = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20)) 
     179        self.initXmax = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT)) 
    89180        msg = "Maximum value on the x-axis for the plotted data." 
    90181        self.initXmax.SetToolTipString(msg) 
     
    98189        self.initXmax.SetBackgroundColour(_BACKGROUND_COLOR) 
    99190 
    100         # Buttons on the bottom 
     191        #set some flags for specific types of fits like Guinier (Rg) and 
     192        #Porod (bg) -- this will determine WHAT boxes show up in the 
     193        #sizer layout and depends on the active axis transform 
    101194        self.bg_on = False 
    102         self.static_line_1 = wx.StaticLine(self, -1) 
    103         self.btFit = wx.Button(self, -1, 'Fit') 
    104         self.btFit.Bind(wx.EVT_BUTTON, self._onFit) 
    105         self.btFit.SetToolTipString("Perform fit.") 
    106         self.btClose = wx.Button(self, wx.ID_CANCEL, 'Close') 
    107         self.btClose.Bind(wx.EVT_BUTTON, self._on_close) 
    108195        if RG_ON: 
    109196            if (self.yLabel == "ln(y)" or self.yLabel == "ln(y*x)") and \ 
     
    112199            if (self.xLabel == "x^(4)") and (self.yLabel == "y*x^(4)"): 
    113200                self.bg_on = True 
    114         # Intro 
    115         explanation = "Perform fit for y(x) = ax + b" 
     201 
     202        # Finally set up static text strings 
     203        warning = "WARNING! Resolution is NOT accounted for. \n" 
     204        warning += "Thus slit smeared data will give very wrong answers!" 
     205        self.textwarn = wx.StaticText(self, -1, warning) 
     206        self.textwarn.SetForegroundColour(wx.RED) 
     207        explanation = "Perform fit for y(x) = ax + b \n" 
    116208        if self.bg_on: 
    117209            param_a = 'Background (= Parameter a)' 
    118210        else: 
    119211            param_a = 'Parameter a' 
    120         vbox.Add(sizer) 
     212 
     213 
     214        #Now set this all up in the GridBagSizer sizer 
    121215        ix = 0 
    122         iy = 1 
     216        iy = 0 
     217        sizer.Add(self.textwarn, (iy, ix), 
     218                  (2, 3), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
     219        iy += 2 
    123220        sizer.Add(wx.StaticText(self, -1, explanation), (iy, ix), 
    124221                  (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
    125         iy += 2 
     222        iy += 1 
    126223        sizer.Add(wx.StaticText(self, -1, param_a), (iy, ix), 
    127224                  (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
     
    281378                      wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    282379 
     380        #Now add some space before the separation line 
    283381        iy += 1 
    284         ix = 1 
    285  
    286         vbox.Add(self.static_line_1, 0, wx.EXPAND, 0) 
    287         sizer_button = wx.BoxSizer(wx.HORIZONTAL) 
     382        ix = 0 
     383        sizer.Add((20,20), (iy, ix), (1, 1), 
     384                      wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
     385 
     386        # Buttons on the bottom 
     387        self.btFit = wx.Button(self, -1, 'Fit') 
     388        self.btFit.Bind(wx.EVT_BUTTON, self._onFit) 
     389        self.btFit.SetToolTipString("Perform fit.") 
     390        self.btClose = wx.Button(self, wx.ID_CANCEL, 'Close') 
     391        self.btClose.Bind(wx.EVT_BUTTON, self._on_close) 
    288392        sizer_button.Add((20, 20), 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    289         sizer_button.Add(self.btFit, 0, wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10) 
     393        sizer_button.Add(self.btFit, 0, 
     394                         wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10) 
    290395        sizer_button.Add(self.btClose, 0, 
    291396                         wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10) 
     397         
     398        vbox.Add(sizer) 
     399        self.static_line_1 = wx.StaticLine(self, -1)         
     400        vbox.Add(self.static_line_1, 0, wx.EXPAND, 0) 
    292401        vbox.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10) 
    293402 
    294         sizer.Add(self.btFit, (iy, ix), (1, 1), wx.LEFT | wx.ADJUST_MINSIZE, 0) 
    295403        # panel.SetSizer(sizer) 
    296404        self.SetSizer(vbox) 
    297405        self.Centre() 
    298         # Receives the type of model for the fitting 
    299         from LineModel import LineModel 
    300         self.model = LineModel() 
    301         # Display the fittings values 
    302         self.default_A = self.model.getParam('A') 
    303         self.default_B = self.model.getParam('B') 
    304         self.cstA = fittings.Parameter(self.model, 'A', self.default_A) 
    305         self.cstB = fittings.Parameter(self.model, 'B', self.default_B) 
    306  
    307         # Set default value of parameter in fit dialog 
    308         if self.Avalue == None: 
    309             self.tcA.SetValue(format_number(self.default_A)) 
    310         else: 
    311             self.tcA.SetLabel(format_number(self.Avalue)) 
    312         if self.Bvalue == None: 
    313             self.tcB.SetValue(format_number(self.default_B)) 
    314         else: 
    315             self.tcB.SetLabel(format_number(self.Bvalue)) 
    316         if self.ErrAvalue == None: 
    317             self.tcErrA.SetLabel(format_number(0.0)) 
    318         else: 
    319             self.tcErrA.SetLabel(format_number(self.ErrAvalue)) 
    320         if self.ErrBvalue == None: 
    321             self.tcErrB.SetLabel(format_number(0.0)) 
    322         else: 
    323             self.tcErrB.SetLabel(format_number(self.ErrBvalue)) 
    324         if self.Chivalue == None: 
    325             self.tcChi.SetLabel(format_number(0.0)) 
    326         else: 
    327             self.tcChi.SetLabel(format_number(self.Chivalue)) 
    328         if self.plottable.x != []: 
    329             # store the values of View in self.x,self.y,self.dx,self.dy 
    330             self.x, self.y, self.dx, \ 
    331                      self.dy = self.plottable.returnValuesOfView() 
    332             try: 
    333                 self.mini = self.floatForwardTransform(min(self.x)) 
    334             except: 
    335                 self.mini = "Invalid" 
    336             try: 
    337                 self.maxi = self.floatForwardTransform(max(self.x)) 
    338             except: 
    339                 self.maxi = "Invalid" 
    340  
    341             self.initXmin.SetValue(format_number(min(self.plottable.x))) 
    342             self.initXmax.SetValue(format_number(max(self.plottable.x))) 
    343             self.mini = min(self.x) 
    344             self.maxi = max(self.x) 
    345             self.xminFit.SetValue(format_number(self.mini)) 
    346             self.xmaxFit.SetValue(format_number(self.maxi)) 
    347406 
    348407    def register_close(self, owner): 
     
    371430        the button Fit.Computes chisqr , 
    372431        A and B parameters of the best linear fit y=Ax +B 
    373         Push a plottable to 
     432        Push a plottable to the caller 
    374433        """ 
    375434        tempx = [] 
     
    389448                xmin = xminView 
    390449                xmax = xmaxView 
     450                # Set the qmin and qmax in the panel that matches the 
     451                # transformed min and max 
     452                self.initXmin.SetValue(format_number(self.floatInvTransform(xmin))) 
     453                self.initXmax.SetValue(format_number(self.floatInvTransform(xmax))) 
    391454                # Store the transformed values of view x, y,dy 
    392455                # in variables  before the fit 
     
    485548                    tempy.append(y_model) 
    486549                # Set the fit parameter display when  FitDialog is opened again 
    487                 self.Avalue = cstB 
    488                 self.Bvalue = cstA 
     550                self.Avalue = cstA 
     551                self.Bvalue = cstB 
    489552                self.ErrAvalue = errA 
    490553                self.ErrBvalue = errB 
     
    494557 
    495558                # Display the fitting value on the Fit Dialog 
    496                 self._onsetValues(cstB, cstA, errA, errB, chisqr) 
     559                self._onsetValues(cstA, cstB, errA, errB, chisqr) 
    497560 
    498561    def _onsetValues(self, cstA, cstB, errA, errB, Chi): 
     
    501564        """ 
    502565        rg = None 
     566        _diam = None 
    503567        self.tcA.SetValue(format_number(cstA)) 
    504568        self.tcB.SetValue(format_number(cstB)) 
     
    516580            if self.Rgerr_tctr.IsShown(): 
    517581                if rg != None and rg != 0: 
    518                     value = format_number(3 * float(cstA) / (2 * rg)) 
     582                    value = format_number(3 * float(errA) / (2 * rg)) 
    519583                else: 
    520584                    value = '' 
    521585                self.Rgerr_tctr.SetValue(value) 
    522586                if self.I0err_tctr.IsShown(): 
    523                     val = numpy.abs(numpy.exp(cstB) - numpy.exp(cstB + errB)) 
     587                    val = numpy.abs(numpy.exp(cstB) * errB) 
    524588                    self.I0err_tctr.SetValue(format_number(val)) 
    525589            if self.Diameter_tctr.IsShown(): 
    526                 rg = 4 * numpy.sqrt(-float(cstA)) 
    527                 value = format_number(rg) 
     590                rg = numpy.sqrt(-2 * float(cstA)) 
     591                _diam = 4 * numpy.sqrt(-float(cstA)) 
     592                value = format_number(_diam) 
    528593                self.Diameter_tctr.SetValue(value) 
    529594            if self.Diametererr_tctr.IsShown(): 
    530595                if rg != None and rg != 0: 
    531                     value = format_number(8 * float(cstA) / rg) 
     596                    value = format_number(8 * float(errA) / _diam) 
    532597                else: 
    533598                    value = '' 
    534599                self.Diametererr_tctr.SetValue(value) 
    535600            if self.RgQmin_tctr.IsShown(): 
    536                 value = format_number(rg * self.mini) 
     601                value = format_number(rg * self.floatInvTransform(self.mini)) 
    537602                self.RgQmin_tctr.SetValue(value) 
    538603            if self.RgQmax_tctr.IsShown(): 
    539                 value = format_number(rg * self.maxi) 
     604                value = format_number(rg * self.floatInvTransform(self.maxi)) 
    540605                self.RgQmax_tctr.SetValue(value) 
    541606 
     
    610675    def floatInvTransform(self, x): 
    611676        """ 
    612         transform a float.It is use to determine the x.View min and x.View 
    613         max for values not in x 
     677        transform a float.It is used to determine the x.View min and x.View 
     678        max for values not in x.  Also used to properly calculate RgQmin, 
     679        RgQmax and to update qmin and qmax in the linear range boxes on the 
     680        panel. 
    614681 
    615682        """ 
     
    617684        # functionality work without rewritting the whole code 
    618685        # with good design (which really should be done...). 
    619         if self.xLabel == "x^(2)": 
     686        if self.xLabel == "x": 
     687            return x 
     688        elif self.xLabel == "x^(2)": 
    620689            return math.sqrt(x) 
     690        elif self.xLabel == "x^(4)": 
     691            return math.sqrt(math.sqrt(x)) 
    621692        elif self.xLabel == "log10(x)": 
    622693            return math.pow(10, x) 
    623694        elif self.xLabel == "ln(x)": 
    624695            return math.exp(x) 
     696        elif self.xLabel == "log10(x^(4))": 
     697            return math.sqrt(math.sqrt(math.pow(10, x))) 
    625698        return x 
    626699 
  • src/sas/sasgui/plottools/fittings.py

    rd7bb526 rdd5bf63  
    11""" 
     2This module is used to fit a set of x,y data to a model passed to it. It is 
     3used to calculate the slope and intercepts for the linearized fits.  Two things 
     4should be noted: 
     5 
     6First, this fitting module uses the NLLSQ module of SciPy rather than a linear 
     7fit.  This along with a few other modules could probably be removed if we 
     8move to a linear regression approach. 
     9 
     10Second, this infrastructure does not allow for resolution smearing of the  
     11the models.  Hence the results are not that accurate even for pinhole 
     12collimation of SANS but may be good for SAXS.  It is completely wrong for  
     13slit smeared data.  
     14 
    215""" 
    316from scipy import optimize 
     
    619class Parameter(object): 
    720    """ 
    8     Class to handle model parameters 
     21    Class to handle model parameters - sets the parameters and their 
     22    initial value from the model based to it. 
    923    """ 
    1024    def __init__(self, model, name, value=None): 
  • src/sas/sasgui/plottools/transform.py

    rd7bb526 r8abd96d  
    291291 
    292292 
    293 def errToYX2(x, y, dx=None, dy=None): 
     293def errToYX2(y, x, dy=None, dx=None): 
    294294    """ 
    295295    """ 
     
    325325 
    326326 
    327 def errToLogYX2(x, y, dx=None, dy=None): 
     327def errToLogYX2(y, x, dy=None, dx=None): 
    328328    """ 
    329329    calculate error of Log(yx**2) 
     
    375375 
    376376 
    377 def errToLogYX4(x, y=None, dx=None, dy=None): 
     377def errToLogYX4(y, x, dy=None, dx=None): 
    378378    """ 
    379379    error for ln(y*x^(4)) 
     
    396396 
    397397 
    398 def errToYX4(x, y=None, dx=None, dy=None): 
     398def errToYX4(y, x, dy=None, dx=None): 
    399399    """ 
    400400    error for (y*x^(4)) 
Note: See TracChangeset for help on using the changeset viewer.