Changeset c5251f6 in sasview for src/sas/sasgui/perspectives


Ignore:
Timestamp:
Apr 1, 2017 2:43:32 PM (7 years ago)
Author:
gonzalezm
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:
80a49c2
Parents:
51335d7 (diff), 7cbbacd (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.
Message:

Merge branch 'master' of https://github.com/SasView/sasview

Location:
src/sas/sasgui/perspectives
Files:
12 edited

Legend:

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

    ra08b89b rddbac66  
    55function of y (usually the intensity).  It also provides a drop down of 
    66standard available math functions.  Finally a full python editor panel for 
    7 complete customizatin is provided. 
    8  
    9 :TODO the writiong of the file and name checking (and maybe some other 
    10 funtions?) should be moved to a computational module which could be called 
    11 fropm a python script.  Basically one just needs to pass the name, 
     7complete customization is provided. 
     8 
     9:TODO the writing of the file and name checking (and maybe some other 
     10functions?) should be moved to a computational module which could be called 
     11from a python script.  Basically one just needs to pass the name, 
    1212description text and function text (or in the case of the composite editor 
    1313the names of the first and second model and the operator to be used). 
     
    6161    """ 
    6262    Dialog for easy custom composite models.  Provides a wx.Dialog panel 
    63     to choose two existing models (including pre-existing custom models which 
     63    to choose two existing models (including pre-existing Plugin Models which 
    6464    may themselves be composite models) as well as an operation on those models 
    6565    (add or multiply) the resulting model will add a scale parameter for summed 
     
    380380            color = 'blue' 
    381381        except: 
    382             msg = "Easy Custom Sum/Multipy: Error occurred..." 
     382            msg = "Easy Sum/Multipy Plugin: Error occurred..." 
    383383            info = 'Error' 
    384384            color = 'red' 
     
    501501        self.factor = factor 
    502502        self._operator = operator 
    503         self.explanation = "  Custom Model = %s %s (model1 %s model2)\n" % \ 
     503        self.explanation = "  Plugin Model = %s %s (model1 %s model2)\n" % \ 
    504504                           (self.factor, f_oper, self._operator) 
    505505        self.explanationctr.SetLabel(self.explanation) 
     
    617617class EditorPanel(wx.ScrolledWindow): 
    618618    """ 
    619     Custom model function editor 
     619    Simple Plugin Model function editor 
    620620    """ 
    621621    def __init__(self, parent, base, path, title, *args, **kwds): 
     
    652652        self.msg_sizer = None 
    653653        self.warning = "" 
    654         self._description = "New Custom Model" 
     654        #This does not seem to be used anywhere so commenting out for now 
     655        #    -- PDB 2/26/17  
     656        #self._description = "New Plugin Model" 
    655657        self.function_tcl = None 
    656658        self.math_combo = None 
     
    991993        else: 
    992994            self._notes = result 
    993             msg = "Successful! Please look for %s in Customized Models."%name 
     995            msg = "Successful! Please look for %s in Plugin Models."%name 
    994996            msg += "  " + self._notes 
    995997            info = 'Info' 
     
    11381140    def on_help(self, event): 
    11391141        """ 
    1140         Bring up the Custom Model Editor Documentation whenever 
     1142        Bring up the New Plugin Model Editor Documentation whenever 
    11411143        the HELP button is clicked. 
    11421144 
     
    11901192        #self.Destroy() 
    11911193 
    1192 ## Templates for custom models 
     1194## Templates for plugin models 
    11931195 
    11941196CUSTOM_TEMPLATE = """ 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    rd472e86 rddbac66  
    302302        success = show_model_output(self, fname) 
    303303 
    304         # Update custom model list in fitpage combobox 
     304        # Update plugin model list in fitpage combobox 
    305305        if success and self._manager != None and self.panel != None: 
    306306            self._manager.set_edit_menu_helper(self.parent) 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r505706a rb301db9  
    5353    ON_MAC = True 
    5454 
     55CUSTOM_MODEL = 'Plugin Models' 
     56 
    5557class BasicPage(ScrolledPanel, PanelBase): 
    5658    """ 
    57     This class provide general structure of fitpanel page 
     59    This class provide general structure of the fitpanel page 
    5860    """ 
    5961    # Internal name for the AUI manager 
     
    118120        self.dxw = None 
    119121        # pinhole smear 
    120         self.dx_min = None 
    121         self.dx_max = None 
     122        self.dx_percent = None 
    122123        # smear attrbs 
    123124        self.enable_smearer = None 
     
    677678    def _copy_info(self, flag): 
    678679        """ 
    679         Send event dpemding on flag 
    680  
    681         : Param flag: flag that distinguish event 
     680        Send event depending on flag 
     681 
     682        : Param flag: flag that distinguishes the event 
    682683        """ 
    683684        # messages depending on the flag 
     
    847848        self.state.pinhole_smearer = \ 
    848849                                copy.deepcopy(self.pinhole_smearer.GetValue()) 
    849         self.state.dx_max = copy.deepcopy(self.dx_max) 
    850         self.state.dx_min = copy.deepcopy(self.dx_min) 
     850        self.state.dx_percent = copy.deepcopy(self.dx_percent) 
    851851        self.state.dxl = copy.deepcopy(self.dxl) 
    852852        self.state.dxw = copy.deepcopy(self.dxw) 
     
    11051105        """ 
    11061106        for key, value in self.master_category_dict.iteritems(): 
     1107            formfactor = state.formfactorcombobox.split(":") 
     1108            if isinstance(formfactor, list): 
     1109                formfactor = formfactor[0] 
    11071110            for list_item in value: 
    1108                 if state.formfactorcombobox in list_item: 
     1111                if formfactor in list_item: 
    11091112                    return self.categorybox.Items.index(key) 
    11101113        return 0 
     
    11161119        :precondition: the page is already drawn or created 
    11171120 
    1118         :postcondition: the state of the underlying data change as well as the 
     1121        :postcondition: the state of the underlying data changes as well as the 
    11191122            state of the graphic interface 
    11201123        """ 
     
    11521155        self._show_combox_helper() 
    11531156        # select the current model 
    1154         try: 
    1155             # to support older version 
    1156             category_pos = int(state.categorycombobox) 
    1157         except: 
    1158             state.formfactorcombobox = state.formfactorcombobox.lower() 
    1159             state.formfactorcombobox = \ 
    1160                 state.formfactorcombobox.replace('model', '') 
    1161             state.formfactorcombobox = unicode(state.formfactorcombobox) 
    1162             state.categorycombobox = unicode(state.categorycombobox) 
    1163             if state.categorycombobox in self.categorybox.Items: 
    1164                 category_pos = self.categorybox.Items.index( 
    1165                     state.categorycombobox) 
    1166             else: 
    1167                 # Look in master list for model name (model.lower) 
    1168                 category_pos = self.get_cat_combo_box_pos(state) 
     1157        state._convert_to_sasmodels() 
     1158        state.categorycombobox = unicode(state.categorycombobox) 
     1159        if state.categorycombobox in self.categorybox.Items: 
     1160            category_pos = self.categorybox.Items.index( 
     1161                state.categorycombobox) 
     1162        else: 
     1163            # Look in master list for model name (model.lower) 
     1164            category_pos = self.get_cat_combo_box_pos(state) 
    11691165 
    11701166        self.categorybox.Select(category_pos) 
    11711167        self._show_combox(None) 
    1172         try: 
    1173             # to support older version 
    1174             formfactor_pos = int(state.formfactorcombobox) 
    1175         except: 
    1176             formfactor_pos = 0 
    1177             for ind_form in range(self.formfactorbox.GetCount()): 
    1178                 if self.formfactorbox.GetString(ind_form) == \ 
    1179                                                     (state.formfactorcombobox): 
    1180                     formfactor_pos = int(ind_form) 
     1168        from models import PLUGIN_NAME_BASE 
     1169        if self.categorybox.GetValue() == CUSTOM_MODEL \ 
     1170                and PLUGIN_NAME_BASE not in state.formfactorcombobox: 
     1171            state.formfactorcombobox = \ 
     1172                PLUGIN_NAME_BASE + state.formfactorcombobox 
     1173        formfactor_pos = 0 
     1174        for ind_form in range(self.formfactorbox.GetCount()): 
     1175            if self.formfactorbox.GetString(ind_form) == \ 
     1176                                                (state.formfactorcombobox): 
     1177                formfactor_pos = int(ind_form) 
     1178                break 
     1179 
     1180        self.formfactorbox.Select(formfactor_pos) 
     1181 
     1182        structfactor_pos = 0 
     1183        if state.structurecombobox is not None: 
     1184            state.structurecombobox = unicode(state.structurecombobox) 
     1185            for ind_struct in range(self.structurebox.GetCount()): 
     1186                if self.structurebox.GetString(ind_struct) == \ 
     1187                                                (state.structurecombobox): 
     1188                    structfactor_pos = int(ind_struct) 
    11811189                    break 
    1182  
    1183         self.formfactorbox.Select(formfactor_pos) 
    1184  
    1185         structfactor_pos = 0 
    1186         try: 
    1187             # to support older version 
    1188             structfactor_pos = int(state.structurecombobox) 
    1189         except: 
    1190             if state.structurecombobox is not None: 
    1191                 state.structurecombobox = unicode(state.structurecombobox) 
    1192                 for ind_struct in range(self.structurebox.GetCount()): 
    1193                     if self.structurebox.GetString(ind_struct) == \ 
    1194                                                     (state.structurecombobox): 
    1195                         structfactor_pos = int(ind_struct) 
    1196                         break 
    11971190 
    11981191        self.structurebox.SetSelection(structfactor_pos) 
     
    12521245        # we have two more options for smearing 
    12531246        if self.pinhole_smearer.GetValue(): 
    1254             self.dx_min = state.dx_min 
    1255             self.dx_max = state.dx_max 
    1256             if self.dx_min is not None: 
    1257                 self.smear_pinhole_min.SetValue(str(self.dx_min)) 
    1258             if self.dx_max is not None: 
    1259                 self.smear_pinhole_max.SetValue(str(self.dx_max)) 
     1247            self.dx_percent = state.dx_percent 
     1248            if self.dx_percent is not None: 
     1249                if state.dx_old: 
     1250                    self.dx_percent = 100 * (self.dx_percent / self.data.x[0]) 
     1251                self.smear_pinhole_percent.SetValue("%.2f" % self.dx_percent) 
    12601252            self.onPinholeSmear(event=None) 
    12611253        elif self.slit_smearer.GetValue(): 
     
    13421334    def _selectDlg(self): 
    13431335        """ 
    1344         open a dialog file to selected the customized dispersity 
     1336        open a dialog file to select the customized polydispersity function 
    13451337        """ 
    13461338        if self.parent is not None: 
     
    13841376        # self.state.struct_rbutton = self.struct_rbutton.GetValue() 
    13851377        # self.state.plugin_rbutton = self.plugin_rbutton.GetValue() 
    1386         self.state.structurecombobox = self.structurebox.GetLabel() 
    1387         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
    1388         self.state.categorycombobox = self.categorybox.GetLabel() 
     1378        self.state.structurecombobox = self.structurebox.GetValue() 
     1379        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1380        self.state.categorycombobox = self.categorybox.GetValue() 
    13891381 
    13901382        # post state to fit panel 
     
    15871579        if len(statelist) == 0 or len(listtorestore) == 0: 
    15881580            return 
    1589         if len(statelist) != len(listtorestore): 
    1590             return 
    15911581 
    15921582        for j in range(len(listtorestore)): 
    1593             item_page = listtorestore[j] 
    1594             item_page_info = statelist[j] 
    1595             # change the state of the check box for simple parameters 
    1596             if item_page[0] is not None: 
    1597                 item_page[0].SetValue(item_page_info[0]) 
    1598             if item_page[2] is not None: 
    1599                 item_page[2].SetValue(item_page_info[2]) 
    1600                 if item_page[2].__class__.__name__ == "ComboBox": 
    1601                     if item_page_info[2] in self.model.fun_list: 
    1602                         fun_val = self.model.fun_list[item_page_info[2]] 
    1603                         self.model.setParam(item_page_info[1], fun_val) 
    1604             if item_page[3] is not None: 
    1605                 # show or hide text +/- 
    1606                 if item_page_info[2]: 
    1607                     item_page[3].Show(True) 
    1608                 else: 
    1609                     item_page[3].Hide() 
    1610             if item_page[4] is not None: 
    1611                 # show of hide the text crtl for fitting error 
    1612                 if item_page_info[4][0]: 
    1613                     item_page[4].Show(True) 
    1614                     item_page[4].SetValue(item_page_info[4][1]) 
    1615                 else: 
    1616                     item_page[3].Hide() 
    1617             if item_page[5] is not None: 
    1618                 # show of hide the text crtl for fitting error 
    1619                 item_page[5].Show(item_page_info[5][0]) 
    1620                 item_page[5].SetValue(item_page_info[5][1]) 
    1621  
    1622             if item_page[6] is not None: 
    1623                 # show of hide the text crtl for fitting error 
    1624                 item_page[6].Show(item_page_info[6][0]) 
    1625                 item_page[6].SetValue(item_page_info[6][1]) 
     1583            for param in statelist: 
     1584                if param[1] == listtorestore[j][1]: 
     1585                    item_page = listtorestore[j] 
     1586                    item_page_info = param 
     1587                    if (item_page_info[1] == "theta" or item_page_info[1] == 
     1588                            "phi") and not self._is_2D(): 
     1589                        break 
     1590                    # change the state of the check box for simple parameters 
     1591                    if item_page[0] is not None: 
     1592                        item_page[0].SetValue(item_page_info[0]) 
     1593                    if item_page[2] is not None: 
     1594                        item_page[2].SetValue(item_page_info[2]) 
     1595                        if item_page[2].__class__.__name__ == "ComboBox": 
     1596                            if item_page_info[2] in self.model.fun_list: 
     1597                                fun_val = self.model.fun_list[item_page_info[2]] 
     1598                                self.model.setParam(item_page_info[1], fun_val) 
     1599                    if item_page[3] is not None: 
     1600                        # show or hide text +/- 
     1601                        if item_page_info[2]: 
     1602                            item_page[3].Show(True) 
     1603                        else: 
     1604                            item_page[3].Hide() 
     1605                    if item_page[4] is not None: 
     1606                        # show of hide the text crtl for fitting error 
     1607                        if item_page_info[4][0]: 
     1608                            item_page[4].Show(True) 
     1609                            item_page[4].SetValue(str(item_page_info[4][1])) 
     1610                        else: 
     1611                            item_page[3].Hide() 
     1612                    if item_page[5] is not None: 
     1613                        # show of hide the text crtl for fitting error 
     1614                        item_page[5].Show(True) 
     1615                        item_page[5].SetValue(str(item_page_info[5][1])) 
     1616                    if item_page[6] is not None: 
     1617                        # show of hide the text crtl for fitting error 
     1618                        item_page[6].Show(True) 
     1619                        item_page[6].SetValue(str(item_page_info[6][1])) 
     1620                    break 
    16261621 
    16271622    def _reset_strparam_state(self, listtorestore, statelist): 
     
    17641759    def _set_multfactor_combobox(self, multiplicity=10): 
    17651760        """ 
    1766         Set comboBox for muitfactor of CoreMultiShellModel 
     1761        Set comboBox for multitfactor of CoreMultiShellModel 
    17671762        :param multiplicit: no. of multi-functionality 
    17681763        """ 
     
    18021797        Fill panel's combo box according to the type of model selected 
    18031798        """ 
    1804         custom_model = 'Customized Models' 
     1799 
    18051800        mod_cat = self.categorybox.GetStringSelection() 
    18061801        self.structurebox.SetSelection(0) 
     
    18111806        m_list = [] 
    18121807        try: 
    1813             if mod_cat == custom_model: 
     1808            if mod_cat == CUSTOM_MODEL: 
    18141809                for model in self.model_list_box[mod_cat]: 
    18151810                    m_list.append(self.model_dict[model.name]) 
     
    34573452        fills out the category list box 
    34583453        """ 
    3459         uncat_str = 'Customized Models' 
     3454        uncat_str = 'Plugin Models' 
    34603455        self._read_category_info() 
    34613456 
     
    34863481        self.model_box.Clear() 
    34873482 
    3488         if category == 'Customized Models': 
     3483        if category == 'Plugin Models': 
    34893484            for model in self.model_list_box[category]: 
    34903485                str_m = str(model).split(".")[0] 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r24fd27a rd85f1d8a  
    2929_BOX_WIDTH = 76 
    3030_DATA_BOX_WIDTH = 300 
    31 SMEAR_SIZE_L = 0.00 
    3231SMEAR_SIZE_H = 0.00 
    33  
     32CUSTOM_MODEL = 'Plugin Models' 
    3433 
    3534class FitPage(BasicPage): 
     
    164163        On_select_data 
    165164        """ 
    166         if event is None and self.dataSource.GetCount() > 0: 
    167             data = self.dataSource.GetClientData(0) 
    168             self.set_data(data) 
    169         elif self.dataSource.GetCount() > 0: 
    170             pos = self.dataSource.GetSelection() 
     165        if self.dataSource.GetCount() > 0: 
     166            pos = self.dataSource.GetSelection() if event is not None else 0 
    171167            data = self.dataSource.GetClientData(pos) 
    172168            self.set_data(data) 
     
    213209              "Please enter only the value of interest to customize smearing..." 
    214210        smear_message_new_psmear = \ 
    215               "Please enter both; the dQ will be generated by interpolation..." 
     211              "Please enter a fixed percentage to be applied to all Q values..." 
    216212        smear_message_2d_x_title = "<dQp>[1/A]:" 
    217213        smear_message_2d_y_title = "<dQs>[1/A]:" 
    218         smear_message_pinhole_min_title = "dQ_low[1/A]:" 
    219         smear_message_pinhole_max_title = "dQ_high[1/A]:" 
     214        smear_message_pinhole_percent_title = "dQ[%]:" 
    220215        smear_message_slit_height_title = "Slit height[1/A]:" 
    221216        smear_message_slit_width_title = "Slit width[1/A]:" 
     
    256251        self.Bind(wx.EVT_RADIOBUTTON, self.onWeighting, 
    257252                  id=self.dI_idata.GetId()) 
    258         self.dI_didata.SetValue(True) 
     253        self.dI_noweight.SetValue(True) 
    259254        # add 4 types of weighting to the sizer 
    260255        sizer_weighting.Add(self.dI_noweight, 0, wx.LEFT, 10) 
     
    266261        sizer_weighting.Add(self.dI_idata) 
    267262        sizer_weighting.Add((10, 10)) 
    268         self.dI_noweight.Enable(False) 
     263        self.dI_noweight.Enable(True) 
    269264        self.dI_didata.Enable(False) 
    270265        self.dI_sqrdata.Enable(False) 
     
    310305         
    311306        # textcntrl for custom resolution 
    312         self.smear_pinhole_max = ModelTextCtrl(self, wx.ID_ANY, 
    313                             size=(_BOX_WIDTH - 25, 20), 
    314                             style=wx.TE_PROCESS_ENTER, 
    315                             text_enter_callback=self.onPinholeSmear) 
    316         self.smear_pinhole_min = ModelTextCtrl(self, wx.ID_ANY, 
    317                             size=(_BOX_WIDTH - 25, 20), 
    318                             style=wx.TE_PROCESS_ENTER, 
    319                             text_enter_callback=self.onPinholeSmear) 
     307        self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY, 
     308                                                   size=(_BOX_WIDTH - 25, 20), 
     309                                                   style=wx.TE_PROCESS_ENTER, 
     310                                                   text_enter_callback= 
     311                                                   self.onPinholeSmear) 
    320312        self.smear_slit_height = ModelTextCtrl(self, wx.ID_ANY, 
    321313                            size=(_BOX_WIDTH - 25, 20), 
     
    336328 
    337329        # set default values for smear 
    338         self.smear_pinhole_max.SetValue(str(self.dx_max)) 
    339         self.smear_pinhole_min.SetValue(str(self.dx_min)) 
     330        self.smear_pinhole_percent.SetValue(str(self.dx_percent)) 
    340331        self.smear_slit_height.SetValue(str(self.dxl)) 
    341332        self.smear_slit_width.SetValue(str(self.dxw)) 
     
    362353        self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, 
    363354                  id=self.slit_smearer.GetId()) 
    364         self.enable_smearer.SetValue(True) 
     355        self.disable_smearer.SetValue(True) 
    365356 
    366357        sizer_smearer.Add(self.disable_smearer, 0, wx.LEFT, 10) 
     
    429420        self.smear_description_2d_y.SetToolTipString( 
    430421                                    " dQs(perpendicular) in q_phi direction.") 
    431         self.smear_description_pin_min = wx.StaticText(self, wx.ID_ANY, 
    432                         smear_message_pinhole_min_title, style=wx.ALIGN_LEFT) 
    433         self.smear_description_pin_max = wx.StaticText(self, wx.ID_ANY, 
    434                         smear_message_pinhole_max_title, style=wx.ALIGN_LEFT) 
     422        self.smear_description_pin_percent = wx.StaticText(self, wx.ID_ANY, 
     423                                            smear_message_pinhole_percent_title, 
     424                                            style=wx.ALIGN_LEFT) 
    435425        self.smear_description_slit_height = wx.StaticText(self, wx.ID_ANY, 
    436426                        smear_message_slit_height_title, style=wx.ALIGN_LEFT) 
     
    456446        self.sizer_new_smear.Add((15, -1)) 
    457447        self.sizer_new_smear.Add(self.smear_description_2d_x, 0, wx.CENTER, 10) 
    458         self.sizer_new_smear.Add(self.smear_description_pin_min, 
    459                                  0, wx.CENTER, 10) 
    460448        self.sizer_new_smear.Add(self.smear_description_slit_height, 
    461449                                 0, wx.CENTER, 10) 
    462450 
    463         self.sizer_new_smear.Add(self.smear_pinhole_min, 0, wx.CENTER, 10) 
    464451        self.sizer_new_smear.Add(self.smear_slit_height, 0, wx.CENTER, 10) 
    465452        self.sizer_new_smear.Add(self.smear_data_left, 0, wx.CENTER, 10) 
     
    467454        self.sizer_new_smear.Add(self.smear_description_2d_y, 
    468455                                 0, wx.CENTER, 10) 
    469         self.sizer_new_smear.Add(self.smear_description_pin_max, 
     456        self.sizer_new_smear.Add(self.smear_description_pin_percent, 
    470457                                 0, wx.CENTER, 10) 
    471458        self.sizer_new_smear.Add(self.smear_description_slit_width, 
    472459                                 0, wx.CENTER, 10) 
    473460 
    474         self.sizer_new_smear.Add(self.smear_pinhole_max, 0, wx.CENTER, 10) 
     461        self.sizer_new_smear.Add(self.smear_pinhole_percent, 0, wx.CENTER, 10) 
    475462        self.sizer_new_smear.Add(self.smear_slit_width, 0, wx.CENTER, 10) 
    476463        self.sizer_new_smear.Add(self.smear_data_right, 0, wx.CENTER, 10) 
     
    11901177        self.state.slit_smearer = self.slit_smearer.GetValue() 
    11911178 
    1192         self.state.structurecombobox = self.structurebox.GetLabel() 
    1193         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
     1179        self.state.structurecombobox = self.structurebox.GetValue() 
     1180        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1181        self.state.categorycombobox = self.categorybox.GetValue() 
    11941182        self.enable_fit_button() 
    11951183        if self.model is not None: 
     
    12481236            wx.PostEvent(self.parent, new_event) 
    12491237            # update list of plugins if new plugin is available 
    1250             custom_model = 'Customized Models' 
     1238            custom_model = CUSTOM_MODEL 
    12511239            mod_cat = self.categorybox.GetStringSelection() 
    12521240            if mod_cat == custom_model: 
     
    12701258            if copy_flag: 
    12711259                self.get_paste_params(copy_flag) 
    1272                 wx.CallAfter(self._onDraw, None) 
     1260            wx.CallAfter(self._onDraw, None) 
    12731261 
    12741262        else: 
     
    15831571        if self.dxw is None: 
    15841572            self.dxw = "" 
    1585         if self.dx_min is None: 
    1586             self.dx_min = SMEAR_SIZE_L 
    1587         if self.dx_max is None: 
    1588             self.dx_max = SMEAR_SIZE_H 
     1573        if self.dx_percent is None: 
     1574            self.dx_percent = SMEAR_SIZE_H 
    15891575 
    15901576    def _get_smear_info(self): 
     
    16261612        elif data.dxl is not None or data.dxw is not None: 
    16271613            self.smear_type = "Slit" 
    1628             if data.dxl is not None and not numpy.all(data.dxl, 0): 
     1614            if data.dxl is not None and numpy.all(data.dxl, 0): 
    16291615                self.dq_l = data.dxl[0] 
    1630             if data.dxw is not None and not numpy.all(data.dxw, 0): 
     1616            if data.dxw is not None and numpy.all(data.dxw, 0): 
    16311617                self.dq_r = data.dxw[0] 
    16321618        # return self.smear_type,self.dq_l,self.dq_r 
     
    16481634            self.smear_description_2d_y.Show(True) 
    16491635            if self.pinhole_smearer.GetValue(): 
    1650                 self.smear_pinhole_min.Show(True) 
    1651                 self.smear_pinhole_max.Show(True) 
     1636                self.smear_pinhole_percent.Show(True) 
    16521637        # smear from data 
    16531638        elif self.enable_smearer.GetValue(): 
     
    16601645                    self.smear_description_slit_width.Show(True) 
    16611646                elif self.smear_type == 'Pinhole': 
    1662                     self.smear_description_pin_min.Show(True) 
    1663                     self.smear_description_pin_max.Show(True) 
     1647                    self.smear_description_pin_percent.Show(True) 
    16641648                self.smear_description_smear_type.Show(True) 
    16651649                self.smear_description_type.Show(True) 
     
    16701654            if self.smear_type == 'Pinhole': 
    16711655                self.smear_message_new_p.Show(True) 
    1672                 self.smear_description_pin_min.Show(True) 
    1673                 self.smear_description_pin_max.Show(True) 
    1674  
    1675             self.smear_pinhole_min.Show(True) 
    1676             self.smear_pinhole_max.Show(True) 
     1656                self.smear_description_pin_percent.Show(True) 
     1657 
     1658            self.smear_pinhole_percent.Show(True) 
    16771659        # custom slit smear 
    16781660        elif self.slit_smearer.GetValue(): 
     
    16991681        self.smear_data_left.Hide() 
    17001682        self.smear_data_right.Hide() 
    1701         self.smear_description_pin_min.Hide() 
    1702         self.smear_pinhole_min.Hide() 
    1703         self.smear_description_pin_max.Hide() 
    1704         self.smear_pinhole_max.Hide() 
     1683        self.smear_description_pin_percent.Hide() 
     1684        self.smear_pinhole_percent.Hide() 
    17051685        self.smear_description_slit_height.Hide() 
    17061686        self.smear_slit_height.Hide() 
     
    19331913 
    19341914            # more disables for 2D 
     1915            di_flag = False 
     1916            dq_flag = False 
    19351917            if self.data.__class__.__name__ == "Data2D" or \ 
    19361918                        self.enable2D: 
     
    19381920                self.pinhole_smearer.Enable(True) 
    19391921                self.default_mask = copy.deepcopy(self.data.mask) 
    1940                 if self.data.err_data is None or\ 
    1941                         numpy.all(err == 1 for err in self.data.err_data) or \ 
    1942                         not numpy.any(self.data.err_data): 
    1943                     self.dI_didata.Enable(False) 
    1944                     self.dI_noweight.SetValue(True) 
    1945                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1946                 else: 
    1947                     self.dI_didata.Enable(True) 
    1948                     self.dI_didata.SetValue(True) 
    1949                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1922                if self.data.err_data is not None \ 
     1923                        and numpy.any(self.data.err_data): 
     1924                    di_flag = True 
     1925                if self.data.dqx_data is not None \ 
     1926                        and numpy.any(self.data.dqx_data): 
     1927                    dq_flag = True 
    19501928            else: 
    19511929                self.slit_smearer.Enable(True) 
    19521930                self.pinhole_smearer.Enable(True) 
    1953  
    1954                 if self.data.dy is None or\ 
    1955                      numpy.all(self.data.dy == 1) or\ 
    1956                      not numpy.any(self.data.dy): 
    1957                     self.dI_didata.Enable(False) 
    1958                     self.dI_noweight.SetValue(True) 
    1959                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1960                 else: 
    1961                     self.dI_didata.Enable(True) 
    1962                     self.dI_didata.SetValue(True) 
    1963                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1931                if self.data.dy is not None and numpy.any(self.data.dy): 
     1932                    di_flag = True 
     1933                if self.data.dx is not None and numpy.any(self.data.dx): 
     1934                    dq_flag = True 
     1935                elif self.data.dxl is not None and numpy.any(self.data.dxl): 
     1936                    dq_flag = True 
     1937 
     1938            if dq_flag: 
     1939                self.enable_smearer.Enable(True) 
     1940                self.enable_smearer.SetValue(True) 
     1941                self.disable_smearer.SetValue(False) 
     1942            else: 
     1943                self.enable_smearer.Disable() 
     1944                self.disable_smearer.Enable(True) 
     1945                self.disable_smearer.SetValue(True) 
     1946 
     1947            if di_flag: 
     1948                self.dI_didata.Enable(True) 
     1949                self.dI_didata.SetValue(True) 
     1950                self.weightbt_string = self.dI_didata.GetLabelText() 
     1951            else: 
     1952                self.dI_didata.Enable(False) 
     1953                self.dI_noweight.SetValue(True) 
     1954                self.weightbt_string = self.dI_noweight.GetLabelText() 
     1955 
    19641956            # Enable weighting radio buttons 
    19651957            self.dI_noweight.Enable(True) 
     
    20031995            self.EditMask_title.Disable() 
    20041996 
     1997        self.on_smear_helper() 
    20051998        self.on_set_focus(None) 
    20061999        self.Refresh() 
     
    22382231            # event case of radio button 
    22392232            if tcrtl.GetValue(): 
    2240                 self.dx_min = 0.0 
    2241                 self.dx_max = 0.0 
     2233                self.dx_percent = 0.0 
    22422234                is_new_pinhole = True 
    22432235            else: 
     
    22762268        """ 
    22772269        # get the values 
    2278         pin_min = self.smear_pinhole_min.GetValue() 
    2279         pin_max = self.smear_pinhole_max.GetValue() 
    2280  
    2281         # Check changes in slit width 
     2270        pin_percent = self.smear_pinhole_percent.GetValue() 
     2271 
     2272        # Check changes in slit heigth 
    22822273        try: 
    2283             dx_min = float(pin_min) 
     2274            dx_percent = float(pin_percent) 
    22842275        except: 
    22852276            return True 
    2286         if self.dx_min != dx_min: 
    2287             return True 
    2288  
    2289         # Check changes in slit heigth 
    2290         try: 
    2291             dx_max = float(pin_max) 
    2292         except: 
    2293             return True 
    2294         if self.dx_max != dx_max: 
     2277        if self.dx_percent != dx_percent: 
    22952278            return True 
    22962279        return False 
     
    23182301        msg = None 
    23192302 
    2320         get_pin_min = self.smear_pinhole_min 
    2321         get_pin_max = self.smear_pinhole_max 
    2322  
    2323         if not check_float(get_pin_min): 
    2324             get_pin_min.SetBackgroundColour("pink") 
    2325             msg = "Model Error:wrong value entered!!!" 
    2326         elif not check_float(get_pin_max): 
    2327             get_pin_max.SetBackgroundColour("pink") 
     2303        get_pin_percent = self.smear_pinhole_percent 
     2304 
     2305        if not check_float(get_pin_percent): 
     2306            get_pin_percent.SetBackgroundColour("pink") 
    23282307            msg = "Model Error:wrong value entered!!!" 
    23292308        else: 
    23302309            if len_data < 2: 
    23312310                len_data = 2 
    2332             self.dx_min = float(get_pin_min.GetValue()) 
    2333             self.dx_max = float(get_pin_max.GetValue()) 
    2334             if self.dx_min < 0: 
    2335                 get_pin_min.SetBackgroundColour("pink") 
     2311            self.dx_percent = float(get_pin_percent.GetValue()) 
     2312            if self.dx_percent < 0: 
     2313                get_pin_percent.SetBackgroundColour("pink") 
    23362314                msg = "Model Error:This value can not be negative!!!" 
    2337             elif self.dx_max < 0: 
    2338                 get_pin_max.SetBackgroundColour("pink") 
    2339                 msg = "Model Error:This value can not be negative!!!" 
    2340             elif self.dx_min is not None and self.dx_max is not None: 
     2315            elif self.dx_percent is not None: 
     2316                percent = self.dx_percent/100 
    23412317                if self._is_2D(): 
    2342                     data.dqx_data[data.dqx_data == 0] = self.dx_min 
    2343                     data.dqy_data[data.dqy_data == 0] = self.dx_max 
    2344                 elif self.dx_min == self.dx_max: 
    2345                     data.dx[data.dx == 0] = self.dx_min 
     2318                    data.dqx_data[data.dqx_data == 0] = percent * data.qx_data 
     2319                    data.dqy_data[data.dqy_data == 0] = percent * data.qy_data 
    23462320                else: 
    2347                     step = (self.dx_max - self.dx_min) / (len_data - 1) 
    2348                     data.dx = numpy.arange(self.dx_min, 
    2349                                            self.dx_max + step / 1.1, 
    2350                                            step) 
    2351             elif self.dx_min is not None: 
    2352                 if self._is_2D(): 
    2353                     data.dqx_data[data.dqx_data == 0] = self.dx_min 
    2354                 else: 
    2355                     data.dx[data.dx == 0] = self.dx_min 
    2356             elif self.dx_max is not None: 
    2357                 if self._is_2D(): 
    2358                     data.dqy_data[data.dqy_data == 0] = self.dx_max 
    2359                 else: 
    2360                     data.dx[data.dx == 0] = self.dx_max 
     2321                    data.dx = percent * data.x 
    23612322            self.current_smearer = smear_selection(data, self.model) 
    23622323            # 2D need to set accuracy 
     
    23682329            wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    23692330        else: 
    2370             get_pin_min.SetBackgroundColour("white") 
    2371             get_pin_max.SetBackgroundColour("white") 
     2331            get_pin_percent.SetBackgroundColour("white") 
    23722332        # set smearing value whether or not the data contain the smearing info 
    23732333 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r73cbeec r4c5098c  
    225225 
    226226        self.id_edit = wx.NewId() 
    227         editmodel_help = "Edit customized model sample file" 
    228227        self.menu1.AppendMenu(self.id_edit, "Plugin Model Operations", 
    229                               self.edit_model_menu, editmodel_help) 
     228                              self.edit_model_menu) 
    230229        #create  menubar items 
    231230        return [(self.menu1, self.sub_menu)] 
     
    260259            self.update_custom_combo() 
    261260            if os.path.isfile(p_path): 
    262                 msg = "Sorry! Could not be able to delete the default " 
    263                 msg += "custom model... \n" 
     261                msg = "Sorry! unable to delete the default " 
     262                msg += "plugin model... \n" 
    264263                msg += "Please manually remove the files (.py, .pyc) " 
    265264                msg += "in the 'plugin_models' folder \n" 
     
    274273                    if item.GetLabel() == label: 
    275274                        self.edit_menu.DeleteItem(item) 
    276                         msg = "The custom model, %s, has been deleted." % label 
     275                        msg = "The plugin model, %s, has been deleted." % label 
    277276                        evt = StatusEvent(status=msg, type='stop', info='info') 
    278277                        wx.PostEvent(self.parent, evt) 
     
    331330            temp = self.fit_panel.reset_pmodel_list() 
    332331            if temp: 
    333                 # Set the new custom model list for all fit pages 
     332                # Set the new plugin model list for all fit pages 
    334333                for uid, page in self.fit_panel.opened_pages.iteritems(): 
    335334                    if hasattr(page, "formfactorbox"): 
     
    17561755                                          data_id="Data  " + data.name + " unsmeared", 
    17571756                                          dy=unsmeared_error) 
    1758                  
    1759             if sq_model is not None and pq_model is not None: 
    1760                 self.create_theory_1D(x, sq_model, page_id, model, data, state, 
    1761                                       data_description=model.name + " S(q)", 
    1762                                       data_id=str(page_id) + " " + data.name + " S(q)") 
    1763                 self.create_theory_1D(x, pq_model, page_id, model, data, state, 
    1764                                       data_description=model.name + " P(q)", 
    1765                                       data_id=str(page_id) + " " + data.name + " P(q)") 
    1766  
     1757            # Comment this out until we can get P*S models with correctly populated parameters 
     1758            #if sq_model is not None and pq_model is not None: 
     1759            #    self.create_theory_1D(x, sq_model, page_id, model, data, state, 
     1760            #                          data_description=model.name + " S(q)", 
     1761            #                          data_id=str(page_id) + " " + data.name + " S(q)") 
     1762            #    self.create_theory_1D(x, pq_model, page_id, model, data, state, 
     1763            #                          data_description=model.name + " P(q)", 
     1764            #                          data_id=str(page_id) + " " + data.name + " P(q)") 
    17671765 
    17681766            current_pg = self.fit_panel.get_page_by_id(page_id) 
     
    19651963                ## then kill itself but cannot.  Paul Kienzle came up with 
    19661964                ## this fix to prevent threads from stepping on each other 
    1967                 ## which was causing a simple custom model to crash Sasview. 
     1965                ## which was causing a simple custom plugin model to crash 
     1966                ##Sasview. 
    19681967                ## We still don't know why the fit sometimes lauched a second 
    19691968                ## thread -- something which should also be investigated. 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r26c8be3 r5295cf5  
    3434*  in *Single* fit mode - individual data sets are fitted independently one-by-one 
    3535 
    36 *  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to the *same* model with/without constrained parameters (this might be useful, for example, if you have measured the same sample at different contrasts) 
     36*  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to 
     37   the *same* model with/without constrained parameters (this might be useful, 
     38   for example, if you have measured the same sample at different contrasts) 
    3739 
    3840*  in *Batch* fit mode - multiple data sets are fitted sequentially to the *same* model (this might be useful, for example, if you have performed a kinetic or time-resolved experiment and have *lots* of data sets!) 
     
    4345----------------- 
    4446 
    45 By default, the models in SasView are grouped into five categories 
    46  
    47 *  *Shapes* - models describing 'objects' (spheres, cylinders, etc) 
     47The models in SasView are grouped into categories. By default these consist of: 
     48 
     49*  *Cylinder* - cylindrical shapes (disc, right cylinder, cylinder with endcaps 
     50   etc) 
     51*  *Ellipsoid* - ellipsoidal shapes (oblate,prolate, core shell, etc) 
     52*  *Parellelepiped* - as the name implies 
     53*  *Sphere* - sheroidal shapes (sphere, core multishell, vesicle, etc) 
     54*  *Lamellae* - lamellar shapes (lamellar, core shell lamellar, stacked 
     55   lamellar, etc) 
    4856*  *Shape-Independent* - models describing structure in terms of density correlation functions, fractals, peaks, power laws, etc 
    49 *  *Customized Models* - SasView- or User-created (non-library) Python models 
    50 *  *Uncategorised* - other models (for reflectivity, etc) 
     57*  *Paracrystal* - semi ordered structures (bcc, fcc, etc) 
    5158*  *Structure Factor* - S(Q) models 
     59*  *Plugin Models* - User-created (custom/non-library) Python models 
    5260 
    5361Use the *Category* drop-down menu to chose a category of model, then select 
     
    8492.. image:: cat_fig0.bmp 
    8593 
    86 The categorization of all models except the customized models can be reassigned, 
    87 added to, and removed using *Category Manager*. Models can also be hidden from view 
    88 in the drop-down menus. 
     94The categorization of all models except the user supplied Plugin Models can be 
     95reassigned, added to, and removed using *Category Manager*. Models can also be 
     96hidden from view in the drop-down menus. 
    8997 
    9098.. image:: cat_fig1.bmp 
     
    93101^^^^^^^^^^^^^^^^^ 
    94102 
    95 To change category, highlight a model in the list by left-clicking on its entry and 
    96 then click the *Modify* button. Use the *Change Category* panel that appears to make 
    97 the required changes. 
     103To change category, highlight a model in the list by left-clicking on its entry 
     104and then click the *Modify* button. Use the *Change Category* panel that appears 
     105to make the required changes. 
    98106 
    99107.. image:: cat_fig2.bmp 
     
    106114^^^^^^^^^^^^^^^^^^^^^ 
    107115 
    108 Use the *Enable All / Disable All* buttons and the check boxes beside each model to 
    109 select the models to show/hide. To apply the selection, click *Ok*. Otherwise click 
    110 *Cancel*. 
     116Use the *Enable All / Disable All* buttons and the check boxes beside each model 
     117to select the models to show/hide. To apply the selection, click *Ok*. Otherwise 
     118click *Cancel*. 
    111119 
    112120*NB: It may be necessary to change to a different category and then back again* 
     
    118126--------------- 
    119127 
    120 For a complete list of all the library models available in SasView, see the `Model Documentation <../../../index.html>`_ . 
     128For a complete list of all the library models available in SasView, see 
     129the `Model Documentation <../../../index.html>`_ . 
    121130 
    122131It is also possible to add your own models. 
     
    131140There are essentially three ways to generate new fitting models for SasView: 
    132141 
    133 * Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners and/or relatively simple models) 
    134 * By copying/editing an existing model (this can include models generated by the *New Plugin Model* dialog) in the :ref:`Python_shell` or :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
    135 * By writing a model from scratch outside of SasView (only recommended for code monkeys!) 
     142*  Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners 
     143   and/or relatively simple models) 
     144*  By copying/editing an existing model (this can include models generated by 
     145   the New Plugin Model* dialog) in the :ref:`Python_shell` or  
     146   :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
     147*  By writing a model from scratch outside of SasView (only recommended for code 
     148   monkeys!) 
    136149 
    137150Please read the guidance on :ref:`Writing_a_Plugin` before proceeding. 
     
    163176^^^^^^^^^^^^^^^^ 
    164177 
    165 Relatively straightforward models can be programmed directly from the SasView GUI  
    166 using the *New Plugin Model Function*. 
     178Relatively straightforward models can be programmed directly from the SasView 
     179GUI using the *New Plugin Model Function*. 
    167180 
    168181.. image:: new_model.bmp 
     
    175188*checked*\ . 
    176189 
    177 Also note that the 'Fit Parameters' have been split into two sections: those which  
    178 can be polydisperse (shape and orientation parameters) and those which are not 
    179 (eg, scattering length densities). 
     190Also note that the 'Fit Parameters' have been split into two sections: those 
     191which can be polydisperse (shape and orientation parameters) and those which are 
     192not (eg, scattering length densities). 
    180193 
    181194A model file generated by this option can be viewed and further modified using 
     
    187200.. image:: sum_model.bmp 
    188201 
    189 This option creates a custom model of the form:: 
    190  
    191      Custom Model = scale_factor \* {(scale_1 \* model_1) \+ (scale_2 \* model_2)} \+ background 
     202This option creates a custom Plugin Model of the form:: 
     203 
     204     Plugin Model = scale_factor * {(scale_1 * model_1) +/- (scale_2 * model_2)} + background 
    192205 
    193206or:: 
    194207 
    195      Custom Model = scale_factor \* model_1 \* model_2 \+ background 
     208     Plugin Model = scale_factor * model_1 /* model_2 + background 
    196209 
    197210In the *Easy Sum/Multi Editor* give the new model a function name and brief 
     
    232245Simply highlight the plugin model to be removed. The operation is final!!! 
    233246 
    234 *NB: Plugin models shipped with SasView cannot be removed in this way.* 
     247*NB: Models shipped with SasView cannot be removed in this way.* 
    235248 
    236249Load Plugin Models 
    237250^^^^^^^^^^^^^^^^^^ 
    238251 
    239 This option loads (or re-loads) all models present in the *~\\.sasview\\plugin_models* folder. 
     252This option loads (or re-loads) all models present in the 
     253*~\\.sasview\\plugin_models* folder. 
    240254 
    241255.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    400414:ref:`Assessing_Fit_Quality`. 
    401415 
    402 *NB: If you need to use a customized model, you must ensure that model is available* 
    403 *first (see* :ref:`Adding_your_own_models` *).* 
     416*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     417available first (see* :ref:`Adding_your_own_models` *).* 
    404418 
    405419Method 
     
    484498If multiple data sets are in one file, load just that file. *Unselect All Data*, then 
    485499select a single initial data set to be fitted. Fit that selected data set as described 
    486 above under :ref:`Single_Fit_Mode` . 
    487  
    488 *NB: If you need to use a customized model, you must ensure that model is available* 
    489 *first (see* :ref:`Adding_your_own_models` *).* 
     500above under :ref:`Single_Fit_Mode`. 
     501 
     502*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     503available first (see* :ref:`Adding_your_own_models` *).* 
    490504 
    491505Method 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    rca6cbc1c r984f3fc  
    2727 
    2828the next time SasView is started it will compile the plugin and add 
    29 it to the list of *Customized Models* in a FitPage. 
     29it to the list of *Plugin Models* in a FitPage. 
    3030 
    3131SasView models can be of three types: 
     
    364364  - the limits will show up as the default limits for the fit making it easy, 
    365365    for example, to force the radius to always be greater than zero. 
     366 
     367  - these are hard limits defining the valid range of parameter values; 
     368    polydisperity distributions will be truncated at the limits. 
    366369 
    367370- **"type"** can be one of: "", "sld", "volume", or "orientation". 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    rc1681ea rc1c9929  
    177177            unsmeared_output = numpy.zeros((len(self.data.x))) 
    178178            unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
     179            self.smearer.model = self.model 
    179180            output = self.smearer(unsmeared_output, first_bin, last_bin) 
    180181 
  • src/sas/sasgui/perspectives/fitting/models.py

    r51335d7 rc5251f6  
    2323PLUGIN_LOG = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR, 
    2424                          "plugins.log") 
     25PLUGIN_NAME_BASE = '[plug-in] ' 
    2526 
    2627def get_model_python_path(): 
     
    181182            try: 
    182183                model = load_custom_model(path) 
    183                 model.name = "[plug-in] "+model.name 
     184                model.name = PLUGIN_NAME_BASE + model.name 
    184185                plugins[model.name] = model 
    185186            except Exception: 
     
    324325                    self.plugins.append(plug) 
    325326                    self.model_dictionary[name] = plug 
    326             self.model_combobox.set_list("Customized Models", self.plugins) 
     327            self.model_combobox.set_list("Plugin Models", self.plugins) 
    327328            return self.model_combobox.get_list() 
    328329        else: 
     
    345346            self.model_dictionary[name] = plug 
    346347 
    347         self.model_combobox.reset_list("Customized Models", self.plugins) 
     348        self.model_combobox.reset_list("Plugin Models", self.plugins) 
    348349        return self.model_combobox.get_list() 
    349350 
     
    388389#                                     self.shape_indep_list) 
    389390        self.model_combobox.set_list("Structure Factors", self.struct_list) 
    390         self.model_combobox.set_list("Customized Models", self.plugins) 
     391        self.model_combobox.set_list("Plugin Models", self.plugins) 
    391392        self.model_combobox.set_list("P(Q)*S(Q)", self.multiplication_factor) 
    392393        self.model_combobox.set_list("multiplication", 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    rc8e1996 r27109e5  
    2525from lxml import etree 
    2626 
     27from sasmodels import convert 
    2728import sasmodels.weights 
    2829 
     
    3233from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 
    3334from sas.sascalc.dataloader.data_info import Process, Aperture 
     35 
    3436# Information to read/write state as xml 
    3537FITTING_NODE_NAME = 'fitting_plug_in' 
    3638CANSAS_NS = "cansas1d/1.0" 
     39 
     40CUSTOM_MODEL = 'Plugin Models' 
     41CUSTOM_MODEL_OLD = 'Customized Models' 
    3742 
    3843LIST_OF_DATA_ATTRIBUTES = [["is_data", "is_data", "bool"], 
     
    6974                            ["dq_l", "dq_l", "float"], 
    7075                            ["dq_r", "dq_r", "float"], 
    71                             ["dx_max", "dx_max", "float"], 
    72                             ["dx_min", "dx_min", "float"], 
     76                            ["dx_percent", "dx_percent", "float"], 
    7377                            ["dxl", "dxl", "float"], 
    7478                            ["dxw", "dxw", "float"]] 
     
    210214        self.dq_l = None 
    211215        self.dq_r = None 
    212         self.dx_max = None 
    213         self.dx_min = None 
     216        self.dx_percent = None 
     217        self.dx_old = False 
    214218        self.dxl = None 
    215219        self.dxw = None 
     
    271275        # store value of chisqr 
    272276        self.tcChi = None 
     277        self.version = (1,0,0) 
    273278 
    274279    def clone(self): 
     
    337342        obj.dq_l = copy.deepcopy(self.dq_l) 
    338343        obj.dq_r = copy.deepcopy(self.dq_r) 
    339         obj.dx_max = copy.deepcopy(self.dx_max) 
    340         obj.dx_min = copy.deepcopy(self.dx_min) 
     344        obj.dx_percent = copy.deepcopy(self.dx_percent) 
     345        obj.dx_old = copy.deepcopy(self.dx_old) 
    341346        obj.dxl = copy.deepcopy(self.dxl) 
    342347        obj.dxw = copy.deepcopy(self.dxw) 
     
    349354        obj.cb1 = copy.deepcopy(self.cb1) 
    350355        obj.smearer = copy.deepcopy(self.smearer) 
     356        obj.version = copy.deepcopy(self.version) 
    351357 
    352358        for name, state in self.saved_states.iteritems(): 
     
    355361            obj.saved_states[copy_name] = copy_state 
    356362        return obj 
     363 
     364    def _old_first_model(self): 
     365        """ 
     366        Handle save states from 4.0.1 and before where the first item in the 
     367        selection boxes of category, formfactor and structurefactor were not 
     368        saved. 
     369        :return: None 
     370        """ 
     371        if self.categorycombobox == CUSTOM_MODEL_OLD: 
     372            self.categorycombobox = CUSTOM_MODEL 
     373        if self.formfactorcombobox == '': 
     374            FIRST_FORM = { 
     375                'Shapes' : 'BCCrystalModel', 
     376                'Uncategorized' : 'LineModel', 
     377                'StructureFactor' : 'HardsphereStructure', 
     378                'Ellipsoid' : 'core_shell_ellipsoid', 
     379                'Lamellae' : 'lamellar', 
     380                'Paracrystal' : 'bcc_paracrystal', 
     381                'Parallelepiped' : 'core_shell_parallelepiped', 
     382                'Shape Independent' : 'be_polyelectrolyte', 
     383                'Sphere' : 'adsorbed_layer', 
     384                'Structure Factor' : 'hardsphere', 
     385                CUSTOM_MODEL : '' 
     386            } 
     387            if self.categorycombobox == '': 
     388                if len(self.parameters) == 3: 
     389                    self.categorycombobox = "Shape-Independent" 
     390                    self.formfactorcombobox = 'PowerLawAbsModel' 
     391                elif len(self.parameters) == 9: 
     392                    self.categorycombobox = 'Cylinder' 
     393                    self.formfactorcombobox = 'barbell' 
     394                else: 
     395                    msg = "Save state does not have enough information to load" 
     396                    msg += " the all of the data." 
     397                    logging.warning(msg=msg) 
     398            else: 
     399                self.formfactorcombobox = FIRST_FORM[self.categorycombobox] 
     400 
     401    @staticmethod 
     402    def param_remap_to_sasmodels_convert(params, is_string=False): 
     403        """ 
     404        Remaps the parameters for sasmodels conversion 
     405 
     406        :param params: list of parameters (likely self.parameters) 
     407        :return: remapped dictionary of parameters 
     408        """ 
     409        p = dict() 
     410        for fittable, name, value, _, uncert, lower, upper, units in params: 
     411            if not value: 
     412                value = numpy.nan 
     413            if not uncert or uncert[1] == '' or uncert[1] == 'None': 
     414                uncert[0] = False 
     415                uncert[1] = numpy.nan 
     416            if not upper or upper[1] == '' or upper[1] == 'None': 
     417                upper[0] = False 
     418                upper[1] = numpy.nan 
     419            if not lower or lower[1] == '' or lower[1] == 'None': 
     420                lower[0] = False 
     421                lower[1] = numpy.nan 
     422            if is_string: 
     423                p[name] = str(value) 
     424            else: 
     425                p[name] = float(value) 
     426            p[name + ".fittable"] = bool(fittable) 
     427            p[name + ".std"] = float(uncert[1]) 
     428            p[name + ".upper"] = float(upper[1]) 
     429            p[name + ".lower"] = float(lower[1]) 
     430            p[name + ".units"] = units 
     431        return p 
     432 
     433    @staticmethod 
     434    def param_remap_from_sasmodels_convert(params): 
     435        """ 
     436        Converts {name : value} map back to [] param list 
     437        :param params: parameter map returned from sasmodels 
     438        :return: None 
     439        """ 
     440        p_map = [] 
     441        for name, info in params.iteritems(): 
     442            if ".fittable" in name or ".std" in name or ".upper" in name or \ 
     443                            ".lower" in name or ".units" in name: 
     444                pass 
     445            else: 
     446                fittable = params.get(name + ".fittable", True) 
     447                std = params.get(name + ".std", '0.0') 
     448                upper = params.get(name + ".upper", 'inf') 
     449                lower = params.get(name + ".lower", '-inf') 
     450                units = params.get(name + ".units") 
     451                if std is not None and std is not numpy.nan: 
     452                    std = [True, str(std)] 
     453                else: 
     454                    std = [False, ''] 
     455                if lower is not None and lower is not numpy.nan: 
     456                    lower = [True, str(lower)] 
     457                else: 
     458                    lower = [True, '-inf'] 
     459                if upper is not None and upper is not numpy.nan: 
     460                    upper = [True, str(upper)] 
     461                else: 
     462                    upper = [True, 'inf'] 
     463                param_list = [bool(fittable), str(name), str(info), 
     464                              "+/-", std, lower, upper, str(units)] 
     465                p_map.append(param_list) 
     466        return p_map 
     467 
     468    def _convert_to_sasmodels(self): 
     469        """ 
     470        Convert parameters to a form usable by sasmodels converter 
     471 
     472        :return: None 
     473        """ 
     474        # Create conversion dictionary to send to sasmodels 
     475        self._old_first_model() 
     476        p = self.param_remap_to_sasmodels_convert(self.parameters) 
     477        structurefactor, params = convert.convert_model(self.structurecombobox, 
     478                                                        p, False, self.version) 
     479        formfactor, params = convert.convert_model(self.formfactorcombobox, 
     480                                                   params, False, self.version) 
     481        if len(self.str_parameters) > 0: 
     482            str_pars = self.param_remap_to_sasmodels_convert( 
     483                self.str_parameters, True) 
     484            formfactor, str_params = convert.convert_model( 
     485                self.formfactorcombobox, str_pars, False, self.version) 
     486            for key, value in str_params.iteritems(): 
     487                params[key] = value 
     488 
     489        if self.formfactorcombobox == 'SphericalSLDModel': 
     490            self.multi_factor += 1 
     491        self.formfactorcombobox = formfactor 
     492        self.structurecombobox = structurefactor 
     493        self.parameters = [] 
     494        self.parameters = self.param_remap_from_sasmodels_convert(params) 
    357495 
    358496    def _repr_helper(self, list, rep): 
     
    423561        rep += "dq_l  : %s\n" % self.dq_l 
    424562        rep += "dq_r  : %s\n" % self.dq_r 
    425         rep += "dx_max  : %s\n" % str(self.dx_max) 
    426         rep += "dx_min : %s\n" % str(self.dx_min) 
     563        rep += "dx_percent  : %s\n" % str(self.dx_percent) 
    427564        rep += "dxl  : %s\n" % str(self.dxl) 
    428565        rep += "dxw : %s\n" % str(self.dxw) 
     
    682819 
    683820        attr = newdoc.createAttribute("version") 
    684         attr.nodeValue = '1.0' 
     821        from sas import sasview 
     822        attr.nodeValue = sasview.__version__ 
     823        # attr.nodeValue = '1.0' 
    685824        top_element.setAttributeNode(attr) 
    686825 
     
    8751014            raise RuntimeError, msg 
    8761015 
    877         if node.get('version') and node.get('version') == '1.0': 
     1016        if node.get('version'): 
     1017            # Get the version for model conversion purposes 
     1018            self.version = tuple(int(e) for e in 
     1019                                 str.split(node.get('version'), ".")) 
     1020            # The tuple must be at least 3 items long 
     1021            while len(self.version) < 3: 
     1022                ver_list = list(self.version) 
     1023                ver_list.append(0) 
     1024                self.version = tuple(ver_list) 
    8781025 
    8791026            # Get file name 
     
    8991046                    setattr(self, item[0], parse_entry_helper(node, item)) 
    9001047 
     1048                dx_old_node = get_content('ns:%s' % 'dx_min', entry) 
    9011049                for item in LIST_OF_STATE_ATTRIBUTES: 
    902                     node = get_content('ns:%s' % item[0], entry) 
    903                     setattr(self, item[0], parse_entry_helper(node, item)) 
     1050                    if item[0] == "dx_percent" and dx_old_node is not None: 
     1051                        dxmin = ["dx_min", "dx_min", "float"] 
     1052                        setattr(self, item[0], parse_entry_helper(dx_old_node, 
     1053                                                                  dxmin)) 
     1054                        self.dx_old = True 
     1055                    else: 
     1056                        node = get_content('ns:%s' % item[0], entry) 
     1057                        setattr(self, item[0], parse_entry_helper(node, item)) 
    9041058 
    9051059                for item in LIST_OF_STATE_PARAMETERS: 
     
    10331187        if self.cansas: 
    10341188            return self._read_cansas(path) 
    1035  
    1036     def _data2d_to_xml_doc(self, datainfo): 
    1037         """ 
    1038         Create an XML document to contain the content of a Data2D 
    1039  
    1040         :param datainfo: Data2D object 
    1041  
    1042         """ 
    1043         if not issubclass(datainfo.__class__, Data2D): 
    1044             raise RuntimeError, "The cansas writer expects a Data2D instance" 
    1045  
    1046         title = "cansas1d/%s" % self.version 
    1047         title += "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" 
    1048         doc = xml.dom.minidom.Document() 
    1049         main_node = doc.createElement("SASroot") 
    1050         main_node.setAttribute("version", self.version) 
    1051         main_node.setAttribute("xmlns", "cansas1d/%s" % self.version) 
    1052         main_node.setAttribute("xmlns:xsi", 
    1053                                "http://www.w3.org/2001/XMLSchema-instance") 
    1054         main_node.setAttribute("xsi:schemaLocation", title) 
    1055  
    1056         doc.appendChild(main_node) 
    1057  
    1058         entry_node = doc.createElement("SASentry") 
    1059         main_node.appendChild(entry_node) 
    1060  
    1061         write_node(doc, entry_node, "Title", datainfo.title) 
    1062         if datainfo is not None: 
    1063             write_node(doc, entry_node, "data_class", 
    1064                        datainfo.__class__.__name__) 
    1065         for item in datainfo.run: 
    1066             runname = {} 
    1067             if item in datainfo.run_name and \ 
    1068                             len(str(datainfo.run_name[item])) > 1: 
    1069                 runname = {'name': datainfo.run_name[item]} 
    1070             write_node(doc, entry_node, "Run", item, runname) 
    1071         # Data info 
    1072         new_node = doc.createElement("SASdata") 
    1073         entry_node.appendChild(new_node) 
    1074         for item in LIST_OF_DATA_2D_ATTR: 
    1075             element = doc.createElement(item[0]) 
    1076             element.setAttribute(item[0], str(getattr(datainfo, item[1]))) 
    1077             new_node.appendChild(element) 
    1078  
    1079         for item in LIST_OF_DATA_2D_VALUES: 
    1080             root_node = doc.createElement(item[0]) 
    1081             new_node.appendChild(root_node) 
    1082             temp_list = getattr(datainfo, item[1]) 
    1083  
    1084             if temp_list is None or len(temp_list) == 0: 
    1085                 element = doc.createElement(item[0]) 
    1086                 element.appendChild(doc.createTextNode(str(temp_list))) 
    1087                 root_node.appendChild(element) 
    1088             else: 
    1089                 for value in temp_list: 
    1090                     element = doc.createElement(item[0]) 
    1091                     element.setAttribute(item[0], str(value)) 
    1092                     root_node.appendChild(element) 
    1093  
    1094         # Sample info 
    1095         sample = doc.createElement("SASsample") 
    1096         if datainfo.sample.name is not None: 
    1097             sample.setAttribute("name", str(datainfo.sample.name)) 
    1098         entry_node.appendChild(sample) 
    1099         write_node(doc, sample, "ID", str(datainfo.sample.ID)) 
    1100         write_node(doc, sample, "thickness", datainfo.sample.thickness, 
    1101                    {"unit": datainfo.sample.thickness_unit}) 
    1102         write_node(doc, sample, "transmission", datainfo.sample.transmission) 
    1103         write_node(doc, sample, "temperature", datainfo.sample.temperature, 
    1104                    {"unit": datainfo.sample.temperature_unit}) 
    1105  
    1106         for item in datainfo.sample.details: 
    1107             write_node(doc, sample, "details", item) 
    1108  
    1109         pos = doc.createElement("position") 
    1110         written = write_node(doc, pos, "x", datainfo.sample.position.x, 
    1111                              {"unit": datainfo.sample.position_unit}) 
    1112         written = written | write_node(doc, pos, "y", 
    1113                                        datainfo.sample.position.y, 
    1114                                        {"unit": datainfo.sample.position_unit}) 
    1115         written = written | write_node(doc, pos, "z", 
    1116                                        datainfo.sample.position.z, 
    1117                                        {"unit": datainfo.sample.position_unit}) 
    1118         if written: 
    1119             sample.appendChild(pos) 
    1120  
    1121         ori = doc.createElement("orientation") 
    1122         written = write_node(doc, ori, "roll", datainfo.sample.orientation.x, 
    1123                              {"unit": datainfo.sample.orientation_unit}) 
    1124         written = written | write_node(doc, ori, "pitch", 
    1125                                        datainfo.sample.orientation.y, 
    1126                                        {"unit": 
    1127                                             datainfo.sample.orientation_unit}) 
    1128         written = written | write_node(doc, ori, "yaw", 
    1129                                        datainfo.sample.orientation.z, 
    1130                                        {"unit": 
    1131                                             datainfo.sample.orientation_unit}) 
    1132         if written: 
    1133             sample.appendChild(ori) 
    1134  
    1135         # Instrument info 
    1136         instr = doc.createElement("SASinstrument") 
    1137         entry_node.appendChild(instr) 
    1138  
    1139         write_node(doc, instr, "name", datainfo.instrument) 
    1140  
    1141         #   Source 
    1142         source = doc.createElement("SASsource") 
    1143         if datainfo.source.name is not None: 
    1144             source.setAttribute("name", str(datainfo.source.name)) 
    1145         instr.appendChild(source) 
    1146  
    1147         write_node(doc, source, "radiation", datainfo.source.radiation) 
    1148         write_node(doc, source, "beam_shape", datainfo.source.beam_shape) 
    1149         size = doc.createElement("beam_size") 
    1150         if datainfo.source.beam_size_name is not None: 
    1151             size.setAttribute("name", str(datainfo.source.beam_size_name)) 
    1152         written = write_node(doc, size, "x", datainfo.source.beam_size.x, 
    1153                              {"unit": datainfo.source.beam_size_unit}) 
    1154         written = written | write_node(doc, size, "y", 
    1155                                        datainfo.source.beam_size.y, 
    1156                                        {"unit": datainfo.source.beam_size_unit}) 
    1157         written = written | write_node(doc, size, "z", 
    1158                                        datainfo.source.beam_size.z, 
    1159                                        {"unit": datainfo.source.beam_size_unit}) 
    1160         if written: 
    1161             source.appendChild(size) 
    1162  
    1163         write_node(doc, source, "wavelength", datainfo.source.wavelength, 
    1164                    {"unit": datainfo.source.wavelength_unit}) 
    1165         write_node(doc, source, "wavelength_min", 
    1166                    datainfo.source.wavelength_min, 
    1167                    {"unit": datainfo.source.wavelength_min_unit}) 
    1168         write_node(doc, source, "wavelength_max", 
    1169                    datainfo.source.wavelength_max, 
    1170                    {"unit": datainfo.source.wavelength_max_unit}) 
    1171         write_node(doc, source, "wavelength_spread", 
    1172                    datainfo.source.wavelength_spread, 
    1173                    {"unit": datainfo.source.wavelength_spread_unit}) 
    1174  
    1175         #   Collimation 
    1176         for item in datainfo.collimation: 
    1177             coll = doc.createElement("SAScollimation") 
    1178             if item.name is not None: 
    1179                 coll.setAttribute("name", str(item.name)) 
    1180             instr.appendChild(coll) 
    1181  
    1182             write_node(doc, coll, "length", item.length, 
    1183                        {"unit": item.length_unit}) 
    1184  
    1185             for apert in item.aperture: 
    1186                 ap = doc.createElement("aperture") 
    1187                 if apert.name is not None: 
    1188                     ap.setAttribute("name", str(apert.name)) 
    1189                 if apert.type is not None: 
    1190                     ap.setAttribute("type", str(apert.type)) 
    1191                 coll.appendChild(ap) 
    1192  
    1193                 write_node(doc, ap, "distance", apert.distance, 
    1194                            {"unit": apert.distance_unit}) 
    1195  
    1196                 size = doc.createElement("size") 
    1197                 if apert.size_name is not None: 
    1198                     size.setAttribute("name", str(apert.size_name)) 
    1199                 written = write_node(doc, size, "x", apert.size.x, 
    1200                                      {"unit": apert.size_unit}) 
    1201                 written = written | write_node(doc, size, "y", apert.size.y, 
    1202                                                {"unit": apert.size_unit}) 
    1203                 written = written | write_node(doc, size, "z", apert.size.z, 
    1204                                                {"unit": apert.size_unit}) 
    1205                 if written: 
    1206                     ap.appendChild(size) 
    1207  
    1208         #   Detectors 
    1209         for item in datainfo.detector: 
    1210             det = doc.createElement("SASdetector") 
    1211             written = write_node(doc, det, "name", item.name) 
    1212             written = written | write_node(doc, det, "SDD", item.distance, 
    1213                                            {"unit": item.distance_unit}) 
    1214             written = written | write_node(doc, det, "slit_length", 
    1215                                            item.slit_length, 
    1216                                            {"unit": item.slit_length_unit}) 
    1217             if written: 
    1218                 instr.appendChild(det) 
    1219  
    1220             off = doc.createElement("offset") 
    1221             written = write_node(doc, off, "x", item.offset.x, 
    1222                                  {"unit": item.offset_unit}) 
    1223             written = written | write_node(doc, off, "y", item.offset.y, 
    1224                                            {"unit": item.offset_unit}) 
    1225             written = written | write_node(doc, off, "z", item.offset.z, 
    1226                                            {"unit": item.offset_unit}) 
    1227             if written: 
    1228                 det.appendChild(off) 
    1229  
    1230             center = doc.createElement("beam_center") 
    1231             written = write_node(doc, center, "x", item.beam_center.x, 
    1232                                  {"unit": item.beam_center_unit}) 
    1233             written = written | write_node(doc, center, "y", 
    1234                                            item.beam_center.y, 
    1235                                            {"unit": item.beam_center_unit}) 
    1236             written = written | write_node(doc, center, "z", 
    1237                                            item.beam_center.z, 
    1238                                            {"unit": item.beam_center_unit}) 
    1239             if written: 
    1240                 det.appendChild(center) 
    1241  
    1242             pix = doc.createElement("pixel_size") 
    1243             written = write_node(doc, pix, "x", item.pixel_size.x, 
    1244                                  {"unit": item.pixel_size_unit}) 
    1245             written = written | write_node(doc, pix, "y", item.pixel_size.y, 
    1246                                            {"unit": item.pixel_size_unit}) 
    1247             written = written | write_node(doc, pix, "z", item.pixel_size.z, 
    1248                                            {"unit": item.pixel_size_unit}) 
    1249             if written: 
    1250                 det.appendChild(pix) 
    1251  
    1252             ori = doc.createElement("orientation") 
    1253             written = write_node(doc, ori, "roll", item.orientation.x, 
    1254                                  {"unit": item.orientation_unit}) 
    1255             written = written | write_node(doc, ori, "pitch", 
    1256                                            item.orientation.y, 
    1257                                            {"unit": item.orientation_unit}) 
    1258             written = written | write_node(doc, ori, "yaw", item.orientation.z, 
    1259                                            {"unit": item.orientation_unit}) 
    1260             if written: 
    1261                 det.appendChild(ori) 
    1262  
    1263         # Processes info 
    1264         for item in datainfo.process: 
    1265             node = doc.createElement("SASprocess") 
    1266             entry_node.appendChild(node) 
    1267  
    1268             write_node(doc, node, "name", item.name) 
    1269             write_node(doc, node, "date", item.date) 
    1270             write_node(doc, node, "description", item.description) 
    1271             for term in item.term: 
    1272                 value = term['value'] 
    1273                 del term['value'] 
    1274                 write_node(doc, node, "term", value, term) 
    1275             for note in item.notes: 
    1276                 write_node(doc, node, "SASprocessnote", note) 
    1277         # Return the document, and the SASentry node associated with 
    1278         # the data we just wrote 
    1279         return doc, entry_node 
    12801189 
    12811190    def _parse_state(self, entry): 
     
    13541263        """ 
    13551264        node = dom.xpath('ns:data_class', namespaces={'ns': CANSAS_NS}) 
    1356         if not node or node[0].text.lstrip().rstrip() != "Data2D": 
    1357             return_value, _ = self._parse_entry(dom) 
    1358             numpy.trim_zeros(return_value.x) 
    1359             numpy.trim_zeros(return_value.y) 
    1360             numpy.trim_zeros(return_value.dy) 
    1361             size_dx = return_value.dx.size 
    1362             size_dxl = return_value.dxl.size 
    1363             size_dxw = return_value.dxw.size 
    1364             if size_dxl == 0 and size_dxw == 0: 
    1365                 return_value.dxl = None 
    1366                 return_value.dxw = None 
    1367                 numpy.trim_zeros(return_value.dx) 
    1368             elif size_dx == 0: 
    1369                 return_value.dx = None 
    1370                 size_dx = size_dxl 
    1371                 numpy.trim_zeros(return_value.dxl) 
    1372                 numpy.trim_zeros(return_value.dxw) 
    1373  
    1374             return return_value, _ 
    1375  
    1376         # Parse 2D 
    1377         data_info = Data2D() 
    1378  
    1379         # Look up title 
    1380         self._store_content('ns:Title', dom, 'title', data_info) 
    1381  
    1382         # Look up run number 
    1383         nodes = dom.xpath('ns:Run', namespaces={'ns': CANSAS_NS}) 
    1384         for item in nodes: 
    1385             if item.text is not None: 
    1386                 value = item.text.strip() 
    1387                 if len(value) > 0: 
    1388                     data_info.run.append(value) 
    1389                     if item.get('name') is not None: 
    1390                         data_info.run_name[value] = item.get('name') 
    1391  
    1392         # Look up instrument name 
    1393         self._store_content('ns:SASinstrument/ns:name', dom, 
    1394                             'instrument', data_info) 
    1395  
    1396         # Notes 
    1397         note_list = dom.xpath('ns:SASnote', namespaces={'ns': CANSAS_NS}) 
    1398         for note in note_list: 
    1399             try: 
    1400                 if note.text is not None: 
    1401                     note_value = note.text.strip() 
    1402                     if len(note_value) > 0: 
    1403                         data_info.notes.append(note_value) 
    1404             except Exception: 
    1405                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1406                 err_mess += "  %s" % sys.exc_value 
    1407                 self.errors.append(err_mess) 
    1408                 logging.error(err_mess) 
    1409  
    1410         # Sample info ################### 
    1411         entry = get_content('ns:SASsample', dom) 
    1412         if entry is not None: 
    1413             data_info.sample.name = entry.get('name') 
    1414  
    1415         self._store_content('ns:SASsample/ns:ID', dom, 'ID', data_info.sample) 
    1416         self._store_float('ns:SASsample/ns:thickness', dom, 'thickness', 
    1417                           data_info.sample) 
    1418         self._store_float('ns:SASsample/ns:transmission', dom, 'transmission', 
    1419                           data_info.sample) 
    1420         self._store_float('ns:SASsample/ns:temperature', dom, 'temperature', 
    1421                           data_info.sample) 
    1422  
    1423         nodes = dom.xpath('ns:SASsample/ns:details', 
    1424                           namespaces={'ns': CANSAS_NS}) 
    1425         for item in nodes: 
    1426             try: 
    1427                 if item.text is not None: 
    1428                     detail_value = item.text.strip() 
    1429                     if len(detail_value) > 0: 
    1430                         data_info.sample.details.append(detail_value) 
    1431             except Exception: 
    1432                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1433                 err_mess += "  %s" % sys.exc_value 
    1434                 self.errors.append(err_mess) 
    1435                 logging.error(err_mess) 
    1436  
    1437         # Position (as a vector) 
    1438         self._store_float('ns:SASsample/ns:position/ns:x', dom, 'position.x', 
    1439                           data_info.sample) 
    1440         self._store_float('ns:SASsample/ns:position/ns:y', dom, 'position.y', 
    1441                           data_info.sample) 
    1442         self._store_float('ns:SASsample/ns:position/ns:z', dom, 'position.z', 
    1443                           data_info.sample) 
    1444  
    1445         # Orientation (as a vector) 
    1446         self._store_float('ns:SASsample/ns:orientation/ns:roll', 
    1447                           dom, 'orientation.x', data_info.sample) 
    1448         self._store_float('ns:SASsample/ns:orientation/ns:pitch', 
    1449                           dom, 'orientation.y', data_info.sample) 
    1450         self._store_float('ns:SASsample/ns:orientation/ns:yaw', 
    1451                           dom, 'orientation.z', data_info.sample) 
    1452  
    1453         # Source info ################### 
    1454         entry = get_content('ns:SASinstrument/ns:SASsource', dom) 
    1455         if entry is not None: 
    1456             data_info.source.name = entry.get('name') 
    1457  
    1458         self._store_content('ns:SASinstrument/ns:SASsource/ns:radiation', 
    1459                             dom, 'radiation', data_info.source) 
    1460         self._store_content('ns:SASinstrument/ns:SASsource/ns:beam_shape', 
    1461                             dom, 'beam_shape', data_info.source) 
    1462         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength', 
    1463                           dom, 'wavelength', data_info.source) 
    1464         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_min', 
    1465                           dom, 'wavelength_min', data_info.source) 
    1466         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_max', 
    1467                           dom, 'wavelength_max', data_info.source) 
    1468         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread', 
    1469                           dom, 'wavelength_spread', data_info.source) 
    1470  
    1471         # Beam size (as a vector) 
    1472         entry = get_content('ns:SASinstrument/ns:SASsource/ns:beam_size', dom) 
    1473         if entry is not None: 
    1474             data_info.source.beam_size_name = entry.get('name') 
    1475  
    1476         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x', 
    1477                           dom, 'beam_size.x', data_info.source) 
    1478         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:y', 
    1479                           dom, 'beam_size.y', data_info.source) 
    1480         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z', 
    1481                           dom, 'beam_size.z', data_info.source) 
    1482  
    1483         # Collimation info ################### 
    1484         nodes = dom.xpath('ns:SASinstrument/ns:SAScollimation', 
    1485                           namespaces={'ns': CANSAS_NS}) 
    1486         for item in nodes: 
    1487             collim = Collimation() 
    1488             if item.get('name') is not None: 
    1489                 collim.name = item.get('name') 
    1490             self._store_float('ns:length', item, 'length', collim) 
    1491  
    1492             # Look for apertures 
    1493             apert_list = item.xpath('ns:aperture', 
    1494                                     namespaces={'ns': CANSAS_NS}) 
    1495             for apert in apert_list: 
    1496                 aperture = Aperture() 
    1497  
    1498                 # Get the name and type of the aperture 
    1499                 aperture.name = apert.get('name') 
    1500                 aperture.type = apert.get('type') 
    1501  
    1502                 self._store_float('ns:distance', apert, 'distance', aperture) 
    1503  
    1504                 entry = get_content('ns:size', apert) 
    1505                 if entry is not None: 
    1506                     aperture.size_name = entry.get('name') 
    1507  
    1508                 self._store_float('ns:size/ns:x', apert, 'size.x', aperture) 
    1509                 self._store_float('ns:size/ns:y', apert, 'size.y', aperture) 
    1510                 self._store_float('ns:size/ns:z', apert, 'size.z', aperture) 
    1511  
    1512                 collim.aperture.append(aperture) 
    1513  
    1514             data_info.collimation.append(collim) 
    1515  
    1516         # Detector info ###################### 
    1517         nodes = dom.xpath('ns:SASinstrument/ns:SASdetector', 
    1518                           namespaces={'ns': CANSAS_NS}) 
    1519         for item in nodes: 
    1520  
    1521             detector = Detector() 
    1522  
    1523             self._store_content('ns:name', item, 'name', detector) 
    1524             self._store_float('ns:SDD', item, 'distance', detector) 
    1525  
    1526             # Detector offset (as a vector) 
    1527             self._store_float('ns:offset/ns:x', item, 'offset.x', detector) 
    1528             self._store_float('ns:offset/ns:y', item, 'offset.y', detector) 
    1529             self._store_float('ns:offset/ns:z', item, 'offset.z', detector) 
    1530  
    1531             # Detector orientation (as a vector) 
    1532             self._store_float('ns:orientation/ns:roll', item, 
    1533                               'orientation.x', detector) 
    1534             self._store_float('ns:orientation/ns:pitch', item, 
    1535                               'orientation.y', detector) 
    1536             self._store_float('ns:orientation/ns:yaw', item, 
    1537                               'orientation.z', detector) 
    1538  
    1539             # Beam center (as a vector) 
    1540             self._store_float('ns:beam_center/ns:x', item, 
    1541                               'beam_center.x', detector) 
    1542             self._store_float('ns:beam_center/ns:y', item, 
    1543                               'beam_center.y', detector) 
    1544             self._store_float('ns:beam_center/ns:z', item, 
    1545                               'beam_center.z', detector) 
    1546  
    1547             # Pixel size (as a vector) 
    1548             self._store_float('ns:pixel_size/ns:x', item, 
    1549                               'pixel_size.x', detector) 
    1550             self._store_float('ns:pixel_size/ns:y', item, 
    1551                               'pixel_size.y', detector) 
    1552             self._store_float('ns:pixel_size/ns:z', item, 
    1553                               'pixel_size.z', detector) 
    1554  
    1555             self._store_float('ns:slit_length', item, 'slit_length', detector) 
    1556  
    1557             data_info.detector.append(detector) 
    1558  
    1559         # Processes info ###################### 
    1560         nodes = dom.xpath('ns:SASprocess', namespaces={'ns': CANSAS_NS}) 
    1561         for item in nodes: 
    1562             process = Process() 
    1563             self._store_content('ns:name', item, 'name', process) 
    1564             self._store_content('ns:date', item, 'date', process) 
    1565             self._store_content('ns:description', item, 'description', process) 
    1566  
    1567             term_list = item.xpath('ns:term', namespaces={'ns': CANSAS_NS}) 
    1568             for term in term_list: 
    1569                 try: 
    1570                     term_attr = {} 
    1571                     for attr in term.keys(): 
    1572                         term_attr[attr] = term.get(attr).strip() 
    1573                     if term.text is not None: 
    1574                         term_attr['value'] = term.text.strip() 
    1575                         process.term.append(term_attr) 
    1576                 except: 
    1577                     err_mess = "cansas_reader.read: error processing " 
    1578                     err_mess += "entry notes\n  %s" % sys.exc_value 
    1579                     self.errors.append(err_mess) 
    1580                     logging.error(err_mess) 
    1581  
    1582             note_list = item.xpath('ns:SASprocessnote', 
    1583                                    namespaces={'ns': CANSAS_NS}) 
    1584             for note in note_list: 
    1585                 if note.text is not None: 
    1586                     process.notes.append(note.text.strip()) 
    1587  
    1588             data_info.process.append(process) 
    1589  
    1590         # Data info ###################### 
    1591         nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 
    1592         if len(nodes) > 1: 
    1593             raise RuntimeError, "CanSAS reader is not compatible with" + \ 
    1594                                 " multiple SASdata entries" 
    1595  
    1596         for entry in nodes: 
    1597             for item in LIST_OF_DATA_2D_ATTR: 
    1598                 # get node 
    1599                 node = get_content('ns:%s' % item[0], entry) 
    1600                 setattr(data_info, item[1], parse_entry_helper(node, item)) 
    1601  
    1602             for item in LIST_OF_DATA_2D_VALUES: 
    1603                 field = get_content('ns:%s' % item[0], entry) 
    1604                 value_list = [] 
    1605                 if field is not None: 
    1606                     value_list = \ 
    1607                         [parse_entry_helper(node, item) for node in field] 
    1608                 if len(value_list) < 2: 
    1609                     setattr(data_info, item[0], None) 
    1610                 else: 
    1611                     setattr(data_info, item[0], numpy.array(value_list)) 
    1612  
    1613         return data_info 
     1265        return_value, _ = self._parse_entry(dom) 
     1266        return return_value, _ 
    16141267 
    16151268    def _read_cansas(self, path): 
     
    16921345                        name = original_fname 
    16931346                    state.data.group_id = name 
     1347                    state.version = fitstate.version 
    16941348                    # store state in fitting 
    16951349                    self.call_back(state=state, 
     
    17451399            state.data.run_name[0] = state.data.name 
    17461400 
    1747         if issubclass(state.data.__class__, 
    1748                       sas.sascalc.dataloader.data_info.Data1D): 
    1749             data = state.data 
    1750             doc, sasentry = self._to_xml_doc(data) 
    1751         else: 
    1752             data = state.data 
    1753             doc, sasentry = self._data2d_to_xml_doc(data) 
     1401        data = state.data 
     1402        doc, sasentry = self._to_xml_doc(data) 
    17541403 
    17551404        if state is not None: 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rcb93b40 rdb5294e  
    423423                    for item in DEFAULT_STATE: 
    424424                        input_field = get_content('ns:%s' % item, entry) 
    425                         val = str(input_field.text.strip()) 
     425                        if input_field.text is not None: 
     426                            val = str(input_field.text.strip()) 
     427                        else: 
     428                            val = '' 
    426429                        if input_field is not None: 
    427430                            temp_state[item] = val 
     
    433436                for item in DEFAULT_STATE: 
    434437                    input_field = get_content('ns:%s' % item, entry) 
    435                     val = str(input_field.text.strip()) 
     438                    if input_field.text is not None: 
     439                        val = str(input_field.text.strip()) 
     440                    else: 
     441                        val = '' 
    436442                    if input_field is not None: 
    437443                        self.set_saved_state(name=item, value=val) 
  • src/sas/sasgui/perspectives/pr/media/pr_help.rst

    r0391dae r1221196  
    1010----------- 
    1111 
    12 This tool calculates a real-space distance distribution function, *P(r)*, using  
    13 the inversion approach (Moore, 1908). 
     12This tool calculates a real-space distance distribution function, *P(r)*, using 
     13the inversion approach (Moore, 1980). 
    1414 
    1515*P(r)* is set to be equal to an expansion of base functions of the type 
     
    2424 
    2525  \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 
    26    
     26 
    2727 
    2828where $I_{meas}(Q_i)$ is the measured scattering intensity and $I_{th}(Q_i)$ is 
    29 the prediction from the Fourier transform of the *P(r)* expansion.  
     29the prediction from the Fourier transform of the *P(r)* expansion. 
    3030 
    31 The $Reg\_term$ term is a regularization term set to the second derivative  
     31The $Reg\_term$ term is a regularization term set to the second derivative 
    3232$d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 
    3333 
     
    4040 
    4141*  *Number of terms*: the number of base functions in the P(r) expansion. 
    42     
     42 
    4343*  *Regularization constant*: a multiplicative constant to set the size of 
    4444   the regularization term. 
Note: See TracChangeset for help on using the changeset viewer.