Changeset 69363c7 in sasview for src/sas/sasgui/perspectives/calculator/model_editor.py
- Timestamp:
- Sep 22, 2017 10:29:48 AM (7 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/calculator/model_editor.py
r277257f r69363c7 109 109 self.model2_string = "cylinder" 110 110 self.name = 'Sum' + M_NAME 111 self.factor = 'scale_factor'112 111 self._notes = '' 113 112 self._operator = '+' … … 136 135 self.model2_name = str(self.model2.GetValue()) 137 136 self.good_name = True 138 self.fill_op rator_combox()137 self.fill_operator_combox() 139 138 140 139 def _layout_name(self): … … 494 493 a sum or multiply model then create the appropriate string 495 494 """ 496 497 495 name = '' 498 499 496 if operator == '*': 500 497 name = 'Multi' 501 factor = 'BackGround' 502 f_oper = '+' 498 factor = 'background' 503 499 else: 504 500 name = 'Sum' 505 501 factor = 'scale_factor' 506 f_oper = '*' 507 508 self.factor = factor 502 509 503 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) 512 506 self.explanationctr.SetLabel(self.explanation) 513 507 self.name = name + M_NAME 514 508 515 509 516 def fill_op rator_combox(self):510 def fill_operator_combox(self): 517 511 """ 518 512 fill the current combobox with the operator … … 530 524 return [self.model1_name, self.model2_name] 531 525 532 def write_string(self, fname, name1, name2):526 def write_string(self, fname, model1_name, model2_name): 533 527 """ 534 528 Write and Save file … … 536 530 self.fname = fname 537 531 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) 609 542 610 543 def compile_file(self, path): … … 646 579 self.name_hsizer = None 647 580 self.name_tcl = None 581 self.overwrite_cb = None 648 582 self.desc_sizer = None 649 583 self.desc_tcl = None … … 692 626 #title name [string] 693 627 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) 698 632 self.name_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1)) 699 633 self.name_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_name) … … 703 637 self.name_tcl.SetToolTipString(hint_name) 704 638 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)]) 706 640 self.name_sizer.AddMany([(name_txt, 0, wx.LEFT | wx.TOP, 10), 707 641 (self.name_hsizer, 0, … … 991 925 info = 'Error' 992 926 color = 'red' 927 self.overwrite_cb.SetValue(True) 928 self.overwrite_name = True 993 929 else: 994 930 self._notes = result … … 1030 966 out_f.write('parameters = [ \n') 1031 967 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): 1033 969 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): 1037 973 param_names.append(pname) 1038 974 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)) 1041 977 out_f.write(' ]\n') 1042 978 … … 1081 1017 for line in param_str.replace(';', ',').split('\n'): 1082 1018 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') 1086 1021 if name: 1087 yield name, value1022 yield [v.strip() for v in (name, value, desc)] 1088 1023 1089 1024 def set_function_helper(self, line): … … 1218 1153 1219 1154 SUM_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!" 1155 from sasmodels.core import load_model_info 1156 from sasmodels.sasview_model import make_model_from_info 1157 1158 model_info = load_model_info('{model1}{operator}{model2}') 1159 model_info.name = '{name}'{desc_line} 1160 Model = make_model_from_info(model_info) 1538 1161 """ 1539 1540 1162 if __name__ == "__main__": 1541 1163 main_app = wx.App()
Note: See TracChangeset
for help on using the changeset viewer.