Changeset c5251f6 in sasview for src/sas/sasgui/perspectives/fitting
- Timestamp:
- Apr 1, 2017 4:43:32 PM (8 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 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. - Location:
- src/sas/sasgui/perspectives/fitting
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/fitting/basepage.py
r505706a rb301db9 53 53 ON_MAC = True 54 54 55 CUSTOM_MODEL = 'Plugin Models' 56 55 57 class BasicPage(ScrolledPanel, PanelBase): 56 58 """ 57 This class provide general structure of fitpanel page59 This class provide general structure of the fitpanel page 58 60 """ 59 61 # Internal name for the AUI manager … … 118 120 self.dxw = None 119 121 # pinhole smear 120 self.dx_min = None 121 self.dx_max = None 122 self.dx_percent = None 122 123 # smear attrbs 123 124 self.enable_smearer = None … … 677 678 def _copy_info(self, flag): 678 679 """ 679 Send event d pemding on flag680 681 : Param flag: flag that distinguish event680 Send event depending on flag 681 682 : Param flag: flag that distinguishes the event 682 683 """ 683 684 # messages depending on the flag … … 847 848 self.state.pinhole_smearer = \ 848 849 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) 851 851 self.state.dxl = copy.deepcopy(self.dxl) 852 852 self.state.dxw = copy.deepcopy(self.dxw) … … 1105 1105 """ 1106 1106 for key, value in self.master_category_dict.iteritems(): 1107 formfactor = state.formfactorcombobox.split(":") 1108 if isinstance(formfactor, list): 1109 formfactor = formfactor[0] 1107 1110 for list_item in value: 1108 if state.formfactorcomboboxin list_item:1111 if formfactor in list_item: 1109 1112 return self.categorybox.Items.index(key) 1110 1113 return 0 … … 1116 1119 :precondition: the page is already drawn or created 1117 1120 1118 :postcondition: the state of the underlying data change as well as the1121 :postcondition: the state of the underlying data changes as well as the 1119 1122 state of the graphic interface 1120 1123 """ … … 1152 1155 self._show_combox_helper() 1153 1156 # 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) 1169 1165 1170 1166 self.categorybox.Select(category_pos) 1171 1167 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) 1181 1189 break 1182 1183 self.formfactorbox.Select(formfactor_pos)1184 1185 structfactor_pos = 01186 try:1187 # to support older version1188 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 break1197 1190 1198 1191 self.structurebox.SetSelection(structfactor_pos) … … 1252 1245 # we have two more options for smearing 1253 1246 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) 1260 1252 self.onPinholeSmear(event=None) 1261 1253 elif self.slit_smearer.GetValue(): … … 1342 1334 def _selectDlg(self): 1343 1335 """ 1344 open a dialog file to select ed the customized dispersity1336 open a dialog file to select the customized polydispersity function 1345 1337 """ 1346 1338 if self.parent is not None: … … 1384 1376 # self.state.struct_rbutton = self.struct_rbutton.GetValue() 1385 1377 # self.state.plugin_rbutton = self.plugin_rbutton.GetValue() 1386 self.state.structurecombobox = self.structurebox.Get Label()1387 self.state.formfactorcombobox = self.formfactorbox.Get Label()1388 self.state.categorycombobox = self.categorybox.Get Label()1378 self.state.structurecombobox = self.structurebox.GetValue() 1379 self.state.formfactorcombobox = self.formfactorbox.GetValue() 1380 self.state.categorycombobox = self.categorybox.GetValue() 1389 1381 1390 1382 # post state to fit panel … … 1587 1579 if len(statelist) == 0 or len(listtorestore) == 0: 1588 1580 return 1589 if len(statelist) != len(listtorestore):1590 return1591 1581 1592 1582 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 1626 1621 1627 1622 def _reset_strparam_state(self, listtorestore, statelist): … … 1764 1759 def _set_multfactor_combobox(self, multiplicity=10): 1765 1760 """ 1766 Set comboBox for mu itfactor of CoreMultiShellModel1761 Set comboBox for multitfactor of CoreMultiShellModel 1767 1762 :param multiplicit: no. of multi-functionality 1768 1763 """ … … 1802 1797 Fill panel's combo box according to the type of model selected 1803 1798 """ 1804 custom_model = 'Customized Models' 1799 1805 1800 mod_cat = self.categorybox.GetStringSelection() 1806 1801 self.structurebox.SetSelection(0) … … 1811 1806 m_list = [] 1812 1807 try: 1813 if mod_cat == custom_model:1808 if mod_cat == CUSTOM_MODEL: 1814 1809 for model in self.model_list_box[mod_cat]: 1815 1810 m_list.append(self.model_dict[model.name]) … … 3457 3452 fills out the category list box 3458 3453 """ 3459 uncat_str = ' CustomizedModels'3454 uncat_str = 'Plugin Models' 3460 3455 self._read_category_info() 3461 3456 … … 3486 3481 self.model_box.Clear() 3487 3482 3488 if category == ' CustomizedModels':3483 if category == 'Plugin Models': 3489 3484 for model in self.model_list_box[category]: 3490 3485 str_m = str(model).split(".")[0] -
src/sas/sasgui/perspectives/fitting/fitpage.py
r24fd27a rd85f1d8a 29 29 _BOX_WIDTH = 76 30 30 _DATA_BOX_WIDTH = 300 31 SMEAR_SIZE_L = 0.0032 31 SMEAR_SIZE_H = 0.00 33 32 CUSTOM_MODEL = 'Plugin Models' 34 33 35 34 class FitPage(BasicPage): … … 164 163 On_select_data 165 164 """ 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 171 167 data = self.dataSource.GetClientData(pos) 172 168 self.set_data(data) … … 213 209 "Please enter only the value of interest to customize smearing..." 214 210 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..." 216 212 smear_message_2d_x_title = "<dQp>[1/A]:" 217 213 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[%]:" 220 215 smear_message_slit_height_title = "Slit height[1/A]:" 221 216 smear_message_slit_width_title = "Slit width[1/A]:" … … 256 251 self.Bind(wx.EVT_RADIOBUTTON, self.onWeighting, 257 252 id=self.dI_idata.GetId()) 258 self.dI_ didata.SetValue(True)253 self.dI_noweight.SetValue(True) 259 254 # add 4 types of weighting to the sizer 260 255 sizer_weighting.Add(self.dI_noweight, 0, wx.LEFT, 10) … … 266 261 sizer_weighting.Add(self.dI_idata) 267 262 sizer_weighting.Add((10, 10)) 268 self.dI_noweight.Enable( False)263 self.dI_noweight.Enable(True) 269 264 self.dI_didata.Enable(False) 270 265 self.dI_sqrdata.Enable(False) … … 310 305 311 306 # 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) 320 312 self.smear_slit_height = ModelTextCtrl(self, wx.ID_ANY, 321 313 size=(_BOX_WIDTH - 25, 20), … … 336 328 337 329 # 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)) 340 331 self.smear_slit_height.SetValue(str(self.dxl)) 341 332 self.smear_slit_width.SetValue(str(self.dxw)) … … 362 353 self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, 363 354 id=self.slit_smearer.GetId()) 364 self. enable_smearer.SetValue(True)355 self.disable_smearer.SetValue(True) 365 356 366 357 sizer_smearer.Add(self.disable_smearer, 0, wx.LEFT, 10) … … 429 420 self.smear_description_2d_y.SetToolTipString( 430 421 " 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) 435 425 self.smear_description_slit_height = wx.StaticText(self, wx.ID_ANY, 436 426 smear_message_slit_height_title, style=wx.ALIGN_LEFT) … … 456 446 self.sizer_new_smear.Add((15, -1)) 457 447 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)460 448 self.sizer_new_smear.Add(self.smear_description_slit_height, 461 449 0, wx.CENTER, 10) 462 450 463 self.sizer_new_smear.Add(self.smear_pinhole_min, 0, wx.CENTER, 10)464 451 self.sizer_new_smear.Add(self.smear_slit_height, 0, wx.CENTER, 10) 465 452 self.sizer_new_smear.Add(self.smear_data_left, 0, wx.CENTER, 10) … … 467 454 self.sizer_new_smear.Add(self.smear_description_2d_y, 468 455 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, 470 457 0, wx.CENTER, 10) 471 458 self.sizer_new_smear.Add(self.smear_description_slit_width, 472 459 0, wx.CENTER, 10) 473 460 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) 475 462 self.sizer_new_smear.Add(self.smear_slit_width, 0, wx.CENTER, 10) 476 463 self.sizer_new_smear.Add(self.smear_data_right, 0, wx.CENTER, 10) … … 1190 1177 self.state.slit_smearer = self.slit_smearer.GetValue() 1191 1178 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() 1194 1182 self.enable_fit_button() 1195 1183 if self.model is not None: … … 1248 1236 wx.PostEvent(self.parent, new_event) 1249 1237 # update list of plugins if new plugin is available 1250 custom_model = 'Customized Models'1238 custom_model = CUSTOM_MODEL 1251 1239 mod_cat = self.categorybox.GetStringSelection() 1252 1240 if mod_cat == custom_model: … … 1270 1258 if copy_flag: 1271 1259 self.get_paste_params(copy_flag) 1272 1260 wx.CallAfter(self._onDraw, None) 1273 1261 1274 1262 else: … … 1583 1571 if self.dxw is None: 1584 1572 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 1589 1575 1590 1576 def _get_smear_info(self): … … 1626 1612 elif data.dxl is not None or data.dxw is not None: 1627 1613 self.smear_type = "Slit" 1628 if data.dxl is not None and n ot numpy.all(data.dxl, 0):1614 if data.dxl is not None and numpy.all(data.dxl, 0): 1629 1615 self.dq_l = data.dxl[0] 1630 if data.dxw is not None and n ot numpy.all(data.dxw, 0):1616 if data.dxw is not None and numpy.all(data.dxw, 0): 1631 1617 self.dq_r = data.dxw[0] 1632 1618 # return self.smear_type,self.dq_l,self.dq_r … … 1648 1634 self.smear_description_2d_y.Show(True) 1649 1635 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) 1652 1637 # smear from data 1653 1638 elif self.enable_smearer.GetValue(): … … 1660 1645 self.smear_description_slit_width.Show(True) 1661 1646 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) 1664 1648 self.smear_description_smear_type.Show(True) 1665 1649 self.smear_description_type.Show(True) … … 1670 1654 if self.smear_type == 'Pinhole': 1671 1655 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) 1677 1659 # custom slit smear 1678 1660 elif self.slit_smearer.GetValue(): … … 1699 1681 self.smear_data_left.Hide() 1700 1682 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() 1705 1685 self.smear_description_slit_height.Hide() 1706 1686 self.smear_slit_height.Hide() … … 1933 1913 1934 1914 # more disables for 2D 1915 di_flag = False 1916 dq_flag = False 1935 1917 if self.data.__class__.__name__ == "Data2D" or \ 1936 1918 self.enable2D: … … 1938 1920 self.pinhole_smearer.Enable(True) 1939 1921 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 1950 1928 else: 1951 1929 self.slit_smearer.Enable(True) 1952 1930 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 1964 1956 # Enable weighting radio buttons 1965 1957 self.dI_noweight.Enable(True) … … 2003 1995 self.EditMask_title.Disable() 2004 1996 1997 self.on_smear_helper() 2005 1998 self.on_set_focus(None) 2006 1999 self.Refresh() … … 2238 2231 # event case of radio button 2239 2232 if tcrtl.GetValue(): 2240 self.dx_min = 0.0 2241 self.dx_max = 0.0 2233 self.dx_percent = 0.0 2242 2234 is_new_pinhole = True 2243 2235 else: … … 2276 2268 """ 2277 2269 # 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 2282 2273 try: 2283 dx_ min = float(pin_min)2274 dx_percent = float(pin_percent) 2284 2275 except: 2285 2276 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: 2295 2278 return True 2296 2279 return False … … 2318 2301 msg = None 2319 2302 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") 2328 2307 msg = "Model Error:wrong value entered!!!" 2329 2308 else: 2330 2309 if len_data < 2: 2331 2310 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") 2336 2314 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 2341 2317 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 2346 2320 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 2361 2322 self.current_smearer = smear_selection(data, self.model) 2362 2323 # 2D need to set accuracy … … 2368 2329 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 2369 2330 else: 2370 get_pin_min.SetBackgroundColour("white") 2371 get_pin_max.SetBackgroundColour("white") 2331 get_pin_percent.SetBackgroundColour("white") 2372 2332 # set smearing value whether or not the data contain the smearing info 2373 2333 -
src/sas/sasgui/perspectives/fitting/fitting.py
r73cbeec r4c5098c 225 225 226 226 self.id_edit = wx.NewId() 227 editmodel_help = "Edit customized model sample file"228 227 self.menu1.AppendMenu(self.id_edit, "Plugin Model Operations", 229 self.edit_model_menu , editmodel_help)228 self.edit_model_menu) 230 229 #create menubar items 231 230 return [(self.menu1, self.sub_menu)] … … 260 259 self.update_custom_combo() 261 260 if os.path.isfile(p_path): 262 msg = "Sorry! Could not beable to delete the default "263 msg += " custommodel... \n"261 msg = "Sorry! unable to delete the default " 262 msg += "plugin model... \n" 264 263 msg += "Please manually remove the files (.py, .pyc) " 265 264 msg += "in the 'plugin_models' folder \n" … … 274 273 if item.GetLabel() == label: 275 274 self.edit_menu.DeleteItem(item) 276 msg = "The custommodel, %s, has been deleted." % label275 msg = "The plugin model, %s, has been deleted." % label 277 276 evt = StatusEvent(status=msg, type='stop', info='info') 278 277 wx.PostEvent(self.parent, evt) … … 331 330 temp = self.fit_panel.reset_pmodel_list() 332 331 if temp: 333 # Set the new custommodel list for all fit pages332 # Set the new plugin model list for all fit pages 334 333 for uid, page in self.fit_panel.opened_pages.iteritems(): 335 334 if hasattr(page, "formfactorbox"): … … 1756 1755 data_id="Data " + data.name + " unsmeared", 1757 1756 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)") 1767 1765 1768 1766 current_pg = self.fit_panel.get_page_by_id(page_id) … … 1965 1963 ## then kill itself but cannot. Paul Kienzle came up with 1966 1964 ## 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. 1968 1967 ## We still don't know why the fit sometimes lauched a second 1969 1968 ## thread -- something which should also be investigated. -
src/sas/sasgui/perspectives/fitting/media/fitting_help.rst
r26c8be3 r5295cf5 34 34 * in *Single* fit mode - individual data sets are fitted independently one-by-one 35 35 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) 37 39 38 40 * 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!) … … 43 45 ----------------- 44 46 45 By default, the models in SasView are grouped into five categories 46 47 * *Shapes* - models describing 'objects' (spheres, cylinders, etc) 47 The 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) 48 56 * *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) 51 58 * *Structure Factor* - S(Q) models 59 * *Plugin Models* - User-created (custom/non-library) Python models 52 60 53 61 Use the *Category* drop-down menu to chose a category of model, then select … … 84 92 .. image:: cat_fig0.bmp 85 93 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.94 The categorization of all models except the user supplied Plugin Models can be 95 reassigned, added to, and removed using *Category Manager*. Models can also be 96 hidden from view in the drop-down menus. 89 97 90 98 .. image:: cat_fig1.bmp … … 93 101 ^^^^^^^^^^^^^^^^^ 94 102 95 To change category, highlight a model in the list by left-clicking on its entry and96 then click the *Modify* button. Use the *Change Category* panel that appears to make 97 t he required changes.103 To change category, highlight a model in the list by left-clicking on its entry 104 and then click the *Modify* button. Use the *Change Category* panel that appears 105 to make the required changes. 98 106 99 107 .. image:: cat_fig2.bmp … … 106 114 ^^^^^^^^^^^^^^^^^^^^^ 107 115 108 Use the *Enable All / Disable All* buttons and the check boxes beside each model to109 select the models to show/hide. To apply the selection, click *Ok*. Otherwise click 110 *Cancel*.116 Use the *Enable All / Disable All* buttons and the check boxes beside each model 117 to select the models to show/hide. To apply the selection, click *Ok*. Otherwise 118 click *Cancel*. 111 119 112 120 *NB: It may be necessary to change to a different category and then back again* … … 118 126 --------------- 119 127 120 For a complete list of all the library models available in SasView, see the `Model Documentation <../../../index.html>`_ . 128 For a complete list of all the library models available in SasView, see 129 the `Model Documentation <../../../index.html>`_ . 121 130 122 131 It is also possible to add your own models. … … 131 140 There are essentially three ways to generate new fitting models for SasView: 132 141 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!) 136 149 137 150 Please read the guidance on :ref:`Writing_a_Plugin` before proceeding. … … 163 176 ^^^^^^^^^^^^^^^^ 164 177 165 Relatively straightforward models can be programmed directly from the SasView GUI166 using the *New Plugin Model Function*.178 Relatively straightforward models can be programmed directly from the SasView 179 GUI using the *New Plugin Model Function*. 167 180 168 181 .. image:: new_model.bmp … … 175 188 *checked*\ . 176 189 177 Also note that the 'Fit Parameters' have been split into two sections: those which178 can be polydisperse (shape and orientation parameters) and those which are not 179 (eg, scattering length densities).190 Also note that the 'Fit Parameters' have been split into two sections: those 191 which can be polydisperse (shape and orientation parameters) and those which are 192 not (eg, scattering length densities). 180 193 181 194 A model file generated by this option can be viewed and further modified using … … 187 200 .. image:: sum_model.bmp 188 201 189 This option creates a custom model of the form::190 191 Custom Model = scale_factor \* {(scale_1 \* model_1) \+ (scale_2 \* model_2)} \+ background202 This option creates a custom Plugin Model of the form:: 203 204 Plugin Model = scale_factor * {(scale_1 * model_1) +/- (scale_2 * model_2)} + background 192 205 193 206 or:: 194 207 195 Custom Model = scale_factor \* model_1 \* model_2 \+ background208 Plugin Model = scale_factor * model_1 /* model_2 + background 196 209 197 210 In the *Easy Sum/Multi Editor* give the new model a function name and brief … … 232 245 Simply highlight the plugin model to be removed. The operation is final!!! 233 246 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.* 235 248 236 249 Load Plugin Models 237 250 ^^^^^^^^^^^^^^^^^^ 238 251 239 This option loads (or re-loads) all models present in the *~\\.sasview\\plugin_models* folder. 252 This option loads (or re-loads) all models present in the 253 *~\\.sasview\\plugin_models* folder. 240 254 241 255 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ … … 400 414 :ref:`Assessing_Fit_Quality`. 401 415 402 *NB: If you need to use a custom ized 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 417 available first (see* :ref:`Adding_your_own_models` *).* 404 418 405 419 Method … … 484 498 If multiple data sets are in one file, load just that file. *Unselect All Data*, then 485 499 select 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 custom ized model, you must ensure that model is available*489 *first (see* :ref:`Adding_your_own_models` *).*500 above under :ref:`Single_Fit_Mode`. 501 502 *NB: If you need to use a custom Plugin Model, you must ensure that model is 503 available first (see* :ref:`Adding_your_own_models` *).* 490 504 491 505 Method -
src/sas/sasgui/perspectives/fitting/media/plugin.rst
rca6cbc1c r984f3fc 27 27 28 28 the next time SasView is started it will compile the plugin and add 29 it to the list of * CustomizedModels* in a FitPage.29 it to the list of *Plugin Models* in a FitPage. 30 30 31 31 SasView models can be of three types: … … 364 364 - the limits will show up as the default limits for the fit making it easy, 365 365 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. 366 369 367 370 - **"type"** can be one of: "", "sld", "volume", or "orientation". -
src/sas/sasgui/perspectives/fitting/model_thread.py
rc1681ea rc1c9929 177 177 unsmeared_output = numpy.zeros((len(self.data.x))) 178 178 unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 179 self.smearer.model = self.model 179 180 output = self.smearer(unsmeared_output, first_bin, last_bin) 180 181 -
src/sas/sasgui/perspectives/fitting/models.py
r51335d7 rc5251f6 23 23 PLUGIN_LOG = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR, 24 24 "plugins.log") 25 PLUGIN_NAME_BASE = '[plug-in] ' 25 26 26 27 def get_model_python_path(): … … 181 182 try: 182 183 model = load_custom_model(path) 183 model.name = "[plug-in] "+model.name184 model.name = PLUGIN_NAME_BASE + model.name 184 185 plugins[model.name] = model 185 186 except Exception: … … 324 325 self.plugins.append(plug) 325 326 self.model_dictionary[name] = plug 326 self.model_combobox.set_list(" CustomizedModels", self.plugins)327 self.model_combobox.set_list("Plugin Models", self.plugins) 327 328 return self.model_combobox.get_list() 328 329 else: … … 345 346 self.model_dictionary[name] = plug 346 347 347 self.model_combobox.reset_list(" CustomizedModels", self.plugins)348 self.model_combobox.reset_list("Plugin Models", self.plugins) 348 349 return self.model_combobox.get_list() 349 350 … … 388 389 # self.shape_indep_list) 389 390 self.model_combobox.set_list("Structure Factors", self.struct_list) 390 self.model_combobox.set_list(" CustomizedModels", self.plugins)391 self.model_combobox.set_list("Plugin Models", self.plugins) 391 392 self.model_combobox.set_list("P(Q)*S(Q)", self.multiplication_factor) 392 393 self.model_combobox.set_list("multiplication", -
src/sas/sasgui/perspectives/fitting/pagestate.py
rc8e1996 r27109e5 25 25 from lxml import etree 26 26 27 from sasmodels import convert 27 28 import sasmodels.weights 28 29 … … 32 33 from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 33 34 from sas.sascalc.dataloader.data_info import Process, Aperture 35 34 36 # Information to read/write state as xml 35 37 FITTING_NODE_NAME = 'fitting_plug_in' 36 38 CANSAS_NS = "cansas1d/1.0" 39 40 CUSTOM_MODEL = 'Plugin Models' 41 CUSTOM_MODEL_OLD = 'Customized Models' 37 42 38 43 LIST_OF_DATA_ATTRIBUTES = [["is_data", "is_data", "bool"], … … 69 74 ["dq_l", "dq_l", "float"], 70 75 ["dq_r", "dq_r", "float"], 71 ["dx_max", "dx_max", "float"], 72 ["dx_min", "dx_min", "float"], 76 ["dx_percent", "dx_percent", "float"], 73 77 ["dxl", "dxl", "float"], 74 78 ["dxw", "dxw", "float"]] … … 210 214 self.dq_l = None 211 215 self.dq_r = None 212 self.dx_ max= None213 self.dx_ min = None216 self.dx_percent = None 217 self.dx_old = False 214 218 self.dxl = None 215 219 self.dxw = None … … 271 275 # store value of chisqr 272 276 self.tcChi = None 277 self.version = (1,0,0) 273 278 274 279 def clone(self): … … 337 342 obj.dq_l = copy.deepcopy(self.dq_l) 338 343 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) 341 346 obj.dxl = copy.deepcopy(self.dxl) 342 347 obj.dxw = copy.deepcopy(self.dxw) … … 349 354 obj.cb1 = copy.deepcopy(self.cb1) 350 355 obj.smearer = copy.deepcopy(self.smearer) 356 obj.version = copy.deepcopy(self.version) 351 357 352 358 for name, state in self.saved_states.iteritems(): … … 355 361 obj.saved_states[copy_name] = copy_state 356 362 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) 357 495 358 496 def _repr_helper(self, list, rep): … … 423 561 rep += "dq_l : %s\n" % self.dq_l 424 562 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) 427 564 rep += "dxl : %s\n" % str(self.dxl) 428 565 rep += "dxw : %s\n" % str(self.dxw) … … 682 819 683 820 attr = newdoc.createAttribute("version") 684 attr.nodeValue = '1.0' 821 from sas import sasview 822 attr.nodeValue = sasview.__version__ 823 # attr.nodeValue = '1.0' 685 824 top_element.setAttributeNode(attr) 686 825 … … 875 1014 raise RuntimeError, msg 876 1015 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) 878 1025 879 1026 # Get file name … … 899 1046 setattr(self, item[0], parse_entry_helper(node, item)) 900 1047 1048 dx_old_node = get_content('ns:%s' % 'dx_min', entry) 901 1049 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)) 904 1058 905 1059 for item in LIST_OF_STATE_PARAMETERS: … … 1033 1187 if self.cansas: 1034 1188 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 Data2D1039 1040 :param datainfo: Data2D object1041 1042 """1043 if not issubclass(datainfo.__class__, Data2D):1044 raise RuntimeError, "The cansas writer expects a Data2D instance"1045 1046 title = "cansas1d/%s" % self.version1047 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 info1072 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 info1095 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 info1136 instr = doc.createElement("SASinstrument")1137 entry_node.appendChild(instr)1138 1139 write_node(doc, instr, "name", datainfo.instrument)1140 1141 # Source1142 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 # Collimation1176 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 # Detectors1209 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 info1264 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 with1278 # the data we just wrote1279 return doc, entry_node1280 1189 1281 1190 def _parse_state(self, entry): … … 1354 1263 """ 1355 1264 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, _ 1614 1267 1615 1268 def _read_cansas(self, path): … … 1692 1345 name = original_fname 1693 1346 state.data.group_id = name 1347 state.version = fitstate.version 1694 1348 # store state in fitting 1695 1349 self.call_back(state=state, … … 1745 1399 state.data.run_name[0] = state.data.name 1746 1400 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) 1754 1403 1755 1404 if state is not None:
Note: See TracChangeset
for help on using the changeset viewer.