Changeset c351bf1 in sasview for src/sas/sasgui/perspectives
- Timestamp:
- Sep 1, 2017 5:20:06 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, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 3b0f8cc
- Parents:
- 9d80623
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/calculator/model_editor.py
r9d80623 rc351bf1 521 521 return [self.model1_name, self.model2_name] 522 522 523 def write_string(self, fname, name1, name2):523 def write_string(self, fname, model1_name, model2_name): 524 524 """ 525 525 Write and Save file … … 527 527 self.fname = fname 528 528 description = self.desc_tcl.GetValue().lstrip().rstrip() 529 if description == '': 530 description = name1 + self._operator + name2 531 operator_text = self._operator_choice.GetValue() 532 f_oper = '*' if '+' in operator_text else '+' 533 path = self.fname 534 output = SUM_TEMPLATE.format(model1=name1, model2=name2, 535 scale_factor_default=1.0, background_default=0.001, 536 factor_operator=f_oper, operator=self._operator, 537 description=description) 538 if self._operator == '*': 539 # Multiplication models only have 1 overall scale factor. Don't use 540 # sub-models' individual scales as fitting params 541 output = output.replace("if name == 'background'", 542 "if name == 'background' or name == 'scale'") 529 desc_line = '' 530 if description.strip() != '': 531 # Sasmodels generates a description for us. If the user provides 532 # their own description, add a line to overwrite the sasmodels one 533 desc_line = "\nmodel_info.description = '{}'".format(description) 534 name = os.path.splitext(os.path.basename(self.fname))[0] 535 output = SUM_TEMPLATE.format(name=name, model1=model1_name, 536 model2=model2_name, operator=self._operator, desc_line=desc_line) 543 537 with open(self.fname, 'w') as out_f: 544 out_f.write(output + "\n")538 out_f.write(output) 545 539 546 540 def compile_file(self, path): … … 1217 1211 """ 1218 1212 SUM_TEMPLATE = """ 1219 # A sample of an experimental model function for Sum/Multiply(Pmodel1,Pmodel2) 1220 import os 1221 import sys 1222 import copy 1223 import collections 1224 1225 import numpy 1226 1227 from sas.sascalc.fit.pluginmodel import Model1DPlugin 1228 from sasmodels.sasview_model import find_model 1229 1230 class Model(Model1DPlugin): 1231 name = os.path.splitext(os.path.basename(__file__))[0] 1232 is_multiplicity_model = False 1233 def __init__(self, multiplicity=1): 1234 Model1DPlugin.__init__(self, name='') 1235 P1 = find_model('{model1}') 1236 P2 = find_model('{model2}') 1237 p_model1 = P1() 1238 p_model2 = P2() 1239 ## Setting model name model description 1240 self.description = '{description}' 1241 if self.name.rstrip().lstrip() == '': 1242 self.name = self._get_name(p_model1.name, p_model2.name) 1243 if self.description.rstrip().lstrip() == '': 1244 self.description = p_model1.name 1245 self.description += p_model2.name 1246 self.fill_description(p_model1, p_model2) 1247 1248 ## Define parameters 1249 self.params = collections.OrderedDict() 1250 1251 ## Parameter details [units, min, max] 1252 self.details = {{}} 1253 ## Magnetic Panrameters 1254 self.magnetic_params = [] 1255 # non-fittable parameters 1256 self.non_fittable = p_model1.non_fittable 1257 self.non_fittable += p_model2.non_fittable 1258 1259 ##models 1260 self.p_model1= p_model1 1261 self.p_model2= p_model2 1262 1263 1264 ## dispersion 1265 self._set_dispersion() 1266 ## Define parameters 1267 self._set_params() 1268 ## New parameter:scaling_factor 1269 self.params['scale_factor'] = {scale_factor_default} 1270 # Set each model's background to 0, and define our own background param 1271 if 'background' in self.p_model1.params: 1272 self.p_model1.setParam('background', 0.0) 1273 if 'background' in self.p_model2.params: 1274 self.p_model2.setParam('background', 0.0) 1275 self.params['background'] = {background_default} 1276 1277 ## Parameter details [units, min, max] 1278 self._set_details() 1279 self.details['scale_factor'] = ['', 0.0, numpy.inf] 1280 self.details['background'] = ['1/cm', 0.0, numpy.inf] 1281 1282 #list of parameter that can be fitted 1283 self._set_fixed_params() 1284 1285 ## parameters with orientation 1286 self.orientation_params = [] 1287 for item in self.p_model1.orientation_params: 1288 new_item = "p1_" + item 1289 if not new_item in self.orientation_params: 1290 self.orientation_params.append(new_item) 1291 1292 for item in self.p_model2.orientation_params: 1293 new_item = "p2_" + item 1294 if not new_item in self.orientation_params: 1295 self.orientation_params.append(new_item) 1296 ## magnetic params 1297 self.magnetic_params = [] 1298 for item in self.p_model1.magnetic_params: 1299 new_item = "p1_" + item 1300 if not new_item in self.magnetic_params: 1301 self.magnetic_params.append(new_item) 1302 1303 for item in self.p_model2.magnetic_params: 1304 new_item = "p2_" + item 1305 if not new_item in self.magnetic_params: 1306 self.magnetic_params.append(new_item) 1307 # get multiplicity if model provide it, else 1. 1308 try: 1309 multiplicity1 = p_model1.multiplicity 1310 try: 1311 multiplicity2 = p_model2.multiplicity 1312 except: 1313 multiplicity2 = 1 1314 except: 1315 multiplicity1 = 1 1316 multiplicity2 = 1 1317 ## functional multiplicity of the model 1318 self.multiplicity1 = multiplicity1 1319 self.multiplicity2 = multiplicity2 1320 self.multiplicity_info = [] 1321 1322 def _clone(self, obj): 1323 import copy 1324 obj.params = copy.deepcopy(self.params) 1325 obj.description = copy.deepcopy(self.description) 1326 obj.details = copy.deepcopy(self.details) 1327 obj.dispersion = copy.deepcopy(self.dispersion) 1328 obj.p_model1 = self.p_model1.clone() 1329 obj.p_model2 = self.p_model2.clone() 1330 #obj = copy.deepcopy(self) 1331 return obj 1332 1333 def _get_name(self, name1, name2): 1334 p1_name = self._get_upper_name(name1) 1335 if not p1_name: 1336 p1_name = name1 1337 name = p1_name 1338 name += "_and_" 1339 p2_name = self._get_upper_name(name2) 1340 if not p2_name: 1341 p2_name = name2 1342 name += p2_name 1343 return name 1344 1345 def _get_upper_name(self, name=None): 1346 if name is None: 1347 return "" 1348 upper_name = "" 1349 str_name = str(name) 1350 for index in range(len(str_name)): 1351 if str_name[index].isupper(): 1352 upper_name += str_name[index] 1353 return upper_name 1354 1355 def _set_dispersion(self): 1356 self.dispersion = collections.OrderedDict() 1357 ##set dispersion only from p_model 1358 for name , value in self.p_model1.dispersion.iteritems(): 1359 #if name.lower() not in self.p_model1.orientation_params: 1360 new_name = "p1_" + name 1361 self.dispersion[new_name]= value 1362 for name , value in self.p_model2.dispersion.iteritems(): 1363 #if name.lower() not in self.p_model2.orientation_params: 1364 new_name = "p2_" + name 1365 self.dispersion[new_name]= value 1366 1367 def function(self, x=0.0): 1368 return 0 1369 1370 def getProfile(self): 1371 try: 1372 x,y = self.p_model1.getProfile() 1373 except: 1374 x = None 1375 y = None 1376 1377 return x, y 1378 1379 def _set_params(self): 1380 for name , value in self.p_model1.params.iteritems(): 1381 # Don't use the model's background param - we've defined our own 1382 if name == 'background': 1383 continue 1384 new_name = "p1_" + name 1385 self.params[new_name] = value 1386 1387 for name , value in self.p_model2.params.iteritems(): 1388 # Don't use the model's background param - we've defined our own 1389 if name == 'background': 1390 continue 1391 new_name = "p2_" + name 1392 self.params[new_name] = value 1393 1394 # Set "scale" as initializing 1395 self._set_scale_factor() 1396 1397 1398 def _set_details(self): 1399 for name ,detail in self.p_model1.details.iteritems(): 1400 if name == 'background': 1401 continue 1402 new_name = "p1_" + name 1403 #if new_name not in self.orientation_params: 1404 self.details[new_name]= detail 1405 1406 for name ,detail in self.p_model2.details.iteritems(): 1407 if name == 'background': 1408 continue 1409 new_name = "p2_" + name 1410 #if new_name not in self.orientation_params: 1411 self.details[new_name]= detail 1412 1413 def _set_scale_factor(self): 1414 pass 1415 1416 1417 def setParam(self, name, value): 1418 # set param to this (p1, p2) model 1419 self._setParamHelper(name, value) 1420 1421 ## setParam to p model 1422 model_pre = '' 1423 new_name = '' 1424 name_split = name.split('_', 1) 1425 if len(name_split) == 2: 1426 model_pre = name.split('_', 1)[0] 1427 new_name = name.split('_', 1)[1] 1428 if model_pre == "p1": 1429 if new_name in self.p_model1.getParamList(): 1430 self.p_model1.setParam(new_name, value) 1431 elif model_pre == "p2": 1432 if new_name in self.p_model2.getParamList(): 1433 self.p_model2.setParam(new_name, value) 1434 elif name == 'scale_factor' or name == 'background': 1435 self.params[name] = value 1436 else: 1437 raise ValueError, "Model does not contain parameter %s" % name 1438 1439 def getParam(self, name): 1440 # Look for dispersion parameters 1441 toks = name.split('.') 1442 if len(toks)==2: 1443 for item in self.dispersion.keys(): 1444 # 2D not supported 1445 if item.lower()==toks[0].lower(): 1446 for par in self.dispersion[item]: 1447 if par.lower() == toks[1].lower(): 1448 return self.dispersion[item][par] 1449 else: 1450 # Look for standard parameter 1451 for item in self.params.keys(): 1452 if item.lower()==name.lower(): 1453 return self.params[item] 1454 return 1455 #raise ValueError, "Model does not contain parameter %s" % name 1456 1457 def _setParamHelper(self, name, value): 1458 # Look for dispersion parameters 1459 toks = name.split('.') 1460 if len(toks)== 2: 1461 for item in self.dispersion.keys(): 1462 if item.lower()== toks[0].lower(): 1463 for par in self.dispersion[item]: 1464 if par.lower() == toks[1].lower(): 1465 self.dispersion[item][par] = value 1466 return 1467 else: 1468 # Look for standard parameter 1469 for item in self.params.keys(): 1470 if item.lower()== name.lower(): 1471 self.params[item] = value 1472 return 1473 1474 raise ValueError, "Model does not contain parameter %s" % name 1475 1476 1477 def _set_fixed_params(self): 1478 self.fixed = [] 1479 for item in self.p_model1.fixed: 1480 new_item = "p1" + item 1481 self.fixed.append(new_item) 1482 for item in self.p_model2.fixed: 1483 new_item = "p2" + item 1484 self.fixed.append(new_item) 1485 1486 self.fixed.sort() 1487 1488 1489 def run(self, x = 0.0): 1490 self._set_scale_factor() 1491 return self.params['scale_factor'] {factor_operator} \ 1492 (self.p_model1.run(x) {operator} self.p_model2.run(x)) + self.params['background'] 1493 1494 def runXY(self, x = 0.0): 1495 self._set_scale_factor() 1496 return self.params['scale_factor'] {factor_operator} \ 1497 (self.p_model1.runXY(x) {operator} self.p_model2.runXY(x)) + self.params['background'] 1498 1499 ## Now (May27,10) directly uses the model eval function 1500 ## instead of the for-loop in Base Component. 1501 def evalDistribution(self, x = []): 1502 self._set_scale_factor() 1503 return self.params['scale_factor'] {factor_operator} \ 1504 (self.p_model1.evalDistribution(x) {operator} \ 1505 self.p_model2.evalDistribution(x)) + self.params['background'] 1506 1507 def set_dispersion(self, parameter, dispersion): 1508 value= None 1509 new_pre = parameter.split("_", 1)[0] 1510 new_parameter = parameter.split("_", 1)[1] 1511 try: 1512 if new_pre == 'p1' and \ 1513 new_parameter in self.p_model1.dispersion.keys(): 1514 value= self.p_model1.set_dispersion(new_parameter, dispersion) 1515 if new_pre == 'p2' and \ 1516 new_parameter in self.p_model2.dispersion.keys(): 1517 value= self.p_model2.set_dispersion(new_parameter, dispersion) 1518 self._set_dispersion() 1519 return value 1520 except: 1521 raise 1522 1523 def fill_description(self, p_model1, p_model2): 1524 description = "" 1525 description += "This model gives the summation or multiplication of" 1526 description += "%s and %s. "% ( p_model1.name, p_model2.name ) 1527 self.description += description 1528 1529 if __name__ == "__main__": 1530 m1= Model() 1531 #m1.setParam("p1_scale", 25) 1532 #m1.setParam("p1_length", 1000) 1533 #m1.setParam("p2_scale", 100) 1534 #m1.setParam("p2_rg", 100) 1535 out1 = m1.runXY(0.01) 1536 1537 m2= Model() 1538 #m2.p_model1.setParam("scale", 25) 1539 #m2.p_model1.setParam("length", 1000) 1540 #m2.p_model2.setParam("scale", 100) 1541 #m2.p_model2.setParam("rg", 100) 1542 out2 = m2.p_model1.runXY(0.01) {operator} m2.p_model2.runXY(0.01)\n 1543 print "My name is %s."% m1.name 1544 print out1, " = ", out2 1545 if out1 == out2: 1546 print "===> Simple Test: Passed!" 1547 else: 1548 print "===> Simple Test: Failed!" 1213 from sasmodels.core import load_model_info 1214 from sasmodels.sasview_model import make_model_from_info 1215 1216 model_info = load_model_info('{model1}{operator}{model2}', force_mixture=True) 1217 model_info.name = '{name}'{desc_line} 1218 Model = make_model_from_info(model_info) 1549 1219 """ 1550 1551 1220 if __name__ == "__main__": 1552 1221 # app = wx.PySimpleApp()
Note: See TracChangeset
for help on using the changeset viewer.