Ignore:
Timestamp:
Sep 22, 2017 10:29:48 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
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, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
ab0b93f
Parents:
1386b2f (diff), d76c43a (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.
git-author:
Paul Kienzle <pkienzle@…> (09/22/17 10:28:48)
git-committer:
Paul Kienzle <pkienzle@…> (09/22/17 10:29:48)
Message:

Merge branch 'master' into ticket-853-fit-gui-to-calc

File:
1 edited

Legend:

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

    r277257f r69363c7  
    109109        self.model2_string = "cylinder" 
    110110        self.name = 'Sum' + M_NAME 
    111         self.factor = 'scale_factor' 
    112111        self._notes = '' 
    113112        self._operator = '+' 
     
    136135        self.model2_name = str(self.model2.GetValue()) 
    137136        self.good_name = True 
    138         self.fill_oprator_combox() 
     137        self.fill_operator_combox() 
    139138 
    140139    def _layout_name(self): 
     
    494493        a sum or multiply model then create the appropriate string 
    495494        """ 
    496  
    497495        name = '' 
    498  
    499496        if operator == '*': 
    500497            name = 'Multi' 
    501             factor = 'BackGround' 
    502             f_oper = '+' 
     498            factor = 'background' 
    503499        else: 
    504500            name = 'Sum' 
    505501            factor = 'scale_factor' 
    506             f_oper = '*' 
    507  
    508         self.factor = factor 
     502 
    509503        self._operator = operator 
    510         self.explanation = "  Plugin Model = %s %s (model1 %s model2)\n" % \ 
    511                            (self.factor, f_oper, self._operator) 
     504        self.explanation = ("  Plugin_model = scale_factor * (model_1 {} " 
     505            "model_2) + background").format(operator) 
    512506        self.explanationctr.SetLabel(self.explanation) 
    513507        self.name = name + M_NAME 
    514508 
    515509 
    516     def fill_oprator_combox(self): 
     510    def fill_operator_combox(self): 
    517511        """ 
    518512        fill the current combobox with the operator 
     
    530524        return [self.model1_name, self.model2_name] 
    531525 
    532     def write_string(self, fname, name1, name2): 
     526    def write_string(self, fname, model1_name, model2_name): 
    533527        """ 
    534528        Write and Save file 
     
    536530        self.fname = fname 
    537531        description = self.desc_tcl.GetValue().lstrip().rstrip() 
    538         if description == '': 
    539             description = name1 + self._operator + name2 
    540         text = self._operator_choice.GetValue() 
    541         if text.count('+') > 0: 
    542             factor = 'scale_factor' 
    543             f_oper = '*' 
    544             default_val = '1.0' 
    545         else: 
    546             factor = 'BackGround' 
    547             f_oper = '+' 
    548             default_val = '0.0' 
    549         path = self.fname 
    550         try: 
    551             out_f = open(path, 'w') 
    552         except: 
    553             raise 
    554         lines = SUM_TEMPLATE.split('\n') 
    555         for line in lines: 
    556             try: 
    557                 if line.count("scale_factor"): 
    558                     line = line.replace('scale_factor', factor) 
    559                     #print "scale_factor", line 
    560                 if line.count("= %s"): 
    561                     out_f.write(line % (default_val) + "\n") 
    562                 elif line.count("import Model as P1"): 
    563                     if self.is_p1_custom: 
    564                         line = line.replace('#', '') 
    565                         out_f.write(line % name1 + "\n") 
    566                     else: 
    567                         out_f.write(line + "\n") 
    568                 elif line.count("import %s as P1"): 
    569                     if not self.is_p1_custom: 
    570                         line = line.replace('#', '') 
    571                         out_f.write(line % (name1) + "\n") 
    572                     else: 
    573                         out_f.write(line + "\n") 
    574                 elif line.count("import Model as P2"): 
    575                     if self.is_p2_custom: 
    576                         line = line.replace('#', '') 
    577                         out_f.write(line % name2 + "\n") 
    578                     else: 
    579                         out_f.write(line + "\n") 
    580                 elif line.count("import %s as P2"): 
    581                     if not self.is_p2_custom: 
    582                         line = line.replace('#', '') 
    583                         out_f.write(line % (name2) + "\n") 
    584                     else: 
    585                         out_f.write(line + "\n") 
    586                 elif line.count("P1 = find_model"): 
    587                     out_f.write(line % (name1) + "\n") 
    588                 elif line.count("P2 = find_model"): 
    589                     out_f.write(line % (name2) + "\n") 
    590  
    591                 elif line.count("self.description = '%s'"): 
    592                     out_f.write(line % description + "\n") 
    593                 #elif line.count("run") and line.count("%s"): 
    594                 #    out_f.write(line % self._operator + "\n") 
    595                 #elif line.count("evalDistribution") and line.count("%s"): 
    596                 #    out_f.write(line % self._operator + "\n") 
    597                 elif line.count("return") and line.count("%s") == 2: 
    598                     #print "line return", line 
    599                     out_f.write(line % (f_oper, self._operator) + "\n") 
    600                 elif line.count("out2")and line.count("%s"): 
    601                     out_f.write(line % self._operator + "\n") 
    602                 else: 
    603                     out_f.write(line + "\n") 
    604             except: 
    605                 raise 
    606         out_f.close() 
    607         #else: 
    608         #    msg = "Name exists already." 
     532        desc_line = '' 
     533        if description.strip() != '': 
     534            # Sasmodels generates a description for us. If the user provides 
     535            # their own description, add a line to overwrite the sasmodels one 
     536            desc_line = "\nmodel_info.description = '{}'".format(description) 
     537        name = os.path.splitext(os.path.basename(self.fname))[0] 
     538        output = SUM_TEMPLATE.format(name=name, model1=model1_name, 
     539            model2=model2_name, operator=self._operator, desc_line=desc_line) 
     540        with open(self.fname, 'w') as out_f: 
     541            out_f.write(output) 
    609542 
    610543    def compile_file(self, path): 
     
    646579        self.name_hsizer = None 
    647580        self.name_tcl = None 
     581        self.overwrite_cb = None 
    648582        self.desc_sizer = None 
    649583        self.desc_tcl = None 
     
    692626        #title name [string] 
    693627        name_txt = wx.StaticText(self, -1, 'Function Name : ') 
    694         overwrite_cb = wx.CheckBox(self, -1, "Overwrite existing plugin model of this name?", (10, 10)) 
    695         overwrite_cb.SetValue(False) 
    696         overwrite_cb.SetToolTipString("Overwrite it if already exists?") 
    697         wx.EVT_CHECKBOX(self, overwrite_cb.GetId(), self.on_over_cb) 
     628        self.overwrite_cb = wx.CheckBox(self, -1, "Overwrite existing plugin model of this name?", (10, 10)) 
     629        self.overwrite_cb.SetValue(False) 
     630        self.overwrite_cb.SetToolTipString("Overwrite it if already exists?") 
     631        wx.EVT_CHECKBOX(self, self.overwrite_cb.GetId(), self.on_over_cb) 
    698632        self.name_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1)) 
    699633        self.name_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_name) 
     
    703637        self.name_tcl.SetToolTipString(hint_name) 
    704638        self.name_hsizer.AddMany([(self.name_tcl, 0, wx.LEFT | wx.TOP, 0), 
    705                                   (overwrite_cb, 0, wx.LEFT, 20)]) 
     639                                  (self.overwrite_cb, 0, wx.LEFT, 20)]) 
    706640        self.name_sizer.AddMany([(name_txt, 0, wx.LEFT | wx.TOP, 10), 
    707641                                 (self.name_hsizer, 0, 
     
    991925            info = 'Error' 
    992926            color = 'red' 
     927            self.overwrite_cb.SetValue(True) 
     928            self.overwrite_name = True 
    993929        else: 
    994930            self._notes = result 
     
    1030966        out_f.write('parameters = [ \n') 
    1031967        out_f.write('#   ["name", "units", default, [lower, upper], "type", "description"],\n') 
    1032         for pname, pvalue in self.get_param_helper(param_str): 
     968        for pname, pvalue, desc in self.get_param_helper(param_str): 
    1033969            param_names.append(pname) 
    1034             out_f.write("    ['%s', '', %s, [-inf, inf], '', ''],\n" 
    1035                         % (pname, pvalue)) 
    1036         for pname, pvalue in self.get_param_helper(pd_param_str): 
     970            out_f.write("    ['%s', '', %s, [-inf, inf], '', '%s'],\n" 
     971                        % (pname, pvalue, desc)) 
     972        for pname, pvalue, desc in self.get_param_helper(pd_param_str): 
    1037973            param_names.append(pname) 
    1038974            pd_params.append(pname) 
    1039             out_f.write("    ['%s', '', %s, [-inf, inf], 'volume', ''],\n" 
    1040                         % (pname, pvalue)) 
     975            out_f.write("    ['%s', '', %s, [-inf, inf], 'volume', '%s'],\n" 
     976                        % (pname, pvalue, desc)) 
    1041977        out_f.write('    ]\n') 
    1042978 
     
    10811017        for line in param_str.replace(';', ',').split('\n'): 
    10821018            for item in line.split(','): 
    1083                 parts = item.plit('=') 
    1084                 name = parts[0].strip() 
    1085                 value = parts[1] if len(parts) > 0 else '1.0' 
     1019                defn, desc = item.split('#', 1) if '#' in item else (item, '') 
     1020                name, value = defn.split('=', 1) if '=' in defn else (defn, '1.0') 
    10861021                if name: 
    1087                     yield name, value 
     1022                    yield [v.strip() for v in (name, value, desc)] 
    10881023 
    10891024    def set_function_helper(self, line): 
     
    12181153 
    12191154SUM_TEMPLATE = """ 
    1220 # A sample of an experimental model function for Sum/Multiply(Pmodel1,Pmodel2) 
    1221 import os 
    1222 import sys 
    1223 import copy 
    1224 import collections 
    1225  
    1226 import numpy 
    1227  
    1228 from sas.sascalc.fit.pluginmodel import Model1DPlugin 
    1229 from sasmodels.sasview_model import find_model 
    1230  
    1231 class Model(Model1DPlugin): 
    1232     name = os.path.splitext(os.path.basename(__file__))[0] 
    1233     is_multiplicity_model = False 
    1234     def __init__(self, multiplicity=1): 
    1235         Model1DPlugin.__init__(self, name='') 
    1236         P1 = find_model('%s') 
    1237         P2 = find_model('%s') 
    1238         p_model1 = P1() 
    1239         p_model2 = P2() 
    1240         ## Setting  model name model description 
    1241         self.description = '%s' 
    1242         if self.name.rstrip().lstrip() == '': 
    1243             self.name = self._get_name(p_model1.name, p_model2.name) 
    1244         if self.description.rstrip().lstrip() == '': 
    1245             self.description = p_model1.name 
    1246             self.description += p_model2.name 
    1247             self.fill_description(p_model1, p_model2) 
    1248  
    1249         ## Define parameters 
    1250         self.params = collections.OrderedDict() 
    1251  
    1252         ## Parameter details [units, min, max] 
    1253         self.details = {} 
    1254         ## Magnetic Panrameters 
    1255         self.magnetic_params = [] 
    1256         # non-fittable parameters 
    1257         self.non_fittable = p_model1.non_fittable 
    1258         self.non_fittable += p_model2.non_fittable 
    1259  
    1260         ##models 
    1261         self.p_model1= p_model1 
    1262         self.p_model2= p_model2 
    1263  
    1264  
    1265         ## dispersion 
    1266         self._set_dispersion() 
    1267         ## Define parameters 
    1268         self._set_params() 
    1269         ## New parameter:scaling_factor 
    1270         self.params['scale_factor'] = %s 
    1271  
    1272         ## Parameter details [units, min, max] 
    1273         self._set_details() 
    1274         self.details['scale_factor'] = ['', 0.0, numpy.inf] 
    1275  
    1276  
    1277         #list of parameter that can be fitted 
    1278         self._set_fixed_params() 
    1279  
    1280         ## parameters with orientation 
    1281         self.orientation_params = [] 
    1282         for item in self.p_model1.orientation_params: 
    1283             new_item = "p1_" + item 
    1284             if not new_item in self.orientation_params: 
    1285                 self.orientation_params.append(new_item) 
    1286  
    1287         for item in self.p_model2.orientation_params: 
    1288             new_item = "p2_" + item 
    1289             if not new_item in self.orientation_params: 
    1290                 self.orientation_params.append(new_item) 
    1291         ## magnetic params 
    1292         self.magnetic_params = [] 
    1293         for item in self.p_model1.magnetic_params: 
    1294             new_item = "p1_" + item 
    1295             if not new_item in self.magnetic_params: 
    1296                 self.magnetic_params.append(new_item) 
    1297  
    1298         for item in self.p_model2.magnetic_params: 
    1299             new_item = "p2_" + item 
    1300             if not new_item in self.magnetic_params: 
    1301                 self.magnetic_params.append(new_item) 
    1302         # get multiplicity if model provide it, else 1. 
    1303         try: 
    1304             multiplicity1 = p_model1.multiplicity 
    1305             try: 
    1306                 multiplicity2 = p_model2.multiplicity 
    1307             except: 
    1308                 multiplicity2 = 1 
    1309         except: 
    1310             multiplicity1 = 1 
    1311             multiplicity2 = 1 
    1312         ## functional multiplicity of the model 
    1313         self.multiplicity1 = multiplicity1 
    1314         self.multiplicity2 = multiplicity2 
    1315         self.multiplicity_info = [] 
    1316  
    1317     def _clone(self, obj): 
    1318         import copy 
    1319         obj.params     = copy.deepcopy(self.params) 
    1320         obj.description     = copy.deepcopy(self.description) 
    1321         obj.details    = copy.deepcopy(self.details) 
    1322         obj.dispersion = copy.deepcopy(self.dispersion) 
    1323         obj.p_model1  = self.p_model1.clone() 
    1324         obj.p_model2  = self.p_model2.clone() 
    1325         #obj = copy.deepcopy(self) 
    1326         return obj 
    1327  
    1328     def _get_name(self, name1, name2): 
    1329         p1_name = self._get_upper_name(name1) 
    1330         if not p1_name: 
    1331             p1_name = name1 
    1332         name = p1_name 
    1333         name += "_and_" 
    1334         p2_name = self._get_upper_name(name2) 
    1335         if not p2_name: 
    1336             p2_name = name2 
    1337         name += p2_name 
    1338         return name 
    1339  
    1340     def _get_upper_name(self, name=None): 
    1341         if name is None: 
    1342             return "" 
    1343         upper_name = "" 
    1344         str_name = str(name) 
    1345         for index in range(len(str_name)): 
    1346             if str_name[index].isupper(): 
    1347                 upper_name += str_name[index] 
    1348         return upper_name 
    1349  
    1350     def _set_dispersion(self): 
    1351         self.dispersion = collections.OrderedDict() 
    1352         ##set dispersion only from p_model 
    1353         for name , value in self.p_model1.dispersion.iteritems(): 
    1354             #if name.lower() not in self.p_model1.orientation_params: 
    1355             new_name = "p1_" + name 
    1356             self.dispersion[new_name]= value 
    1357         for name , value in self.p_model2.dispersion.iteritems(): 
    1358             #if name.lower() not in self.p_model2.orientation_params: 
    1359             new_name = "p2_" + name 
    1360             self.dispersion[new_name]= value 
    1361  
    1362     def function(self, x=0.0): 
    1363         return 0 
    1364  
    1365     def getProfile(self): 
    1366         try: 
    1367             x,y = self.p_model1.getProfile() 
    1368         except: 
    1369             x = None 
    1370             y = None 
    1371  
    1372         return x, y 
    1373  
    1374     def _set_params(self): 
    1375         for name , value in self.p_model1.params.iteritems(): 
    1376             # No 2D-supported 
    1377             #if name not in self.p_model1.orientation_params: 
    1378             new_name = "p1_" + name 
    1379             self.params[new_name]= value 
    1380  
    1381         for name , value in self.p_model2.params.iteritems(): 
    1382             # No 2D-supported 
    1383             #if name not in self.p_model2.orientation_params: 
    1384             new_name = "p2_" + name 
    1385             self.params[new_name]= value 
    1386  
    1387         # Set "scale" as initializing 
    1388         self._set_scale_factor() 
    1389  
    1390  
    1391     def _set_details(self): 
    1392         for name ,detail in self.p_model1.details.iteritems(): 
    1393             new_name = "p1_" + name 
    1394             #if new_name not in self.orientation_params: 
    1395             self.details[new_name]= detail 
    1396  
    1397         for name ,detail in self.p_model2.details.iteritems(): 
    1398             new_name = "p2_" + name 
    1399             #if new_name not in self.orientation_params: 
    1400             self.details[new_name]= detail 
    1401  
    1402     def _set_scale_factor(self): 
    1403         pass 
    1404  
    1405  
    1406     def setParam(self, name, value): 
    1407         # set param to this (p1, p2) model 
    1408         self._setParamHelper(name, value) 
    1409  
    1410         ## setParam to p model 
    1411         model_pre = '' 
    1412         new_name = '' 
    1413         name_split = name.split('_', 1) 
    1414         if len(name_split) == 2: 
    1415             model_pre = name.split('_', 1)[0] 
    1416             new_name = name.split('_', 1)[1] 
    1417         if model_pre == "p1": 
    1418             if new_name in self.p_model1.getParamList(): 
    1419                 self.p_model1.setParam(new_name, value) 
    1420         elif model_pre == "p2": 
    1421              if new_name in self.p_model2.getParamList(): 
    1422                 self.p_model2.setParam(new_name, value) 
    1423         elif name == 'scale_factor': 
    1424             self.params['scale_factor'] = value 
    1425         else: 
    1426             raise ValueError, "Model does not contain parameter %s" % name 
    1427  
    1428     def getParam(self, name): 
    1429         # Look for dispersion parameters 
    1430         toks = name.split('.') 
    1431         if len(toks)==2: 
    1432             for item in self.dispersion.keys(): 
    1433                 # 2D not supported 
    1434                 if item.lower()==toks[0].lower(): 
    1435                     for par in self.dispersion[item]: 
    1436                         if par.lower() == toks[1].lower(): 
    1437                             return self.dispersion[item][par] 
    1438         else: 
    1439             # Look for standard parameter 
    1440             for item in self.params.keys(): 
    1441                 if item.lower()==name.lower(): 
    1442                     return self.params[item] 
    1443         return 
    1444         #raise ValueError, "Model does not contain parameter %s" % name 
    1445  
    1446     def _setParamHelper(self, name, value): 
    1447         # Look for dispersion parameters 
    1448         toks = name.split('.') 
    1449         if len(toks)== 2: 
    1450             for item in self.dispersion.keys(): 
    1451                 if item.lower()== toks[0].lower(): 
    1452                     for par in self.dispersion[item]: 
    1453                         if par.lower() == toks[1].lower(): 
    1454                             self.dispersion[item][par] = value 
    1455                             return 
    1456         else: 
    1457             # Look for standard parameter 
    1458             for item in self.params.keys(): 
    1459                 if item.lower()== name.lower(): 
    1460                     self.params[item] = value 
    1461                     return 
    1462  
    1463         raise ValueError, "Model does not contain parameter %s" % name 
    1464  
    1465  
    1466     def _set_fixed_params(self): 
    1467         self.fixed = [] 
    1468         for item in self.p_model1.fixed: 
    1469             new_item = "p1" + item 
    1470             self.fixed.append(new_item) 
    1471         for item in self.p_model2.fixed: 
    1472             new_item = "p2" + item 
    1473             self.fixed.append(new_item) 
    1474  
    1475         self.fixed.sort() 
    1476  
    1477  
    1478     def run(self, x = 0.0): 
    1479         self._set_scale_factor() 
    1480         return self.params['scale_factor'] %s \ 
    1481 (self.p_model1.run(x) %s self.p_model2.run(x)) 
    1482  
    1483     def runXY(self, x = 0.0): 
    1484         self._set_scale_factor() 
    1485         return self.params['scale_factor'] %s \ 
    1486 (self.p_model1.runXY(x) %s self.p_model2.runXY(x)) 
    1487  
    1488     ## Now (May27,10) directly uses the model eval function 
    1489     ## instead of the for-loop in Base Component. 
    1490     def evalDistribution(self, x = []): 
    1491         self._set_scale_factor() 
    1492         return self.params['scale_factor'] %s \ 
    1493 (self.p_model1.evalDistribution(x) %s \ 
    1494 self.p_model2.evalDistribution(x)) 
    1495  
    1496     def set_dispersion(self, parameter, dispersion): 
    1497         value= None 
    1498         new_pre = parameter.split("_", 1)[0] 
    1499         new_parameter = parameter.split("_", 1)[1] 
    1500         try: 
    1501             if new_pre == 'p1' and \ 
    1502 new_parameter in self.p_model1.dispersion.keys(): 
    1503                 value= self.p_model1.set_dispersion(new_parameter, dispersion) 
    1504             if new_pre == 'p2' and \ 
    1505 new_parameter in self.p_model2.dispersion.keys(): 
    1506                 value= self.p_model2.set_dispersion(new_parameter, dispersion) 
    1507             self._set_dispersion() 
    1508             return value 
    1509         except: 
    1510             raise 
    1511  
    1512     def fill_description(self, p_model1, p_model2): 
    1513         description = "" 
    1514         description += "This model gives the summation or multiplication of" 
    1515         description += "%s and %s. "% ( p_model1.name, p_model2.name ) 
    1516         self.description += description 
    1517  
    1518 if __name__ == "__main__": 
    1519     m1= Model() 
    1520     #m1.setParam("p1_scale", 25) 
    1521     #m1.setParam("p1_length", 1000) 
    1522     #m1.setParam("p2_scale", 100) 
    1523     #m1.setParam("p2_rg", 100) 
    1524     out1 = m1.runXY(0.01) 
    1525  
    1526     m2= Model() 
    1527     #m2.p_model1.setParam("scale", 25) 
    1528     #m2.p_model1.setParam("length", 1000) 
    1529     #m2.p_model2.setParam("scale", 100) 
    1530     #m2.p_model2.setParam("rg", 100) 
    1531     out2 = m2.p_model1.runXY(0.01) %s m2.p_model2.runXY(0.01)\n 
    1532     print "My name is %s."% m1.name 
    1533     print out1, " = ", out2 
    1534     if out1 == out2: 
    1535         print "===> Simple Test: Passed!" 
    1536     else: 
    1537         print "===> Simple Test: Failed!" 
     1155from sasmodels.core import load_model_info 
     1156from sasmodels.sasview_model import make_model_from_info 
     1157 
     1158model_info = load_model_info('{model1}{operator}{model2}') 
     1159model_info.name = '{name}'{desc_line} 
     1160Model = make_model_from_info(model_info) 
    15381161""" 
    1539  
    15401162if __name__ == "__main__": 
    15411163    main_app = wx.App() 
Note: See TracChangeset for help on using the changeset viewer.