Changes in / [632fda9:66acafe] in sasview


Ignore:
Files:
4 added
18 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • sasview/sasview.py

    rf36e01f r3b0f8cc  
    7474PLUGIN_MODEL_DIR = 'plugin_models' 
    7575APP_NAME = 'SasView' 
     76 
     77# Set SAS_MODELPATH so sasmodels can find our custom models 
     78os.environ['SAS_MODELPATH'] = os.path.join(sasdir, PLUGIN_MODEL_DIR) 
    7679 
    7780from matplotlib import backend_bases 
  • src/sas/sasgui/perspectives/calculator/image_viewer.py

    ra1b8fee r412e9e8b  
    5959            _, extension = os.path.splitext(basename) 
    6060            try: 
     61                # Note that matplotlib only reads png natively. 
     62                # Any other formats (tiff, jpeg, etc) are passed 
     63                # to PIL which seems to have a problem in version 
     64                # 1.1.7 that causes a close error which shows up in  
     65                # the log file.  This does not seem to have any adverse 
     66                # effects.  PDB   --- September 17, 2017. 
    6167                img = mpimg.imread(file_path) 
    6268                is_png = extension.lower() == '.png' 
     
    8995        if location is None: 
    9096            location = os.getcwd() 
    91         dlg = wx.FileDialog(self.parent, "Image Viewer: Choose a image file", 
    92                             location, "", "", style=wx.FD_OPEN | wx.FD_MULTIPLE) 
     97        wildcard="Images (*.bmp;*.gif;*jpeg,*jpg;*.png;*tif;*.tiff)|*bmp;\ 
     98            *.gif; *.jpg; *.jpeg;*png;*.png;*.tif;*.tiff|"\ 
     99            "Bitmap (*.bmp)|*.bmp|"\ 
     100            "GIF (*.gif)|*.gif|"\ 
     101            "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|"\ 
     102            "PNG (*.png)|*.png|"\ 
     103            "TIFF (*.tif;*.tiff)|*.tif;*tiff|"\ 
     104            "All Files (*.*)|*.*|" 
     105 
     106        dlg = wx.FileDialog(self.parent, "Image Viewer: Choose an image file", 
     107                            location, "", wildcard, style=wx.FD_OPEN 
     108                            | wx.FD_MULTIPLE) 
    93109        if dlg.ShowModal() == wx.ID_OK: 
    94110            path = dlg.GetPaths() 
  • src/sas/sasgui/perspectives/calculator/media/image_viewer_help.rst

    rda456fb r412e9e8b  
    3434   will be displayed. 
    3535 
    36 .. image:: load_image.bmp 
     36.. image:: load_image.png 
    3737 
    38383) To save, print, or copy the image, or to apply a grid overlay, right-click  
    3939   anywhere in the plot. 
    4040 
    41 .. image:: pic_plot.bmp 
     41.. image:: pic_plot.png 
    4242 
    43434. If the image is taken from a 2D detector, SasView can attempt to convert  
     
    5151   then click the OK. 
    5252 
    53 .. image:: pic_convert.bmp 
     53.. image:: pic_convert.png 
    5454 
    5555.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    r07ec714 r23359ccb  
    106106        self.model2_string = "cylinder" 
    107107        self.name = 'Sum' + M_NAME 
    108         self.factor = 'scale_factor' 
    109108        self._notes = '' 
    110109        self._operator = '+' 
     
    133132        self.model2_name = str(self.model2.GetValue()) 
    134133        self.good_name = True 
    135         self.fill_oprator_combox() 
     134        self.fill_operator_combox() 
    136135 
    137136    def _layout_name(self): 
     
    491490        a sum or multiply model then create the appropriate string 
    492491        """ 
    493  
    494492        name = '' 
    495  
    496493        if operator == '*': 
    497494            name = 'Multi' 
    498             factor = 'BackGround' 
    499             f_oper = '+' 
     495            factor = 'background' 
    500496        else: 
    501497            name = 'Sum' 
    502498            factor = 'scale_factor' 
    503             f_oper = '*' 
    504  
    505         self.factor = factor 
     499 
    506500        self._operator = operator 
    507         self.explanation = "  Plugin Model = %s %s (model1 %s model2)\n" % \ 
    508                            (self.factor, f_oper, self._operator) 
     501        self.explanation = ("  Plugin_model = scale_factor * (model_1 {} " 
     502            "model_2) + background").format(operator) 
    509503        self.explanationctr.SetLabel(self.explanation) 
    510504        self.name = name + M_NAME 
    511505 
    512506 
    513     def fill_oprator_combox(self): 
     507    def fill_operator_combox(self): 
    514508        """ 
    515509        fill the current combobox with the operator 
     
    527521        return [self.model1_name, self.model2_name] 
    528522 
    529     def write_string(self, fname, name1, name2): 
     523    def write_string(self, fname, model1_name, model2_name): 
    530524        """ 
    531525        Write and Save file 
     
    533527        self.fname = fname 
    534528        description = self.desc_tcl.GetValue().lstrip().rstrip() 
    535         if description == '': 
    536             description = name1 + self._operator + name2 
    537         text = self._operator_choice.GetValue() 
    538         if text.count('+') > 0: 
    539             factor = 'scale_factor' 
    540             f_oper = '*' 
    541             default_val = '1.0' 
    542         else: 
    543             factor = 'BackGround' 
    544             f_oper = '+' 
    545             default_val = '0.0' 
    546         path = self.fname 
    547         try: 
    548             out_f = open(path, 'w') 
    549         except: 
    550             raise 
    551         lines = SUM_TEMPLATE.split('\n') 
    552         for line in lines: 
    553             try: 
    554                 if line.count("scale_factor"): 
    555                     line = line.replace('scale_factor', factor) 
    556                     #print "scale_factor", line 
    557                 if line.count("= %s"): 
    558                     out_f.write(line % (default_val) + "\n") 
    559                 elif line.count("import Model as P1"): 
    560                     if self.is_p1_custom: 
    561                         line = line.replace('#', '') 
    562                         out_f.write(line % name1 + "\n") 
    563                     else: 
    564                         out_f.write(line + "\n") 
    565                 elif line.count("import %s as P1"): 
    566                     if not self.is_p1_custom: 
    567                         line = line.replace('#', '') 
    568                         out_f.write(line % (name1) + "\n") 
    569                     else: 
    570                         out_f.write(line + "\n") 
    571                 elif line.count("import Model as P2"): 
    572                     if self.is_p2_custom: 
    573                         line = line.replace('#', '') 
    574                         out_f.write(line % name2 + "\n") 
    575                     else: 
    576                         out_f.write(line + "\n") 
    577                 elif line.count("import %s as P2"): 
    578                     if not self.is_p2_custom: 
    579                         line = line.replace('#', '') 
    580                         out_f.write(line % (name2) + "\n") 
    581                     else: 
    582                         out_f.write(line + "\n") 
    583                 elif line.count("P1 = find_model"): 
    584                     out_f.write(line % (name1) + "\n") 
    585                 elif line.count("P2 = find_model"): 
    586                     out_f.write(line % (name2) + "\n") 
    587  
    588                 elif line.count("self.description = '%s'"): 
    589                     out_f.write(line % description + "\n") 
    590                 #elif line.count("run") and line.count("%s"): 
    591                 #    out_f.write(line % self._operator + "\n") 
    592                 #elif line.count("evalDistribution") and line.count("%s"): 
    593                 #    out_f.write(line % self._operator + "\n") 
    594                 elif line.count("return") and line.count("%s") == 2: 
    595                     #print "line return", line 
    596                     out_f.write(line % (f_oper, self._operator) + "\n") 
    597                 elif line.count("out2")and line.count("%s"): 
    598                     out_f.write(line % self._operator + "\n") 
    599                 else: 
    600                     out_f.write(line + "\n") 
    601             except: 
    602                 raise 
    603         out_f.close() 
    604         #else: 
    605         #    msg = "Name exists already." 
     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) 
     537        with open(self.fname, 'w') as out_f: 
     538            out_f.write(output) 
    606539 
    607540    def compile_file(self, path): 
     
    12781211""" 
    12791212SUM_TEMPLATE = """ 
    1280 # A sample of an experimental model function for Sum/Multiply(Pmodel1,Pmodel2) 
    1281 import os 
    1282 import sys 
    1283 import copy 
    1284 import collections 
    1285  
    1286 import numpy 
    1287  
    1288 from sas.sascalc.fit.pluginmodel import Model1DPlugin 
    1289 from sasmodels.sasview_model import find_model 
    1290  
    1291 class Model(Model1DPlugin): 
    1292     name = os.path.splitext(os.path.basename(__file__))[0] 
    1293     is_multiplicity_model = False 
    1294     def __init__(self, multiplicity=1): 
    1295         Model1DPlugin.__init__(self, name='') 
    1296         P1 = find_model('%s') 
    1297         P2 = find_model('%s') 
    1298         p_model1 = P1() 
    1299         p_model2 = P2() 
    1300         ## Setting  model name model description 
    1301         self.description = '%s' 
    1302         if self.name.rstrip().lstrip() == '': 
    1303             self.name = self._get_name(p_model1.name, p_model2.name) 
    1304         if self.description.rstrip().lstrip() == '': 
    1305             self.description = p_model1.name 
    1306             self.description += p_model2.name 
    1307             self.fill_description(p_model1, p_model2) 
    1308  
    1309         ## Define parameters 
    1310         self.params = collections.OrderedDict() 
    1311  
    1312         ## Parameter details [units, min, max] 
    1313         self.details = {} 
    1314         ## Magnetic Panrameters 
    1315         self.magnetic_params = [] 
    1316         # non-fittable parameters 
    1317         self.non_fittable = p_model1.non_fittable 
    1318         self.non_fittable += p_model2.non_fittable 
    1319  
    1320         ##models 
    1321         self.p_model1= p_model1 
    1322         self.p_model2= p_model2 
    1323  
    1324  
    1325         ## dispersion 
    1326         self._set_dispersion() 
    1327         ## Define parameters 
    1328         self._set_params() 
    1329         ## New parameter:scaling_factor 
    1330         self.params['scale_factor'] = %s 
    1331  
    1332         ## Parameter details [units, min, max] 
    1333         self._set_details() 
    1334         self.details['scale_factor'] = ['', 0.0, numpy.inf] 
    1335  
    1336  
    1337         #list of parameter that can be fitted 
    1338         self._set_fixed_params() 
    1339  
    1340         ## parameters with orientation 
    1341         self.orientation_params = [] 
    1342         for item in self.p_model1.orientation_params: 
    1343             new_item = "p1_" + item 
    1344             if not new_item in self.orientation_params: 
    1345                 self.orientation_params.append(new_item) 
    1346  
    1347         for item in self.p_model2.orientation_params: 
    1348             new_item = "p2_" + item 
    1349             if not new_item in self.orientation_params: 
    1350                 self.orientation_params.append(new_item) 
    1351         ## magnetic params 
    1352         self.magnetic_params = [] 
    1353         for item in self.p_model1.magnetic_params: 
    1354             new_item = "p1_" + item 
    1355             if not new_item in self.magnetic_params: 
    1356                 self.magnetic_params.append(new_item) 
    1357  
    1358         for item in self.p_model2.magnetic_params: 
    1359             new_item = "p2_" + item 
    1360             if not new_item in self.magnetic_params: 
    1361                 self.magnetic_params.append(new_item) 
    1362         # get multiplicity if model provide it, else 1. 
    1363         try: 
    1364             multiplicity1 = p_model1.multiplicity 
    1365             try: 
    1366                 multiplicity2 = p_model2.multiplicity 
    1367             except: 
    1368                 multiplicity2 = 1 
    1369         except: 
    1370             multiplicity1 = 1 
    1371             multiplicity2 = 1 
    1372         ## functional multiplicity of the model 
    1373         self.multiplicity1 = multiplicity1 
    1374         self.multiplicity2 = multiplicity2 
    1375         self.multiplicity_info = [] 
    1376  
    1377     def _clone(self, obj): 
    1378         import copy 
    1379         obj.params     = copy.deepcopy(self.params) 
    1380         obj.description     = copy.deepcopy(self.description) 
    1381         obj.details    = copy.deepcopy(self.details) 
    1382         obj.dispersion = copy.deepcopy(self.dispersion) 
    1383         obj.p_model1  = self.p_model1.clone() 
    1384         obj.p_model2  = self.p_model2.clone() 
    1385         #obj = copy.deepcopy(self) 
    1386         return obj 
    1387  
    1388     def _get_name(self, name1, name2): 
    1389         p1_name = self._get_upper_name(name1) 
    1390         if not p1_name: 
    1391             p1_name = name1 
    1392         name = p1_name 
    1393         name += "_and_" 
    1394         p2_name = self._get_upper_name(name2) 
    1395         if not p2_name: 
    1396             p2_name = name2 
    1397         name += p2_name 
    1398         return name 
    1399  
    1400     def _get_upper_name(self, name=None): 
    1401         if name is None: 
    1402             return "" 
    1403         upper_name = "" 
    1404         str_name = str(name) 
    1405         for index in range(len(str_name)): 
    1406             if str_name[index].isupper(): 
    1407                 upper_name += str_name[index] 
    1408         return upper_name 
    1409  
    1410     def _set_dispersion(self): 
    1411         self.dispersion = collections.OrderedDict() 
    1412         ##set dispersion only from p_model 
    1413         for name , value in self.p_model1.dispersion.iteritems(): 
    1414             #if name.lower() not in self.p_model1.orientation_params: 
    1415             new_name = "p1_" + name 
    1416             self.dispersion[new_name]= value 
    1417         for name , value in self.p_model2.dispersion.iteritems(): 
    1418             #if name.lower() not in self.p_model2.orientation_params: 
    1419             new_name = "p2_" + name 
    1420             self.dispersion[new_name]= value 
    1421  
    1422     def function(self, x=0.0): 
    1423         return 0 
    1424  
    1425     def getProfile(self): 
    1426         try: 
    1427             x,y = self.p_model1.getProfile() 
    1428         except: 
    1429             x = None 
    1430             y = None 
    1431  
    1432         return x, y 
    1433  
    1434     def _set_params(self): 
    1435         for name , value in self.p_model1.params.iteritems(): 
    1436             # No 2D-supported 
    1437             #if name not in self.p_model1.orientation_params: 
    1438             new_name = "p1_" + name 
    1439             self.params[new_name]= value 
    1440  
    1441         for name , value in self.p_model2.params.iteritems(): 
    1442             # No 2D-supported 
    1443             #if name not in self.p_model2.orientation_params: 
    1444             new_name = "p2_" + name 
    1445             self.params[new_name]= value 
    1446  
    1447         # Set "scale" as initializing 
    1448         self._set_scale_factor() 
    1449  
    1450  
    1451     def _set_details(self): 
    1452         for name ,detail in self.p_model1.details.iteritems(): 
    1453             new_name = "p1_" + name 
    1454             #if new_name not in self.orientation_params: 
    1455             self.details[new_name]= detail 
    1456  
    1457         for name ,detail in self.p_model2.details.iteritems(): 
    1458             new_name = "p2_" + name 
    1459             #if new_name not in self.orientation_params: 
    1460             self.details[new_name]= detail 
    1461  
    1462     def _set_scale_factor(self): 
    1463         pass 
    1464  
    1465  
    1466     def setParam(self, name, value): 
    1467         # set param to this (p1, p2) model 
    1468         self._setParamHelper(name, value) 
    1469  
    1470         ## setParam to p model 
    1471         model_pre = '' 
    1472         new_name = '' 
    1473         name_split = name.split('_', 1) 
    1474         if len(name_split) == 2: 
    1475             model_pre = name.split('_', 1)[0] 
    1476             new_name = name.split('_', 1)[1] 
    1477         if model_pre == "p1": 
    1478             if new_name in self.p_model1.getParamList(): 
    1479                 self.p_model1.setParam(new_name, value) 
    1480         elif model_pre == "p2": 
    1481              if new_name in self.p_model2.getParamList(): 
    1482                 self.p_model2.setParam(new_name, value) 
    1483         elif name == 'scale_factor': 
    1484             self.params['scale_factor'] = value 
    1485         else: 
    1486             raise ValueError, "Model does not contain parameter %s" % name 
    1487  
    1488     def getParam(self, name): 
    1489         # Look for dispersion parameters 
    1490         toks = name.split('.') 
    1491         if len(toks)==2: 
    1492             for item in self.dispersion.keys(): 
    1493                 # 2D not supported 
    1494                 if item.lower()==toks[0].lower(): 
    1495                     for par in self.dispersion[item]: 
    1496                         if par.lower() == toks[1].lower(): 
    1497                             return self.dispersion[item][par] 
    1498         else: 
    1499             # Look for standard parameter 
    1500             for item in self.params.keys(): 
    1501                 if item.lower()==name.lower(): 
    1502                     return self.params[item] 
    1503         return 
    1504         #raise ValueError, "Model does not contain parameter %s" % name 
    1505  
    1506     def _setParamHelper(self, name, value): 
    1507         # Look for dispersion parameters 
    1508         toks = name.split('.') 
    1509         if len(toks)== 2: 
    1510             for item in self.dispersion.keys(): 
    1511                 if item.lower()== toks[0].lower(): 
    1512                     for par in self.dispersion[item]: 
    1513                         if par.lower() == toks[1].lower(): 
    1514                             self.dispersion[item][par] = value 
    1515                             return 
    1516         else: 
    1517             # Look for standard parameter 
    1518             for item in self.params.keys(): 
    1519                 if item.lower()== name.lower(): 
    1520                     self.params[item] = value 
    1521                     return 
    1522  
    1523         raise ValueError, "Model does not contain parameter %s" % name 
    1524  
    1525  
    1526     def _set_fixed_params(self): 
    1527         self.fixed = [] 
    1528         for item in self.p_model1.fixed: 
    1529             new_item = "p1" + item 
    1530             self.fixed.append(new_item) 
    1531         for item in self.p_model2.fixed: 
    1532             new_item = "p2" + item 
    1533             self.fixed.append(new_item) 
    1534  
    1535         self.fixed.sort() 
    1536  
    1537  
    1538     def run(self, x = 0.0): 
    1539         self._set_scale_factor() 
    1540         return self.params['scale_factor'] %s \ 
    1541 (self.p_model1.run(x) %s self.p_model2.run(x)) 
    1542  
    1543     def runXY(self, x = 0.0): 
    1544         self._set_scale_factor() 
    1545         return self.params['scale_factor'] %s \ 
    1546 (self.p_model1.runXY(x) %s self.p_model2.runXY(x)) 
    1547  
    1548     ## Now (May27,10) directly uses the model eval function 
    1549     ## instead of the for-loop in Base Component. 
    1550     def evalDistribution(self, x = []): 
    1551         self._set_scale_factor() 
    1552         return self.params['scale_factor'] %s \ 
    1553 (self.p_model1.evalDistribution(x) %s \ 
    1554 self.p_model2.evalDistribution(x)) 
    1555  
    1556     def set_dispersion(self, parameter, dispersion): 
    1557         value= None 
    1558         new_pre = parameter.split("_", 1)[0] 
    1559         new_parameter = parameter.split("_", 1)[1] 
    1560         try: 
    1561             if new_pre == 'p1' and \ 
    1562 new_parameter in self.p_model1.dispersion.keys(): 
    1563                 value= self.p_model1.set_dispersion(new_parameter, dispersion) 
    1564             if new_pre == 'p2' and \ 
    1565 new_parameter in self.p_model2.dispersion.keys(): 
    1566                 value= self.p_model2.set_dispersion(new_parameter, dispersion) 
    1567             self._set_dispersion() 
    1568             return value 
    1569         except: 
    1570             raise 
    1571  
    1572     def fill_description(self, p_model1, p_model2): 
    1573         description = "" 
    1574         description += "This model gives the summation or multiplication of" 
    1575         description += "%s and %s. "% ( p_model1.name, p_model2.name ) 
    1576         self.description += description 
    1577  
    1578 if __name__ == "__main__": 
    1579     m1= Model() 
    1580     #m1.setParam("p1_scale", 25) 
    1581     #m1.setParam("p1_length", 1000) 
    1582     #m1.setParam("p2_scale", 100) 
    1583     #m1.setParam("p2_rg", 100) 
    1584     out1 = m1.runXY(0.01) 
    1585  
    1586     m2= Model() 
    1587     #m2.p_model1.setParam("scale", 25) 
    1588     #m2.p_model1.setParam("length", 1000) 
    1589     #m2.p_model2.setParam("scale", 100) 
    1590     #m2.p_model2.setParam("rg", 100) 
    1591     out2 = m2.p_model1.runXY(0.01) %s m2.p_model2.runXY(0.01)\n 
    1592     print "My name is %s."% m1.name 
    1593     print out1, " = ", out2 
    1594     if out1 == out2: 
    1595         print "===> Simple Test: Passed!" 
    1596     else: 
    1597         print "===> Simple Test: Failed!" 
     1213from sasmodels.core import load_model_info 
     1214from sasmodels.sasview_model import make_model_from_info 
     1215 
     1216model_info = load_model_info('{model1}{operator}{model2}') 
     1217model_info.name = '{name}'{desc_line} 
     1218Model = make_model_from_info(model_info) 
    15981219""" 
    1599  
    16001220if __name__ == "__main__": 
    16011221#    app = wx.PySimpleApp() 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r33dc18f r33dc18f  
    29282928            return False 
    29292929 
     2930 
     2931    def _get_copy_params_details(self): 
     2932        """ 
     2933        Combines polydisperse parameters with self.parameters so that they can 
     2934        be written to the clipboard (for Excel or LaTeX). Also returns a list of 
     2935        the names of parameters that have been fitted 
     2936 
     2937        :returns: all_params - A list of all parameters, in the format of  
     2938        self.parameters 
     2939        :returns: fitted_par_names - A list of the names of parameters that have 
     2940        been fitted 
     2941        """ 
     2942        # Names of params that are being fitted 
     2943        fitted_par_names = [param[1] for param in self.param_toFit] 
     2944        # Names of params with associated polydispersity 
     2945        disp_params = [param[1].split('.')[0] for param in self.fittable_param] 
     2946 
     2947        # Create array of all parameters 
     2948        all_params = copy.copy(self.parameters) 
     2949        for param in self.parameters: 
     2950            if param[1] in disp_params: 
     2951                # Polydisperse params aren't in self.parameters, so need adding 
     2952                # to all_params 
     2953                name = param[1] + ".width" 
     2954                index = all_params.index(param) + 1 
     2955                to_insert = [] 
     2956                if name in fitted_par_names: 
     2957                    # Param is fitted, so already has a param list in self.param_toFit 
     2958                    to_insert = self.param_toFit[fitted_par_names.index(name)] 
     2959                else: 
     2960                    # Param isn't fitted, so mockup a param list 
     2961                    to_insert = [None, name, self.model.getParam(name), None, None] 
     2962                all_params.insert(index, to_insert) 
     2963        return all_params, fitted_par_names 
     2964 
    29302965    def get_copy_excel(self): 
    29312966        """ 
     
    29412976        Get the string copies of the param names and values in the tap 
    29422977        """ 
     2978        if not self.parameters: 
     2979            # Do nothing if parameters doesn't exist 
     2980            return False 
     2981 
    29432982        content = '' 
    2944  
    29452983        crlf = chr(13) + chr(10) 
    29462984        tab = chr(9) 
    29472985 
    2948         # Do it if params exist 
    2949         if self.parameters: 
    2950  
    2951             for param in self.parameters: 
    2952                 content += param[1]  # parameter name 
     2986        all_params, fitted_param_names = self._get_copy_params_details() 
     2987 
     2988        # Construct row of parameter names 
     2989        for param in all_params: 
     2990            name = param[1] # Parameter name 
     2991            content += name 
     2992            content += tab 
     2993            if name in fitted_param_names: 
     2994                # Only print errors for fitted parameters 
     2995                content += name + "_err" 
    29532996                content += tab 
    2954                 content += param[1] + "_err" 
    2955                 content += tab 
    2956  
    2957             content += crlf 
    2958  
    2959             # row of values and errors... 
    2960             for param in self.parameters: 
    2961                 content += param[2].GetValue()  # value 
    2962                 content += tab 
    2963                 content += param[4].GetValue()  # error 
    2964                 content += tab 
    2965  
    2966             return content 
    2967         else: 
    2968             return False 
     2997 
     2998        content += crlf 
     2999 
     3000        # Construct row of parameter values and errors 
     3001        for param in all_params: 
     3002            value = param[2] 
     3003            if hasattr(value, 'GetValue'): 
     3004                # param[2] is a text box 
     3005                value = value.GetValue() 
     3006            else: 
     3007                # param[2] is a float (from our self._get_copy_params_details) 
     3008                value = str(value) 
     3009            content += value 
     3010            content += tab 
     3011            if param[1] in fitted_param_names: 
     3012                # Only print errors for fitted parameters 
     3013                content += param[4].GetValue() 
     3014                content += tab  
     3015 
     3016        return content 
    29693017 
    29703018    def get_copy_latex(self): 
     
    29813029        Get the string copies of the param names and values in the tap 
    29823030        """ 
     3031        if not self.parameters: 
     3032            # Do nothing if self.parameters doesn't exist 
     3033            return False 
     3034         
    29833035        content = '\\begin{table}' 
    29843036        content += '\\begin{tabular}[h]' 
     
    29873039        tab = chr(9) 
    29883040 
    2989         # Do it if params exist 
    2990         if self.parameters: 
    2991  
    2992             content += '{|' 
    2993             for param in self.parameters: 
    2994                 content += 'l|l|' 
    2995             content += '}\hline' 
    2996             content += crlf 
    2997  
    2998             for index, param in enumerate(self.parameters): 
    2999                 content += param[1].replace('_', '\_')  # parameter name 
     3041        all_params, fitted_param_names = self._get_copy_params_details() 
     3042 
     3043        content += '{|' 
     3044        for param in all_params: 
     3045            content += 'l|l|' 
     3046        content += '}\hline' 
     3047        content += crlf 
     3048 
     3049        # Construct row of parameter names 
     3050        for index, param in enumerate(all_params): 
     3051            name = param[1] # Parameter name 
     3052            content += name.replace('_', '\_')  # Escape underscores 
     3053            if name in fitted_param_names: 
     3054                # Only print errors for fitted parameters 
    30003055                content += ' & ' 
    3001                 content += param[1].replace('_', '\_') + "\_err" 
    3002                 if index < len(self.parameters) - 1: 
    3003                     content += ' & ' 
    3004             content += '\\\\ \\hline' 
    3005             content += crlf 
    3006  
    3007             # row of values and errors... 
    3008             for index, param in enumerate(self.parameters): 
    3009                 content += param[2].GetValue()  # parameter value 
     3056                content += name.replace('_', '\_') + "\_err" 
     3057            if index < len(all_params) - 1: 
    30103058                content += ' & ' 
    3011                 content += param[4].GetValue()  # parameter error 
    3012                 if index < len(self.parameters) - 1: 
    3013                     content += ' & ' 
    3014             content += '\\\\ \\hline' 
    3015             content += crlf 
    3016  
    3017             content += '\\end{tabular}' 
    3018             content += '\\end{table}' 
    3019             return content 
    3020         else: 
    3021             return False 
     3059 
     3060        content += '\\\\ \\hline' 
     3061        content += crlf 
     3062 
     3063        # Construct row of values and errors 
     3064        for index, param in enumerate(all_params): 
     3065            value = param[2] 
     3066            if hasattr(value, "GetValue"): 
     3067                # value is a text box 
     3068                value = value.GetValue() 
     3069            else: 
     3070                # value is a float (from self._get_copy_params_details) 
     3071                value = str(value) 
     3072            content += value 
     3073            if param[1] in fitted_param_names: 
     3074                # Only print errors for fitted params 
     3075                content += ' & ' 
     3076                content += param[4].GetValue() 
     3077            if index < len(all_params) - 1: 
     3078                content += ' & ' 
     3079         
     3080        content += '\\\\ \\hline' 
     3081        content += crlf 
     3082        content += '\\end{tabular}' 
     3083        content += '\\end{table}' 
     3084 
     3085        return content 
    30223086 
    30233087    def set_clipboard(self, content=None): 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r79e6a33 r79e6a33  
    289289        self.btFitHelp.SetToolTipString("General fitting help.") 
    290290        self.btFitHelp.Bind(wx.EVT_BUTTON, self._onFitHelp) 
    291          
     291 
    292292        # Resolution Smearing Help button (for now use same technique as 
    293293        # used for dI help to get tiniest possible button that works 
     
    303303        self.btSmearHelp.SetToolTipString("Resolution smearing help.") 
    304304        self.btSmearHelp.Bind(wx.EVT_BUTTON, self._onSmearHelp) 
    305          
     305 
    306306        # textcntrl for custom resolution 
    307307        self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY, 
     
    564564        sizer.Add(self.draw_button, 0, 0) 
    565565        sizer.Add((-1, 5)) 
    566          
     566 
    567567        sizer.Add(self.tcChi, 0, 0) 
    568568        sizer.Add(self.Npts_fit, 0, 0) 
     
    570570        sizer.Add(self.btFit, 0, 0) 
    571571        sizer.Add(self.btFitHelp, 0, 0) 
    572          
     572 
    573573        boxsizer_range.Add(sizer_chi2) 
    574574        boxsizer_range.Add(sizer) 
     
    21882188        self.save_current_state() 
    21892189 
     2190        if not self.is_mac: 
     2191            self.Layout() 
     2192            self.Refresh() 
    21902193        # plot model ( when drawing, do not update chisqr value again) 
    21912194        self._draw_model(update_chisqr=False, source='fit') 
     
    27822785            else: 
    27832786                return cmp(a.lower(), b.lower()) 
    2784          
     2787 
    27852788        # keys obtained now from ordered dict, so commenting alphabetical 
    27862789        # ordering keys.sort(custom_compare) 
  • src/sas/sasgui/perspectives/fitting/fitpanel.py

    r67b0a99 r6f9abd3  
    501501            if data is None: 
    502502                return None 
     503        focused_page = self.GetPage(self.GetSelection()) 
    503504        for page in self.opened_pages.values(): 
    504505            # check if the selected data existing in the fitpanel 
    505506            pos = self.GetPageIndex(page) 
    506507            if not check_data_validity(page.get_data()) and not page.batch_on: 
     508                if page.model is not None and page != focused_page: 
     509                    # Page has an active theory and is in background - don't 
     510                    # send data here. 
     511                    continue 
    507512                # make sure data get placed in 1D empty tab if data is 1D 
    508513                # else data get place on 2D tab empty tab 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r2504b5a r2504b5a  
    13371337 
    13381338                is_data2d = issubclass(data.__class__, Data2D) 
    1339                 #check consistency of arrays 
     1339                # Check consistency of arrays 
    13401340                if not is_data2d: 
    13411341                    if len(res.theory) == len(res.index[res.index]) and \ 
     
    13481348                    new_theory[res.index == False] = np.nan 
    13491349                    correct_result = True 
    1350                 #get all fittable parameters of the current model 
     1350                # Get all fittable parameters of the current model 
    13511351                param_list = model.getParamList() 
    13521352                for param in model.getDispParamList(): 
    1353                     if not model.is_fittable(param) and \ 
     1353                    if '.' in param and param in param_list: 
     1354                        # Ensure polydispersity results are displayed 
     1355                        p1, p2 = param.split('.') 
     1356                        if not model.is_fittable(p1) and not (p2 == 'width' and param in res.param_list)\ 
     1357                            and param in param_list: 
     1358                            param_list.remove(param) 
     1359                    elif not model.is_fittable(param) and \ 
    13541360                        param in param_list: 
    13551361                        param_list.remove(param) 
     
    13721378                    batch_outputs["Chi2"].append(ERROR) 
    13731379                    for param in param_list: 
    1374                         # save value of  fixed parameters 
     1380                        # Save value of  fixed parameters 
    13751381                        if param not in res.param_list: 
    13761382                            batch_outputs[str(param)].append(ERROR) 
    13771383                        else: 
    1378                             #save only fitted values 
     1384                            # Save only fitted values 
    13791385                            batch_outputs[param].append(ERROR) 
    13801386                            batch_inputs["error on %s" % str(param)].append(ERROR) 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r05b0bf6 rca383a0  
    195195the :ref:`Advanced_Plugin_Editor` . 
    196196 
     197**SasView version 4.2** made it possible to specify whether a plugin created with  
     198the *New Plugin Model* dialog is actually a form factor P(Q) or a structure factor  
     199S(Q). To do this, simply add one or other of the following lines under the *import*  
     200statements. 
     201 
     202For a form factor:: 
     203 
     204     form_factor = True 
     205          
     206or for a structure factor:: 
     207 
     208     structure_factor = True 
     209          
     210If the plugin is a structure factor it is *also* necessary to add two variables to  
     211the parameter list:: 
     212 
     213     parameters = [  
     214                     ['radius_effective', '', 1, [0.0, numpy.inf], 'volume', ''], 
     215                     ['volfraction', '', 1, [0.0, 1.0], '', ''], 
     216                     [...], 
     217 
     218and to the declarations of the functions Iq and Iqxy::: 
     219 
     220     def Iq(x , radius_effective, volfraction, ...): 
     221 
     222     def Iqxy(x, y, radius_effective, volfraction, ...): 
     223 
     224Such a plugin should then be available in the S(Q) drop-down box on a FitPage (once  
     225a P(Q) model has been selected). 
     226 
    197227Sum|Multi(p1,p2) 
    198228^^^^^^^^^^^^^^^^ 
     
    206236or:: 
    207237 
    208      Plugin Model = scale_factor * model_1 /* model_2 + background 
     238     Plugin Model = scale_factor * (model1 * model2) + background 
    209239 
    210240In the *Easy Sum/Multi Editor* give the new model a function name and brief 
    211241description (to appear under the *Details* button on the *FitPage*). Then select 
    212242two existing models, as p1 and p2, and the required operator, '+' or '*' between 
    213 them. Finally, click the *Apply* button to generate the model and then click *Close*. 
    214  
    215 Any changes to a plugin model generated in this way only become effective *after* it is re-selected from the model drop-down menu on the FitPage. 
     243them. Finally, click the *Apply* button to generate and test the model and then click *Close*. 
     244 
     245Any changes to a plugin model generated in this way only become effective *after* it is re-selected  
     246from the plugin models drop-down menu on the FitPage. If the model is not listed you can force a  
     247recompilation of the plugins by selecting *Fitting* > *Plugin Model Operations* > *Load Plugin Models*. 
     248 
     249**SasView version 4.2** introduced a much simplified and more extensible structure for plugin models  
     250generated through the Easy Sum/Multi Editor. For example, the code for a combination of a sphere model  
     251with a power law model now looks like this:: 
     252 
     253     from sasmodels.core import load_model_info 
     254     from sasmodels.sasview_model import make_model_from_info 
     255      
     256     model_info = load_model_info('sphere+power_law') 
     257     model_info.name = 'MyPluginModel' 
     258     model_info.description = 'sphere + power_law' 
     259     Model = make_model_from_info(model_info) 
     260 
     261To change the models or operators contributing to this plugin it is only necessary to edit the string  
     262in the brackets after *load_model_info*, though it would also be a good idea to update the model name  
     263and description too!!! 
     264 
     265The model specification string can handle multiple models and combinations of operators (+ or *) which  
     266are processed according to normal conventions. Thus 'model1+model2*model3' would be valid and would  
     267multiply model2 by model3 before adding model1. In this example, parameters in the *FitPage* would be  
     268prefixed A (for model2), B (for model3) and C (for model1). Whilst this might appear a little  
     269confusing, unless you were creating a plugin model from multiple instances of the same model the parameter  
     270assignments ought to be obvious when you load the plugin. 
     271 
     272If you need to include another plugin model in the model specification string, just prefix the name of  
     273that model with *custom*. For instance:: 
     274 
     275     sphere+custom.MyPluginModel 
     276 
     277To create a P(Q)*\S(Q) model use the @ symbol instead of * like this:: 
     278 
     279     sphere@hardsphere 
     280      
     281This streamlined approach to building complex plugin models from existing library models, or models  
     282available on the *Model Marketplace*, also permits the creation of P(Q)*\S(Q) plugin models, something  
     283that was not possible in earlier versions of SasView.  
    216284 
    217285.. _Advanced_Plugin_Editor: 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    r72100ee re081946  
    1818* By writing a model from scratch outside of SasView (only recommended for 
    1919  code monkeys!) 
     20 
     21**What follows below is quite technical. If you just want a helping hand to get  
     22started creating your own models see** :ref:`Adding_your_own_models`. 
    2023 
    2124Overview 
  • test/corfunc/test/utest_corfunc.py

    r253eb6c6 r968d67e  
    1717            upperq=(0.15, 0.24)) 
    1818        self.extrapolation = None 
     19        self.transformation = None 
    1920 
    2021    def extrapolate(self): 
Note: See TracChangeset for help on using the changeset viewer.