Changes in / [c79304b:a235f715] in sasview


Ignore:
Files:
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • docs/sphinx-docs/source/user/sasgui/perspectives/invariant/invariant_help.rst

    r9bbc074 r5f5c596  
    44.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
    55 
    6 Invariant Calculation 
    7 ===================== 
     6Invariant Calculation Perspective 
     7================================= 
    88 
    99Description 
     
    1919.. image:: image001.gif 
    2020 
    21 where *g = q* for pinhole geometry (SAS) and *g = q*\ :sub:`v` (the slit height) for   
     21where *g = Q* for pinhole geometry (SAS) and *g = Qv* (the slit height) for   
    2222slit geometry (USAS). 
    2323 
     
    4545.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    4646 
    47 Using invariant analysis 
    48 ------------------------ 
     47Using the perspective 
     48--------------------- 
    4949 
    50501) Select *Invariant* from the *Analysis* menu on the SasView toolbar. 
     
    5353 
    54543) Select a dataset and use the *Send To* button on the *Data Explorer* to load  
    55    the dataset into the *Invariant* panel. 
     55   the dataset into the *Invariant* perspective. 
    5656 
    57 4) Use the *Customised Input* boxes on the *Invariant* panel to subtract  
     574) Use the *Customised Input* boxes on the *Invariant* perspective to subtract  
    5858   any background, specify the contrast (i.e. difference in SLDs - this must be  
    5959   specified for the eventual value of Q*\  to be on an absolute scale), or to  
     
    7373 
    74748) If the value of Q*\  calculated with the extrapolated regions is invalid, a  
    75    red warning will appear at the top of the *Invariant* panel. 
     75   red warning will appear at the top of the *Invariant* perspective panel. 
    7676 
    7777   The details of the calculation are available by clicking the *Details*  
  • docs/sphinx-docs/source/user/user.rst

    r20a3c55 r5a71761  
    1414          
    1515   Working with SasView <working> 
    16  
    17    Computations with GPU <gpu_computations> 
  • sasview/local_config.py

    r9bbc074 rd85c194  
    8282_corner_image = os.path.join(icon_path, "angles_flat.png") 
    8383_welcome_image = os.path.join(icon_path, "SVwelcome.png") 
    84 _copyright = "(c) 2009 - 2016, UTK, UMD, NIST, ORNL, ISIS, ESS and ILL" 
     84_copyright = "(c) 2009 - 2013, UTK, UMD, NIST, ORNL, ISIS, ESS and ILL" 
    8585 
    8686 
  • sasview/setup_exe.py

    r9bbc074 r525aaa2  
    165165        self.version = local_config.__version__ 
    166166        self.company_name = "SasView.org" 
    167         self.copyright = "copyright 2009 - 2016" 
     167        self.copyright = "copyright 2009 - 2013" 
    168168        self.name = "SasView" 
    169169         
  • src/sas/sasgui/guiframe/utils.py

    ra0373d5 rd85c194  
    4646    return flag 
    4747 
    48  
    49 def check_int(item): 
    50     """ 
    51     :param item: txtcrtl containing a value 
    52     """ 
    53     flag = True 
    54     try: 
    55         mini = int(item.GetValue()) 
    56         item.SetBackgroundColour(wx.WHITE) 
    57         item.Refresh() 
    58     except: 
    59         flag = False 
    60         item.SetBackgroundColour("pink") 
    61         item.Refresh() 
    62     return flag 
    63  
    64  
     48     
    6549class PanelMenu(wx.Menu): 
    6650    """ 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r6c382da ree4b3cb  
    1717from wx.lib.scrolledpanel import ScrolledPanel 
    1818 
    19 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
    20  
     19import sasmodels.sasview_model 
    2120from sas.sasgui.guiframe.panel_base import PanelBase 
    22 from sas.sasgui.guiframe.utils import format_number, check_float, IdList, check_int 
     21from sas.sasgui.guiframe.utils import format_number, check_float, IdList 
    2322from sas.sasgui.guiframe.events import PanelOnFocusEvent 
    2423from sas.sasgui.guiframe.events import StatusEvent 
     
    627626        self.disp_help_bt.Bind(wx.EVT_BUTTON, self.on_pd_help_clicked, 
    628627                               id=self.disp_help_bt.GetId()) 
    629         self.disp_help_bt.SetToolTipString("Help for polydispersion.") 
     628        self.disp_help_bt.SetToolTipString("Helps for Polydispersion.") 
    630629 
    631630        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, 
     
    933932        if len(self._disp_obj_dict) > 0: 
    934933            for k, v in self._disp_obj_dict.iteritems(): 
    935                 self.state._disp_obj_dict[k] = v.type 
     934                self.state._disp_obj_dict[k] = v 
    936935 
    937936            self.state.values = copy.deepcopy(self.values) 
     
    10101009            if len(self._disp_obj_dict) > 0: 
    10111010                for k, v in self._disp_obj_dict.iteritems(): 
    1012                     self.state._disp_obj_dict[k] = v.type 
     1011                    self.state._disp_obj_dict[k] = v 
    10131012 
    10141013            self.state.values = copy.deepcopy(self.values) 
     
    11241123                                                    state.disp_cb_dict[item]) 
    11251124                        # Create the dispersion objects 
    1126                         disp_model = POLYDISPERSITY_MODELS['array']() 
     1125                        from sas.models.dispersion_models import ArrayDispersion 
     1126                        disp_model = ArrayDispersion() 
    11271127                        if hasattr(state, "values") and \ 
    11281128                                 self.disp_cb_dict[item].GetValue() == True: 
     
    13791379        self.weights = copy.deepcopy(state.weights) 
    13801380 
    1381         for key, disp_type in state._disp_obj_dict.iteritems(): 
    1382             #disp_model = disp 
    1383             disp_model = POLYDISPERSITY_MODELS[disp_type]() 
     1381        for key, disp in state._disp_obj_dict.iteritems(): 
     1382            # From saved file, disp_model can not be sent in model obj. 
     1383            # it will be sent as a string here, then converted to model object. 
     1384            if disp.__class__.__name__ == 'str': 
     1385                disp_model = None 
     1386                com_str = "from sasmodels.weights " 
     1387                com_str += "import %s as disp_func \ndisp_model = disp_func()" 
     1388                exec com_str % disp 
     1389            else: 
     1390                disp_model = disp 
    13841391            self._disp_obj_dict[key] = disp_model 
    13851392            param_name = key.split('.')[0] 
     
    22742281                continue 
    22752282 
    2276             value_ctrl = item[2] 
    2277             if not value_ctrl.IsEnabled(): 
    2278                 # ArrayDispersion disables PD, Min, Max, Npts, Nsigs 
     2283            name = str(item[1]) 
     2284            if name.endswith(".npts") or name.endswith(".nsigmas"): 
    22792285                continue 
    22802286 
    2281             name = item[1] 
     2287            # Check that min, max and value are floats 
     2288            value_ctrl, min_ctrl, max_ctrl = item[2], item[5], item[6] 
     2289            min_str = min_ctrl.GetValue().strip() 
     2290            max_str = max_ctrl.GetValue().strip() 
    22822291            value_str = value_ctrl.GetValue().strip() 
    2283             if name.endswith(".npts"): 
    2284                 validity = check_int(value_ctrl) 
    2285                 if not validity: 
    2286                     continue 
    2287                 value = int(value_str) 
    2288  
    2289             elif name.endswith(".nsigmas"): 
    2290                 validity = check_float(value_ctrl) 
    2291                 if not validity: 
    2292                     continue 
    2293                 value = float(value_str) 
    2294  
    2295             else:  # value or polydispersity 
    2296  
    2297                 # Check that min, max and value are floats 
    2298                 min_ctrl, max_ctrl = item[5], item[6] 
    2299                 min_str = min_ctrl.GetValue().strip() 
    2300                 max_str = max_ctrl.GetValue().strip() 
    2301                 validity = check_float(value_ctrl) 
    2302                 if min_str != "": 
    2303                     validity = validity and check_float(min_ctrl) 
    2304                 if max_str != "": 
    2305                     validity = validity and check_float(max_ctrl) 
    2306                 if not validity: 
    2307                     continue 
    2308  
    2309                 # Check that min is less than max 
    2310                 low = -numpy.inf if min_str == "" else float(min_str) 
    2311                 high = numpy.inf if max_str == "" else float(max_str) 
    2312                 if high < low: 
    2313                     min_ctrl.SetBackgroundColour("pink") 
    2314                     min_ctrl.Refresh() 
    2315                     max_ctrl.SetBackgroundColour("pink") 
    2316                     max_ctrl.Refresh() 
    2317                     #msg = "Invalid fit range for %s: min must be smaller than max"%name 
    2318                     #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    2319                     continue 
    2320  
    2321                 # Force value between min and max 
    2322                 value = float(value_str) 
    2323                 if value < low: 
    2324                     value = low 
    2325                     value_ctrl.SetValue(format_number(value)) 
    2326                 elif value > high: 
    2327                     value = high 
    2328                     value_ctrl.SetValue(format_number(value)) 
    2329  
    2330                 if name not in self.model.details.keys(): 
    2331                     self.model.details[name] = ["", None, None] 
    2332                 old_low, old_high = self.model.details[name][1:3] 
    2333                 if old_low != low or old_high != high: 
    2334                     # The configuration has changed but it won't change the 
    2335                     # computed curve so no need to set is_modified to True 
    2336                     #is_modified = True 
    2337                     self.model.details[name][1:3] = low, high 
     2292            validity = check_float(value_ctrl) 
     2293            if min_str != "": 
     2294                validity = validity and check_float(min_ctrl) 
     2295            if max_str != "": 
     2296                validity = validity and check_float(max_ctrl) 
     2297            if not validity: 
     2298                continue 
     2299 
     2300            # Check that min is less than max 
     2301            low = -numpy.inf if min_str == "" else float(min_str) 
     2302            high = numpy.inf if max_str == "" else float(max_str) 
     2303            if high < low: 
     2304                min_ctrl.SetBackgroundColour("pink") 
     2305                min_ctrl.Refresh() 
     2306                max_ctrl.SetBackgroundColour("pink") 
     2307                max_ctrl.Refresh() 
     2308                #msg = "Invalid fit range for %s: min must be smaller than max"%name 
     2309                #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2310                continue 
     2311 
     2312            # Force value between min and max 
     2313            value = float(value_str) 
     2314            if value < low: 
     2315                value = low 
     2316                value_ctrl.SetValue(format_number(value)) 
     2317            elif value > high: 
     2318                value = high 
     2319                value_ctrl.SetValue(format_number(value)) 
    23382320 
    23392321            # Update value in model if it has changed 
     
    23412323                self.model.setParam(name, value) 
    23422324                is_modified = True 
     2325 
     2326            if name not in self.model.details.keys(): 
     2327                self.model.details[name] = ["", None, None] 
     2328            old_low, old_high = self.model.details[name][1:3] 
     2329            if old_low != low or old_high != high: 
     2330                # The configuration has changed but it won't change the 
     2331                # computed curve so no need to set is_modified to True 
     2332                #is_modified = True 
     2333                self.model.details[name][1:3] = low, high 
    23432334 
    23442335        return is_modified 
     
    25132504                self._disp_obj_dict[name1] = disp_model 
    25142505                self.model.set_dispersion(param_name, disp_model) 
    2515                 self.state._disp_obj_dict[name1] = disp_model.type 
     2506                self.state._disp_obj_dict[name1] = disp_model 
    25162507 
    25172508                value1 = str(format_number(self.model.getParam(name1), True)) 
     
    25362527                        item[0].Enable() 
    25372528                        item[2].Enable() 
    2538                         item[3].Show(True) 
    2539                         item[4].Show(True) 
    25402529                        item[5].Enable() 
    25412530                        item[6].Enable() 
     
    26302619        self._disp_obj_dict[name] = disp 
    26312620        self.model.set_dispersion(name.split('.')[0], disp) 
    2632         self.state._disp_obj_dict[name] = disp.type 
     2621        self.state._disp_obj_dict[name] = disp 
    26332622        self.values[name] = values 
    26342623        self.weights[name] = weights 
     
    26982687        :param disp_function: dispersion distr. function 
    26992688        """ 
     2689        # List of the poly_model name in the combobox 
     2690        list = ["RectangleDispersion", "ArrayDispersion", 
     2691                "LogNormalDispersion", "GaussianDispersion", 
     2692                "SchulzDispersion"] 
     2693 
    27002694        # Find the selection 
    2701         if disp_func is not None: 
    2702             try: 
    2703                 return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 
    2704             except ValueError: 
    2705                 pass  # Fall through to default class 
    2706         return POLYDISPERSITY_MODELS.keys().index('gaussian') 
     2695        try: 
     2696            selection = list.index(disp_func.__class__.__name__) 
     2697            return selection 
     2698        except: 
     2699            return 3 
    27072700 
    27082701    def on_reset_clicked(self, event): 
     
    32913284                    pd = content[name][1] 
    32923285                    if name.count('.') > 0: 
    3293                         # If this is parameter.width, then pd may be a floating 
    3294                         # point value or it may be an array distribution. 
    3295                         # Nothing to do for parameter.npts or parameter.nsigmas. 
    32963286                        try: 
    32973287                            float(pd) 
    3298                             if name.endswith('.npts'): 
    3299                                 pd = int(pd) 
    3300                         except Exception: 
     3288                        except: 
    33013289                            #continue 
    33023290                            if not pd and pd != '': 
     
    33063294                        # Only array func has pd == '' case. 
    33073295                        item[2].Enable(False) 
    3308                     else: 
    3309                         item[2].Enable(True) 
    33103296                    if item[2].__class__.__name__ == "ComboBox": 
    33113297                        if content[name][1] in self.model.fun_list: 
     
    33343320                        pd = value[0] 
    33353321                        if name.count('.') > 0: 
    3336                             # If this is parameter.width, then pd may be a floating 
    3337                             # point value or it may be an array distribution. 
    3338                             # Nothing to do for parameter.npts or parameter.nsigmas. 
    33393322                            try: 
    33403323                                pd = float(pd) 
    3341                                 if name.endswith('.npts'): 
    3342                                     pd = int(pd) 
    33433324                            except: 
    33443325                                #continue 
     
    33493330                            # Only array func has pd == '' case. 
    33503331                            item[2].Enable(False) 
    3351                         else: 
    3352                             item[2].Enable(True) 
    33533332                        if item[2].__class__.__name__ == "ComboBox": 
    33543333                            if value[0] in self.model.fun_list: 
     
    33703349        Helps get paste for poly function 
    33713350 
    3372         *item* is the parameter name 
    3373  
    3374         *value* depends on which parameter is being processed, and whether it 
    3375         has array polydispersity. 
    3376  
    3377         For parameters without array polydispersity: 
    3378  
    3379             parameter => ['FLOAT', ''] 
    3380             parameter.width => ['FLOAT', 'DISTRIBUTION', ''] 
    3381             parameter.npts => ['FLOAT', ''] 
    3382             parameter.nsigmas => ['FLOAT', ''] 
    3383  
    3384         For parameters with array polydispersity: 
    3385  
    3386             parameter => ['FLOAT', ''] 
    3387             parameter.width => ['FILENAME', 'array', [x1, ...], [w1, ...]] 
    3388             parameter.npts => ['FLOAT', ''] 
    3389             parameter.nsigmas => ['FLOAT', ''] 
    3390         """ 
    3391         # Do nothing if not setting polydispersity 
    3392         if len(value[1]) == 0: 
    3393             return 
    3394  
    3395         try: 
    3396             name = item[7].Name 
    3397             param_name = name.split('.')[0] 
    3398             item[7].SetValue(value[1]) 
    3399             selection = item[7].GetCurrentSelection() 
    3400             dispersity = item[7].GetClientData(selection) 
    3401             disp_model = dispersity() 
    3402  
    3403             if value[1] == 'array': 
    3404                 pd_vals = numpy.array(value[2]) 
    3405                 pd_weights = numpy.array(value[3]) 
    3406                 if len(pd_vals) == 0 or len(pd_vals) != len(pd_weights): 
    3407                     msg = ("bad array distribution parameters for %s" 
    3408                            % param_name) 
    3409                     raise ValueError(msg) 
    3410                 self._set_disp_cb(True, item=item) 
    3411                 self._set_array_disp_model(name=name, 
    3412                                            disp=disp_model, 
    3413                                            values=pd_vals, 
    3414                                            weights=pd_weights) 
    3415             else: 
    3416                 self._set_disp_cb(False, item=item) 
    3417                 self._disp_obj_dict[name] = disp_model 
    3418                 self.model.set_dispersion(param_name, disp_model) 
    3419                 self.state._disp_obj_dict[name] = disp_model.type 
    3420                 # TODO: It's not an array, why update values and weights? 
    3421                 self.model._persistency_dict[param_name] = \ 
    3422                     [self.values, self.weights] 
    3423                 self.state.values = self.values 
    3424                 self.state.weights = self.weights 
    3425  
    3426         except Exception: 
    3427             logging.error(traceback.format_exc()) 
    3428             print "Error in BasePage._paste_poly_help: %s" % \ 
    3429                                     sys.exc_info()[1] 
    3430  
    3431     def _set_disp_cb(self, isarray, item): 
     3351        :param item: Gui param items 
     3352        :param value: the values for parameter ctrols 
     3353        """ 
     3354        is_array = False 
     3355        if len(value[1]) > 0: 
     3356            # Only for dispersion func.s 
     3357            try: 
     3358                item[7].SetValue(value[1]) 
     3359                selection = item[7].GetCurrentSelection() 
     3360                name = item[7].Name 
     3361                param_name = name.split('.')[0] 
     3362                dispersity = item[7].GetClientData(selection) 
     3363                disp_model = dispersity() 
     3364                # Only for array disp 
     3365                try: 
     3366                    pd_vals = numpy.array(value[2]) 
     3367                    pd_weights = numpy.array(value[3]) 
     3368                    if len(pd_vals) > 0 and len(pd_vals) > 0: 
     3369                        if len(pd_vals) == len(pd_weights): 
     3370                            self._set_disp_array_cb(item=item) 
     3371                            self._set_array_disp_model(name=name, 
     3372                                                       disp=disp_model, 
     3373                                                       values=pd_vals, 
     3374                                                       weights=pd_weights) 
     3375                            is_array = True 
     3376                except Exception: 
     3377                    logging.error(traceback.format_exc()) 
     3378                if not is_array: 
     3379                    self._disp_obj_dict[name] = disp_model 
     3380                    self.model.set_dispersion(name, 
     3381                                              disp_model) 
     3382                    self.state._disp_obj_dict[name] = \ 
     3383                                              disp_model 
     3384                    self.model.set_dispersion(param_name, disp_model) 
     3385                    self.state.values = self.values 
     3386                    self.state.weights = self.weights 
     3387                    self.model._persistency_dict[param_name] = \ 
     3388                                            [self.state.values, 
     3389                                             self.state.weights] 
     3390 
     3391            except Exception: 
     3392                logging.error(traceback.format_exc()) 
     3393                print "Error in BasePage._paste_poly_help: %s" % \ 
     3394                                        sys.exc_info()[1] 
     3395 
     3396    def _set_disp_array_cb(self, item): 
    34323397        """ 
    34333398        Set cb for array disp 
    34343399        """ 
    3435         if isarray: 
    3436             item[0].SetValue(False) 
    3437             item[0].Enable(False) 
    3438             item[2].Enable(False) 
    3439             item[3].Show(False) 
    3440             item[4].Show(False) 
    3441             item[5].SetValue('') 
    3442             item[5].Enable(False) 
    3443             item[6].SetValue('') 
    3444             item[6].Enable(False) 
    3445         else: 
    3446             item[0].Enable() 
    3447             item[2].Enable() 
    3448             item[3].Show(True) 
    3449             item[4].Show(True) 
    3450             item[5].Enable() 
    3451             item[6].Enable() 
     3400        item[0].SetValue(False) 
     3401        item[0].Enable(False) 
     3402        item[2].Enable(False) 
     3403        item[3].Show(False) 
     3404        item[4].Show(False) 
     3405        item[5].SetValue('') 
     3406        item[5].Enable(False) 
     3407        item[6].SetValue('') 
     3408        item[6].Enable(False) 
    34523409 
    34533410    def update_pinhole_smear(self): 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r6c382da ree4b3cb  
    1010import math 
    1111import time 
    12 import traceback 
    1312 
    1413from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
     
    20592058            msg = "Error: This model state has missing or outdated " 
    20602059            msg += "information.\n" 
    2061             msg += traceback.format_exc() 
     2060            msg += "%s" % (sys.exc_value) 
    20622061            wx.PostEvent(self._manager.parent, 
    20632062                         StatusEvent(status=msg, info="error")) 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    re925f61 r05829fb  
    11.. _Writing_a_Plugin: 
    22 
    3 Writing a Plugin Model 
    4 ====================== 
    5  
    6 Overview 
    7 ^^^^^^^^ 
    8  
    9 You can write your own model and save it to the the SasView 
     3Writing a Plugin 
     4================ 
     5 
     6Users can write their own models and save it to the the SasView 
    107*plugin_models* folder 
    118 
    12   *C:\\Users\\[username]\\.sasview\\plugin_models* (on Windows) 
     9  *C:\\Users\\[username]\\.sasview\\plugin_models* - (on Windows) 
    1310 
    1411The next time SasView is started it will compile the plugin and add 
    15 it to the list of *Customized Models* in a FitPage.  It is recommended that an 
     12it to the list of *Customized Models*.  It is recommended that an 
    1613existing model be used as a template. 
     14 
     15This page was originally written by our MOST experienced developers, 
     16but has subsequently been edited by our LEAST experienced developer who felt 
     17some instructions could have been clearer, and learnt one or two things that 
     18were missing altogether! But they succeeded in converting a model that passed 
     19testing, so there is no reason why you should not be able to do the same. 
    1720 
    1821SasView has three ways of writing models: 
     
    2629  `cylinder.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/cylinder.c>`_ 
    2730 
    28 The built-in modules are available in the *sasmodels-data\\models* subdirectory 
    29 of your SasView installation folder.  On Windows, this will be something like 
    30 *C:\\Program Files (x86)\\SasView\\sasmodels-data\\models*.  On Mac OSX, these will be within 
     31Many models are available for download from the 
     32`model marketplace <http://marketplace.sasview.org/>`_. 
     33 
     34The builtin modules are available in the *sasmodels-data/models* subdirectory 
     35of the sasview distribution.  On Windows, this will be something like 
     36*C:\Program Files (x86)\SasView\models*.  On MacOSX, these will be within 
    3137the application bundle as 
    3238*/Applications/SasView 4.0.app/Contents/Resources/sasmodels-data/models*. 
    3339 
    34 Other models are available for download from our 
    35 `Model Marketplace <http://marketplace.sasview.org/>`_. You can contribute your own models to the  
    36 Marketplace aswell. 
    37  
    3840Create New Model Files 
    3941^^^^^^^^^^^^^^^^^^^^^^ 
    4042 
    41 In the *~\\.sasview\\plugin_models* directory, copy the appropriate files 
     43In the *~/.sasview/plugin_models* directory, copy the appropriate files 
    4244(using the examples above as templates) to mymodel.py (and mymodel.c, etc) 
    4345as required, where "mymodel" is the name for the model you are creating. 
     
    4547*Please follow these naming rules:* 
    4648 
    47 - No capitalization and thus no CamelCase 
    48 - If necessary use underscore to separate words (i.e. barbell not BarBell or 
     49- No capitalization and thus no CamelCase. 
     50- If necessary use underscore to separate (i.e. barbell not BarBell or 
    4951  broad_peak not BroadPeak) 
    50 - Do not include “model” in the name (i.e. barbell not BarBellModel) 
     52- Don't include “model” in the name (i.e. barbell not BarBellModel) 
    5153 
    5254 
    5355Edit New Model Files 
    5456^^^^^^^^^^^^^^^^^^^^ 
    55  
    56 Model Contents 
    57 .............. 
    5857 
    5958The model interface definition is in the .py file.  This file contains: 
     
    6665    - without spaces (use underscores to separate words instead) 
    6766    - without any capitalization or CamelCase 
    68     - without incorporating the word "model" 
     67    - without incorporating the word 'model' 
    6968    - examples: *barbell* **not** *BarBell*; *broad_peak* **not** *BroadPeak*;  
    7069      *barbell* **not** *BarBellModel* 
     
    7372   - this is the **title** string in the *.py* file 
    7473   - this is a one or two line description of the model, which will appear 
    75      at the start of the model documentation and as a tooltip in the SasView GUI 
     74     at the start of the model documentation and as a tooltip in the GUI 
    7675 
    7776- a **short discription**: 
    7877   - this is the **description** string in the *.py* file 
    7978   - this is a medium length description which appears when you click 
    80      *Description* on the model FitPage 
     79     *Description* on the model fit page 
    8180 
    8281- a **parameter table**: 
     
    8685   - this is ReStructuredText enclosed between the r""" and """ delimiters 
    8786     at the top of the *.py* file 
    88    - what you write here is abstracted into the SasView help documentation 
    89    - this is what other users will refer to when they want to know what your model does;  
    90      so please be helpful! 
    9187 
    9288- a **definition** of the model: 
     
    10197 
    10298- a **plot** of the function, with a **figure caption**: 
    103    - this is automatically generated from your default parameters 
     99   - this is automatically generated from the default parameters 
    104100 
    105101- at least one **reference**: 
     
    111107   - the *.py* file should also contain a comment identifying *who* 
    112108     converted/created the model file 
    113  
    114 Models that do not conform to these requirements will *never* be incorporated  
    115 into the built-in library. 
    116109 
    117110More complete documentation for the sasmodels package can be found at 
     
    177170 
    178171The model should include a **formula** written using LaTeX markup. 
    179 The example above uses the *math* command to make a displayed equation.  You 
     172The above example uses the *math* command to make a displayed equation.  You 
    180173can also use *\$formula\$* for an inline formula. This is handy for defining 
    181174the relationship between the model parameters and formula variables, such 
    182175as the phrase "\$r\$ is the radius" used above.  The live demo MathJax 
    183176page `<http://www.mathjax.org/>`_ is handy for checking that the equations 
    184 will look like you intend. 
     177will look like you expect. 
    185178 
    186179Math layout uses the `amsmath <http://www.ams.org/publications/authors/tex/amslatex>`_ 
     
    214207 
    215208    name = "sphere"  # optional: defaults to the filename without .py 
    216  
    217209    title = "Spheres with uniform scattering length density" 
    218  
    219210    description = """\ 
    220211    P(q)=(scale/V)*[3V(sld-sld_solvent)*(sin(qr)-qr cos(qr)) 
     
    225216        sld_solvent: the SLD of the solvent 
    226217    """ 
    227  
    228218    category = "shape:sphere" 
    229  
    230219    single = True   # optional: defaults to True 
    231  
    232220    opencl = False  # optional: defaults to False 
    233  
    234221    structure_factor = False  # optional: defaults to False 
    235222 
     
    242229**title = "short description"** is short description of the model which 
    243230is included after the model name in the automatically generated documentation. 
    244 The title can also be used for a tooltip. 
     231The title can also be used for a tooltip, for example. 
    245232 
    246233**description = """doc string"""** is a longer description of the model. It 
    247 shows up when you press the "Description" button of the SasView FitPage. 
     234shows up when you press the "Description" button of the SasView fit page. 
    248235It should give a brief description of the equation and the parameters 
    249236without the need to read the entire model documentation. The triple quotes 
    250237allow you to write the description over multiple lines. Keep the lines 
    251238short since the GUI will wrap each one separately if they are too long. 
    252 **Make sure the parameter names in the description match the model definition!** 
     239**Make sure the parameter names in the description match the model definition.** 
    253240 
    254241**category = "shape:sphere"** defines where the model will appear in the 
    255242model documentation.  In this example, the model will appear alphabetically 
    256 in the list of spheroid models in the *Shape* category. 
     243in the list of spheroid models. 
    257244 
    258245**single = True** indicates that the model can be run using single 
     
    288275        ["radius",      "Ang",        50, [0, inf],    "volume", "Sphere radius"], 
    289276    ] 
    290     # pylint: enable=bad-whitespace, line-too-long 
     277    # pylint: disable=bad-whitespace, line-too-long 
    291278 
    292279**parameters = [["name", "units", default, [min,max], "type", "tooltip"],...]** 
    293 defines the parameters that form the model. 
    294  
    295 **Note: The order of the parameters in the definition will be the order of the  
    296 parameters in the user interface and the order of the parameters in Iq(),  
    297 Iqxy() and form_volume(). And** *scale* **and** *background* **parameters are  
    298 implicit to all models, so they do not need to be included in the parameter table.** 
    299  
    300 - **"name"** is the name of the parameter shown on the FitPage. 
     280defines the parameters form the model. 
     281 
     282- **the order of the parameters in the definition will be the order of 
     283  the parameters in the user interface and the order of the parameters 
     284  in Iq(), Iqxy() and form_volume().** 
     285 
     286- **scale and background parameters are implicit to all models, so 
     287  they do not need to be included in the parameter table** 
     288 
     289- **"name"** is the name of the parameter shown on the fit screen 
    301290 
    302291  - parameter names should follow the mathematical convention; e.g., 
    303     *radius_core* not *core_radius*, or *sld_solvent* not *solvent_sld*. 
    304  
     292    *radius_core* not *core_radius*, or *sld_solvent* not *solvent_sld* 
    305293  - model parameter names should be consistent between different models, 
    306294    so *sld_solvent*, for example, should have exactly the same name 
    307     in every model. 
    308  
     295    in every model 
    309296  - to see all the parameter names currently in use, type the following in the 
    310297    python shell/editor under the Tools menu:: 
     
    314301 
    315302    *re-use* as many as possible!!! 
    316  
    317303  - use "name[n]" for multiplicity parameters, where *n* is the name of 
    318304    the parameter defining the number of shells/layers/segments, etc. 
     
    320306- **"units"** are displayed along with the parameter name 
    321307 
    322   - every parameter should have units; use "None" if there are no units. 
    323  
     308  - every parameter should have units; use "None" if there are no units 
    324309  - **sld's should be given in units of 1e-6/Ang^2, and not simply 
    325310    1/Ang^2 to be consistent with the builtin models.  Adjust your formulas 
    326311    appropriately.** 
    327  
    328312  - fancy units markup is available for some units, including:: 
    329313 
     
    338322      and using negative exponents instead of the / operator, though 
    339323      the unit name should use the / operator for consistency. 
    340     - please post a message to the SasView developers mailing list with your changes. 
    341  
    342 - **default** is the initial value for the parameter. 
     324    - post a message to the sasview developers list with the changes 
     325 
     326- **default** is the initial value for the parameter 
    343327 
    344328  - **the parameter default values are used to auto-generate a plot of 
    345329    the model function in the documentation.** 
    346330 
    347 - **[min, max]** are the lower and upper limits on the parameter. 
    348  
    349   - lower and upper limits can be any number, or *-inf* or *inf*. 
    350  
     331- **[min, max]** are the lower and upper limits on the parameter 
     332 
     333  - lower and upper limits can be any number, or -inf or inf. 
    351334  - the limits will show up as the default limits for the fit making it easy, 
    352335    for example, to force the radius to always be greater than zero. 
    353336 
    354 - **"type"** can be one of: "", "sld", "volume", or "orientation". 
     337- **"type"** can be one of: "", "sld", "volume", or "orientation" 
    355338 
    356339  - "sld" parameters can have magnetic moments when fitting magnetic models; 
    357340    depending on the spin polarization of the beam and the $q$ value being 
    358341    examined, the effective sld for that material will be used to compute the 
    359     scattered intensity. 
    360  
     342    scattered intensity 
    361343  - "volume" parameters are passed to Iq(), Iqxy(), and form_volume(), and 
    362344    have polydispersity loops generated automatically. 
    363  
    364345  - "orientation" parameters are only passed to Iqxy(), and have angular 
    365346    dispersion. 
     
    399380............. 
    400381 
    401 For pure python models, define the *Iq* function:: 
     382For pure python models, define the Iq funtion:: 
    402383 
    403384      import numpy as np 
     
    410391The parameters *par1, par2, ...* are the list of non-orientation parameters 
    411392to the model in the order that they appear in the parameter table. 
    412 **Note that the autogenerated model file uses** *x* **rather than** *q*. 
     393**Note that the autogenerated model file uses *x* rather than *q*.** 
    413394 
    414395The *.py* file should import trigonometric and exponential functions from 
    415 numpy rather than from math.  This lets us evaluate the model for the whole 
     396numpy rather that from math.  This lets us evaluate the model for the whole 
    416397range of $q$ values at once rather than looping over each $q$ separately in 
    417398python.  With $q$ as a vector, you cannot use if statements, but must instead 
     
    449430list includes the *volume* parameters in order.  This is used for a weighted 
    450431volume normalization so that scattering is on an absolute scale.  If 
    451 *form_volume* is not defined, then the default *form_volume = 1.0* will be 
     432*form_volume* is not definded, then the default *form_volume = 1.0* will be 
    452433used. 
    453434 
     
    455436................. 
    456437 
    457 Like pure python models, inline C models need to define an *Iq* function:: 
     438Like pure python models, inline C models need define an *Iq* function:: 
    458439 
    459440    Iq = """ 
     
    535516These functions have been tuned to be fast and numerically stable down 
    536517to $q=0$ even in single precision.  In some cases they work around bugs 
    537 which appear on some platforms but not others. So use them where needed!!! 
     518which appear on some platforms but not others. 
    538519 
    539520Models are defined using double precision declarations for the 
    540521parameters and return values.  Declarations and constants will be converted 
    541522to float or long double depending on the precision requested. 
    542  
    543523**Floating point constants must include the decimal point.**  This allows us 
    544524to convert values such as 1.0 (double precision) to 1.0f (single precision) 
     
    560540 
    561541A value defined as SAS_DOUBLE will stay double precision; this should 
    562 not be used since some graphics cards do not support double precision. 
     542not be used since some graphics card don't support double precision. 
    563543 
    564544 
     
    577557Form Factors 
    578558............ 
     559 
     560:: 
     561 
     562    def ER(radius, thickness): 
     563        """Effective radius of a core-shell sphere.""" 
     564        return radius + thickness 
    579565 
    580566Away from the dilute limit you can estimate scattering including 
     
    586572form averaged over all the polydispersity values. 
    587573 
    588 :: 
    589  
    590     def ER(radius, thickness): 
    591         """Effective radius of a core-shell sphere.""" 
    592         return radius + thickness 
    593  
    594 Now consider the *core_shell_sphere*, which has a simple effective radius 
     574Consider the *core_shell_sphere*, which has a simple effective radius 
    595575equal to the radius of the core plus the thickness of the shell, as 
    596576shown above. Given polydispersity over *(r1, r2, ..., rm)* in radius and 
     
    617597one return value for each point in the mesh grid. 
    618598 
    619 *NOTE: we may be removing or modifying this feature soon. As of the  
    620 time of writing, core-shell sphere returns (1., 1.) for VR, giving a volume 
    621 ratio of 1.0.* 
     599*NOTE: we may be removing or modifying this feature soon.*  As of this 
     600writing, core-shell sphere returns (1., 1.) for *VR*, giving a volume 
     601ratio of 1.0. 
    622602 
    623603Unit Tests 
     
    660640^^^^^^^^^^^^^^^^^^^ 
    661641 
    662 Installed SasView 
    663 ................. 
    664  
    665642If you are editing your model from the SasView GUI, you can test it 
    666 by selecting *Run > Compile* from the *Model Editor* menu bar. An 
     643by selecting *Run -> Compile* from the *Model Editor* menu bar. An 
    667644*Info* box will appear with the results of the compilation and a 
    668645check that the model runs. 
    669646 
    670  
    671 Built SasView 
    672 ............. 
    673  
    674647If the model compiles and runs, you can next run the unit tests that 
    675 you have added using the **test =** values. Switch to the *Shell* tab 
     648you have added using the **test=** values. Switch to the *Shell* tab 
    676649and type the following:: 
    677650 
     
    713686For the random models, 
    714687 
    715 - *sld* will be in the range (-0.5,10.5), 
    716 - angles (*theta, phi, psi*) will be in the range (-180,180), 
    717 - angular dispersion will be in the range (0,45), 
    718 - polydispersity will be in the range (0,1) 
    719 - other values will be in the range (0, 2\ *v*), where *v* is the value of the parameter in demo. 
    720  
    721 Dispersion parameters *n*\, *sigma* and *type* will be unchanged from demo so that 
     688- sld will be in(-0.5,10.5), 
     689- angles (theta, phi, psi) will be in (-180,180), 
     690- angular dispersion will be in (0,45), 
     691- polydispersity will be in (0,1) 
     692- other values will be in (0, 2*v) where v is the value of the parameter in demo. 
     693 
     694Dispersion parameters n, sigma and type will be unchanged from demo so that 
    722695run times are predictable. 
    723696 
     
    728701 
    729702 
    730 Clean Lint - (Developer Version Only) 
    731 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    732  
    733 **NB: For now we are not providing pylint with the installer version of SasView;  
    734 so unless you have a SasView build environment available, you can ignore this section!** 
     703Clean Lint 
     704^^^^^^^^^^ 
     705 
     706**NB: For now we are not providing pylint with SasView; unless you have a 
     707SasView development environment available, you can ignore this section.** 
    735708 
    736709Run the lint check with:: 
     
    744717for standard model functions *Iq*, *Iqxy*, etc. 
    745718 
    746 We will have delinting sessions at the SasView Code Camps, where we can 
     719We will have delinting sessions at the SasView code camps, where we can 
    747720decide on standards for model files, parameter names, etc. 
    748721 
    749 For now, you can tell pylint to ignore things.  For example, to align your 
     722For now, you can tell pylint to ignore things.  For example, to align you 
    750723parameters in blocks:: 
    751724 
     
    765738Don't put in too many pylint statements, though, since they make the code ugly. 
    766739 
    767 Check The Docs - (Developer Version Only) 
    768 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
     740Check The Docs 
     741^^^^^^^^^^^^^^ 
    769742 
    770743You can get a rough idea of how the documentation will look using the 
     
    783756- `amsmath <http://www.ams.org/publications/authors/tex/amslatex>`_ 
    784757 
    785 There is also a neat online WYSIWYG ReStructuredText editor at http://rst.ninjs.org\ . 
    786  
    787 Share Your Model! 
    788 ^^^^^^^^^^^^^^^^^ 
     758Finally 
     759^^^^^^^ 
    789760 
    790761Once compare and the unit test(s) pass properly and everything is done, 
    791762consider adding your model to the 
    792 `Model Marketplace <http://marketplace.sasview.org/>`_ so that others may use it! 
     763`model marketplace <http://marketplace.sasview.org/>`_. 
     764 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    r6c382da r654e8e0  
    2424from xml.dom.minidom import parseString 
    2525from lxml import etree 
    26  
    27 import sasmodels.weights 
    2826 
    2927import sas.sascalc.dataloader 
     
    476474                value = content[1] 
    477475            except Exception: 
    478                 msg = "Report string expected 'name: value' but got %r"%line 
    479                 logging.error(msg) 
     476                logging.error(traceback.format_exc()) 
    480477            if name.count("State created"): 
    481478                repo_time = "" + value 
     
    519516                        title_name = HEADER % title 
    520517                except Exception: 
    521                     msg = "While parsing 'data: ...'\n" 
    522                     logging.error(msg + traceback.format_exc()) 
     518                    logging.error(traceback.format_exc()) 
    523519            if name == "model name ": 
    524520                try: 
     
    535531                    q_range = CENTRE % q_name 
    536532                except Exception: 
    537                     msg = "While parsing 'Plotting Range: ...'\n" 
    538                     logging.error(msg + traceback.format_exc()) 
     533                    logging.error(traceback.format_exc()) 
    539534        paramval = "" 
    540535        for lines in param_string.split(":"): 
     
    716711        # For self.values ={ disp_param_name: [vals,...],...} 
    717712        # and for self.weights ={ disp_param_name: [weights,...],...} 
     713        value_list = {} 
    718714        for item in LIST_OF_MODEL_ATTRIBUTES: 
    719715            element = newdoc.createElement(item[0]) 
     
    729725 
    730726        # Create doc for the dictionary of self._disp_obj_dic 
    731         for tagname, varname, tagtype in DISPERSION_LIST: 
    732             element = newdoc.createElement(tagname) 
    733             value_list = getattr(self, varname) 
    734             for key, value in value_list.iteritems(): 
     727        for item in DISPERSION_LIST: 
     728            element = newdoc.createElement(item[0]) 
     729            value_list = getattr(self, item[1]) 
     730            for key, val in value_list.iteritems(): 
     731                value = repr(val) 
    735732                sub_element = newdoc.createElement(key) 
    736733                sub_element.setAttribute('name', str(key)) 
     
    850847                # Recover _disp_obj_dict from xml file 
    851848                self._disp_obj_dict = {} 
    852                 for tagname, varname, tagtype in DISPERSION_LIST: 
    853                     node = get_content("ns:%s" % tagname, entry) 
     849                for item in DISPERSION_LIST: 
     850                    # Get node 
     851                    node = get_content("ns:%s" % item[0], entry) 
    854852                    for attr in node: 
    855                         parameter = str(attr.get('name')) 
    856                         value = attr.get('value') 
    857                         if value.startswith("<"): 
    858                             try: 
    859                                 # <path.to.NamedDistribution object/instance...> 
    860                                 cls_name = value[1:].split()[0].split('.')[-1] 
    861                                 cls = getattr(sasmodels.weights, cls_name) 
    862                                 value = cls.type 
    863                             except Exception: 
    864                                 logging.error("unable to load distribution %r for %s" 
    865                                               % (value, parameter)) 
    866                                 continue 
    867                         _disp_obj_dict = getattr(self, varname) 
    868                         _disp_obj_dict[parameter] = value 
     853                        name = str(attr.get('name')) 
     854                        val = attr.get('value') 
     855                        value = val.split(" instance")[0] 
     856                        disp_name = value.split("<")[1] 
     857                        try: 
     858                            # Try to recover disp_model object from strings 
     859                            com = "from sas.models.dispersion_models " 
     860                            com += "import %s as disp" 
     861                            com_name = disp_name.split(".")[3] 
     862                            exec com % com_name 
     863                            disp_model = disp() 
     864                            attribute = getattr(self, item[1]) 
     865                            attribute[name] = com_name 
     866                        except Exception: 
     867                            logging.error(traceback.format_exc()) 
    869868 
    870869                # get self.values and self.weights dic. if exists 
    871                 for tagname, varname in LIST_OF_MODEL_ATTRIBUTES: 
    872                     node = get_content("ns:%s" % tagname, entry) 
     870                for item in LIST_OF_MODEL_ATTRIBUTES: 
     871                    node = get_content("ns:%s" % item[0], entry) 
    873872                    dic = {} 
    874873                    value_list = [] 
    875874                    for par in node: 
    876875                        name = par.get('name') 
    877                         values = par.text.split() 
     876                        values = par.text.split('\n') 
    878877                        # Get lines only with numbers 
    879878                        for line in values: 
     
    883882                            except Exception: 
    884883                                # pass if line is empty (it happens) 
    885                                 msg = ("Error reading %r from %s %s\n" 
    886                                        % (line, tagname, name)) 
    887                                 logging.error(msg + traceback.format_exc()) 
     884                                logging.error(traceback.format_exc()) 
    888885                        dic[name] = numpy.array(value_list) 
    889                     setattr(self, varname, dic) 
     886                    setattr(self, item[1], dic) 
    890887 
    891888    def set_plot_state(self, figs, canvases): 
     
    12341231 
    12351232        except: 
    1236             logging.info("XML document does not contain fitting information.\n" 
    1237                          + traceback.format_exc()) 
     1233            logging.info("XML document does not contain fitting information.\n %s" % sys.exc_value) 
    12381234 
    12391235        return state 
Note: See TracChangeset for help on using the changeset viewer.