Changeset 8fa3fb8 in sasview for src/sas/sasgui


Ignore:
Timestamp:
Mar 1, 2017 9:46:54 AM (7 years ago)
Author:
butler
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
a97aebd
Parents:
cb1e9a5 (diff), 775e0b7 (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 remote-tracking branch 'origin/master' into expandable-de-688

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

Legend:

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

    r212bfc2 rddbac66  
    123123        compile it and install 
    124124        :param homefile: Override the default home directory 
    125         :param model_list: List of model names except customized models 
     125        :param model_list: List of model names except those in Plugin Models 
     126               which are user supplied. 
    126127        """ 
    127128        _model_dict = { model.name: model for model in model_list} 
  • src/sas/sasgui/guiframe/customdir.py

    r212bfc2 r73cbeec  
    3434        if not os.path.isfile(config_file): 
    3535            shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) 
     36 
     37        #Adding SAS_OPENCL if it doesn't exist in the config file 
     38        # - to support backcompability 
     39        if not "SAS_OPENCL" in open(config_file).read(): 
     40            open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") 
    3641    except: 
    3742        # Check for data path next to exe/zip file. 
  • src/sas/sasgui/guiframe/dataFitting.py

    r9b6d62d r68adf86  
    1717    """ 
    1818    """ 
    19     def __init__(self, x=None, y=None, dx=None, dy=None): 
     19 
     20    def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=False): 
    2021        """ 
    2122        """ 
     
    2425        if y is None: 
    2526            y = [] 
    26         PlotData1D.__init__(self, x, y, dx, dy) 
    27         LoadData1D.__init__(self, x, y, dx, dy) 
     27        self.isSesans = isSesans 
     28        PlotData1D.__init__(self, x, y, dx, dy, lam, dlam) 
     29        LoadData1D.__init__(self, x, y, dx, dy, lam, dlam, isSesans) 
     30 
    2831        self.id = None 
    2932        self.list_group_id = [] 
     
    3235        self.path = None 
    3336        self.xtransform = None 
     37        if self.isSesans: 
     38            self.xtransform = "x" 
    3439        self.ytransform = None 
     40        if self.isSesans: 
     41            self.ytransform = "y" 
    3542        self.title = "" 
    3643        self.scale = None 
     
    6875        # First, check the data compatibility 
    6976        dy, dy_other = self._validity_check(other) 
    70         result = Data1D(x=[], y=[], dx=None, dy=None) 
     77        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 
    7178        result.clone_without_data(length=len(self.x), clone=self) 
    7279        result.copy_from_datainfo(data1d=self) 
     
    115122        # First, check the data compatibility 
    116123        self._validity_check_union(other) 
    117         result = Data1D(x=[], y=[], dx=None, dy=None) 
     124        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 
    118125        tot_length = len(self.x) + len(other.x) 
    119126        result = self.clone_without_data(length=tot_length, clone=result) 
     127        if self.dlam == None or other.dlam is None: 
     128            result.dlam = None 
     129        else: 
     130            result.dlam = numpy.zeros(tot_length) 
    120131        if self.dy == None or other.dy is None: 
    121132            result.dy = None 
     
    141152        result.y = numpy.append(self.y, other.y) 
    142153        result.y = result.y[ind] 
     154        result.lam = numpy.append(self.lam, other.lam) 
     155        result.lam = result.lam[ind] 
     156        if result.dlam != None: 
     157            result.dlam = numpy.append(self.dlam, other.dlam) 
     158            result.dlam = result.dlam[ind] 
    143159        if result.dy != None: 
    144160            result.dy = numpy.append(self.dy, other.dy) 
     
    260276        # First, check the data compatibility 
    261277        self._validity_check_union(other) 
    262         result = Data1D(x=[], y=[], dx=None, dy=None) 
     278        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=[]) 
    263279        tot_length = len(self.x)+len(other.x) 
    264280        result.clone_without_data(length=tot_length, clone=self) 
     281        if self.dlam == None or other.dlam is None: 
     282            result.dlam = None 
     283        else: 
     284            result.dlam = numpy.zeros(tot_length) 
    265285        if self.dy == None or other.dy is None: 
    266286            result.dy = None 
     
    285305        result.y = numpy.append(self.y, other.y) 
    286306        result.y = result.y[ind] 
     307        result.lam = numpy.append(self.lam, other.lam) 
     308        result.lam = result.lam[ind] 
    287309        if result.dy != None: 
    288310            result.dy = numpy.append(self.dy, other.dy) 
  • src/sas/sasgui/guiframe/data_manager.py

    rd85c194 r2ffe241  
    6161         
    6262        if issubclass(Data2D, data.__class__): 
    63             new_plot = Data2D(image=None, err_image=None)  
    64         else:  
    65             new_plot = Data1D(x=[], y=[], dx=None, dy=None) 
    66             
     63            new_plot = Data2D(image=None, err_image=None) # For now, isSesans for 2D data is always false 
     64        else: 
     65            new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=data.isSesans) 
     66 
     67 
     68        #elif data.meta_data['loader'] == 'SESANS': 
     69        #    new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=True) 
     70        #else: 
     71        #    new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None) #SESANS check??? 
     72 
    6773        new_plot.copy_from_datainfo(data) 
    6874        data.clone_without_data(clone=new_plot) 
  • src/sas/sasgui/guiframe/gui_manager.py

    rc8e1996 r73cbeec  
    152152SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT 
    153153SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME 
     154SAS_OPENCL = config.SAS_OPENCL 
    154155if not WELCOME_PANEL_ON: 
    155156    WELCOME_PANEL_SHOW = False 
     
    176177    else: 
    177178        DEFAULT_OPEN_FOLDER = PATH_APP 
     179    SAS_OPENCL = custom_config.SAS_OPENCL 
    178180except: 
    179181    DATALOADER_SHOW = True 
     
    190192    CLEANUP_PLOT = False 
    191193    DEFAULT_OPEN_FOLDER = PATH_APP 
    192  
     194    SAS_OPENCL = None 
    193195DEFAULT_STYLE = config.DEFAULT_STYLE 
    194196 
     
    225227        CHILD_FRAME = wx.Frame 
    226228 
     229#Initiliaze enviromental variable with custom setting but only if variable not set 
     230if SAS_OPENCL and not "SAS_OPENCL" in os.environ: 
     231    os.environ["SAS_OPENCL"] = SAS_OPENCL 
    227232 
    228233class ViewerFrame(PARENT_FRAME): 
     
    19501955                    item, _, _ = value 
    19511956                    item.Check(True) 
    1952             self._data_panel.on_remove(None, False) 
    19531957 
    19541958            wx.PostEvent(self, StatusEvent(status="Loading Project file...")) 
     
    19631967                # Reset to a base state 
    19641968                self._on_reset_state() 
     1969                self._data_panel.on_remove(None, False) 
    19651970                # Load the project file 
    19661971                self.load_state(path=path, is_project=True) 
     
    19901995                wx.PostEvent(self, 
    19911996                             StatusEvent(status="Completed saving.")) 
    1992             except: 
     1997            except Exception: 
    19931998                msg = "Error occurred while saving: " 
     1999                msg += traceback.format_exc() 
    19942000                msg += "To save, the application panel should have a data set.." 
    19952001                wx.PostEvent(self, StatusEvent(status=msg)) 
     
    20402046                logging.warning(msg) 
    20412047                wx.PostEvent(self, StatusEvent(status=msg, info="error")) 
    2042         except: 
     2048        except Exception: 
    20432049            msg = "Error occurred while saving: " 
     2050            msg += traceback.format_exc() 
    20442051            msg += "To save, at least one application panel " 
    20452052            msg += "should have a data set.." 
     
    21022109        Quit the application 
    21032110        """ 
     2111        #IF SAS_OPENCL is set, settings are stored in the custom config file 
     2112        self._write_opencl_config_file() 
    21042113        logging.info(" --- SasView session was closed --- \n") 
    21052114        wx.Exit() 
    21062115        sys.exit() 
     2116 
     2117    def _write_opencl_config_file(self): 
     2118        """ 
     2119        Writes OpenCL settings to custom config file, so they can be remmbered 
     2120        from session to session 
     2121        """ 
     2122        if custom_config is not None: 
     2123            sas_opencl = os.environ.get("SAS_OPENCL",None) 
     2124            new_config_lines = [] 
     2125            config_file = open(custom_config.__file__) 
     2126            config_lines = config_file.readlines() 
     2127            for line in config_lines: 
     2128                if "SAS_OPENCL" in line: 
     2129                    if sas_opencl: 
     2130                        new_config_lines.append("SAS_OPENCL = \""+sas_opencl+"\"") 
     2131                    else: 
     2132                        new_config_lines.append("SAS_OPENCL = None") 
     2133                else: 
     2134                    new_config_lines.append(line) 
     2135            config_file.close() 
     2136 
     2137            #If custom_config is None, settings will not be remmbered 
     2138            new_config_file = open(custom_config.__file__,"w") 
     2139            new_config_file.writelines(new_config_lines) 
     2140            new_config_file.close() 
     2141        else: 
     2142            logging.info("Failed to save OPENCL settings in custom config file") 
     2143 
    21072144 
    21082145    def _check_update(self, event=None): 
     
    24562493                                                group_id=group_id, 
    24572494                                                action='remove')) 
    2458                 # remove res plot: Todo: improve 
    24592495                wx.CallAfter(self._remove_res_plot, new_plot.id) 
    24602496        self._data_manager.delete_data(data_id=data_id, 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py

    r245ae18 r29e872e  
    6565        # context menu 
    6666        self._slicerpop = None 
    67  
    6867        self._available_data = [] 
    6968        self._symbol_labels = self.get_symbol_label() 
     
    732731                self.subplot.set_ylim(y_range) 
    733732                self.subplot.figure.canvas.draw_idle() 
     733                self.is_zoomed = True 
    734734        d.Destroy() 
    735735 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py

    r1a696bf rb2b36932  
    316316 
    317317        slicerpop.AppendSeparator() 
    318         if len(self.data2D.detector) == 1: 
     318        if len(self.data2D.detector) <= 1: 
    319319            item_list = self.parent.get_current_context_menu(self) 
    320320            if (not item_list == None) and (not len(item_list) == 0) and\ 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py

    r6ffa0dd rca224b1  
    134134        """ 
    135135        for group_id in self.plot_panels.keys(): 
    136             panel = self.plot_panels[group_id] 
    137             panel.graph.reset() 
    138             self.hide_panel(group_id) 
     136            self.clear_panel_by_id(group_id) 
    139137        self.plot_panels = {} 
    140138 
  • src/sas/sasgui/guiframe/startup_configuration.py

    rd85c194 r73cbeec  
    3131                   'CLEANUP_PLOT':False, 
    3232                   'DEFAULT_PERSPECTIVE':'Fitting', 
    33                    'DEFAULT_OPEN_FOLDER': None} 
     33                   'DEFAULT_OPEN_FOLDER': None, 
     34                   'SAS_OPENCL': None} 
    3435try: 
    3536    CURRENT_STRINGS = {'GUIFRAME_WIDTH':CURRENT.GUIFRAME_WIDTH, 
     
    4546                       'CLEANUP_PLOT':CURRENT.CLEANUP_PLOT, 
    4647                       'DEFAULT_PERSPECTIVE':CURRENT.DEFAULT_PERSPECTIVE, 
    47                        'DEFAULT_OPEN_FOLDER':CURRENT.DEFAULT_OPEN_FOLDER} 
     48                       'DEFAULT_OPEN_FOLDER':CURRENT.DEFAULT_OPEN_FOLDER, 
     49                       'SAS_OPENCL': None} 
    4850except: 
    4951    CURRENT_STRINGS = DEFAULT_STRINGS 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    r94f0873f rddbac66  
    55function of y (usually the intensity).  It also provides a drop down of 
    66standard available math functions.  Finally a full python editor panel for 
    7 complete customizatin is provided. 
    8  
    9 :TODO the writiong of the file and name checking (and maybe some other 
    10 funtions?) should be moved to a computational module which could be called 
    11 fropm a python script.  Basically one just needs to pass the name, 
     7complete customization is provided. 
     8 
     9:TODO the writing of the file and name checking (and maybe some other 
     10functions?) should be moved to a computational module which could be called 
     11from a python script.  Basically one just needs to pass the name, 
    1212description text and function text (or in the case of the composite editor 
    1313the names of the first and second model and the operator to be used). 
     
    6161    """ 
    6262    Dialog for easy custom composite models.  Provides a wx.Dialog panel 
    63     to choose two existing models (including pre-existing custom models which 
     63    to choose two existing models (including pre-existing Plugin Models which 
    6464    may themselves be composite models) as well as an operation on those models 
    6565    (add or multiply) the resulting model will add a scale parameter for summed 
     
    380380            color = 'blue' 
    381381        except: 
    382             msg = "Easy Custom Sum/Multipy: Error occurred..." 
     382            msg = "Easy Sum/Multipy Plugin: Error occurred..." 
    383383            info = 'Error' 
    384384            color = 'red' 
     
    501501        self.factor = factor 
    502502        self._operator = operator 
    503         self.explanation = "  Custom Model = %s %s (model1 %s model2)\n" % \ 
     503        self.explanation = "  Plugin Model = %s %s (model1 %s model2)\n" % \ 
    504504                           (self.factor, f_oper, self._operator) 
    505505        self.explanationctr.SetLabel(self.explanation) 
     
    617617class EditorPanel(wx.ScrolledWindow): 
    618618    """ 
    619     Custom model function editor 
     619    Simple Plugin Model function editor 
    620620    """ 
    621621    def __init__(self, parent, base, path, title, *args, **kwds): 
     
    652652        self.msg_sizer = None 
    653653        self.warning = "" 
    654         self._description = "New Custom Model" 
     654        #This does not seem to be used anywhere so commenting out for now 
     655        #    -- PDB 2/26/17  
     656        #self._description = "New Plugin Model" 
    655657        self.function_tcl = None 
    656658        self.math_combo = None 
     
    991993        else: 
    992994            self._notes = result 
    993             msg = "Successful! Please look for %s in Customized Models."%name 
     995            msg = "Successful! Please look for %s in Plugin Models."%name 
    994996            msg += "  " + self._notes 
    995997            info = 'Info' 
     
    11381140    def on_help(self, event): 
    11391141        """ 
    1140         Bring up the Custom Model Editor Documentation whenever 
     1142        Bring up the New Plugin Model Editor Documentation whenever 
    11411143        the HELP button is clicked. 
    11421144 
     
    11521154 
    11531155        _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 
    1154         _PageAnchor = "#New_Plugin_Model" 
     1156        _PageAnchor = "#new-plugin-model" 
    11551157        _doc_viewer = DocumentationWindow(self, -1, _TreeLocation, _PageAnchor, 
    11561158                                          "Plugin Model Editor Help") 
     
    11901192        #self.Destroy() 
    11911193 
    1192 ## Templates for custom models 
     1194## Templates for plugin models 
    11931195 
    11941196CUSTOM_TEMPLATE = """ 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    rd472e86 rddbac66  
    302302        success = show_model_output(self, fname) 
    303303 
    304         # Update custom model list in fitpage combobox 
     304        # Update plugin model list in fitpage combobox 
    305305        if success and self._manager != None and self.panel != None: 
    306306            self._manager.set_edit_menu_helper(self.parent) 
  • src/sas/sasgui/perspectives/corfunc/corfunc.py

    r96d293da r1dc8ec9  
    3232        self._always_active = True 
    3333        self.state_reader = Reader(self.set_state) 
    34         self._extensions = '.cor' 
     34        self._extensions = '.crf' 
    3535 
    3636    def get_panels(self, parent): 
     
    4848 
    4949        l = Loader() 
    50         l.associate_file_reader('.cor', self.state_reader) 
     50        l.associate_file_reader('.crf', self.state_reader) 
    5151 
    5252        return [self.corfunc_panel] 
     
    6767            return [] 
    6868        data = plotpanel.plots[graph.selected_plottable] 
    69         if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL: 
     69        if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL1 or data.id == TRANSFORM_LABEL3: 
    7070            return [] 
    7171        item = plotpanel.plots[graph.selected_plottable] 
     
    8181    def set_state(self, state=None, datainfo=None): 
    8282        """ 
    83         Callback for CorfuncState reader. Called when a .cor file is loaded 
     83        Callback for CorfuncState reader. Called when a .crf file is loaded 
    8484        """ 
    8585        if isinstance(datainfo, list): 
     
    179179                # Show the extrapolation as a curve instead of points 
    180180                new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 
    181         elif label == TRANSFORM_LABEL: 
     181        elif label == TRANSFORM_LABEL1 or label == TRANSFORM_LABEL3: 
    182182            new_plot.xaxis("{x}", 'A') 
    183183            new_plot.yaxis("{\\Gamma}", '') 
  • src/sas/sasgui/perspectives/corfunc/corfunc_panel.py

    rd45d590 r1dc8ec9  
    274274        plot_x = transform.x[np.where(transform.x <= 200)] 
    275275        plot_y = transform.y[np.where(transform.x <= 200)] 
    276         self._manager.show_data(Data1D(plot_x, plot_y), TRANSFORM_LABEL) 
     276        self._manager.show_data(Data1D(plot_x, plot_y), TRANSFORM_LABEL1) 
    277277        # Only enable extract params button if a fourier trans. has been done 
    278278        if self.transform_type == 'fourier': 
     
    325325        dlg = wx.FileDialog(self, "Choose a file", 
    326326                            default_save_location, \ 
    327                             self.window_caption, "*.cor", wx.SAVE) 
     327                            self.window_caption, "*.crf", wx.SAVE) 
    328328        if dlg.ShowModal() == wx.ID_OK: 
    329329            path = dlg.GetPath() 
     
    336336        dlg.Destroy() 
    337337        # MAC always needs the extension for saving 
    338         extens = ".cor" 
     338        extens = ".crf" 
    339339        # Make sure the ext included in the file name 
    340340        f_name = os.path.splitext(path)[0] + extens 
  • src/sas/sasgui/perspectives/corfunc/corfunc_state.py

    rd45d590 rae9b8bf  
    9696            self.background = value 
    9797 
    98     def toXML(self, filename='corfunc_state.cor', doc=None, entry_node=None): 
     98    def toXML(self, filename='corfunc_state.crf', doc=None, entry_node=None): 
    9999        """ 
    100100        Writes the state of the CorfuncPanel panel to file, as XML. 
     
    257257    type_name = "Corfunc" 
    258258 
    259     type = ["Corfunc file (*.cor)|*.cor", 
     259    type = ["Corfunc file (*.crf)|*.crf", 
    260260            "SASView file (*.svs)|*.svs"] 
    261261 
    262     ext = ['.cor', '.COR', '.svs', '.SVS'] 
     262    ext = ['.crf', '.CRF', '.svs', '.SVS'] 
    263263 
    264264    def __init__(self, callback): 
  • src/sas/sasgui/perspectives/corfunc/plot_labels.py

    rff11b21 r1dc8ec9  
    44 
    55GROUP_ID_TRANSFORM = r"$\Gamma(x)$" 
    6 TRANSFORM_LABEL = r"$\Gamma(x)$" 
     6TRANSFORM_LABEL1 = r"$\Gamma1(x)$" 
     7TRANSFORM_LABEL3 = r"$\Gamma3(x)$" 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    rc8e1996 r7a5aedd  
    5353    ON_MAC = True 
    5454 
     55CUSTOM_MODEL = 'Plugin Models' 
    5556 
    5657class BasicPage(ScrolledPanel, PanelBase): 
    5758    """ 
    58     This class provide general structure of fitpanel page 
     59    This class provide general structure of the fitpanel page 
    5960    """ 
    6061    # Internal name for the AUI manager 
     
    678679    def _copy_info(self, flag): 
    679680        """ 
    680         Send event dpemding on flag 
    681  
    682         : Param flag: flag that distinguish event 
     681        Send event depending on flag 
     682 
     683        : Param flag: flag that distinguishes the event 
    683684        """ 
    684685        # messages depending on the flag 
     
    10421043                        disp_model = POLYDISPERSITY_MODELS['array']() 
    10431044                        if hasattr(state, "values") and \ 
    1044                                  self.disp_cb_dict[item].GetValue() is True: 
     1045                                 self.disp_cb_dict[item].GetValue(): 
    10451046                            if len(state.values) > 0: 
    10461047                                self.values = state.values 
     
    11061107        """ 
    11071108        for key, value in self.master_category_dict.iteritems(): 
     1109            formfactor = state.formfactorcombobox.split(":") 
     1110            if isinstance(formfactor, list): 
     1111                formfactor = formfactor[0] 
    11081112            for list_item in value: 
    1109                 if state.formfactorcombobox in list_item: 
     1113                if formfactor in list_item: 
    11101114                    return self.categorybox.Items.index(key) 
    11111115        return 0 
     
    11171121        :precondition: the page is already drawn or created 
    11181122 
    1119         :postcondition: the state of the underlying data change as well as the 
     1123        :postcondition: the state of the underlying data changes as well as the 
    11201124            state of the graphic interface 
    11211125        """ 
     
    11531157        self._show_combox_helper() 
    11541158        # select the current model 
    1155         try: 
    1156             # to support older version 
    1157             category_pos = int(state.categorycombobox) 
    1158         except: 
    1159             state.formfactorcombobox = state.formfactorcombobox.lower() 
    1160             state.formfactorcombobox = \ 
    1161                 state.formfactorcombobox.replace('model', '') 
    1162             state.formfactorcombobox = unicode(state.formfactorcombobox) 
    1163             state.categorycombobox = unicode(state.categorycombobox) 
    1164             if state.categorycombobox in self.categorybox.Items: 
    1165                 category_pos = self.categorybox.Items.index( 
    1166                     state.categorycombobox) 
    1167             else: 
    1168                 # Look in master list for model name (model.lower) 
    1169                 category_pos = self.get_cat_combo_box_pos(state) 
     1159        state._convert_to_sasmodels() 
     1160        state.categorycombobox = unicode(state.categorycombobox) 
     1161        if state.categorycombobox in self.categorybox.Items: 
     1162            category_pos = self.categorybox.Items.index( 
     1163                state.categorycombobox) 
     1164        else: 
     1165            # Look in master list for model name (model.lower) 
     1166            category_pos = self.get_cat_combo_box_pos(state) 
    11701167 
    11711168        self.categorybox.Select(category_pos) 
    11721169        self._show_combox(None) 
    1173         try: 
    1174             # to support older version 
    1175             formfactor_pos = int(state.formfactorcombobox) 
    1176         except: 
    1177             formfactor_pos = 0 
    1178             for ind_form in range(self.formfactorbox.GetCount()): 
    1179                 if self.formfactorbox.GetString(ind_form) == \ 
    1180                                                     (state.formfactorcombobox): 
    1181                     formfactor_pos = int(ind_form) 
     1170        from models import PLUGIN_NAME_BASE 
     1171        if self.categorybox.GetValue() == CUSTOM_MODEL \ 
     1172                and PLUGIN_NAME_BASE not in state.formfactorcombobox: 
     1173            state.formfactorcombobox = \ 
     1174                PLUGIN_NAME_BASE + state.formfactorcombobox 
     1175        formfactor_pos = 0 
     1176        for ind_form in range(self.formfactorbox.GetCount()): 
     1177            if self.formfactorbox.GetString(ind_form) == \ 
     1178                                                (state.formfactorcombobox): 
     1179                formfactor_pos = int(ind_form) 
     1180                break 
     1181 
     1182        self.formfactorbox.Select(formfactor_pos) 
     1183 
     1184        structfactor_pos = 0 
     1185        if state.structurecombobox is not None: 
     1186            state.structurecombobox = unicode(state.structurecombobox) 
     1187            for ind_struct in range(self.structurebox.GetCount()): 
     1188                if self.structurebox.GetString(ind_struct) == \ 
     1189                                                (state.structurecombobox): 
     1190                    structfactor_pos = int(ind_struct) 
    11821191                    break 
    1183  
    1184         self.formfactorbox.Select(formfactor_pos) 
    1185  
    1186         structfactor_pos = 0 
    1187         try: 
    1188             # to support older version 
    1189             structfactor_pos = int(state.structurecombobox) 
    1190         except: 
    1191             if state.structurecombobox is not None: 
    1192                 state.structurecombobox = unicode(state.structurecombobox) 
    1193                 for ind_struct in range(self.structurebox.GetCount()): 
    1194                     if self.structurebox.GetString(ind_struct) == \ 
    1195                                                     (state.structurecombobox): 
    1196                         structfactor_pos = int(ind_struct) 
    1197                         break 
    11981192 
    11991193        self.structurebox.SetSelection(structfactor_pos) 
     
    13431337    def _selectDlg(self): 
    13441338        """ 
    1345         open a dialog file to selected the customized dispersity 
     1339        open a dialog file to select the customized polydispersity function 
    13461340        """ 
    13471341        if self.parent is not None: 
     
    13851379        # self.state.struct_rbutton = self.struct_rbutton.GetValue() 
    13861380        # self.state.plugin_rbutton = self.plugin_rbutton.GetValue() 
    1387         self.state.structurecombobox = self.structurebox.GetLabel() 
    1388         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
    1389         self.state.categorycombobox = self.categorybox.GetLabel() 
     1381        self.state.structurecombobox = self.structurebox.GetValue() 
     1382        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1383        self.state.categorycombobox = self.categorybox.GetValue() 
    13901384 
    13911385        # post state to fit panel 
     
    14351429                    self.qmax_x = tempmax 
    14361430                    is_modified = True 
    1437  
    14381431                if is_2Ddata: 
    1439                     # set mask 
    14401432                    is_modified = self._validate_Npts() 
    1441  
     1433                else: 
     1434                    is_modified = self._validate_Npts_1D() 
    14421435            else: 
    14431436                self.fitrange = False 
     
    14541447                # Theory case: need to get npts value to draw 
    14551448                self.npts_x = float(self.Npts_total.GetValue()) 
     1449                self.Npts_fit.SetValue(str(self.Npts_total.GetValue())) 
     1450                self._save_plotting_range() 
    14561451                self.create_default_data() 
    14571452                self.state_change = True 
    14581453                self._draw_model() 
     1454                # Time delay has been introduced to prevent _handle error 
     1455                # on Windows 
     1456                # This part of code is executed when model is selected and 
     1457                # it's parameters are changed (with respect to previously 
     1458                # selected model). There are two Iq evaluations occuring one 
     1459                # after another and therefore there may be compilation error 
     1460                # if model is calculated for the first time. 
     1461                # This seems to be Windows only issue - haven't tested on Linux 
     1462                # though.The proper solution (other than time delay) requires 
     1463                # more fundemental code refatoring 
     1464                # Wojtek P. Nov 7, 2016 
     1465                if not ON_MAC: 
     1466                    time.sleep(0.1) 
    14591467                self.Refresh() 
    14601468 
     
    15281536                        index_data = ((self.qmin_x <= self.data.x) & 
    15291537                                      (self.data.x <= self.qmax_x)) 
    1530                         val = str(len(self.data.x[index_data is True])) 
     1538                        val = str(len(self.data.x[index_data])) 
    15311539                        self.Npts_fit.SetValue(val) 
    15321540                    else: 
     
    15741582        if len(statelist) == 0 or len(listtorestore) == 0: 
    15751583            return 
    1576         if len(statelist) != len(listtorestore): 
    1577             return 
    15781584 
    15791585        for j in range(len(listtorestore)): 
    1580             item_page = listtorestore[j] 
    1581             item_page_info = statelist[j] 
    1582             # change the state of the check box for simple parameters 
    1583             if item_page[0] is not None: 
    1584                 item_page[0].SetValue(item_page_info[0]) 
    1585             if item_page[2] is not None: 
    1586                 item_page[2].SetValue(item_page_info[2]) 
    1587                 if item_page[2].__class__.__name__ == "ComboBox": 
    1588                     if item_page_info[2] in self.model.fun_list: 
    1589                         fun_val = self.model.fun_list[item_page_info[2]] 
    1590                         self.model.setParam(item_page_info[1], fun_val) 
    1591             if item_page[3] is not None: 
    1592                 # show or hide text +/- 
    1593                 if item_page_info[2]: 
    1594                     item_page[3].Show(True) 
    1595                 else: 
    1596                     item_page[3].Hide() 
    1597             if item_page[4] is not None: 
    1598                 # show of hide the text crtl for fitting error 
    1599                 if item_page_info[4][0]: 
    1600                     item_page[4].Show(True) 
    1601                     item_page[4].SetValue(item_page_info[4][1]) 
    1602                 else: 
    1603                     item_page[3].Hide() 
    1604             if item_page[5] is not None: 
    1605                 # show of hide the text crtl for fitting error 
    1606                 item_page[5].Show(item_page_info[5][0]) 
    1607                 item_page[5].SetValue(item_page_info[5][1]) 
    1608  
    1609             if item_page[6] is not None: 
    1610                 # show of hide the text crtl for fitting error 
    1611                 item_page[6].Show(item_page_info[6][0]) 
    1612                 item_page[6].SetValue(item_page_info[6][1]) 
     1586            for param in statelist: 
     1587                if param[1] == listtorestore[j][1]: 
     1588                    item_page = listtorestore[j] 
     1589                    item_page_info = param 
     1590                    if (item_page_info[1] == "theta" or item_page_info[1] == 
     1591                            "phi") and not self._is_2D(): 
     1592                        break 
     1593                    # change the state of the check box for simple parameters 
     1594                    if item_page[0] is not None: 
     1595                        item_page[0].SetValue(item_page_info[0]) 
     1596                    if item_page[2] is not None: 
     1597                        item_page[2].SetValue(item_page_info[2]) 
     1598                        if item_page[2].__class__.__name__ == "ComboBox": 
     1599                            if item_page_info[2] in self.model.fun_list: 
     1600                                fun_val = self.model.fun_list[item_page_info[2]] 
     1601                                self.model.setParam(item_page_info[1], fun_val) 
     1602                    if item_page[3] is not None: 
     1603                        # show or hide text +/- 
     1604                        if item_page_info[2]: 
     1605                            item_page[3].Show(True) 
     1606                        else: 
     1607                            item_page[3].Hide() 
     1608                    if item_page[4] is not None: 
     1609                        # show of hide the text crtl for fitting error 
     1610                        if item_page_info[4][0]: 
     1611                            item_page[4].Show(True) 
     1612                            item_page[4].SetValue(str(item_page_info[4][1])) 
     1613                        else: 
     1614                            item_page[3].Hide() 
     1615                    if item_page[5] is not None: 
     1616                        # show of hide the text crtl for fitting error 
     1617                        item_page[5].Show(True) 
     1618                        item_page[5].SetValue(str(item_page_info[5][1])) 
     1619                    if item_page[6] is not None: 
     1620                        # show of hide the text crtl for fitting error 
     1621                        item_page[6].Show(True) 
     1622                        item_page[6].SetValue(str(item_page_info[6][1])) 
     1623                    break 
    16131624 
    16141625    def _reset_strparam_state(self, listtorestore, statelist): 
     
    17511762    def _set_multfactor_combobox(self, multiplicity=10): 
    17521763        """ 
    1753         Set comboBox for muitfactor of CoreMultiShellModel 
     1764        Set comboBox for multitfactor of CoreMultiShellModel 
    17541765        :param multiplicit: no. of multi-functionality 
    17551766        """ 
     
    17891800        Fill panel's combo box according to the type of model selected 
    17901801        """ 
    1791         custom_model = 'Customized Models' 
     1802 
    17921803        mod_cat = self.categorybox.GetStringSelection() 
    17931804        self.structurebox.SetSelection(0) 
     
    17981809        m_list = [] 
    17991810        try: 
    1800             if mod_cat == custom_model: 
     1811            if mod_cat == CUSTOM_MODEL: 
    18011812                for model in self.model_list_box[mod_cat]: 
    18021813                    m_list.append(self.model_dict[model.name]) 
     
    21322143                flag = False 
    21332144            else: 
    2134                 self.Npts_fit.SetValue(str(len(index_data[index_data is True]))) 
     2145                self.Npts_fit.SetValue(str(len(index_data[index_data]))) 
    21352146                self.fitrange = True 
    21362147 
     
    21672178                flag = False 
    21682179            else: 
    2169                 self.Npts_fit.SetValue(str(len(index_data[index_data is True]))) 
     2180                self.Npts_fit.SetValue(str(len(index_data[index_data]))) 
    21702181                self.fitrange = True 
    21712182 
     
    23912402 
    23922403        # Redraw the model 
    2393         self._draw_model() 
     2404        #  Wojtek P. Nov 7, 2016: Redrawing seems to be unnecessary here 
     2405        # self._draw_model() 
    23942406        # self._undo.Enable(True) 
    23952407        event = PageInfoEvent(page=self) 
     
    26102622            Layout after self._draw_model 
    26112623        """ 
    2612         if ON_MAC is True: 
     2624        if ON_MAC: 
    26132625            time.sleep(1) 
    26142626 
     
    34433455        fills out the category list box 
    34443456        """ 
    3445         uncat_str = 'Customized Models' 
     3457        uncat_str = 'Plugin Models' 
    34463458        self._read_category_info() 
    34473459 
     
    34723484        self.model_box.Clear() 
    34733485 
    3474         if category == 'Customized Models': 
     3486        if category == 'Plugin Models': 
    34753487            for model in self.model_list_box[category]: 
    34763488                str_m = str(model).split(".")[0] 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    rc8e1996 ref2cdb3  
    3131SMEAR_SIZE_L = 0.00 
    3232SMEAR_SIZE_H = 0.00 
    33  
     33CUSTOM_MODEL = 'Plugin Models' 
    3434 
    3535class FitPage(BasicPage): 
     
    8181        flag = check_data_validity(self.data) & (self.model is not None) 
    8282        self.btFit.Enable(flag) 
    83          
     83 
    8484    def on_set_focus(self, event): 
    8585        """ 
    86         Override the basepage focus method to ensure the save flag is set  
     86        Override the basepage focus method to ensure the save flag is set 
    8787        properly when focusing on the fit page. 
    8888        """ 
     
    238238 
    239239        weighting_set_box = wx.StaticBox(self, wx.ID_ANY, 
    240                                 'Set Weighting by Selecting dI Source') 
     240                                         'Set Weighting by Selecting dI Source') 
    241241        weighting_box = wx.StaticBoxSizer(weighting_set_box, wx.HORIZONTAL) 
    242242        sizer_weighting = wx.BoxSizer(wx.HORIZONTAL) 
     
    362362        self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, 
    363363                  id=self.slit_smearer.GetId()) 
    364         self.enable_smearer.SetValue(True) 
     364        self.disable_smearer.SetValue(True) 
    365365 
    366366        sizer_smearer.Add(self.disable_smearer, 0, wx.LEFT, 10) 
     
    11641164        if event is not None: 
    11651165            if (event.GetEventObject() == self.formfactorbox 
    1166                         and self.structurebox.GetLabel() != 'None')\ 
    1167                         or event.GetEventObject() == self.structurebox\ 
    1168                         or event.GetEventObject() == self.multifactorbox: 
     1166                    and self.structurebox.GetLabel() != 'None')\ 
     1167                    or event.GetEventObject() == self.structurebox\ 
     1168                    or event.GetEventObject() == self.multifactorbox: 
    11691169                copy_flag = self.get_copy_params() 
    11701170                is_poly_enabled = self.enable_disp.GetValue() 
     
    11901190        self.state.slit_smearer = self.slit_smearer.GetValue() 
    11911191 
    1192         self.state.structurecombobox = self.structurebox.GetLabel() 
    1193         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
     1192        self.state.structurecombobox = self.structurebox.GetValue() 
     1193        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1194        self.state.categorycombobox = self.categorybox.GetValue() 
    11941195        self.enable_fit_button() 
    11951196        if self.model is not None: 
     
    12051206                    self._keep.Enable(not self.batch_on) 
    12061207                    self._set_save_flag(True) 
    1207                     self._set_smear(self.data) 
     1208            #Setting smearing for cases with and without data. 
     1209            self._set_smear(self.data) 
    12081210 
    12091211            # more disables for 2D 
     
    12121214            try: 
    12131215                # update smearer sizer 
    1214                 self.onSmear(None) 
     1216                #This call for smearing set up caused double evaluation of 
     1217                #I(q) and double compilation as results 
     1218                #self.onSmear(None) 
    12151219                temp_smear = None 
    12161220                if not self.disable_smearer.GetValue(): 
     
    12261230            # set smearing value whether or not data contain the smearing info 
    12271231            evt = ModelEventbox(model=self.model, 
    1228                             smearer=temp_smear, 
    1229                             enable_smearer=not self.disable_smearer.GetValue(), 
    1230                             qmin=float(self.qmin_x), 
    1231                             uid=self.uid, 
    1232                             caption=self.window_caption, 
    1233                             qmax=float(self.qmax_x)) 
     1232                                smearer=temp_smear, 
     1233                                enable_smearer=not self.disable_smearer.GetValue(), 
     1234                                qmin=float(self.qmin_x), 
     1235                                uid=self.uid, 
     1236                                caption=self.window_caption, 
     1237                                qmax=float(self.qmax_x)) 
    12341238 
    12351239            self._manager._on_model_panel(evt=evt) 
     
    12451249            wx.PostEvent(self.parent, new_event) 
    12461250            # update list of plugins if new plugin is available 
    1247             custom_model = 'Customized Models' 
     1251            custom_model = CUSTOM_MODEL 
    12481252            mod_cat = self.categorybox.GetStringSelection() 
    12491253            if mod_cat == custom_model: 
     
    16151619                return 
    16161620        # check if it is pinhole smear and get min max if it is. 
    1617         if data.dx is not None and not numpy.any(data.dx): 
     1621        if data.dx is not None and numpy.any(data.dx): 
    16181622            self.smear_type = "Pinhole" 
    16191623            self.dq_l = data.dx[0] 
     
    19301934 
    19311935            # more disables for 2D 
     1936            di_flag = False 
     1937            dq_flag = False 
    19321938            if self.data.__class__.__name__ == "Data2D" or \ 
    19331939                        self.enable2D: 
     
    19351941                self.pinhole_smearer.Enable(True) 
    19361942                self.default_mask = copy.deepcopy(self.data.mask) 
    1937                 if self.data.err_data is None or\ 
    1938                         numpy.all(err == 1 for err in self.data.err_data) or \ 
    1939                         not numpy.any(self.data.err_data): 
    1940                     self.dI_didata.Enable(False) 
    1941                     self.dI_noweight.SetValue(True) 
    1942                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1943                 else: 
    1944                     self.dI_didata.Enable(True) 
    1945                     self.dI_didata.SetValue(True) 
    1946                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1943                if self.data.err_data is not None \ 
     1944                        and numpy.any(self.data.err_data): 
     1945                    di_flag = True 
     1946                if self.data.dqx_data is not None \ 
     1947                        and numpy.any(self.data.dqx_data): 
     1948                    dq_flag = True 
    19471949            else: 
    19481950                self.slit_smearer.Enable(True) 
    19491951                self.pinhole_smearer.Enable(True) 
    1950  
    1951                 if self.data.dy is None or\ 
    1952                      numpy.all(self.data.dy == 1) or\ 
    1953                      not numpy.any(self.data.dy): 
    1954                     self.dI_didata.Enable(False) 
    1955                     self.dI_noweight.SetValue(True) 
    1956                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1957                 else: 
    1958                     self.dI_didata.Enable(True) 
    1959                     self.dI_didata.SetValue(True) 
    1960                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1952                if self.data.dy is not None and numpy.any(self.data.dy): 
     1953                    di_flag = True 
     1954                if self.data.dx is not None and numpy.any(self.data.dx): 
     1955                    dq_flag = True 
     1956                elif self.data.dxl is not None and numpy.any(self.data.dxl): 
     1957                    dq_flag = True 
     1958 
     1959            if dq_flag: 
     1960                self.enable_smearer.Enable(True) 
     1961                self.enable_smearer.SetValue(True) 
     1962                self.disable_smearer.SetValue(False) 
     1963            else: 
     1964                self.enable_smearer.Disable() 
     1965                self.disable_smearer.Enable(True) 
     1966                self.disable_smearer.SetValue(True) 
     1967 
     1968            if di_flag: 
     1969                self.dI_didata.Enable(True) 
     1970                self.dI_didata.SetValue(True) 
     1971                self.weightbt_string = self.dI_didata.GetLabelText() 
     1972            else: 
     1973                self.dI_didata.Enable(False) 
     1974                self.dI_noweight.SetValue(True) 
     1975                self.weightbt_string = self.dI_noweight.GetLabelText() 
     1976 
    19611977            # Enable weighting radio buttons 
    19621978            self.dI_noweight.Enable(True) 
     
    20002016            self.EditMask_title.Disable() 
    20012017 
     2018        self.onSmear(event=None) 
    20022019        self.on_set_focus(None) 
    20032020        self.Refresh() 
  • src/sas/sasgui/perspectives/fitting/fitpanel.py

    rc8e1996 r67b0a99  
    189189        # use while-loop, for-loop will not do the job well. 
    190190        while (self.GetPageCount() > 0): 
    191             # delete the first page until no page exists 
    192             page = self.GetPage(0) 
     191            page = self.GetPage(self.GetPageCount() - 1) 
    193192            if self._manager.parent.panel_on_focus == page: 
    194193                self._manager.parent.panel_on_focus = None 
    195194            self._close_helper(selected_page=page) 
    196             self.DeletePage(0) 
     195            self.DeletePage(self.GetPageCount() - 1) 
    197196        # Clear list of names 
    198197        self.fit_page_name = {} 
     
    400399                    temp = self.GetSelection() 
    401400                    self.DeletePage(temp) 
     401            if self.sim_page is not None: 
     402                if len(self.sim_page.model_list) == 0: 
     403                    pos = self.GetPageIndex(self.sim_page) 
     404                    self.SetSelection(pos) 
     405                    self.on_close_page(event=None) 
     406                    temp = self.GetSelection() 
     407                    self.DeletePage(temp) 
     408                    self.sim_page = None 
     409                    self.batch_on = False 
    402410            if self.GetPageCount() == 0: 
    403411                self._manager.on_add_new_page(event=None) 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    rec72ceb rddbac66  
    4545from sas.sasgui.guiframe.gui_manager import MDIFrame 
    4646from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     47from sas.sasgui.perspectives.fitting.gpu_options import GpuOptions 
    4748 
    4849from . import models 
     
    193194        self.bumps_options_menu.Enable(True) 
    194195 
     196        self.id_gpu_options_panel = wx.NewId() 
     197        self.menu1.Append(self.id_gpu_options_panel, "OpenCL Options", "Choose OpenCL driver or turn it off") 
     198        wx.EVT_MENU(owner, self.id_gpu_options_panel, self.on_gpu_options) 
     199 
    195200        self.id_result_panel = wx.NewId() 
    196201        self.menu1.Append(self.id_result_panel, "Fit Results", "Show fit results panel") 
     
    220225 
    221226        self.id_edit = wx.NewId() 
    222         editmodel_help = "Edit customized model sample file" 
    223227        self.menu1.AppendMenu(self.id_edit, "Plugin Model Operations", 
    224                               self.edit_model_menu, editmodel_help) 
     228                              self.edit_model_menu) 
    225229        #create  menubar items 
    226230        return [(self.menu1, self.sub_menu)] 
     
    255259            self.update_custom_combo() 
    256260            if os.path.isfile(p_path): 
    257                 msg = "Sorry! Could not be able to delete the default " 
    258                 msg += "custom model... \n" 
     261                msg = "Sorry! unable to delete the default " 
     262                msg += "plugin model... \n" 
    259263                msg += "Please manually remove the files (.py, .pyc) " 
    260264                msg += "in the 'plugin_models' folder \n" 
     
    269273                    if item.GetLabel() == label: 
    270274                        self.edit_menu.DeleteItem(item) 
    271                         msg = "The custom model, %s, has been deleted." % label 
     275                        msg = "The plugin model, %s, has been deleted." % label 
    272276                        evt = StatusEvent(status=msg, type='stop', info='info') 
    273277                        wx.PostEvent(self.parent, evt) 
     
    326330            temp = self.fit_panel.reset_pmodel_list() 
    327331            if temp: 
    328                 # Set the new custom model list for all fit pages 
     332                # Set the new plugin model list for all fit pages 
    329333                for uid, page in self.fit_panel.opened_pages.iteritems(): 
    330334                    if hasattr(page, "formfactorbox"): 
     
    802806        self.result_frame.Raise() 
    803807 
     808    def on_gpu_options(self, event=None): 
     809        """ 
     810        Make the Fit Results panel visible. 
     811        """ 
     812        dialog = GpuOptions(None, wx.ID_ANY, "") 
     813        dialog.Show() 
     814 
    804815    def stop_fit(self, uid): 
    805816        """ 
     
    864875                enable1D=enable1D, enable2D=enable2D, 
    865876                qmin=qmin, qmax=qmax, weight=weight) 
    866             self._mac_sleep(0.2) 
    867877 
    868878    def _mac_sleep(self, sec=0.2): 
     
    15211531            for uid in page_id: 
    15221532                res = result[index] 
     1533                fit_msg = res.mesg 
    15231534                if res.fitness is None or \ 
    15241535                    not numpy.isfinite(res.fitness) or \ 
    15251536                    numpy.any(res.pvec == None) or \ 
    15261537                    not numpy.all(numpy.isfinite(res.pvec)): 
    1527                     msg = "Fitting did not converge!!!" 
    1528                     evt = StatusEvent(status=msg, info="warning", type="stop") 
    1529                     wx.PostEvent(self.parent, evt) 
     1538                    fit_msg += "\nFitting did not converge!!!" 
    15301539                    wx.CallAfter(self._update_fit_button, page_id) 
    15311540                else: 
     
    15501559                        wx.CallAfter(cpage._on_fit_complete) 
    15511560                    except KeyboardInterrupt: 
    1552                         msg = "Singular point: Fitting Stoped." 
    1553                         evt = StatusEvent(status=msg, info="info", type="stop") 
    1554                         wx.PostEvent(self.parent, evt) 
     1561                        fit_msg += "\nSingular point: Fitting stopped." 
    15551562                    except: 
    1556                         msg = "Singular point: Fitting Error occurred." 
    1557                         evt = StatusEvent(status=msg, info="error", type="stop") 
    1558                         wx.PostEvent(self.parent, evt) 
     1563                        fit_msg += "\nSingular point: Fitting error occurred." 
     1564                if fit_msg: 
     1565                   evt = StatusEvent(status=fit_msg, info="warning", type="stop") 
     1566                   wx.PostEvent(self.parent, evt) 
    15591567 
    15601568        except: 
     
    19561964                ## then kill itself but cannot.  Paul Kienzle came up with 
    19571965                ## this fix to prevent threads from stepping on each other 
    1958                 ## which was causing a simple custom model to crash Sasview. 
     1966                ## which was causing a simple custom plugin model to crash 
     1967                ##Sasview. 
    19591968                ## We still don't know why the fit sometimes lauched a second 
    19601969                ## thread -- something which should also be investigated. 
     
    19661975                ## May need rethinking   
    19671976                ## 
    1968                 ##    -PDB August 12, 2014                   
     1977                ##    -PDB August 12, 2014 
    19691978                while self.calc_1D.isrunning(): 
    19701979                    time.sleep(0.1) 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r26c8be3 r5295cf5  
    3434*  in *Single* fit mode - individual data sets are fitted independently one-by-one 
    3535 
    36 *  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to the *same* model with/without constrained parameters (this might be useful, for example, if you have measured the same sample at different contrasts) 
     36*  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to 
     37   the *same* model with/without constrained parameters (this might be useful, 
     38   for example, if you have measured the same sample at different contrasts) 
    3739 
    3840*  in *Batch* fit mode - multiple data sets are fitted sequentially to the *same* model (this might be useful, for example, if you have performed a kinetic or time-resolved experiment and have *lots* of data sets!) 
     
    4345----------------- 
    4446 
    45 By default, the models in SasView are grouped into five categories 
    46  
    47 *  *Shapes* - models describing 'objects' (spheres, cylinders, etc) 
     47The models in SasView are grouped into categories. By default these consist of: 
     48 
     49*  *Cylinder* - cylindrical shapes (disc, right cylinder, cylinder with endcaps 
     50   etc) 
     51*  *Ellipsoid* - ellipsoidal shapes (oblate,prolate, core shell, etc) 
     52*  *Parellelepiped* - as the name implies 
     53*  *Sphere* - sheroidal shapes (sphere, core multishell, vesicle, etc) 
     54*  *Lamellae* - lamellar shapes (lamellar, core shell lamellar, stacked 
     55   lamellar, etc) 
    4856*  *Shape-Independent* - models describing structure in terms of density correlation functions, fractals, peaks, power laws, etc 
    49 *  *Customized Models* - SasView- or User-created (non-library) Python models 
    50 *  *Uncategorised* - other models (for reflectivity, etc) 
     57*  *Paracrystal* - semi ordered structures (bcc, fcc, etc) 
    5158*  *Structure Factor* - S(Q) models 
     59*  *Plugin Models* - User-created (custom/non-library) Python models 
    5260 
    5361Use the *Category* drop-down menu to chose a category of model, then select 
     
    8492.. image:: cat_fig0.bmp 
    8593 
    86 The categorization of all models except the customized models can be reassigned, 
    87 added to, and removed using *Category Manager*. Models can also be hidden from view 
    88 in the drop-down menus. 
     94The categorization of all models except the user supplied Plugin Models can be 
     95reassigned, added to, and removed using *Category Manager*. Models can also be 
     96hidden from view in the drop-down menus. 
    8997 
    9098.. image:: cat_fig1.bmp 
     
    93101^^^^^^^^^^^^^^^^^ 
    94102 
    95 To change category, highlight a model in the list by left-clicking on its entry and 
    96 then click the *Modify* button. Use the *Change Category* panel that appears to make 
    97 the required changes. 
     103To change category, highlight a model in the list by left-clicking on its entry 
     104and then click the *Modify* button. Use the *Change Category* panel that appears 
     105to make the required changes. 
    98106 
    99107.. image:: cat_fig2.bmp 
     
    106114^^^^^^^^^^^^^^^^^^^^^ 
    107115 
    108 Use the *Enable All / Disable All* buttons and the check boxes beside each model to 
    109 select the models to show/hide. To apply the selection, click *Ok*. Otherwise click 
    110 *Cancel*. 
     116Use the *Enable All / Disable All* buttons and the check boxes beside each model 
     117to select the models to show/hide. To apply the selection, click *Ok*. Otherwise 
     118click *Cancel*. 
    111119 
    112120*NB: It may be necessary to change to a different category and then back again* 
     
    118126--------------- 
    119127 
    120 For a complete list of all the library models available in SasView, see the `Model Documentation <../../../index.html>`_ . 
     128For a complete list of all the library models available in SasView, see 
     129the `Model Documentation <../../../index.html>`_ . 
    121130 
    122131It is also possible to add your own models. 
     
    131140There are essentially three ways to generate new fitting models for SasView: 
    132141 
    133 * Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners and/or relatively simple models) 
    134 * By copying/editing an existing model (this can include models generated by the *New Plugin Model* dialog) in the :ref:`Python_shell` or :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
    135 * By writing a model from scratch outside of SasView (only recommended for code monkeys!) 
     142*  Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners 
     143   and/or relatively simple models) 
     144*  By copying/editing an existing model (this can include models generated by 
     145   the New Plugin Model* dialog) in the :ref:`Python_shell` or  
     146   :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
     147*  By writing a model from scratch outside of SasView (only recommended for code 
     148   monkeys!) 
    136149 
    137150Please read the guidance on :ref:`Writing_a_Plugin` before proceeding. 
     
    163176^^^^^^^^^^^^^^^^ 
    164177 
    165 Relatively straightforward models can be programmed directly from the SasView GUI  
    166 using the *New Plugin Model Function*. 
     178Relatively straightforward models can be programmed directly from the SasView 
     179GUI using the *New Plugin Model Function*. 
    167180 
    168181.. image:: new_model.bmp 
     
    175188*checked*\ . 
    176189 
    177 Also note that the 'Fit Parameters' have been split into two sections: those which  
    178 can be polydisperse (shape and orientation parameters) and those which are not 
    179 (eg, scattering length densities). 
     190Also note that the 'Fit Parameters' have been split into two sections: those 
     191which can be polydisperse (shape and orientation parameters) and those which are 
     192not (eg, scattering length densities). 
    180193 
    181194A model file generated by this option can be viewed and further modified using 
     
    187200.. image:: sum_model.bmp 
    188201 
    189 This option creates a custom model of the form:: 
    190  
    191      Custom Model = scale_factor \* {(scale_1 \* model_1) \+ (scale_2 \* model_2)} \+ background 
     202This option creates a custom Plugin Model of the form:: 
     203 
     204     Plugin Model = scale_factor * {(scale_1 * model_1) +/- (scale_2 * model_2)} + background 
    192205 
    193206or:: 
    194207 
    195      Custom Model = scale_factor \* model_1 \* model_2 \+ background 
     208     Plugin Model = scale_factor * model_1 /* model_2 + background 
    196209 
    197210In the *Easy Sum/Multi Editor* give the new model a function name and brief 
     
    232245Simply highlight the plugin model to be removed. The operation is final!!! 
    233246 
    234 *NB: Plugin models shipped with SasView cannot be removed in this way.* 
     247*NB: Models shipped with SasView cannot be removed in this way.* 
    235248 
    236249Load Plugin Models 
    237250^^^^^^^^^^^^^^^^^^ 
    238251 
    239 This option loads (or re-loads) all models present in the *~\\.sasview\\plugin_models* folder. 
     252This option loads (or re-loads) all models present in the 
     253*~\\.sasview\\plugin_models* folder. 
    240254 
    241255.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    400414:ref:`Assessing_Fit_Quality`. 
    401415 
    402 *NB: If you need to use a customized model, you must ensure that model is available* 
    403 *first (see* :ref:`Adding_your_own_models` *).* 
     416*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     417available first (see* :ref:`Adding_your_own_models` *).* 
    404418 
    405419Method 
     
    484498If multiple data sets are in one file, load just that file. *Unselect All Data*, then 
    485499select a single initial data set to be fitted. Fit that selected data set as described 
    486 above under :ref:`Single_Fit_Mode` . 
    487  
    488 *NB: If you need to use a customized model, you must ensure that model is available* 
    489 *first (see* :ref:`Adding_your_own_models` *).* 
     500above under :ref:`Single_Fit_Mode`. 
     501 
     502*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     503available first (see* :ref:`Adding_your_own_models` *).* 
    490504 
    491505Method 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    r20cfa23 r5295cf5  
    2727 
    2828the next time SasView is started it will compile the plugin and add 
    29 it to the list of *Customized Models* in a FitPage. 
     29it to the list of *Plugin Models* in a FitPage. 
    3030 
    3131SasView models can be of three types: 
     
    560560 
    561561    M_PI_180, M_4PI_3: 
    562         $\pi/{180}$, $\tfrac{4}{3}\pi$ 
     562        $\frac{\pi}{180}$, $\frac{4\pi}{3}$ 
    563563    SINCOS(x, s, c): 
    564564        Macro which sets s=sin(x) and c=cos(x). The variables *c* and *s* 
     
    568568    cube(x): 
    569569        $x^3$ 
    570     sinc(x): 
     570    sas_sinx_x(x): 
    571571        $\sin(x)/x$, with limit $\sin(0)/0 = 1$. 
    572572    powr(x, y): 
     
    596596These functions have been tuned to be fast and numerically stable down 
    597597to $q=0$ even in single precision.  In some cases they work around bugs 
    598 which appear on some platforms but not others. So use them where needed!!! 
     598which appear on some platforms but not others, so use them where needed. 
     599Add the files listed in :code:`source = ["lib/file.c", ...]` to your *model.py* 
     600file in the order given, otherwise these functions will not be available. 
    599601 
    600602    polevl(x, c, n): 
    601         Polynomial evaluation $p(x) = \sum_{i=0}^n c_i x^{n-i}$ using Horner's 
     603        Polynomial evaluation $p(x) = \sum_{i=0}^n c_i x^i$ using Horner's 
    602604        method so it is faster and more accurate. 
    603605 
     606        $c = \{c_n, c_{n-1}, \ldots, c_0 \}$ is the table of coefficients, 
     607        sorted from highest to lowest. 
     608 
     609        :code:`source = ["lib/polevl.c", ...]` (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/polevl.c>`_) 
     610 
     611    p1evl(x, c, n): 
     612        Evaluation of normalized polynomial $p(x) = x^n + \sum_{i=0}^{n-1} c_i x^i$ 
     613        using Horner's method so it is faster and more accurate. 
     614 
     615        $c = \{c_{n-1}, c_{n-2} \ldots, c_0 \}$ is the table of coefficients, 
     616        sorted from highest to lowest. 
     617 
    604618        :code:`source = ["lib/polevl.c", ...]` 
    605  
    606     sas_gamma: 
    607         Gamma function $\text{sas_gamma}(x) = \Gamma(x)$.  The standard math 
    608         library gamma function, tgamma(x) is unstable below 1 on some platforms. 
     619        (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/polevl.c>`_) 
     620 
     621    sas_gamma(x): 
     622        Gamma function $\text{sas_gamma}(x) = \Gamma(x)$. 
     623 
     624        The standard math function, tgamma(x) is unstable for $x < 1$ 
     625        on some platforms. 
    609626 
    610627        :code:`source = ["lib/sasgamma.c", ...]` 
    611  
    612     erf, erfc: 
     628        (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_gamma.c>`_) 
     629 
     630    sas_erf(x), sas_erfc(x): 
    613631        Error function 
    614         $\text{erf}(x) = \frac{1}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$ 
     632        $\text{sas_erf}(x) = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$ 
    615633        and complementary error function 
    616         $\text{erfc}(x) = \frac{1}{\sqrt\pi}\int_x^\inf e^{-t^2}\,dt$. 
    617         The standard math library erf and erfc are slower and broken 
     634        $\text{sas_erfc}(x) = \frac{2}{\sqrt\pi}\int_x^{\infty} e^{-t^2}\,dt$. 
     635 
     636        The standard math functions erf(x) and erfc(x) are slower and broken 
    618637        on some platforms. 
    619638 
    620639        :code:`source = ["lib/polevl.c", "lib/sas_erf.c", ...]` 
    621  
    622     sas_J0: 
    623         Bessel function of the first kind where 
     640        (`link to error functions' code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_erf.c>`_) 
     641 
     642    sas_J0(x): 
     643        Bessel function of the first kind $\text{sas_J0}(x)=J_0(x)$ where 
    624644        $J_0(x) = \frac{1}{\pi}\int_0^\pi \cos(x\sin(\tau))\,d\tau$. 
    625645 
     646        The standard math function j0(x) is not available on all platforms. 
     647 
    626648        :code:`source = ["lib/polevl.c", "lib/sas_J0.c", ...]` 
    627  
    628     sas_J1: 
    629         Bessel function of the first kind where 
     649        (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J0.c>`_) 
     650 
     651    sas_J1(x): 
     652        Bessel function of the first kind  $\text{sas_J1}(x)=J_1(x)$ where 
    630653        $J_1(x) = \frac{1}{\pi}\int_0^\pi \cos(\tau - x\sin(\tau))\,d\tau$. 
    631654 
     655        The standard math function j1(x) is not available on all platforms. 
     656 
    632657        :code:`source = ["lib/polevl.c", "lib/sas_J1.c", ...]` 
    633  
    634     sas_JN: 
    635         Bessel function of the first kind where 
     658        (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J1.c>`_) 
     659 
     660    sas_JN(n, x): 
     661        Bessel function of the first kind and integer order $n$: 
     662        $\text{sas_JN}(n, x)=J_n(x)$ where 
    636663        $J_n(x) = \frac{1}{\pi}\int_0^\pi \cos(n\tau - x\sin(\tau))\,d\tau$. 
     664        If $n$ = 0 or 1, it uses sas_J0(x) or sas_J1(x), respectively. 
     665 
     666        The standard math function jn(n, x) is not available on all platforms. 
    637667 
    638668        :code:`source = ["lib/polevl.c", "lib/sas_J0.c", "lib/sas_J1.c", "lib/sas_JN.c", ...]` 
    639  
    640     Si: 
     669        (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_JN.c>`_) 
     670 
     671    sas_Si(x): 
    641672        Sine integral $\text{Si}(x) = \int_0^x \tfrac{\sin t}{t}\,dt$. 
    642673 
    643         :code:`soure = ["lib/Si.c", ...]` 
    644  
    645     sph_j1c(qr): 
     674        This function uses Taylor series for small and large arguments: 
     675 
     676        For large arguments, 
     677 
     678        .. math:: 
     679 
     680             \text{Si}(x) \sim \frac{\pi}{2} 
     681             - \frac{\cos(x)}{x}\left(1 - \frac{2!}{x^2} + \frac{4!}{x^4} - \frac{6!}{x^6} \right) 
     682             - \frac{\sin(x)}{x}\left(\frac{1}{x} - \frac{3!}{x^3} + \frac{5!}{x^5} - \frac{7!}{x^7}\right) 
     683 
     684        For small arguments, 
     685 
     686        .. math:: 
     687 
     688           \text{Si}(x) \sim x 
     689           - \frac{x^3}{3\times 3!} + \frac{x^5}{5 \times 5!} - \frac{x^7}{7 \times 7!} 
     690           + \frac{x^9}{9\times 9!} - \frac{x^{11}}{11\times 11!} 
     691 
     692        :code:`source = ["lib/Si.c", ...]` 
     693        (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/Si.c>`_) 
     694 
     695    sas_3j1x_x(x): 
    646696        Spherical Bessel form 
    647         $F(qr) = 3 j_1(qr)/(qr) = 3 (\sin(qr) - qr \cos(qr))/{(qr)^3}$, 
    648         with a limiting value of 1 at $qr=0$.  This function uses a Taylor 
    649         series for small $qr$ for numerical accuracy. 
    650  
    651         :code:`source = ["lib/sph_j1c.c", ...]` 
    652  
    653     sas_J1c(qr): 
    654         Bessel form $F(qr) = 2 J_1(qr)/{(qr)}$, with a limiting value of 1 at $qr=0$. 
     697        $\text{sph_j1c}(x) = 3 j_1(x)/x = 3 (\sin(x) - x \cos(x))/x^3$, 
     698        with a limiting value of 1 at $x=0$, where $j_1(x)$ is the spherical 
     699        Bessel function of the first kind and first order. 
     700 
     701        This function uses a Taylor series for small $x$ for numerical accuracy. 
     702 
     703        :code:`source = ["lib/sas_3j1x_x.c", ...]` 
     704        (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_3j1x_x.c>`_) 
     705 
     706 
     707    sas_2J1x_x(x): 
     708        Bessel form $\text{sas_J1c}(x) = 2 J_1(x)/x$, with a limiting value 
     709        of 1 at $x=0$, where $J_1(x)$ is the Bessel function of first kind 
     710        and first order. 
    655711 
    656712        :code:`source = ["lib/polevl.c", "lib/sas_J1.c", ...]` 
    657  
    658     Gauss76z[i], Gauss76Wt[i]: 
    659         Points $z_i$ and weights $w_i$ for 76-point Gaussian quadrature, 
    660         computing $\int_{-1}^1 f(z)\,dz \approx \sum_{i=1}^{76} w_i f(z_i)$. 
    661         Similar arrays are available in :code:`gauss20.c` for 20 point 
    662         quadrature and in :code:`gauss150.c` for 150 point quadrature. 
    663  
    664         :code:`source = ["gauss76.c", ...]` 
     713        (`link to Bessel form's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J1.c>`_) 
     714 
     715 
     716    Gauss76Z[i], Gauss76Wt[i]: 
     717        Points $z_i$ and weights $w_i$ for 76-point Gaussian quadrature, respectively, 
     718        computing $\int_{-1}^1 f(z)\,dz \approx \sum_{i=1}^{76} w_i\,f(z_i)$. 
     719 
     720        Similar arrays are available in :code:`gauss20.c` for 20-point 
     721        quadrature and in :code:`gauss150.c` for 150-point quadrature. 
     722 
     723        :code:`source = ["lib/gauss76.c", ...]` 
     724        (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/gauss76.c>`_) 
     725 
     726 
    665727 
    666728Problems with C models 
  • src/sas/sasgui/perspectives/fitting/media/sm_help.rst

    r7805458 r27aabc1  
    2020================== 
    2121 
    22 Sometimes it will be necessary to correct reduced experimental data for the 
    23 physical effects of the instrumental geometry in use. This process is called 
    24 *desmearing*. However, calculated/simulated data - which by definition will be 
    25 perfect/exact - can be *smeared* to make it more representative of what might 
    26 actually be measured experimentally. 
    27  
    28 SasView provides the following three smearing algorithms: 
     22Sometimes the instrumental geometry used to acquire the experimental data has  
     23an impact on the clarity of features in the reduced scattering curve. For  
     24example, peaks or fringes might be slightly broadened. This is known as  
     25*Q resolution smearing*. To compensate for this effect one can either try and  
     26remove the resolution contribution - a process called *desmearing* - or add the  
     27resolution contribution into a model calculation/simulation (which by definition  
     28will be exact) to make it more representative of what has been measured  
     29experimentally - a process called *smearing*. SasView will do the latter. 
     30 
     31Both smearing and desmearing rely on functions to describe the resolution  
     32effect. SasView provides three smearing algorithms: 
    2933 
    3034*  *Slit Smearing* 
    3135*  *Pinhole Smearing* 
    3236*  *2D Smearing* 
     37 
     38SasView also has an option to use Q resolution data (estimated at the time of  
     39data reduction) supplied in a reduced data file: the *Use dQ data* radio button. 
     40 
     41.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     42 
     43dQ Smearing 
     44----------- 
     45  
     46If this option is checked, SasView will assume that the supplied dQ values  
     47represent the standard deviations of Gaussian functions. 
    3348 
    3449.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    r286c757 rc1681ea  
    8282            fn.set_model(self.model) 
    8383            fn.set_index(index_model) 
    84             # Get necessary data from self.data and set the data for smearing 
    85             fn.get_data() 
    8684            # Calculate smeared Intensity 
    8785            #(by Gaussian averaging): DataLoader/smearing2d/Smearer2D() 
     
    8987        else: 
    9088            # calculation w/o smearing 
    91             value = self.model.evalDistribution(\ 
    92                 [self.data.qx_data[index_model], 
    93                  self.data.qy_data[index_model]]) 
     89            value = self.model.evalDistribution([ 
     90                self.data.qx_data[index_model], 
     91                self.data.qy_data[index_model] 
     92            ]) 
    9493        output = numpy.zeros(len(self.data.qx_data)) 
    9594        # output default is None 
     
    198197            output[index] = self.model.evalDistribution(self.data.x[index]) 
    199198 
    200         sq_model = None 
    201         pq_model = None 
     199        sq_values = None 
     200        pq_values = None 
     201        s_model = None 
     202        p_model = None 
    202203        if isinstance(self.model, MultiplicationModel): 
    203             sq_model = numpy.zeros((len(self.data.x))) 
    204             pq_model = numpy.zeros((len(self.data.x))) 
    205             sq_model[index] = self.model.s_model.evalDistribution(self.data.x[index]) 
    206             pq_model[index] = self.model.p_model.evalDistribution(self.data.x[index]) 
     204            s_model = self.model.s_model 
     205            p_model = self.model.p_model 
     206        elif hasattr(self.model, "get_composition_models"): 
     207            p_model, s_model = self.model.get_composition_models() 
     208 
     209        if p_model is not None and s_model is not None: 
     210            sq_values = numpy.zeros((len(self.data.x))) 
     211            pq_values = numpy.zeros((len(self.data.x))) 
     212            sq_values[index] = s_model.evalDistribution(self.data.x[index]) 
     213            pq_values[index] = p_model.evalDistribution(self.data.x[index]) 
    207214 
    208215        elapsed = time.time() - self.starttime 
     
    221228                      unsmeared_data=unsmeared_data, 
    222229                      unsmeared_error=unsmeared_error, 
    223                       pq_model=pq_model, 
    224                       sq_model=sq_model) 
     230                      pq_model=pq_values, 
     231                      sq_model=sq_values) 
    225232 
    226233    def results(self): 
  • src/sas/sasgui/perspectives/fitting/models.py

    r313c5c9 r11b094f  
    2323PLUGIN_LOG = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR, 
    2424                          "plugins.log") 
     25PLUGIN_NAME_BASE = '[plug-in] ' 
    2526 
    2627def get_model_python_path(): 
     
    181182            try: 
    182183                model = load_custom_model(path) 
    183                 model.name = "[plug-in] "+model.name 
     184                model.name = PLUGIN_NAME_BASE + model.name 
    184185                plugins[model.name] = model 
    185186            except Exception: 
     
    324325                    self.plugins.append(plug) 
    325326                    self.model_dictionary[name] = plug 
    326             self.model_combobox.set_list("Customized Models", self.plugins) 
     327            self.model_combobox.set_list("Plugin Models", self.plugins) 
    327328            return self.model_combobox.get_list() 
    328329        else: 
     
    345346            self.model_dictionary[name] = plug 
    346347 
    347         self.model_combobox.reset_list("Customized Models", self.plugins) 
     348        self.model_combobox.reset_list("Plugin Models", self.plugins) 
    348349        return self.model_combobox.get_list() 
    349350 
     
    388389#                                     self.shape_indep_list) 
    389390        self.model_combobox.set_list("Structure Factors", self.struct_list) 
    390         self.model_combobox.set_list("Customized Models", self.plugins) 
     391        self.model_combobox.set_list("Plugin Models", self.plugins) 
    391392        self.model_combobox.set_list("P(Q)*S(Q)", self.multiplication_factor) 
    392393        self.model_combobox.set_list("multiplication", 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    rc8e1996 r71601312  
    2525from lxml import etree 
    2626 
     27from sasmodels import convert 
    2728import sasmodels.weights 
    2829 
     
    3233from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 
    3334from sas.sascalc.dataloader.data_info import Process, Aperture 
     35 
    3436# Information to read/write state as xml 
    3537FITTING_NODE_NAME = 'fitting_plug_in' 
    3638CANSAS_NS = "cansas1d/1.0" 
     39 
     40CUSTOM_MODEL = 'Plugin Models' 
     41CUSTOM_MODEL_OLD = 'Customized Models' 
    3742 
    3843LIST_OF_DATA_ATTRIBUTES = [["is_data", "is_data", "bool"], 
     
    271276        # store value of chisqr 
    272277        self.tcChi = None 
     278        self.version = (1,0,0) 
    273279 
    274280    def clone(self): 
     
    349355        obj.cb1 = copy.deepcopy(self.cb1) 
    350356        obj.smearer = copy.deepcopy(self.smearer) 
     357        obj.version = copy.deepcopy(self.version) 
    351358 
    352359        for name, state in self.saved_states.iteritems(): 
     
    355362            obj.saved_states[copy_name] = copy_state 
    356363        return obj 
     364 
     365    def _old_first_model(self): 
     366        """ 
     367        Handle save states from 4.0.1 and before where the first item in the 
     368        selection boxes of category, formfactor and structurefactor were not 
     369        saved. 
     370        :return: None 
     371        """ 
     372        if self.categorycombobox == CUSTOM_MODEL_OLD: 
     373            self.categorycombobox = CUSTOM_MODEL 
     374        if self.formfactorcombobox == '': 
     375            FIRST_FORM = { 
     376                'Shapes' : 'BCCrystalModel', 
     377                'Uncategorized' : 'LineModel', 
     378                'StructureFactor' : 'HardsphereStructure', 
     379                'Ellipsoid' : 'core_shell_ellipsoid', 
     380                'Lamellae' : 'lamellar', 
     381                'Paracrystal' : 'bcc_paracrystal', 
     382                'Parallelepiped' : 'core_shell_parallelepiped', 
     383                'Shape Independent' : 'be_polyelectrolyte', 
     384                'Sphere' : 'adsorbed_layer', 
     385                'Structure Factor' : 'hardsphere', 
     386                CUSTOM_MODEL : '' 
     387            } 
     388            if self.categorycombobox == '': 
     389                if len(self.parameters) == 3: 
     390                    self.categorycombobox = "Shape-Independent" 
     391                    self.formfactorcombobox = 'PowerLawAbsModel' 
     392                elif len(self.parameters) == 9: 
     393                    self.categorycombobox = 'Cylinder' 
     394                    self.formfactorcombobox = 'barbell' 
     395                else: 
     396                    msg = "Save state does not have enough information to load" 
     397                    msg += " the all of the data." 
     398                    logging.warning(msg=msg) 
     399            else: 
     400                self.formfactorcombobox = FIRST_FORM[self.categorycombobox] 
     401 
     402    @staticmethod 
     403    def param_remap_to_sasmodels_convert(params, is_string=False): 
     404        """ 
     405        Remaps the parameters for sasmodels conversion 
     406 
     407        :param params: list of parameters (likely self.parameters) 
     408        :return: remapped dictionary of parameters 
     409        """ 
     410        p = dict() 
     411        for fittable, name, value, _, uncert, lower, upper, units in params: 
     412            if not value: 
     413                value = numpy.nan 
     414            if not uncert or uncert[1] == '' or uncert[1] == 'None': 
     415                uncert[0] = False 
     416                uncert[1] = numpy.nan 
     417            if not upper or upper[1] == '' or upper[1] == 'None': 
     418                upper[0] = False 
     419                upper[1] = numpy.nan 
     420            if not lower or lower[1] == '' or lower[1] == 'None': 
     421                lower[0] = False 
     422                lower[1] = numpy.nan 
     423            if is_string: 
     424                p[name] = str(value) 
     425            else: 
     426                p[name] = float(value) 
     427            p[name + ".fittable"] = bool(fittable) 
     428            p[name + ".std"] = float(uncert[1]) 
     429            p[name + ".upper"] = float(upper[1]) 
     430            p[name + ".lower"] = float(lower[1]) 
     431            p[name + ".units"] = units 
     432        return p 
     433 
     434    @staticmethod 
     435    def param_remap_from_sasmodels_convert(params): 
     436        """ 
     437        Converts {name : value} map back to [] param list 
     438        :param params: parameter map returned from sasmodels 
     439        :return: None 
     440        """ 
     441        p_map = [] 
     442        for name, info in params.iteritems(): 
     443            if ".fittable" in name or ".std" in name or ".upper" in name or \ 
     444                            ".lower" in name or ".units" in name: 
     445                pass 
     446            else: 
     447                fittable = params.get(name + ".fittable", True) 
     448                std = params.get(name + ".std", '0.0') 
     449                upper = params.get(name + ".upper", 'inf') 
     450                lower = params.get(name + ".lower", '-inf') 
     451                units = params.get(name + ".units") 
     452                if std is not None and std is not numpy.nan: 
     453                    std = [True, str(std)] 
     454                else: 
     455                    std = [False, ''] 
     456                if lower is not None and lower is not numpy.nan: 
     457                    lower = [True, str(lower)] 
     458                else: 
     459                    lower = [True, '-inf'] 
     460                if upper is not None and upper is not numpy.nan: 
     461                    upper = [True, str(upper)] 
     462                else: 
     463                    upper = [True, 'inf'] 
     464                param_list = [bool(fittable), str(name), str(info), 
     465                              "+/-", std, lower, upper, str(units)] 
     466                p_map.append(param_list) 
     467        return p_map 
     468 
     469    def _convert_to_sasmodels(self): 
     470        """ 
     471        Convert parameters to a form usable by sasmodels converter 
     472 
     473        :return: None 
     474        """ 
     475        # Create conversion dictionary to send to sasmodels 
     476        self._old_first_model() 
     477        p = self.param_remap_to_sasmodels_convert(self.parameters) 
     478        structurefactor, params = convert.convert_model(self.structurecombobox, 
     479                                                        p, False, self.version) 
     480        formfactor, params = convert.convert_model(self.formfactorcombobox, 
     481                                                   params, False, self.version) 
     482        if len(self.str_parameters) > 0: 
     483            str_pars = self.param_remap_to_sasmodels_convert( 
     484                self.str_parameters, True) 
     485            formfactor, str_params = convert.convert_model( 
     486                self.formfactorcombobox, str_pars, False, self.version) 
     487            for key, value in str_params.iteritems(): 
     488                params[key] = value 
     489 
     490        if self.formfactorcombobox == 'SphericalSLDModel': 
     491            self.multi_factor += 1 
     492        self.formfactorcombobox = formfactor 
     493        self.structurecombobox = structurefactor 
     494        self.parameters = [] 
     495        self.parameters = self.param_remap_from_sasmodels_convert(params) 
    357496 
    358497    def _repr_helper(self, list, rep): 
     
    682821 
    683822        attr = newdoc.createAttribute("version") 
    684         attr.nodeValue = '1.0' 
     823        import sasview 
     824        attr.nodeValue = sasview.__version__ 
     825        # attr.nodeValue = '1.0' 
    685826        top_element.setAttributeNode(attr) 
    686827 
     
    8751016            raise RuntimeError, msg 
    8761017 
    877         if node.get('version') and node.get('version') == '1.0': 
     1018        if node.get('version'): 
     1019            # Get the version for model conversion purposes 
     1020            self.version = tuple(int(e) for e in 
     1021                                 str.split(node.get('version'), ".")) 
     1022            # The tuple must be at least 3 items long 
     1023            while len(self.version) < 3: 
     1024                ver_list = list(self.version) 
     1025                ver_list.append(0) 
     1026                self.version = tuple(ver_list) 
    8781027 
    8791028            # Get file name 
     
    10331182        if self.cansas: 
    10341183            return self._read_cansas(path) 
    1035  
    1036     def _data2d_to_xml_doc(self, datainfo): 
    1037         """ 
    1038         Create an XML document to contain the content of a Data2D 
    1039  
    1040         :param datainfo: Data2D object 
    1041  
    1042         """ 
    1043         if not issubclass(datainfo.__class__, Data2D): 
    1044             raise RuntimeError, "The cansas writer expects a Data2D instance" 
    1045  
    1046         title = "cansas1d/%s" % self.version 
    1047         title += "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" 
    1048         doc = xml.dom.minidom.Document() 
    1049         main_node = doc.createElement("SASroot") 
    1050         main_node.setAttribute("version", self.version) 
    1051         main_node.setAttribute("xmlns", "cansas1d/%s" % self.version) 
    1052         main_node.setAttribute("xmlns:xsi", 
    1053                                "http://www.w3.org/2001/XMLSchema-instance") 
    1054         main_node.setAttribute("xsi:schemaLocation", title) 
    1055  
    1056         doc.appendChild(main_node) 
    1057  
    1058         entry_node = doc.createElement("SASentry") 
    1059         main_node.appendChild(entry_node) 
    1060  
    1061         write_node(doc, entry_node, "Title", datainfo.title) 
    1062         if datainfo is not None: 
    1063             write_node(doc, entry_node, "data_class", 
    1064                        datainfo.__class__.__name__) 
    1065         for item in datainfo.run: 
    1066             runname = {} 
    1067             if item in datainfo.run_name and \ 
    1068                             len(str(datainfo.run_name[item])) > 1: 
    1069                 runname = {'name': datainfo.run_name[item]} 
    1070             write_node(doc, entry_node, "Run", item, runname) 
    1071         # Data info 
    1072         new_node = doc.createElement("SASdata") 
    1073         entry_node.appendChild(new_node) 
    1074         for item in LIST_OF_DATA_2D_ATTR: 
    1075             element = doc.createElement(item[0]) 
    1076             element.setAttribute(item[0], str(getattr(datainfo, item[1]))) 
    1077             new_node.appendChild(element) 
    1078  
    1079         for item in LIST_OF_DATA_2D_VALUES: 
    1080             root_node = doc.createElement(item[0]) 
    1081             new_node.appendChild(root_node) 
    1082             temp_list = getattr(datainfo, item[1]) 
    1083  
    1084             if temp_list is None or len(temp_list) == 0: 
    1085                 element = doc.createElement(item[0]) 
    1086                 element.appendChild(doc.createTextNode(str(temp_list))) 
    1087                 root_node.appendChild(element) 
    1088             else: 
    1089                 for value in temp_list: 
    1090                     element = doc.createElement(item[0]) 
    1091                     element.setAttribute(item[0], str(value)) 
    1092                     root_node.appendChild(element) 
    1093  
    1094         # Sample info 
    1095         sample = doc.createElement("SASsample") 
    1096         if datainfo.sample.name is not None: 
    1097             sample.setAttribute("name", str(datainfo.sample.name)) 
    1098         entry_node.appendChild(sample) 
    1099         write_node(doc, sample, "ID", str(datainfo.sample.ID)) 
    1100         write_node(doc, sample, "thickness", datainfo.sample.thickness, 
    1101                    {"unit": datainfo.sample.thickness_unit}) 
    1102         write_node(doc, sample, "transmission", datainfo.sample.transmission) 
    1103         write_node(doc, sample, "temperature", datainfo.sample.temperature, 
    1104                    {"unit": datainfo.sample.temperature_unit}) 
    1105  
    1106         for item in datainfo.sample.details: 
    1107             write_node(doc, sample, "details", item) 
    1108  
    1109         pos = doc.createElement("position") 
    1110         written = write_node(doc, pos, "x", datainfo.sample.position.x, 
    1111                              {"unit": datainfo.sample.position_unit}) 
    1112         written = written | write_node(doc, pos, "y", 
    1113                                        datainfo.sample.position.y, 
    1114                                        {"unit": datainfo.sample.position_unit}) 
    1115         written = written | write_node(doc, pos, "z", 
    1116                                        datainfo.sample.position.z, 
    1117                                        {"unit": datainfo.sample.position_unit}) 
    1118         if written: 
    1119             sample.appendChild(pos) 
    1120  
    1121         ori = doc.createElement("orientation") 
    1122         written = write_node(doc, ori, "roll", datainfo.sample.orientation.x, 
    1123                              {"unit": datainfo.sample.orientation_unit}) 
    1124         written = written | write_node(doc, ori, "pitch", 
    1125                                        datainfo.sample.orientation.y, 
    1126                                        {"unit": 
    1127                                             datainfo.sample.orientation_unit}) 
    1128         written = written | write_node(doc, ori, "yaw", 
    1129                                        datainfo.sample.orientation.z, 
    1130                                        {"unit": 
    1131                                             datainfo.sample.orientation_unit}) 
    1132         if written: 
    1133             sample.appendChild(ori) 
    1134  
    1135         # Instrument info 
    1136         instr = doc.createElement("SASinstrument") 
    1137         entry_node.appendChild(instr) 
    1138  
    1139         write_node(doc, instr, "name", datainfo.instrument) 
    1140  
    1141         #   Source 
    1142         source = doc.createElement("SASsource") 
    1143         if datainfo.source.name is not None: 
    1144             source.setAttribute("name", str(datainfo.source.name)) 
    1145         instr.appendChild(source) 
    1146  
    1147         write_node(doc, source, "radiation", datainfo.source.radiation) 
    1148         write_node(doc, source, "beam_shape", datainfo.source.beam_shape) 
    1149         size = doc.createElement("beam_size") 
    1150         if datainfo.source.beam_size_name is not None: 
    1151             size.setAttribute("name", str(datainfo.source.beam_size_name)) 
    1152         written = write_node(doc, size, "x", datainfo.source.beam_size.x, 
    1153                              {"unit": datainfo.source.beam_size_unit}) 
    1154         written = written | write_node(doc, size, "y", 
    1155                                        datainfo.source.beam_size.y, 
    1156                                        {"unit": datainfo.source.beam_size_unit}) 
    1157         written = written | write_node(doc, size, "z", 
    1158                                        datainfo.source.beam_size.z, 
    1159                                        {"unit": datainfo.source.beam_size_unit}) 
    1160         if written: 
    1161             source.appendChild(size) 
    1162  
    1163         write_node(doc, source, "wavelength", datainfo.source.wavelength, 
    1164                    {"unit": datainfo.source.wavelength_unit}) 
    1165         write_node(doc, source, "wavelength_min", 
    1166                    datainfo.source.wavelength_min, 
    1167                    {"unit": datainfo.source.wavelength_min_unit}) 
    1168         write_node(doc, source, "wavelength_max", 
    1169                    datainfo.source.wavelength_max, 
    1170                    {"unit": datainfo.source.wavelength_max_unit}) 
    1171         write_node(doc, source, "wavelength_spread", 
    1172                    datainfo.source.wavelength_spread, 
    1173                    {"unit": datainfo.source.wavelength_spread_unit}) 
    1174  
    1175         #   Collimation 
    1176         for item in datainfo.collimation: 
    1177             coll = doc.createElement("SAScollimation") 
    1178             if item.name is not None: 
    1179                 coll.setAttribute("name", str(item.name)) 
    1180             instr.appendChild(coll) 
    1181  
    1182             write_node(doc, coll, "length", item.length, 
    1183                        {"unit": item.length_unit}) 
    1184  
    1185             for apert in item.aperture: 
    1186                 ap = doc.createElement("aperture") 
    1187                 if apert.name is not None: 
    1188                     ap.setAttribute("name", str(apert.name)) 
    1189                 if apert.type is not None: 
    1190                     ap.setAttribute("type", str(apert.type)) 
    1191                 coll.appendChild(ap) 
    1192  
    1193                 write_node(doc, ap, "distance", apert.distance, 
    1194                            {"unit": apert.distance_unit}) 
    1195  
    1196                 size = doc.createElement("size") 
    1197                 if apert.size_name is not None: 
    1198                     size.setAttribute("name", str(apert.size_name)) 
    1199                 written = write_node(doc, size, "x", apert.size.x, 
    1200                                      {"unit": apert.size_unit}) 
    1201                 written = written | write_node(doc, size, "y", apert.size.y, 
    1202                                                {"unit": apert.size_unit}) 
    1203                 written = written | write_node(doc, size, "z", apert.size.z, 
    1204                                                {"unit": apert.size_unit}) 
    1205                 if written: 
    1206                     ap.appendChild(size) 
    1207  
    1208         #   Detectors 
    1209         for item in datainfo.detector: 
    1210             det = doc.createElement("SASdetector") 
    1211             written = write_node(doc, det, "name", item.name) 
    1212             written = written | write_node(doc, det, "SDD", item.distance, 
    1213                                            {"unit": item.distance_unit}) 
    1214             written = written | write_node(doc, det, "slit_length", 
    1215                                            item.slit_length, 
    1216                                            {"unit": item.slit_length_unit}) 
    1217             if written: 
    1218                 instr.appendChild(det) 
    1219  
    1220             off = doc.createElement("offset") 
    1221             written = write_node(doc, off, "x", item.offset.x, 
    1222                                  {"unit": item.offset_unit}) 
    1223             written = written | write_node(doc, off, "y", item.offset.y, 
    1224                                            {"unit": item.offset_unit}) 
    1225             written = written | write_node(doc, off, "z", item.offset.z, 
    1226                                            {"unit": item.offset_unit}) 
    1227             if written: 
    1228                 det.appendChild(off) 
    1229  
    1230             center = doc.createElement("beam_center") 
    1231             written = write_node(doc, center, "x", item.beam_center.x, 
    1232                                  {"unit": item.beam_center_unit}) 
    1233             written = written | write_node(doc, center, "y", 
    1234                                            item.beam_center.y, 
    1235                                            {"unit": item.beam_center_unit}) 
    1236             written = written | write_node(doc, center, "z", 
    1237                                            item.beam_center.z, 
    1238                                            {"unit": item.beam_center_unit}) 
    1239             if written: 
    1240                 det.appendChild(center) 
    1241  
    1242             pix = doc.createElement("pixel_size") 
    1243             written = write_node(doc, pix, "x", item.pixel_size.x, 
    1244                                  {"unit": item.pixel_size_unit}) 
    1245             written = written | write_node(doc, pix, "y", item.pixel_size.y, 
    1246                                            {"unit": item.pixel_size_unit}) 
    1247             written = written | write_node(doc, pix, "z", item.pixel_size.z, 
    1248                                            {"unit": item.pixel_size_unit}) 
    1249             if written: 
    1250                 det.appendChild(pix) 
    1251  
    1252             ori = doc.createElement("orientation") 
    1253             written = write_node(doc, ori, "roll", item.orientation.x, 
    1254                                  {"unit": item.orientation_unit}) 
    1255             written = written | write_node(doc, ori, "pitch", 
    1256                                            item.orientation.y, 
    1257                                            {"unit": item.orientation_unit}) 
    1258             written = written | write_node(doc, ori, "yaw", item.orientation.z, 
    1259                                            {"unit": item.orientation_unit}) 
    1260             if written: 
    1261                 det.appendChild(ori) 
    1262  
    1263         # Processes info 
    1264         for item in datainfo.process: 
    1265             node = doc.createElement("SASprocess") 
    1266             entry_node.appendChild(node) 
    1267  
    1268             write_node(doc, node, "name", item.name) 
    1269             write_node(doc, node, "date", item.date) 
    1270             write_node(doc, node, "description", item.description) 
    1271             for term in item.term: 
    1272                 value = term['value'] 
    1273                 del term['value'] 
    1274                 write_node(doc, node, "term", value, term) 
    1275             for note in item.notes: 
    1276                 write_node(doc, node, "SASprocessnote", note) 
    1277         # Return the document, and the SASentry node associated with 
    1278         # the data we just wrote 
    1279         return doc, entry_node 
    12801184 
    12811185    def _parse_state(self, entry): 
     
    13541258        """ 
    13551259        node = dom.xpath('ns:data_class', namespaces={'ns': CANSAS_NS}) 
    1356         if not node or node[0].text.lstrip().rstrip() != "Data2D": 
    1357             return_value, _ = self._parse_entry(dom) 
    1358             numpy.trim_zeros(return_value.x) 
    1359             numpy.trim_zeros(return_value.y) 
    1360             numpy.trim_zeros(return_value.dy) 
    1361             size_dx = return_value.dx.size 
    1362             size_dxl = return_value.dxl.size 
    1363             size_dxw = return_value.dxw.size 
    1364             if size_dxl == 0 and size_dxw == 0: 
    1365                 return_value.dxl = None 
    1366                 return_value.dxw = None 
    1367                 numpy.trim_zeros(return_value.dx) 
    1368             elif size_dx == 0: 
    1369                 return_value.dx = None 
    1370                 size_dx = size_dxl 
    1371                 numpy.trim_zeros(return_value.dxl) 
    1372                 numpy.trim_zeros(return_value.dxw) 
    1373  
    1374             return return_value, _ 
    1375  
    1376         # Parse 2D 
    1377         data_info = Data2D() 
    1378  
    1379         # Look up title 
    1380         self._store_content('ns:Title', dom, 'title', data_info) 
    1381  
    1382         # Look up run number 
    1383         nodes = dom.xpath('ns:Run', namespaces={'ns': CANSAS_NS}) 
    1384         for item in nodes: 
    1385             if item.text is not None: 
    1386                 value = item.text.strip() 
    1387                 if len(value) > 0: 
    1388                     data_info.run.append(value) 
    1389                     if item.get('name') is not None: 
    1390                         data_info.run_name[value] = item.get('name') 
    1391  
    1392         # Look up instrument name 
    1393         self._store_content('ns:SASinstrument/ns:name', dom, 
    1394                             'instrument', data_info) 
    1395  
    1396         # Notes 
    1397         note_list = dom.xpath('ns:SASnote', namespaces={'ns': CANSAS_NS}) 
    1398         for note in note_list: 
    1399             try: 
    1400                 if note.text is not None: 
    1401                     note_value = note.text.strip() 
    1402                     if len(note_value) > 0: 
    1403                         data_info.notes.append(note_value) 
    1404             except Exception: 
    1405                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1406                 err_mess += "  %s" % sys.exc_value 
    1407                 self.errors.append(err_mess) 
    1408                 logging.error(err_mess) 
    1409  
    1410         # Sample info ################### 
    1411         entry = get_content('ns:SASsample', dom) 
    1412         if entry is not None: 
    1413             data_info.sample.name = entry.get('name') 
    1414  
    1415         self._store_content('ns:SASsample/ns:ID', dom, 'ID', data_info.sample) 
    1416         self._store_float('ns:SASsample/ns:thickness', dom, 'thickness', 
    1417                           data_info.sample) 
    1418         self._store_float('ns:SASsample/ns:transmission', dom, 'transmission', 
    1419                           data_info.sample) 
    1420         self._store_float('ns:SASsample/ns:temperature', dom, 'temperature', 
    1421                           data_info.sample) 
    1422  
    1423         nodes = dom.xpath('ns:SASsample/ns:details', 
    1424                           namespaces={'ns': CANSAS_NS}) 
    1425         for item in nodes: 
    1426             try: 
    1427                 if item.text is not None: 
    1428                     detail_value = item.text.strip() 
    1429                     if len(detail_value) > 0: 
    1430                         data_info.sample.details.append(detail_value) 
    1431             except Exception: 
    1432                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1433                 err_mess += "  %s" % sys.exc_value 
    1434                 self.errors.append(err_mess) 
    1435                 logging.error(err_mess) 
    1436  
    1437         # Position (as a vector) 
    1438         self._store_float('ns:SASsample/ns:position/ns:x', dom, 'position.x', 
    1439                           data_info.sample) 
    1440         self._store_float('ns:SASsample/ns:position/ns:y', dom, 'position.y', 
    1441                           data_info.sample) 
    1442         self._store_float('ns:SASsample/ns:position/ns:z', dom, 'position.z', 
    1443                           data_info.sample) 
    1444  
    1445         # Orientation (as a vector) 
    1446         self._store_float('ns:SASsample/ns:orientation/ns:roll', 
    1447                           dom, 'orientation.x', data_info.sample) 
    1448         self._store_float('ns:SASsample/ns:orientation/ns:pitch', 
    1449                           dom, 'orientation.y', data_info.sample) 
    1450         self._store_float('ns:SASsample/ns:orientation/ns:yaw', 
    1451                           dom, 'orientation.z', data_info.sample) 
    1452  
    1453         # Source info ################### 
    1454         entry = get_content('ns:SASinstrument/ns:SASsource', dom) 
    1455         if entry is not None: 
    1456             data_info.source.name = entry.get('name') 
    1457  
    1458         self._store_content('ns:SASinstrument/ns:SASsource/ns:radiation', 
    1459                             dom, 'radiation', data_info.source) 
    1460         self._store_content('ns:SASinstrument/ns:SASsource/ns:beam_shape', 
    1461                             dom, 'beam_shape', data_info.source) 
    1462         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength', 
    1463                           dom, 'wavelength', data_info.source) 
    1464         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_min', 
    1465                           dom, 'wavelength_min', data_info.source) 
    1466         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_max', 
    1467                           dom, 'wavelength_max', data_info.source) 
    1468         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread', 
    1469                           dom, 'wavelength_spread', data_info.source) 
    1470  
    1471         # Beam size (as a vector) 
    1472         entry = get_content('ns:SASinstrument/ns:SASsource/ns:beam_size', dom) 
    1473         if entry is not None: 
    1474             data_info.source.beam_size_name = entry.get('name') 
    1475  
    1476         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x', 
    1477                           dom, 'beam_size.x', data_info.source) 
    1478         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:y', 
    1479                           dom, 'beam_size.y', data_info.source) 
    1480         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z', 
    1481                           dom, 'beam_size.z', data_info.source) 
    1482  
    1483         # Collimation info ################### 
    1484         nodes = dom.xpath('ns:SASinstrument/ns:SAScollimation', 
    1485                           namespaces={'ns': CANSAS_NS}) 
    1486         for item in nodes: 
    1487             collim = Collimation() 
    1488             if item.get('name') is not None: 
    1489                 collim.name = item.get('name') 
    1490             self._store_float('ns:length', item, 'length', collim) 
    1491  
    1492             # Look for apertures 
    1493             apert_list = item.xpath('ns:aperture', 
    1494                                     namespaces={'ns': CANSAS_NS}) 
    1495             for apert in apert_list: 
    1496                 aperture = Aperture() 
    1497  
    1498                 # Get the name and type of the aperture 
    1499                 aperture.name = apert.get('name') 
    1500                 aperture.type = apert.get('type') 
    1501  
    1502                 self._store_float('ns:distance', apert, 'distance', aperture) 
    1503  
    1504                 entry = get_content('ns:size', apert) 
    1505                 if entry is not None: 
    1506                     aperture.size_name = entry.get('name') 
    1507  
    1508                 self._store_float('ns:size/ns:x', apert, 'size.x', aperture) 
    1509                 self._store_float('ns:size/ns:y', apert, 'size.y', aperture) 
    1510                 self._store_float('ns:size/ns:z', apert, 'size.z', aperture) 
    1511  
    1512                 collim.aperture.append(aperture) 
    1513  
    1514             data_info.collimation.append(collim) 
    1515  
    1516         # Detector info ###################### 
    1517         nodes = dom.xpath('ns:SASinstrument/ns:SASdetector', 
    1518                           namespaces={'ns': CANSAS_NS}) 
    1519         for item in nodes: 
    1520  
    1521             detector = Detector() 
    1522  
    1523             self._store_content('ns:name', item, 'name', detector) 
    1524             self._store_float('ns:SDD', item, 'distance', detector) 
    1525  
    1526             # Detector offset (as a vector) 
    1527             self._store_float('ns:offset/ns:x', item, 'offset.x', detector) 
    1528             self._store_float('ns:offset/ns:y', item, 'offset.y', detector) 
    1529             self._store_float('ns:offset/ns:z', item, 'offset.z', detector) 
    1530  
    1531             # Detector orientation (as a vector) 
    1532             self._store_float('ns:orientation/ns:roll', item, 
    1533                               'orientation.x', detector) 
    1534             self._store_float('ns:orientation/ns:pitch', item, 
    1535                               'orientation.y', detector) 
    1536             self._store_float('ns:orientation/ns:yaw', item, 
    1537                               'orientation.z', detector) 
    1538  
    1539             # Beam center (as a vector) 
    1540             self._store_float('ns:beam_center/ns:x', item, 
    1541                               'beam_center.x', detector) 
    1542             self._store_float('ns:beam_center/ns:y', item, 
    1543                               'beam_center.y', detector) 
    1544             self._store_float('ns:beam_center/ns:z', item, 
    1545                               'beam_center.z', detector) 
    1546  
    1547             # Pixel size (as a vector) 
    1548             self._store_float('ns:pixel_size/ns:x', item, 
    1549                               'pixel_size.x', detector) 
    1550             self._store_float('ns:pixel_size/ns:y', item, 
    1551                               'pixel_size.y', detector) 
    1552             self._store_float('ns:pixel_size/ns:z', item, 
    1553                               'pixel_size.z', detector) 
    1554  
    1555             self._store_float('ns:slit_length', item, 'slit_length', detector) 
    1556  
    1557             data_info.detector.append(detector) 
    1558  
    1559         # Processes info ###################### 
    1560         nodes = dom.xpath('ns:SASprocess', namespaces={'ns': CANSAS_NS}) 
    1561         for item in nodes: 
    1562             process = Process() 
    1563             self._store_content('ns:name', item, 'name', process) 
    1564             self._store_content('ns:date', item, 'date', process) 
    1565             self._store_content('ns:description', item, 'description', process) 
    1566  
    1567             term_list = item.xpath('ns:term', namespaces={'ns': CANSAS_NS}) 
    1568             for term in term_list: 
    1569                 try: 
    1570                     term_attr = {} 
    1571                     for attr in term.keys(): 
    1572                         term_attr[attr] = term.get(attr).strip() 
    1573                     if term.text is not None: 
    1574                         term_attr['value'] = term.text.strip() 
    1575                         process.term.append(term_attr) 
    1576                 except: 
    1577                     err_mess = "cansas_reader.read: error processing " 
    1578                     err_mess += "entry notes\n  %s" % sys.exc_value 
    1579                     self.errors.append(err_mess) 
    1580                     logging.error(err_mess) 
    1581  
    1582             note_list = item.xpath('ns:SASprocessnote', 
    1583                                    namespaces={'ns': CANSAS_NS}) 
    1584             for note in note_list: 
    1585                 if note.text is not None: 
    1586                     process.notes.append(note.text.strip()) 
    1587  
    1588             data_info.process.append(process) 
    1589  
    1590         # Data info ###################### 
    1591         nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 
    1592         if len(nodes) > 1: 
    1593             raise RuntimeError, "CanSAS reader is not compatible with" + \ 
    1594                                 " multiple SASdata entries" 
    1595  
    1596         for entry in nodes: 
    1597             for item in LIST_OF_DATA_2D_ATTR: 
    1598                 # get node 
    1599                 node = get_content('ns:%s' % item[0], entry) 
    1600                 setattr(data_info, item[1], parse_entry_helper(node, item)) 
    1601  
    1602             for item in LIST_OF_DATA_2D_VALUES: 
    1603                 field = get_content('ns:%s' % item[0], entry) 
    1604                 value_list = [] 
    1605                 if field is not None: 
    1606                     value_list = \ 
    1607                         [parse_entry_helper(node, item) for node in field] 
    1608                 if len(value_list) < 2: 
    1609                     setattr(data_info, item[0], None) 
    1610                 else: 
    1611                     setattr(data_info, item[0], numpy.array(value_list)) 
    1612  
    1613         return data_info 
     1260        return_value, _ = self._parse_entry(dom) 
     1261        return return_value, _ 
    16141262 
    16151263    def _read_cansas(self, path): 
     
    16921340                        name = original_fname 
    16931341                    state.data.group_id = name 
     1342                    state.version = fitstate.version 
    16941343                    # store state in fitting 
    16951344                    self.call_back(state=state, 
     
    17451394            state.data.run_name[0] = state.data.name 
    17461395 
    1747         if issubclass(state.data.__class__, 
    1748                       sas.sascalc.dataloader.data_info.Data1D): 
    1749             data = state.data 
    1750             doc, sasentry = self._to_xml_doc(data) 
    1751         else: 
    1752             data = state.data 
    1753             doc, sasentry = self._data2d_to_xml_doc(data) 
     1396        data = state.data 
     1397        doc, sasentry = self._to_xml_doc(data) 
    17541398 
    17551399        if state is not None: 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rcb93b40 rdb5294e  
    423423                    for item in DEFAULT_STATE: 
    424424                        input_field = get_content('ns:%s' % item, entry) 
    425                         val = str(input_field.text.strip()) 
     425                        if input_field.text is not None: 
     426                            val = str(input_field.text.strip()) 
     427                        else: 
     428                            val = '' 
    426429                        if input_field is not None: 
    427430                            temp_state[item] = val 
     
    433436                for item in DEFAULT_STATE: 
    434437                    input_field = get_content('ns:%s' % item, entry) 
    435                     val = str(input_field.text.strip()) 
     438                    if input_field.text is not None: 
     439                        val = str(input_field.text.strip()) 
     440                    else: 
     441                        val = '' 
    436442                    if input_field is not None: 
    437443                        self.set_saved_state(name=item, value=val) 
  • src/sas/sasgui/perspectives/invariant/media/invariant_help.rst

    rb64b87c r484141c  
    116116Academic Press, New York, 1982 
    117117 
    118 http://physchem.kfunigraz.ac.at/sm/ 
     118http://web.archive.org/web/20110824105537/http://physchem.kfunigraz.ac.at/sm/Service/Glatter_Kratky_SAXS_1982.zip 
    119119 
    120120.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
  • src/sas/sasgui/perspectives/pr/media/pr_help.rst

    r0391dae r1221196  
    1010----------- 
    1111 
    12 This tool calculates a real-space distance distribution function, *P(r)*, using  
    13 the inversion approach (Moore, 1908). 
     12This tool calculates a real-space distance distribution function, *P(r)*, using 
     13the inversion approach (Moore, 1980). 
    1414 
    1515*P(r)* is set to be equal to an expansion of base functions of the type 
     
    2424 
    2525  \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 
    26    
     26 
    2727 
    2828where $I_{meas}(Q_i)$ is the measured scattering intensity and $I_{th}(Q_i)$ is 
    29 the prediction from the Fourier transform of the *P(r)* expansion.  
     29the prediction from the Fourier transform of the *P(r)* expansion. 
    3030 
    31 The $Reg\_term$ term is a regularization term set to the second derivative  
     31The $Reg\_term$ term is a regularization term set to the second derivative 
    3232$d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 
    3333 
     
    4040 
    4141*  *Number of terms*: the number of base functions in the P(r) expansion. 
    42     
     42 
    4343*  *Regularization constant*: a multiplicative constant to set the size of 
    4444   the regularization term. 
  • src/sas/sasgui/plottools/PlotPanel.py

    r1a8e2e8e r198fa76  
    452452        """ 
    453453        self.cusor_line(event) 
    454         if self.gotLegend == 1: 
     454        if self.gotLegend == 1 and self.leftdown: 
    455455            self._on_legend_motion(event) 
    456456            return 
  • src/sas/sasgui/plottools/plottables.py

    r8abd96d ra9f579c  
    212212                self.color += plottable.colors() 
    213213                self.plottables[plottable] = self.color 
     214                plottable.custom_color = self.color 
    214215 
    215216    def changed(self): 
     
    10221023    """ 
    10231024 
    1024     def __init__(self, x, y, dx=None, dy=None): 
     1025    def __init__(self, x, y, dx=None, dy=None, lam=None, dlam=None): 
    10251026        """ 
    10261027        Draw points specified by x[i],y[i] in the current color/symbol. 
     
    10361037        self.x = x 
    10371038        self.y = y 
     1039        self.lam = lam 
    10381040        self.dx = dx 
    10391041        self.dy = dy 
     1042        self.dlam = dlam 
    10401043        self.source = None 
    10411044        self.detector = None 
  • src/sas/sasgui/guiframe/data_panel.py

    rc8e1996 rcb1e9a5  
    520520        Add a listcrtl in the panel 
    521521        """ 
    522         tree_ctrl_label = wx.StaticText(self, -1, "Data") 
    523         tree_ctrl_label.SetForegroundColour('blue') 
    524         self.tree_ctrl = DataTreeCtrl(parent=self, style=wx.SUNKEN_BORDER) 
     522        # Add splitter 
     523        w, h = self.parent.GetSize() 
     524        splitter = wx.SplitterWindow(self) 
     525        splitter.SetMinimumPaneSize(50) 
     526        splitter.SetSashGravity(1.0) 
     527 
     528        file_sizer = wx.BoxSizer(wx.VERTICAL) 
     529        file_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 
     530        theory_sizer = wx.BoxSizer(wx.VERTICAL) 
     531        theory_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 
     532 
     533        self.tree_ctrl = DataTreeCtrl(parent=splitter, style=wx.SUNKEN_BORDER) 
     534 
    525535        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_CHECKING, self.on_check_item) 
    526536        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_MENU, self.on_right_click_data) 
     
    557567        wx.EVT_MENU(self, self.editmask_id, self.on_edit_data) 
    558568 
    559         tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory") 
    560         tree_ctrl_theory_label.SetForegroundColour('blue') 
    561         self.tree_ctrl_theory = DataTreeCtrl(parent=self, 
     569        self.tree_ctrl_theory = DataTreeCtrl(parent=splitter, 
    562570                                             style=wx.SUNKEN_BORDER) 
    563571        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING, 
     
    565573        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU, 
    566574                                   self.on_right_click_theory) 
    567         self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10) 
    568         self.sizer1.Add(self.tree_ctrl, 1, wx.EXPAND | wx.ALL, 10) 
    569         self.sizer1.Add(tree_ctrl_theory_label, 0,  wx.LEFT, 10) 
    570         self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND | wx.ALL, 10) 
     575        self.tree_ctrl.InsertItem(self.tree_ctrl.root, -1, " Data") 
     576        self.tree_ctrl_theory.InsertItem(self.tree_ctrl_theory.root, 
     577                                         -1, " Theory") 
     578        splitter.SplitHorizontally(self.tree_ctrl, self.tree_ctrl_theory) 
     579        self.sizer1.Add(splitter, 1, wx.EXPAND | wx.ALL, 10) 
    571580 
    572581    def on_right_click_theory(self, event): 
Note: See TracChangeset for help on using the changeset viewer.