Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/fitting/basepage.py

    re4c897b rc65a265  
    1717from wx.lib.scrolledpanel import ScrolledPanel 
    1818 
    19 import sasmodels.sasview_model 
     19from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
     20 
    2021from sas.sasgui.guiframe.panel_base import PanelBase 
    21 from sas.sasgui.guiframe.utils import format_number, check_float, IdList 
     22from sas.sasgui.guiframe.utils import format_number, check_float, IdList, check_int 
    2223from sas.sasgui.guiframe.events import PanelOnFocusEvent 
    2324from sas.sasgui.guiframe.events import StatusEvent 
     
    626627        self.disp_help_bt.Bind(wx.EVT_BUTTON, self.on_pd_help_clicked, 
    627628                               id=self.disp_help_bt.GetId()) 
    628         self.disp_help_bt.SetToolTipString("Helps for Polydispersion.") 
     629        self.disp_help_bt.SetToolTipString("Help for polydispersion.") 
    629630 
    630631        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, 
     
    932933        if len(self._disp_obj_dict) > 0: 
    933934            for k, v in self._disp_obj_dict.iteritems(): 
    934                 self.state._disp_obj_dict[k] = v 
     935                self.state._disp_obj_dict[k] = v.type 
    935936 
    936937            self.state.values = copy.deepcopy(self.values) 
     
    10091010            if len(self._disp_obj_dict) > 0: 
    10101011                for k, v in self._disp_obj_dict.iteritems(): 
    1011                     self.state._disp_obj_dict[k] = v 
     1012                    self.state._disp_obj_dict[k] = v.type 
    10121013 
    10131014            self.state.values = copy.deepcopy(self.values) 
     
    11231124                                                    state.disp_cb_dict[item]) 
    11241125                        # Create the dispersion objects 
    1125                         from sas.models.dispersion_models import ArrayDispersion 
    1126                         disp_model = ArrayDispersion() 
     1126                        disp_model = POLYDISPERSITY_MODELS['array']() 
    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 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 
     1381        for key, disp_type in state._disp_obj_dict.iteritems(): 
     1382            #disp_model = disp 
     1383            disp_model = POLYDISPERSITY_MODELS[disp_type]() 
    13911384            self._disp_obj_dict[key] = disp_model 
    13921385            param_name = key.split('.')[0] 
     
    15041497            is_2Ddata = True 
    15051498        if self.model != None: 
    1506             try: 
    1507                 is_modified = self._check_value_enter(self.fittable_param, 
    1508                                                       is_modified) 
    1509                 is_modified = self._check_value_enter(self.fixed_param, 
    1510                                                       is_modified) 
    1511                 is_modified = self._check_value_enter(self.parameters, 
    1512                                                       is_modified) 
    1513             except Exception: 
    1514                 logging.error(traceback.format_exc()) 
     1499            is_modified = (self._check_value_enter(self.fittable_param) 
     1500                           or self._check_value_enter(self.fixed_param) 
     1501                           or self._check_value_enter(self.parameters)) 
    15151502 
    15161503            # Here we should check whether the boundaries have been modified. 
     
    15331520            else: 
    15341521                self.fitrange = False 
    1535  
    1536             if not self.data.is_data: 
    1537                 is_modified = True 
    15381522 
    15391523            ## if any value is modify draw model with new value 
     
    15521536                self._draw_model() 
    15531537                self.Refresh() 
     1538 
     1539        logging.info("is_modified flag set to %g",is_modified) 
    15541540        return is_modified 
    15551541 
     
    15611547        flag = True 
    15621548        self.fitrange = True 
    1563         is_modified = False 
    15641549 
    15651550        #wx.PostEvent(self._manager.parent, StatusEvent(status=" \ 
     
    15741559                                                                [self.data]) 
    15751560            ##Check the values 
    1576             self._check_value_enter(self.fittable_param, is_modified) 
    1577             self._check_value_enter(self.fixed_param, is_modified) 
    1578             self._check_value_enter(self.parameters, is_modified) 
     1561            self._check_value_enter(self.fittable_param) 
     1562            self._check_value_enter(self.fixed_param) 
     1563            self._check_value_enter(self.parameters) 
    15791564 
    15801565            # If qmin and qmax have been modified, update qmin and qmax and 
     
    16601645        return flag 
    16611646 
    1662     def _is_modified(self, is_modified): 
    1663         """ 
    1664         return to self._is_modified 
    1665         """ 
    1666         return is_modified 
    1667  
    16681647    def _reset_parameters_state(self, listtorestore, statelist): 
    16691648        """ 
     
    19641943        wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    19651944        # Flag to register when a parameter has changed. 
    1966         #is_modified = False 
    19671945        if tcrtl.GetValue().lstrip().rstrip() != "": 
    19681946            try: 
     
    19941972                    if temp_npts != self.num_points: 
    19951973                        self.num_points = temp_npts 
    1996                         #is_modified = True 
    19971974                else: 
    19981975                    msg = "Cannot plot: No points in Q range!!!  " 
     
    21702147        self.Layout() 
    21712148 
     2149 
    21722150    def _validate_qrange(self, qmin_ctrl, qmax_ctrl): 
    21732151        """ 
     
    22762254        return flag 
    22772255 
    2278     def _check_value_enter(self, list, modified): 
     2256    def _check_value_enter(self, list): 
    22792257        """ 
    22802258        :param list: model parameter and panel info 
     
    22862264                parameter's maximum value , 
    22872265                parameter's units] 
    2288         """ 
    2289         is_modified = modified 
    2290         if len(list) == 0: 
    2291             return is_modified 
     2266 
     2267        Returns True if the model parameters have changed. 
     2268        """ 
     2269        is_modified = False 
    22922270        for item in list: 
    22932271            #skip angle parameters for 1D 
    2294             if not self.enable2D: 
    2295                 if item in self.orientation_params: 
     2272            if not self.enable2D and item in self.orientation_params: 
     2273                continue 
     2274 
     2275            value_ctrl = item[2] 
     2276            if not value_ctrl.IsEnabled(): 
     2277                # ArrayDispersion disables PD, Min, Max, Npts, Nsigs 
     2278                continue 
     2279 
     2280            name = item[1] 
     2281            value_str = value_ctrl.GetValue().strip() 
     2282            if name.endswith(".npts"): 
     2283                validity = check_int(value_ctrl) 
     2284                if not validity: 
    22962285                    continue 
    2297             #try: 
    2298             name = str(item[1]) 
    2299  
    2300             if string.find(name, ".npts") == -1 and \ 
    2301                                         string.find(name, ".nsigmas") == -1: 
    2302                 ## check model parameters range 
    2303                 param_min = None 
    2304                 param_max = None 
    2305  
    2306                 ## check minimun value 
    2307                 if item[5] != None and item[5] != "": 
    2308                     if item[5].GetValue().lstrip().rstrip() != "": 
    2309                         try: 
    2310                             param_min = float(item[5].GetValue()) 
    2311                             if not self._validate_qrange(item[5], item[2]): 
    2312                                 if numpy.isfinite(param_min): 
    2313                                     item[2].SetValue(format_number(param_min)) 
    2314  
    2315                             item[5].SetBackgroundColour(wx.WHITE) 
    2316                             item[2].SetBackgroundColour(wx.WHITE) 
    2317  
    2318                         except: 
    2319                             msg = "Wrong fit parameter range entered" 
    2320                             wx.PostEvent(self._manager.parent, 
    2321                                          StatusEvent(status=msg)) 
    2322                             raise ValueError, msg 
    2323                         is_modified = True 
    2324                 ## check maximum value 
    2325                 if item[6] != None and item[6] != "": 
    2326                     if item[6].GetValue().lstrip().rstrip() != "": 
    2327                         try: 
    2328                             param_max = float(item[6].GetValue()) 
    2329                             if not self._validate_qrange(item[2], item[6]): 
    2330                                 if numpy.isfinite(param_max): 
    2331                                     item[2].SetValue(format_number(param_max)) 
    2332  
    2333                             item[6].SetBackgroundColour(wx.WHITE) 
    2334                             item[2].SetBackgroundColour(wx.WHITE) 
    2335                         except: 
    2336                             msg = "Wrong Fit parameter range entered " 
    2337                             wx.PostEvent(self._manager.parent, 
    2338                                          StatusEvent(status=msg)) 
    2339                             raise ValueError, msg 
    2340                         is_modified = True 
    2341  
    2342                 if param_min != None and param_max != None: 
    2343                     if not self._validate_qrange(item[5], item[6]): 
    2344                         msg = "Wrong Fit range entered for parameter " 
    2345                         msg += "name %s of model %s " % (name, self.model.name) 
    2346                         wx.PostEvent(self._manager.parent, 
    2347                                      StatusEvent(status=msg)) 
    2348  
    2349                 if name in self.model.details.keys(): 
    2350                     self.model.details[name][1:3] = param_min, param_max 
    2351                     is_modified = True 
    2352                 else: 
    2353                     self.model.details[name] = ["", param_min, param_max] 
    2354                     is_modified = True 
    2355             try: 
    2356                 # Check if the textctr is enabled 
    2357                 if item[2].IsEnabled(): 
    2358                     value = float(item[2].GetValue()) 
    2359                     item[2].SetBackgroundColour("white") 
    2360                     # If the value of the parameter has changed, 
    2361                     # +update the model and set the is_modified flag 
    2362                     if value != self.model.getParam(name) and \ 
    2363                                                 numpy.isfinite(value): 
    2364                         self.model.setParam(name, value) 
    2365             except: 
    2366                 item[2].SetBackgroundColour("pink") 
    2367                 msg = "Wrong Fit parameter value entered " 
    2368                 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2286                value = int(value_str) 
     2287 
     2288            elif name.endswith(".nsigmas"): 
     2289                validity = check_float(value_ctrl) 
     2290                if not validity: 
     2291                    continue 
     2292                value = float(value_str) 
     2293 
     2294            else:  # value or polydispersity 
     2295 
     2296                # Check that min, max and value are floats 
     2297                min_ctrl, max_ctrl = item[5], item[6] 
     2298                min_str = min_ctrl.GetValue().strip() 
     2299                max_str = max_ctrl.GetValue().strip() 
     2300                validity = check_float(value_ctrl) 
     2301                if min_str != "": 
     2302                    validity = validity and check_float(min_ctrl) 
     2303                if max_str != "": 
     2304                    validity = validity and check_float(max_ctrl) 
     2305                if not validity: 
     2306                    continue 
     2307 
     2308                # Check that min is less than max 
     2309                low = -numpy.inf if min_str == "" else float(min_str) 
     2310                high = numpy.inf if max_str == "" else float(max_str) 
     2311                if high < low: 
     2312                    min_ctrl.SetBackgroundColour("pink") 
     2313                    min_ctrl.Refresh() 
     2314                    max_ctrl.SetBackgroundColour("pink") 
     2315                    max_ctrl.Refresh() 
     2316                    #msg = "Invalid fit range for %s: min must be smaller than max"%name 
     2317                    #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2318                    continue 
     2319 
     2320                # Force value between min and max 
     2321                value = float(value_str) 
     2322                if value < low: 
     2323                    value = low 
     2324                    value_ctrl.SetValue(format_number(value)) 
     2325                elif value > high: 
     2326                    value = high 
     2327                    value_ctrl.SetValue(format_number(value)) 
     2328 
     2329                if name not in self.model.details.keys(): 
     2330                    self.model.details[name] = ["", None, None] 
     2331                old_low, old_high = self.model.details[name][1:3] 
     2332                if old_low != low or old_high != high: 
     2333                    # The configuration has changed but it won't change the 
     2334                    # computed curve so no need to set is_modified to True 
     2335                    #is_modified = True 
     2336                    self.model.details[name][1:3] = low, high 
     2337 
     2338            # Update value in model if it has changed 
     2339            if value != self.model.getParam(name): 
     2340                self.model.setParam(name, value) 
     2341                is_modified = True 
    23692342 
    23702343        return is_modified 
     
    25392512                self._disp_obj_dict[name1] = disp_model 
    25402513                self.model.set_dispersion(param_name, disp_model) 
    2541                 self.state._disp_obj_dict[name1] = disp_model 
     2514                self.state._disp_obj_dict[name1] = disp_model.type 
    25422515 
    25432516                value1 = str(format_number(self.model.getParam(name1), True)) 
     
    25622535                        item[0].Enable() 
    25632536                        item[2].Enable() 
     2537                        item[3].Show(True) 
     2538                        item[4].Show(True) 
    25642539                        item[5].Enable() 
    25652540                        item[6].Enable() 
     
    26542629        self._disp_obj_dict[name] = disp 
    26552630        self.model.set_dispersion(name.split('.')[0], disp) 
    2656         self.state._disp_obj_dict[name] = disp 
     2631        self.state._disp_obj_dict[name] = disp.type 
    26572632        self.values[name] = values 
    26582633        self.weights[name] = weights 
     
    27222697        :param disp_function: dispersion distr. function 
    27232698        """ 
    2724         # List of the poly_model name in the combobox 
    2725         list = ["RectangleDispersion", "ArrayDispersion", 
    2726                 "LogNormalDispersion", "GaussianDispersion", 
    2727                 "SchulzDispersion"] 
    2728  
    27292699        # Find the selection 
    2730         try: 
    2731             selection = list.index(disp_func.__class__.__name__) 
    2732             return selection 
    2733         except: 
    2734             return 3 
     2700        if disp_func is not None: 
     2701            try: 
     2702                return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 
     2703            except ValueError: 
     2704                pass  # Fall through to default class 
     2705        return POLYDISPERSITY_MODELS.keys().index('gaussian') 
    27352706 
    27362707    def on_reset_clicked(self, event): 
     
    33193290                    pd = content[name][1] 
    33203291                    if name.count('.') > 0: 
     3292                        # If this is parameter.width, then pd may be a floating 
     3293                        # point value or it may be an array distribution. 
     3294                        # Nothing to do for parameter.npts or parameter.nsigmas. 
    33213295                        try: 
    33223296                            float(pd) 
    3323                         except: 
     3297                            if name.endswith('.npts'): 
     3298                                pd = int(pd) 
     3299                        except Exception: 
    33243300                            #continue 
    33253301                            if not pd and pd != '': 
     
    33293305                        # Only array func has pd == '' case. 
    33303306                        item[2].Enable(False) 
     3307                    else: 
     3308                        item[2].Enable(True) 
    33313309                    if item[2].__class__.__name__ == "ComboBox": 
    33323310                        if content[name][1] in self.model.fun_list: 
     
    33553333                        pd = value[0] 
    33563334                        if name.count('.') > 0: 
     3335                            # If this is parameter.width, then pd may be a floating 
     3336                            # point value or it may be an array distribution. 
     3337                            # Nothing to do for parameter.npts or parameter.nsigmas. 
    33573338                            try: 
    33583339                                pd = float(pd) 
     3340                                if name.endswith('.npts'): 
     3341                                    pd = int(pd) 
    33593342                            except: 
    33603343                                #continue 
     
    33653348                            # Only array func has pd == '' case. 
    33663349                            item[2].Enable(False) 
     3350                        else: 
     3351                            item[2].Enable(True) 
    33673352                        if item[2].__class__.__name__ == "ComboBox": 
    33683353                            if value[0] in self.model.fun_list: 
     
    33843369        Helps get paste for poly function 
    33853370 
    3386         :param item: Gui param items 
    3387         :param value: the values for parameter ctrols 
    3388         """ 
    3389         is_array = False 
    3390         if len(value[1]) > 0: 
    3391             # Only for dispersion func.s 
    3392             try: 
    3393                 item[7].SetValue(value[1]) 
    3394                 selection = item[7].GetCurrentSelection() 
    3395                 name = item[7].Name 
    3396                 param_name = name.split('.')[0] 
    3397                 dispersity = item[7].GetClientData(selection) 
    3398                 disp_model = dispersity() 
    3399                 # Only for array disp 
    3400                 try: 
    3401                     pd_vals = numpy.array(value[2]) 
    3402                     pd_weights = numpy.array(value[3]) 
    3403                     if len(pd_vals) > 0 and len(pd_vals) > 0: 
    3404                         if len(pd_vals) == len(pd_weights): 
    3405                             self._set_disp_array_cb(item=item) 
    3406                             self._set_array_disp_model(name=name, 
    3407                                                        disp=disp_model, 
    3408                                                        values=pd_vals, 
    3409                                                        weights=pd_weights) 
    3410                             is_array = True 
    3411                 except Exception: 
    3412                     logging.error(traceback.format_exc()) 
    3413                 if not is_array: 
    3414                     self._disp_obj_dict[name] = disp_model 
    3415                     self.model.set_dispersion(name, 
    3416                                               disp_model) 
    3417                     self.state._disp_obj_dict[name] = \ 
    3418                                               disp_model 
    3419                     self.model.set_dispersion(param_name, disp_model) 
    3420                     self.state.values = self.values 
    3421                     self.state.weights = self.weights 
    3422                     self.model._persistency_dict[param_name] = \ 
    3423                                             [self.state.values, 
    3424                                              self.state.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_array_cb(self, item): 
     3371        *item* is the parameter name 
     3372 
     3373        *value* depends on which parameter is being processed, and whether it 
     3374        has array polydispersity. 
     3375 
     3376        For parameters without array polydispersity: 
     3377 
     3378            parameter => ['FLOAT', ''] 
     3379            parameter.width => ['FLOAT', 'DISTRIBUTION', ''] 
     3380            parameter.npts => ['FLOAT', ''] 
     3381            parameter.nsigmas => ['FLOAT', ''] 
     3382 
     3383        For parameters with array polydispersity: 
     3384 
     3385            parameter => ['FLOAT', ''] 
     3386            parameter.width => ['FILENAME', 'array', [x1, ...], [w1, ...]] 
     3387            parameter.npts => ['FLOAT', ''] 
     3388            parameter.nsigmas => ['FLOAT', ''] 
     3389        """ 
     3390        # Do nothing if not setting polydispersity 
     3391        if len(value[1]) == 0: 
     3392            return 
     3393 
     3394        try: 
     3395            name = item[7].Name 
     3396            param_name = name.split('.')[0] 
     3397            item[7].SetValue(value[1]) 
     3398            selection = item[7].GetCurrentSelection() 
     3399            dispersity = item[7].GetClientData(selection) 
     3400            disp_model = dispersity() 
     3401 
     3402            if value[1] == 'array': 
     3403                pd_vals = numpy.array(value[2]) 
     3404                pd_weights = numpy.array(value[3]) 
     3405                if len(pd_vals) == 0 or len(pd_vals) != len(pd_weights): 
     3406                    msg = ("bad array distribution parameters for %s" 
     3407                           % param_name) 
     3408                    raise ValueError(msg) 
     3409                self._set_disp_cb(True, item=item) 
     3410                self._set_array_disp_model(name=name, 
     3411                                           disp=disp_model, 
     3412                                           values=pd_vals, 
     3413                                           weights=pd_weights) 
     3414            else: 
     3415                self._set_disp_cb(False, item=item) 
     3416                self._disp_obj_dict[name] = disp_model 
     3417                self.model.set_dispersion(param_name, disp_model) 
     3418                self.state._disp_obj_dict[name] = disp_model.type 
     3419                # TODO: It's not an array, why update values and weights? 
     3420                self.model._persistency_dict[param_name] = \ 
     3421                    [self.values, self.weights] 
     3422                self.state.values = self.values 
     3423                self.state.weights = self.weights 
     3424 
     3425        except Exception: 
     3426            logging.error(traceback.format_exc()) 
     3427            print "Error in BasePage._paste_poly_help: %s" % \ 
     3428                                    sys.exc_info()[1] 
     3429 
     3430    def _set_disp_cb(self, isarray, item): 
    34323431        """ 
    34333432        Set cb for array disp 
    34343433        """ 
    3435         item[0].SetValue(False) 
    3436         item[0].Enable(False) 
    3437         item[2].Enable(False) 
    3438         item[3].Show(False) 
    3439         item[4].Show(False) 
    3440         item[5].SetValue('') 
    3441         item[5].Enable(False) 
    3442         item[6].SetValue('') 
    3443         item[6].Enable(False) 
     3434        if isarray: 
     3435            item[0].SetValue(False) 
     3436            item[0].Enable(False) 
     3437            item[2].Enable(False) 
     3438            item[3].Show(False) 
     3439            item[4].Show(False) 
     3440            item[5].SetValue('') 
     3441            item[5].Enable(False) 
     3442            item[6].SetValue('') 
     3443            item[6].Enable(False) 
     3444        else: 
     3445            item[0].Enable() 
     3446            item[2].Enable() 
     3447            item[3].Show(True) 
     3448            item[4].Show(True) 
     3449            item[5].Enable() 
     3450            item[6].Enable() 
    34443451 
    34453452    def update_pinhole_smear(self): 
Note: See TracChangeset for help on using the changeset viewer.