Changeset 8fa3fb8 in sasview for src/sas/sasgui
- Timestamp:
- Mar 1, 2017 9:46:54 AM (7 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- a97aebd
- Parents:
- cb1e9a5 (diff), 775e0b7 (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
- Files:
-
- 1 added
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/CategoryInstaller.py
r212bfc2 rddbac66 123 123 compile it and install 124 124 :param homefile: Override the default home directory 125 :param model_list: List of model names except customized models 125 :param model_list: List of model names except those in Plugin Models 126 which are user supplied. 126 127 """ 127 128 _model_dict = { model.name: model for model in model_list} -
src/sas/sasgui/guiframe/customdir.py
r212bfc2 r73cbeec 34 34 if not os.path.isfile(config_file): 35 35 shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) 36 37 #Adding SAS_OPENCL if it doesn't exist in the config file 38 # - to support backcompability 39 if not "SAS_OPENCL" in open(config_file).read(): 40 open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") 36 41 except: 37 42 # Check for data path next to exe/zip file. -
src/sas/sasgui/guiframe/dataFitting.py
r9b6d62d r68adf86 17 17 """ 18 18 """ 19 def __init__(self, x=None, y=None, dx=None, dy=None): 19 20 def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=False): 20 21 """ 21 22 """ … … 24 25 if y is None: 25 26 y = [] 26 PlotData1D.__init__(self, x, y, dx, dy) 27 LoadData1D.__init__(self, x, y, dx, dy) 27 self.isSesans = isSesans 28 PlotData1D.__init__(self, x, y, dx, dy, lam, dlam) 29 LoadData1D.__init__(self, x, y, dx, dy, lam, dlam, isSesans) 30 28 31 self.id = None 29 32 self.list_group_id = [] … … 32 35 self.path = None 33 36 self.xtransform = None 37 if self.isSesans: 38 self.xtransform = "x" 34 39 self.ytransform = None 40 if self.isSesans: 41 self.ytransform = "y" 35 42 self.title = "" 36 43 self.scale = None … … 68 75 # First, check the data compatibility 69 76 dy, dy_other = self._validity_check(other) 70 result = Data1D(x=[], y=[], dx=None, dy=None)77 result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 71 78 result.clone_without_data(length=len(self.x), clone=self) 72 79 result.copy_from_datainfo(data1d=self) … … 115 122 # First, check the data compatibility 116 123 self._validity_check_union(other) 117 result = Data1D(x=[], y=[], dx=None, dy=None)124 result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 118 125 tot_length = len(self.x) + len(other.x) 119 126 result = self.clone_without_data(length=tot_length, clone=result) 127 if self.dlam == None or other.dlam is None: 128 result.dlam = None 129 else: 130 result.dlam = numpy.zeros(tot_length) 120 131 if self.dy == None or other.dy is None: 121 132 result.dy = None … … 141 152 result.y = numpy.append(self.y, other.y) 142 153 result.y = result.y[ind] 154 result.lam = numpy.append(self.lam, other.lam) 155 result.lam = result.lam[ind] 156 if result.dlam != None: 157 result.dlam = numpy.append(self.dlam, other.dlam) 158 result.dlam = result.dlam[ind] 143 159 if result.dy != None: 144 160 result.dy = numpy.append(self.dy, other.dy) … … 260 276 # First, check the data compatibility 261 277 self._validity_check_union(other) 262 result = Data1D(x=[], y=[], dx=None, dy=None)278 result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=[]) 263 279 tot_length = len(self.x)+len(other.x) 264 280 result.clone_without_data(length=tot_length, clone=self) 281 if self.dlam == None or other.dlam is None: 282 result.dlam = None 283 else: 284 result.dlam = numpy.zeros(tot_length) 265 285 if self.dy == None or other.dy is None: 266 286 result.dy = None … … 285 305 result.y = numpy.append(self.y, other.y) 286 306 result.y = result.y[ind] 307 result.lam = numpy.append(self.lam, other.lam) 308 result.lam = result.lam[ind] 287 309 if result.dy != None: 288 310 result.dy = numpy.append(self.dy, other.dy) -
src/sas/sasgui/guiframe/data_manager.py
rd85c194 r2ffe241 61 61 62 62 if issubclass(Data2D, data.__class__): 63 new_plot = Data2D(image=None, err_image=None) 64 else: 65 new_plot = Data1D(x=[], y=[], dx=None, dy=None) 66 63 new_plot = Data2D(image=None, err_image=None) # For now, isSesans for 2D data is always false 64 else: 65 new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=data.isSesans) 66 67 68 #elif data.meta_data['loader'] == 'SESANS': 69 # new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=True) 70 #else: 71 # new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None) #SESANS check??? 72 67 73 new_plot.copy_from_datainfo(data) 68 74 data.clone_without_data(clone=new_plot) -
src/sas/sasgui/guiframe/gui_manager.py
rc8e1996 r73cbeec 152 152 SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT 153 153 SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME 154 SAS_OPENCL = config.SAS_OPENCL 154 155 if not WELCOME_PANEL_ON: 155 156 WELCOME_PANEL_SHOW = False … … 176 177 else: 177 178 DEFAULT_OPEN_FOLDER = PATH_APP 179 SAS_OPENCL = custom_config.SAS_OPENCL 178 180 except: 179 181 DATALOADER_SHOW = True … … 190 192 CLEANUP_PLOT = False 191 193 DEFAULT_OPEN_FOLDER = PATH_APP 192 194 SAS_OPENCL = None 193 195 DEFAULT_STYLE = config.DEFAULT_STYLE 194 196 … … 225 227 CHILD_FRAME = wx.Frame 226 228 229 #Initiliaze enviromental variable with custom setting but only if variable not set 230 if SAS_OPENCL and not "SAS_OPENCL" in os.environ: 231 os.environ["SAS_OPENCL"] = SAS_OPENCL 227 232 228 233 class ViewerFrame(PARENT_FRAME): … … 1950 1955 item, _, _ = value 1951 1956 item.Check(True) 1952 self._data_panel.on_remove(None, False)1953 1957 1954 1958 wx.PostEvent(self, StatusEvent(status="Loading Project file...")) … … 1963 1967 # Reset to a base state 1964 1968 self._on_reset_state() 1969 self._data_panel.on_remove(None, False) 1965 1970 # Load the project file 1966 1971 self.load_state(path=path, is_project=True) … … 1990 1995 wx.PostEvent(self, 1991 1996 StatusEvent(status="Completed saving.")) 1992 except :1997 except Exception: 1993 1998 msg = "Error occurred while saving: " 1999 msg += traceback.format_exc() 1994 2000 msg += "To save, the application panel should have a data set.." 1995 2001 wx.PostEvent(self, StatusEvent(status=msg)) … … 2040 2046 logging.warning(msg) 2041 2047 wx.PostEvent(self, StatusEvent(status=msg, info="error")) 2042 except :2048 except Exception: 2043 2049 msg = "Error occurred while saving: " 2050 msg += traceback.format_exc() 2044 2051 msg += "To save, at least one application panel " 2045 2052 msg += "should have a data set.." … … 2102 2109 Quit the application 2103 2110 """ 2111 #IF SAS_OPENCL is set, settings are stored in the custom config file 2112 self._write_opencl_config_file() 2104 2113 logging.info(" --- SasView session was closed --- \n") 2105 2114 wx.Exit() 2106 2115 sys.exit() 2116 2117 def _write_opencl_config_file(self): 2118 """ 2119 Writes OpenCL settings to custom config file, so they can be remmbered 2120 from session to session 2121 """ 2122 if custom_config is not None: 2123 sas_opencl = os.environ.get("SAS_OPENCL",None) 2124 new_config_lines = [] 2125 config_file = open(custom_config.__file__) 2126 config_lines = config_file.readlines() 2127 for line in config_lines: 2128 if "SAS_OPENCL" in line: 2129 if sas_opencl: 2130 new_config_lines.append("SAS_OPENCL = \""+sas_opencl+"\"") 2131 else: 2132 new_config_lines.append("SAS_OPENCL = None") 2133 else: 2134 new_config_lines.append(line) 2135 config_file.close() 2136 2137 #If custom_config is None, settings will not be remmbered 2138 new_config_file = open(custom_config.__file__,"w") 2139 new_config_file.writelines(new_config_lines) 2140 new_config_file.close() 2141 else: 2142 logging.info("Failed to save OPENCL settings in custom config file") 2143 2107 2144 2108 2145 def _check_update(self, event=None): … … 2456 2493 group_id=group_id, 2457 2494 action='remove')) 2458 # remove res plot: Todo: improve2459 2495 wx.CallAfter(self._remove_res_plot, new_plot.id) 2460 2496 self._data_manager.delete_data(data_id=data_id, -
src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py
r245ae18 r29e872e 65 65 # context menu 66 66 self._slicerpop = None 67 68 67 self._available_data = [] 69 68 self._symbol_labels = self.get_symbol_label() … … 732 731 self.subplot.set_ylim(y_range) 733 732 self.subplot.figure.canvas.draw_idle() 733 self.is_zoomed = True 734 734 d.Destroy() 735 735 -
src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py
r1a696bf rb2b36932 316 316 317 317 slicerpop.AppendSeparator() 318 if len(self.data2D.detector) == 1:318 if len(self.data2D.detector) <= 1: 319 319 item_list = self.parent.get_current_context_menu(self) 320 320 if (not item_list == None) and (not len(item_list) == 0) and\ -
src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py
r6ffa0dd rca224b1 134 134 """ 135 135 for group_id in self.plot_panels.keys(): 136 panel = self.plot_panels[group_id] 137 panel.graph.reset() 138 self.hide_panel(group_id) 136 self.clear_panel_by_id(group_id) 139 137 self.plot_panels = {} 140 138 -
src/sas/sasgui/guiframe/startup_configuration.py
rd85c194 r73cbeec 31 31 'CLEANUP_PLOT':False, 32 32 'DEFAULT_PERSPECTIVE':'Fitting', 33 'DEFAULT_OPEN_FOLDER': None} 33 'DEFAULT_OPEN_FOLDER': None, 34 'SAS_OPENCL': None} 34 35 try: 35 36 CURRENT_STRINGS = {'GUIFRAME_WIDTH':CURRENT.GUIFRAME_WIDTH, … … 45 46 'CLEANUP_PLOT':CURRENT.CLEANUP_PLOT, 46 47 'DEFAULT_PERSPECTIVE':CURRENT.DEFAULT_PERSPECTIVE, 47 'DEFAULT_OPEN_FOLDER':CURRENT.DEFAULT_OPEN_FOLDER} 48 'DEFAULT_OPEN_FOLDER':CURRENT.DEFAULT_OPEN_FOLDER, 49 'SAS_OPENCL': None} 48 50 except: 49 51 CURRENT_STRINGS = DEFAULT_STRINGS -
src/sas/sasgui/perspectives/calculator/model_editor.py
r94f0873f rddbac66 5 5 function of y (usually the intensity). It also provides a drop down of 6 6 standard available math functions. Finally a full python editor panel for 7 complete customizati n is provided.8 9 :TODO the writi ong of the file and name checking (and maybe some other10 fun tions?) should be moved to a computational module which could be called11 fro pm a python script. Basically one just needs to pass the name,7 complete customization is provided. 8 9 :TODO the writing of the file and name checking (and maybe some other 10 functions?) should be moved to a computational module which could be called 11 from a python script. Basically one just needs to pass the name, 12 12 description text and function text (or in the case of the composite editor 13 13 the names of the first and second model and the operator to be used). … … 61 61 """ 62 62 Dialog for easy custom composite models. Provides a wx.Dialog panel 63 to choose two existing models (including pre-existing custom models which63 to choose two existing models (including pre-existing Plugin Models which 64 64 may themselves be composite models) as well as an operation on those models 65 65 (add or multiply) the resulting model will add a scale parameter for summed … … 380 380 color = 'blue' 381 381 except: 382 msg = "Easy Custom Sum/Multipy: Error occurred..."382 msg = "Easy Sum/Multipy Plugin: Error occurred..." 383 383 info = 'Error' 384 384 color = 'red' … … 501 501 self.factor = factor 502 502 self._operator = operator 503 self.explanation = " CustomModel = %s %s (model1 %s model2)\n" % \503 self.explanation = " Plugin Model = %s %s (model1 %s model2)\n" % \ 504 504 (self.factor, f_oper, self._operator) 505 505 self.explanationctr.SetLabel(self.explanation) … … 617 617 class EditorPanel(wx.ScrolledWindow): 618 618 """ 619 Custom model function editor619 Simple Plugin Model function editor 620 620 """ 621 621 def __init__(self, parent, base, path, title, *args, **kwds): … … 652 652 self.msg_sizer = None 653 653 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" 655 657 self.function_tcl = None 656 658 self.math_combo = None … … 991 993 else: 992 994 self._notes = result 993 msg = "Successful! Please look for %s in CustomizedModels."%name995 msg = "Successful! Please look for %s in Plugin Models."%name 994 996 msg += " " + self._notes 995 997 info = 'Info' … … 1138 1140 def on_help(self, event): 1139 1141 """ 1140 Bring up the CustomModel Editor Documentation whenever1142 Bring up the New Plugin Model Editor Documentation whenever 1141 1143 the HELP button is clicked. 1142 1144 … … 1152 1154 1153 1155 _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 1154 _PageAnchor = "# New_Plugin_Model"1156 _PageAnchor = "#new-plugin-model" 1155 1157 _doc_viewer = DocumentationWindow(self, -1, _TreeLocation, _PageAnchor, 1156 1158 "Plugin Model Editor Help") … … 1190 1192 #self.Destroy() 1191 1193 1192 ## Templates for custommodels1194 ## Templates for plugin models 1193 1195 1194 1196 CUSTOM_TEMPLATE = """ -
src/sas/sasgui/perspectives/calculator/pyconsole.py
rd472e86 rddbac66 302 302 success = show_model_output(self, fname) 303 303 304 # Update custommodel list in fitpage combobox304 # Update plugin model list in fitpage combobox 305 305 if success and self._manager != None and self.panel != None: 306 306 self._manager.set_edit_menu_helper(self.parent) -
src/sas/sasgui/perspectives/corfunc/corfunc.py
r96d293da r1dc8ec9 32 32 self._always_active = True 33 33 self.state_reader = Reader(self.set_state) 34 self._extensions = '.c or'34 self._extensions = '.crf' 35 35 36 36 def get_panels(self, parent): … … 48 48 49 49 l = Loader() 50 l.associate_file_reader('.c or', self.state_reader)50 l.associate_file_reader('.crf', self.state_reader) 51 51 52 52 return [self.corfunc_panel] … … 67 67 return [] 68 68 data = plotpanel.plots[graph.selected_plottable] 69 if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL :69 if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL1 or data.id == TRANSFORM_LABEL3: 70 70 return [] 71 71 item = plotpanel.plots[graph.selected_plottable] … … 81 81 def set_state(self, state=None, datainfo=None): 82 82 """ 83 Callback for CorfuncState reader. Called when a .c orfile is loaded83 Callback for CorfuncState reader. Called when a .crf file is loaded 84 84 """ 85 85 if isinstance(datainfo, list): … … 179 179 # Show the extrapolation as a curve instead of points 180 180 new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 181 elif label == TRANSFORM_LABEL :181 elif label == TRANSFORM_LABEL1 or label == TRANSFORM_LABEL3: 182 182 new_plot.xaxis("{x}", 'A') 183 183 new_plot.yaxis("{\\Gamma}", '') -
src/sas/sasgui/perspectives/corfunc/corfunc_panel.py
rd45d590 r1dc8ec9 274 274 plot_x = transform.x[np.where(transform.x <= 200)] 275 275 plot_y = transform.y[np.where(transform.x <= 200)] 276 self._manager.show_data(Data1D(plot_x, plot_y), TRANSFORM_LABEL )276 self._manager.show_data(Data1D(plot_x, plot_y), TRANSFORM_LABEL1) 277 277 # Only enable extract params button if a fourier trans. has been done 278 278 if self.transform_type == 'fourier': … … 325 325 dlg = wx.FileDialog(self, "Choose a file", 326 326 default_save_location, \ 327 self.window_caption, "*.c or", wx.SAVE)327 self.window_caption, "*.crf", wx.SAVE) 328 328 if dlg.ShowModal() == wx.ID_OK: 329 329 path = dlg.GetPath() … … 336 336 dlg.Destroy() 337 337 # MAC always needs the extension for saving 338 extens = ".c or"338 extens = ".crf" 339 339 # Make sure the ext included in the file name 340 340 f_name = os.path.splitext(path)[0] + extens -
src/sas/sasgui/perspectives/corfunc/corfunc_state.py
rd45d590 rae9b8bf 96 96 self.background = value 97 97 98 def toXML(self, filename='corfunc_state.c or', doc=None, entry_node=None):98 def toXML(self, filename='corfunc_state.crf', doc=None, entry_node=None): 99 99 """ 100 100 Writes the state of the CorfuncPanel panel to file, as XML. … … 257 257 type_name = "Corfunc" 258 258 259 type = ["Corfunc file (*.c or)|*.cor",259 type = ["Corfunc file (*.crf)|*.crf", 260 260 "SASView file (*.svs)|*.svs"] 261 261 262 ext = ['.c or', '.COR', '.svs', '.SVS']262 ext = ['.crf', '.CRF', '.svs', '.SVS'] 263 263 264 264 def __init__(self, callback): -
src/sas/sasgui/perspectives/corfunc/plot_labels.py
rff11b21 r1dc8ec9 4 4 5 5 GROUP_ID_TRANSFORM = r"$\Gamma(x)$" 6 TRANSFORM_LABEL = r"$\Gamma(x)$" 6 TRANSFORM_LABEL1 = r"$\Gamma1(x)$" 7 TRANSFORM_LABEL3 = r"$\Gamma3(x)$" -
src/sas/sasgui/perspectives/fitting/basepage.py
rc8e1996 r7a5aedd 53 53 ON_MAC = True 54 54 55 CUSTOM_MODEL = 'Plugin Models' 55 56 56 57 class BasicPage(ScrolledPanel, PanelBase): 57 58 """ 58 This class provide general structure of fitpanel page59 This class provide general structure of the fitpanel page 59 60 """ 60 61 # Internal name for the AUI manager … … 678 679 def _copy_info(self, flag): 679 680 """ 680 Send event d pemding on flag681 682 : Param flag: flag that distinguish event681 Send event depending on flag 682 683 : Param flag: flag that distinguishes the event 683 684 """ 684 685 # messages depending on the flag … … 1042 1043 disp_model = POLYDISPERSITY_MODELS['array']() 1043 1044 if hasattr(state, "values") and \ 1044 self.disp_cb_dict[item].GetValue() is True:1045 self.disp_cb_dict[item].GetValue(): 1045 1046 if len(state.values) > 0: 1046 1047 self.values = state.values … … 1106 1107 """ 1107 1108 for key, value in self.master_category_dict.iteritems(): 1109 formfactor = state.formfactorcombobox.split(":") 1110 if isinstance(formfactor, list): 1111 formfactor = formfactor[0] 1108 1112 for list_item in value: 1109 if state.formfactorcomboboxin list_item:1113 if formfactor in list_item: 1110 1114 return self.categorybox.Items.index(key) 1111 1115 return 0 … … 1117 1121 :precondition: the page is already drawn or created 1118 1122 1119 :postcondition: the state of the underlying data change as well as the1123 :postcondition: the state of the underlying data changes as well as the 1120 1124 state of the graphic interface 1121 1125 """ … … 1153 1157 self._show_combox_helper() 1154 1158 # select the current model 1155 try: 1156 # to support older version 1157 category_pos = int(state.categorycombobox) 1158 except: 1159 state.formfactorcombobox = state.formfactorcombobox.lower() 1160 state.formfactorcombobox = \ 1161 state.formfactorcombobox.replace('model', '') 1162 state.formfactorcombobox = unicode(state.formfactorcombobox) 1163 state.categorycombobox = unicode(state.categorycombobox) 1164 if state.categorycombobox in self.categorybox.Items: 1165 category_pos = self.categorybox.Items.index( 1166 state.categorycombobox) 1167 else: 1168 # Look in master list for model name (model.lower) 1169 category_pos = self.get_cat_combo_box_pos(state) 1159 state._convert_to_sasmodels() 1160 state.categorycombobox = unicode(state.categorycombobox) 1161 if state.categorycombobox in self.categorybox.Items: 1162 category_pos = self.categorybox.Items.index( 1163 state.categorycombobox) 1164 else: 1165 # Look in master list for model name (model.lower) 1166 category_pos = self.get_cat_combo_box_pos(state) 1170 1167 1171 1168 self.categorybox.Select(category_pos) 1172 1169 self._show_combox(None) 1173 try: 1174 # to support older version 1175 formfactor_pos = int(state.formfactorcombobox) 1176 except: 1177 formfactor_pos = 0 1178 for ind_form in range(self.formfactorbox.GetCount()): 1179 if self.formfactorbox.GetString(ind_form) == \ 1180 (state.formfactorcombobox): 1181 formfactor_pos = int(ind_form) 1170 from models import PLUGIN_NAME_BASE 1171 if self.categorybox.GetValue() == CUSTOM_MODEL \ 1172 and PLUGIN_NAME_BASE not in state.formfactorcombobox: 1173 state.formfactorcombobox = \ 1174 PLUGIN_NAME_BASE + state.formfactorcombobox 1175 formfactor_pos = 0 1176 for ind_form in range(self.formfactorbox.GetCount()): 1177 if self.formfactorbox.GetString(ind_form) == \ 1178 (state.formfactorcombobox): 1179 formfactor_pos = int(ind_form) 1180 break 1181 1182 self.formfactorbox.Select(formfactor_pos) 1183 1184 structfactor_pos = 0 1185 if state.structurecombobox is not None: 1186 state.structurecombobox = unicode(state.structurecombobox) 1187 for ind_struct in range(self.structurebox.GetCount()): 1188 if self.structurebox.GetString(ind_struct) == \ 1189 (state.structurecombobox): 1190 structfactor_pos = int(ind_struct) 1182 1191 break 1183 1184 self.formfactorbox.Select(formfactor_pos)1185 1186 structfactor_pos = 01187 try:1188 # to support older version1189 structfactor_pos = int(state.structurecombobox)1190 except:1191 if state.structurecombobox is not None:1192 state.structurecombobox = unicode(state.structurecombobox)1193 for ind_struct in range(self.structurebox.GetCount()):1194 if self.structurebox.GetString(ind_struct) == \1195 (state.structurecombobox):1196 structfactor_pos = int(ind_struct)1197 break1198 1192 1199 1193 self.structurebox.SetSelection(structfactor_pos) … … 1343 1337 def _selectDlg(self): 1344 1338 """ 1345 open a dialog file to select ed the customized dispersity1339 open a dialog file to select the customized polydispersity function 1346 1340 """ 1347 1341 if self.parent is not None: … … 1385 1379 # self.state.struct_rbutton = self.struct_rbutton.GetValue() 1386 1380 # self.state.plugin_rbutton = self.plugin_rbutton.GetValue() 1387 self.state.structurecombobox = self.structurebox.Get Label()1388 self.state.formfactorcombobox = self.formfactorbox.Get Label()1389 self.state.categorycombobox = self.categorybox.Get Label()1381 self.state.structurecombobox = self.structurebox.GetValue() 1382 self.state.formfactorcombobox = self.formfactorbox.GetValue() 1383 self.state.categorycombobox = self.categorybox.GetValue() 1390 1384 1391 1385 # post state to fit panel … … 1435 1429 self.qmax_x = tempmax 1436 1430 is_modified = True 1437 1438 1431 if is_2Ddata: 1439 # set mask1440 1432 is_modified = self._validate_Npts() 1441 1433 else: 1434 is_modified = self._validate_Npts_1D() 1442 1435 else: 1443 1436 self.fitrange = False … … 1454 1447 # Theory case: need to get npts value to draw 1455 1448 self.npts_x = float(self.Npts_total.GetValue()) 1449 self.Npts_fit.SetValue(str(self.Npts_total.GetValue())) 1450 self._save_plotting_range() 1456 1451 self.create_default_data() 1457 1452 self.state_change = True 1458 1453 self._draw_model() 1454 # Time delay has been introduced to prevent _handle error 1455 # on Windows 1456 # This part of code is executed when model is selected and 1457 # it's parameters are changed (with respect to previously 1458 # selected model). There are two Iq evaluations occuring one 1459 # after another and therefore there may be compilation error 1460 # if model is calculated for the first time. 1461 # This seems to be Windows only issue - haven't tested on Linux 1462 # though.The proper solution (other than time delay) requires 1463 # more fundemental code refatoring 1464 # Wojtek P. Nov 7, 2016 1465 if not ON_MAC: 1466 time.sleep(0.1) 1459 1467 self.Refresh() 1460 1468 … … 1528 1536 index_data = ((self.qmin_x <= self.data.x) & 1529 1537 (self.data.x <= self.qmax_x)) 1530 val = str(len(self.data.x[index_data is True]))1538 val = str(len(self.data.x[index_data])) 1531 1539 self.Npts_fit.SetValue(val) 1532 1540 else: … … 1574 1582 if len(statelist) == 0 or len(listtorestore) == 0: 1575 1583 return 1576 if len(statelist) != len(listtorestore):1577 return1578 1584 1579 1585 for j in range(len(listtorestore)): 1580 item_page = listtorestore[j] 1581 item_page_info = statelist[j] 1582 # change the state of the check box for simple parameters 1583 if item_page[0] is not None: 1584 item_page[0].SetValue(item_page_info[0]) 1585 if item_page[2] is not None: 1586 item_page[2].SetValue(item_page_info[2]) 1587 if item_page[2].__class__.__name__ == "ComboBox": 1588 if item_page_info[2] in self.model.fun_list: 1589 fun_val = self.model.fun_list[item_page_info[2]] 1590 self.model.setParam(item_page_info[1], fun_val) 1591 if item_page[3] is not None: 1592 # show or hide text +/- 1593 if item_page_info[2]: 1594 item_page[3].Show(True) 1595 else: 1596 item_page[3].Hide() 1597 if item_page[4] is not None: 1598 # show of hide the text crtl for fitting error 1599 if item_page_info[4][0]: 1600 item_page[4].Show(True) 1601 item_page[4].SetValue(item_page_info[4][1]) 1602 else: 1603 item_page[3].Hide() 1604 if item_page[5] is not None: 1605 # show of hide the text crtl for fitting error 1606 item_page[5].Show(item_page_info[5][0]) 1607 item_page[5].SetValue(item_page_info[5][1]) 1608 1609 if item_page[6] is not None: 1610 # show of hide the text crtl for fitting error 1611 item_page[6].Show(item_page_info[6][0]) 1612 item_page[6].SetValue(item_page_info[6][1]) 1586 for param in statelist: 1587 if param[1] == listtorestore[j][1]: 1588 item_page = listtorestore[j] 1589 item_page_info = param 1590 if (item_page_info[1] == "theta" or item_page_info[1] == 1591 "phi") and not self._is_2D(): 1592 break 1593 # change the state of the check box for simple parameters 1594 if item_page[0] is not None: 1595 item_page[0].SetValue(item_page_info[0]) 1596 if item_page[2] is not None: 1597 item_page[2].SetValue(item_page_info[2]) 1598 if item_page[2].__class__.__name__ == "ComboBox": 1599 if item_page_info[2] in self.model.fun_list: 1600 fun_val = self.model.fun_list[item_page_info[2]] 1601 self.model.setParam(item_page_info[1], fun_val) 1602 if item_page[3] is not None: 1603 # show or hide text +/- 1604 if item_page_info[2]: 1605 item_page[3].Show(True) 1606 else: 1607 item_page[3].Hide() 1608 if item_page[4] is not None: 1609 # show of hide the text crtl for fitting error 1610 if item_page_info[4][0]: 1611 item_page[4].Show(True) 1612 item_page[4].SetValue(str(item_page_info[4][1])) 1613 else: 1614 item_page[3].Hide() 1615 if item_page[5] is not None: 1616 # show of hide the text crtl for fitting error 1617 item_page[5].Show(True) 1618 item_page[5].SetValue(str(item_page_info[5][1])) 1619 if item_page[6] is not None: 1620 # show of hide the text crtl for fitting error 1621 item_page[6].Show(True) 1622 item_page[6].SetValue(str(item_page_info[6][1])) 1623 break 1613 1624 1614 1625 def _reset_strparam_state(self, listtorestore, statelist): … … 1751 1762 def _set_multfactor_combobox(self, multiplicity=10): 1752 1763 """ 1753 Set comboBox for mu itfactor of CoreMultiShellModel1764 Set comboBox for multitfactor of CoreMultiShellModel 1754 1765 :param multiplicit: no. of multi-functionality 1755 1766 """ … … 1789 1800 Fill panel's combo box according to the type of model selected 1790 1801 """ 1791 custom_model = 'Customized Models' 1802 1792 1803 mod_cat = self.categorybox.GetStringSelection() 1793 1804 self.structurebox.SetSelection(0) … … 1798 1809 m_list = [] 1799 1810 try: 1800 if mod_cat == custom_model:1811 if mod_cat == CUSTOM_MODEL: 1801 1812 for model in self.model_list_box[mod_cat]: 1802 1813 m_list.append(self.model_dict[model.name]) … … 2132 2143 flag = False 2133 2144 else: 2134 self.Npts_fit.SetValue(str(len(index_data[index_data is True])))2145 self.Npts_fit.SetValue(str(len(index_data[index_data]))) 2135 2146 self.fitrange = True 2136 2147 … … 2167 2178 flag = False 2168 2179 else: 2169 self.Npts_fit.SetValue(str(len(index_data[index_data is True])))2180 self.Npts_fit.SetValue(str(len(index_data[index_data]))) 2170 2181 self.fitrange = True 2171 2182 … … 2391 2402 2392 2403 # Redraw the model 2393 self._draw_model() 2404 # Wojtek P. Nov 7, 2016: Redrawing seems to be unnecessary here 2405 # self._draw_model() 2394 2406 # self._undo.Enable(True) 2395 2407 event = PageInfoEvent(page=self) … … 2610 2622 Layout after self._draw_model 2611 2623 """ 2612 if ON_MAC is True:2624 if ON_MAC: 2613 2625 time.sleep(1) 2614 2626 … … 3443 3455 fills out the category list box 3444 3456 """ 3445 uncat_str = ' CustomizedModels'3457 uncat_str = 'Plugin Models' 3446 3458 self._read_category_info() 3447 3459 … … 3472 3484 self.model_box.Clear() 3473 3485 3474 if category == ' CustomizedModels':3486 if category == 'Plugin Models': 3475 3487 for model in self.model_list_box[category]: 3476 3488 str_m = str(model).split(".")[0] -
src/sas/sasgui/perspectives/fitting/fitpage.py
rc8e1996 ref2cdb3 31 31 SMEAR_SIZE_L = 0.00 32 32 SMEAR_SIZE_H = 0.00 33 33 CUSTOM_MODEL = 'Plugin Models' 34 34 35 35 class FitPage(BasicPage): … … 81 81 flag = check_data_validity(self.data) & (self.model is not None) 82 82 self.btFit.Enable(flag) 83 83 84 84 def on_set_focus(self, event): 85 85 """ 86 Override the basepage focus method to ensure the save flag is set 86 Override the basepage focus method to ensure the save flag is set 87 87 properly when focusing on the fit page. 88 88 """ … … 238 238 239 239 weighting_set_box = wx.StaticBox(self, wx.ID_ANY, 240 'Set Weighting by Selecting dI Source')240 'Set Weighting by Selecting dI Source') 241 241 weighting_box = wx.StaticBoxSizer(weighting_set_box, wx.HORIZONTAL) 242 242 sizer_weighting = wx.BoxSizer(wx.HORIZONTAL) … … 362 362 self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, 363 363 id=self.slit_smearer.GetId()) 364 self. enable_smearer.SetValue(True)364 self.disable_smearer.SetValue(True) 365 365 366 366 sizer_smearer.Add(self.disable_smearer, 0, wx.LEFT, 10) … … 1164 1164 if event is not None: 1165 1165 if (event.GetEventObject() == self.formfactorbox 1166 1167 1168 1166 and self.structurebox.GetLabel() != 'None')\ 1167 or event.GetEventObject() == self.structurebox\ 1168 or event.GetEventObject() == self.multifactorbox: 1169 1169 copy_flag = self.get_copy_params() 1170 1170 is_poly_enabled = self.enable_disp.GetValue() … … 1190 1190 self.state.slit_smearer = self.slit_smearer.GetValue() 1191 1191 1192 self.state.structurecombobox = self.structurebox.GetLabel() 1193 self.state.formfactorcombobox = self.formfactorbox.GetLabel() 1192 self.state.structurecombobox = self.structurebox.GetValue() 1193 self.state.formfactorcombobox = self.formfactorbox.GetValue() 1194 self.state.categorycombobox = self.categorybox.GetValue() 1194 1195 self.enable_fit_button() 1195 1196 if self.model is not None: … … 1205 1206 self._keep.Enable(not self.batch_on) 1206 1207 self._set_save_flag(True) 1207 self._set_smear(self.data) 1208 #Setting smearing for cases with and without data. 1209 self._set_smear(self.data) 1208 1210 1209 1211 # more disables for 2D … … 1212 1214 try: 1213 1215 # update smearer sizer 1214 self.onSmear(None) 1216 #This call for smearing set up caused double evaluation of 1217 #I(q) and double compilation as results 1218 #self.onSmear(None) 1215 1219 temp_smear = None 1216 1220 if not self.disable_smearer.GetValue(): … … 1226 1230 # set smearing value whether or not data contain the smearing info 1227 1231 evt = ModelEventbox(model=self.model, 1228 smearer=temp_smear,1229 enable_smearer=not self.disable_smearer.GetValue(),1230 qmin=float(self.qmin_x),1231 uid=self.uid,1232 caption=self.window_caption,1233 qmax=float(self.qmax_x))1232 smearer=temp_smear, 1233 enable_smearer=not self.disable_smearer.GetValue(), 1234 qmin=float(self.qmin_x), 1235 uid=self.uid, 1236 caption=self.window_caption, 1237 qmax=float(self.qmax_x)) 1234 1238 1235 1239 self._manager._on_model_panel(evt=evt) … … 1245 1249 wx.PostEvent(self.parent, new_event) 1246 1250 # update list of plugins if new plugin is available 1247 custom_model = 'Customized Models'1251 custom_model = CUSTOM_MODEL 1248 1252 mod_cat = self.categorybox.GetStringSelection() 1249 1253 if mod_cat == custom_model: … … 1615 1619 return 1616 1620 # check if it is pinhole smear and get min max if it is. 1617 if data.dx is not None and n ot numpy.any(data.dx):1621 if data.dx is not None and numpy.any(data.dx): 1618 1622 self.smear_type = "Pinhole" 1619 1623 self.dq_l = data.dx[0] … … 1930 1934 1931 1935 # more disables for 2D 1936 di_flag = False 1937 dq_flag = False 1932 1938 if self.data.__class__.__name__ == "Data2D" or \ 1933 1939 self.enable2D: … … 1935 1941 self.pinhole_smearer.Enable(True) 1936 1942 self.default_mask = copy.deepcopy(self.data.mask) 1937 if self.data.err_data is None or\ 1938 numpy.all(err == 1 for err in self.data.err_data) or \ 1939 not numpy.any(self.data.err_data): 1940 self.dI_didata.Enable(False) 1941 self.dI_noweight.SetValue(True) 1942 self.weightbt_string = self.dI_noweight.GetLabelText() 1943 else: 1944 self.dI_didata.Enable(True) 1945 self.dI_didata.SetValue(True) 1946 self.weightbt_string = self.dI_didata.GetLabelText() 1943 if self.data.err_data is not None \ 1944 and numpy.any(self.data.err_data): 1945 di_flag = True 1946 if self.data.dqx_data is not None \ 1947 and numpy.any(self.data.dqx_data): 1948 dq_flag = True 1947 1949 else: 1948 1950 self.slit_smearer.Enable(True) 1949 1951 self.pinhole_smearer.Enable(True) 1950 1951 if self.data.dy is None or\ 1952 numpy.all(self.data.dy == 1) or\ 1953 not numpy.any(self.data.dy): 1954 self.dI_didata.Enable(False) 1955 self.dI_noweight.SetValue(True) 1956 self.weightbt_string = self.dI_noweight.GetLabelText() 1957 else: 1958 self.dI_didata.Enable(True) 1959 self.dI_didata.SetValue(True) 1960 self.weightbt_string = self.dI_didata.GetLabelText() 1952 if self.data.dy is not None and numpy.any(self.data.dy): 1953 di_flag = True 1954 if self.data.dx is not None and numpy.any(self.data.dx): 1955 dq_flag = True 1956 elif self.data.dxl is not None and numpy.any(self.data.dxl): 1957 dq_flag = True 1958 1959 if dq_flag: 1960 self.enable_smearer.Enable(True) 1961 self.enable_smearer.SetValue(True) 1962 self.disable_smearer.SetValue(False) 1963 else: 1964 self.enable_smearer.Disable() 1965 self.disable_smearer.Enable(True) 1966 self.disable_smearer.SetValue(True) 1967 1968 if di_flag: 1969 self.dI_didata.Enable(True) 1970 self.dI_didata.SetValue(True) 1971 self.weightbt_string = self.dI_didata.GetLabelText() 1972 else: 1973 self.dI_didata.Enable(False) 1974 self.dI_noweight.SetValue(True) 1975 self.weightbt_string = self.dI_noweight.GetLabelText() 1976 1961 1977 # Enable weighting radio buttons 1962 1978 self.dI_noweight.Enable(True) … … 2000 2016 self.EditMask_title.Disable() 2001 2017 2018 self.onSmear(event=None) 2002 2019 self.on_set_focus(None) 2003 2020 self.Refresh() -
src/sas/sasgui/perspectives/fitting/fitpanel.py
rc8e1996 r67b0a99 189 189 # use while-loop, for-loop will not do the job well. 190 190 while (self.GetPageCount() > 0): 191 # delete the first page until no page exists 192 page = self.GetPage(0) 191 page = self.GetPage(self.GetPageCount() - 1) 193 192 if self._manager.parent.panel_on_focus == page: 194 193 self._manager.parent.panel_on_focus = None 195 194 self._close_helper(selected_page=page) 196 self.DeletePage( 0)195 self.DeletePage(self.GetPageCount() - 1) 197 196 # Clear list of names 198 197 self.fit_page_name = {} … … 400 399 temp = self.GetSelection() 401 400 self.DeletePage(temp) 401 if self.sim_page is not None: 402 if len(self.sim_page.model_list) == 0: 403 pos = self.GetPageIndex(self.sim_page) 404 self.SetSelection(pos) 405 self.on_close_page(event=None) 406 temp = self.GetSelection() 407 self.DeletePage(temp) 408 self.sim_page = None 409 self.batch_on = False 402 410 if self.GetPageCount() == 0: 403 411 self._manager.on_add_new_page(event=None) -
src/sas/sasgui/perspectives/fitting/fitting.py
rec72ceb rddbac66 45 45 from sas.sasgui.guiframe.gui_manager import MDIFrame 46 46 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 47 from sas.sasgui.perspectives.fitting.gpu_options import GpuOptions 47 48 48 49 from . import models … … 193 194 self.bumps_options_menu.Enable(True) 194 195 196 self.id_gpu_options_panel = wx.NewId() 197 self.menu1.Append(self.id_gpu_options_panel, "OpenCL Options", "Choose OpenCL driver or turn it off") 198 wx.EVT_MENU(owner, self.id_gpu_options_panel, self.on_gpu_options) 199 195 200 self.id_result_panel = wx.NewId() 196 201 self.menu1.Append(self.id_result_panel, "Fit Results", "Show fit results panel") … … 220 225 221 226 self.id_edit = wx.NewId() 222 editmodel_help = "Edit customized model sample file"223 227 self.menu1.AppendMenu(self.id_edit, "Plugin Model Operations", 224 self.edit_model_menu , editmodel_help)228 self.edit_model_menu) 225 229 #create menubar items 226 230 return [(self.menu1, self.sub_menu)] … … 255 259 self.update_custom_combo() 256 260 if os.path.isfile(p_path): 257 msg = "Sorry! Could not beable to delete the default "258 msg += " custommodel... \n"261 msg = "Sorry! unable to delete the default " 262 msg += "plugin model... \n" 259 263 msg += "Please manually remove the files (.py, .pyc) " 260 264 msg += "in the 'plugin_models' folder \n" … … 269 273 if item.GetLabel() == label: 270 274 self.edit_menu.DeleteItem(item) 271 msg = "The custommodel, %s, has been deleted." % label275 msg = "The plugin model, %s, has been deleted." % label 272 276 evt = StatusEvent(status=msg, type='stop', info='info') 273 277 wx.PostEvent(self.parent, evt) … … 326 330 temp = self.fit_panel.reset_pmodel_list() 327 331 if temp: 328 # Set the new custommodel list for all fit pages332 # Set the new plugin model list for all fit pages 329 333 for uid, page in self.fit_panel.opened_pages.iteritems(): 330 334 if hasattr(page, "formfactorbox"): … … 802 806 self.result_frame.Raise() 803 807 808 def on_gpu_options(self, event=None): 809 """ 810 Make the Fit Results panel visible. 811 """ 812 dialog = GpuOptions(None, wx.ID_ANY, "") 813 dialog.Show() 814 804 815 def stop_fit(self, uid): 805 816 """ … … 864 875 enable1D=enable1D, enable2D=enable2D, 865 876 qmin=qmin, qmax=qmax, weight=weight) 866 self._mac_sleep(0.2)867 877 868 878 def _mac_sleep(self, sec=0.2): … … 1521 1531 for uid in page_id: 1522 1532 res = result[index] 1533 fit_msg = res.mesg 1523 1534 if res.fitness is None or \ 1524 1535 not numpy.isfinite(res.fitness) or \ 1525 1536 numpy.any(res.pvec == None) or \ 1526 1537 not numpy.all(numpy.isfinite(res.pvec)): 1527 msg = "Fitting did not converge!!!" 1528 evt = StatusEvent(status=msg, info="warning", type="stop") 1529 wx.PostEvent(self.parent, evt) 1538 fit_msg += "\nFitting did not converge!!!" 1530 1539 wx.CallAfter(self._update_fit_button, page_id) 1531 1540 else: … … 1550 1559 wx.CallAfter(cpage._on_fit_complete) 1551 1560 except KeyboardInterrupt: 1552 msg = "Singular point: Fitting Stoped." 1553 evt = StatusEvent(status=msg, info="info", type="stop") 1554 wx.PostEvent(self.parent, evt) 1561 fit_msg += "\nSingular point: Fitting stopped." 1555 1562 except: 1556 msg = "Singular point: Fitting Error occurred." 1557 evt = StatusEvent(status=msg, info="error", type="stop") 1558 wx.PostEvent(self.parent, evt) 1563 fit_msg += "\nSingular point: Fitting error occurred." 1564 if fit_msg: 1565 evt = StatusEvent(status=fit_msg, info="warning", type="stop") 1566 wx.PostEvent(self.parent, evt) 1559 1567 1560 1568 except: … … 1956 1964 ## then kill itself but cannot. Paul Kienzle came up with 1957 1965 ## this fix to prevent threads from stepping on each other 1958 ## which was causing a simple custom model to crash Sasview. 1966 ## which was causing a simple custom plugin model to crash 1967 ##Sasview. 1959 1968 ## We still don't know why the fit sometimes lauched a second 1960 1969 ## thread -- something which should also be investigated. … … 1966 1975 ## May need rethinking 1967 1976 ## 1968 ## -PDB August 12, 2014 1977 ## -PDB August 12, 2014 1969 1978 while self.calc_1D.isrunning(): 1970 1979 time.sleep(0.1) -
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
r20cfa23 r5295cf5 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: … … 560 560 561 561 M_PI_180, M_4PI_3: 562 $\ pi/{180}$, $\tfrac{4}{3}\pi$562 $\frac{\pi}{180}$, $\frac{4\pi}{3}$ 563 563 SINCOS(x, s, c): 564 564 Macro which sets s=sin(x) and c=cos(x). The variables *c* and *s* … … 568 568 cube(x): 569 569 $x^3$ 570 s inc(x):570 sas_sinx_x(x): 571 571 $\sin(x)/x$, with limit $\sin(0)/0 = 1$. 572 572 powr(x, y): … … 596 596 These functions have been tuned to be fast and numerically stable down 597 597 to $q=0$ even in single precision. In some cases they work around bugs 598 which appear on some platforms but not others. So use them where needed!!! 598 which appear on some platforms but not others, so use them where needed. 599 Add the files listed in :code:`source = ["lib/file.c", ...]` to your *model.py* 600 file in the order given, otherwise these functions will not be available. 599 601 600 602 polevl(x, c, n): 601 Polynomial evaluation $p(x) = \sum_{i=0}^n c_i x^ {n-i}$ using Horner's603 Polynomial evaluation $p(x) = \sum_{i=0}^n c_i x^i$ using Horner's 602 604 method so it is faster and more accurate. 603 605 606 $c = \{c_n, c_{n-1}, \ldots, c_0 \}$ is the table of coefficients, 607 sorted from highest to lowest. 608 609 :code:`source = ["lib/polevl.c", ...]` (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/polevl.c>`_) 610 611 p1evl(x, c, n): 612 Evaluation of normalized polynomial $p(x) = x^n + \sum_{i=0}^{n-1} c_i x^i$ 613 using Horner's method so it is faster and more accurate. 614 615 $c = \{c_{n-1}, c_{n-2} \ldots, c_0 \}$ is the table of coefficients, 616 sorted from highest to lowest. 617 604 618 :code:`source = ["lib/polevl.c", ...]` 605 606 sas_gamma: 607 Gamma function $\text{sas_gamma}(x) = \Gamma(x)$. The standard math 608 library gamma function, tgamma(x) is unstable below 1 on some platforms. 619 (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/polevl.c>`_) 620 621 sas_gamma(x): 622 Gamma function $\text{sas_gamma}(x) = \Gamma(x)$. 623 624 The standard math function, tgamma(x) is unstable for $x < 1$ 625 on some platforms. 609 626 610 627 :code:`source = ["lib/sasgamma.c", ...]` 611 612 erf, erfc: 628 (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_gamma.c>`_) 629 630 sas_erf(x), sas_erfc(x): 613 631 Error function 614 $\text{ erf}(x) = \frac{1}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$632 $\text{sas_erf}(x) = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$ 615 633 and complementary error function 616 $\text{erfc}(x) = \frac{1}{\sqrt\pi}\int_x^\inf e^{-t^2}\,dt$. 617 The standard math library erf and erfc are slower and broken 634 $\text{sas_erfc}(x) = \frac{2}{\sqrt\pi}\int_x^{\infty} e^{-t^2}\,dt$. 635 636 The standard math functions erf(x) and erfc(x) are slower and broken 618 637 on some platforms. 619 638 620 639 :code:`source = ["lib/polevl.c", "lib/sas_erf.c", ...]` 621 622 sas_J0: 623 Bessel function of the first kind where 640 (`link to error functions' code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_erf.c>`_) 641 642 sas_J0(x): 643 Bessel function of the first kind $\text{sas_J0}(x)=J_0(x)$ where 624 644 $J_0(x) = \frac{1}{\pi}\int_0^\pi \cos(x\sin(\tau))\,d\tau$. 625 645 646 The standard math function j0(x) is not available on all platforms. 647 626 648 :code:`source = ["lib/polevl.c", "lib/sas_J0.c", ...]` 627 628 sas_J1: 629 Bessel function of the first kind where 649 (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J0.c>`_) 650 651 sas_J1(x): 652 Bessel function of the first kind $\text{sas_J1}(x)=J_1(x)$ where 630 653 $J_1(x) = \frac{1}{\pi}\int_0^\pi \cos(\tau - x\sin(\tau))\,d\tau$. 631 654 655 The standard math function j1(x) is not available on all platforms. 656 632 657 :code:`source = ["lib/polevl.c", "lib/sas_J1.c", ...]` 633 634 sas_JN: 635 Bessel function of the first kind where 658 (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J1.c>`_) 659 660 sas_JN(n, x): 661 Bessel function of the first kind and integer order $n$: 662 $\text{sas_JN}(n, x)=J_n(x)$ where 636 663 $J_n(x) = \frac{1}{\pi}\int_0^\pi \cos(n\tau - x\sin(\tau))\,d\tau$. 664 If $n$ = 0 or 1, it uses sas_J0(x) or sas_J1(x), respectively. 665 666 The standard math function jn(n, x) is not available on all platforms. 637 667 638 668 :code:`source = ["lib/polevl.c", "lib/sas_J0.c", "lib/sas_J1.c", "lib/sas_JN.c", ...]` 639 640 Si: 669 (`link to Bessel function's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_JN.c>`_) 670 671 sas_Si(x): 641 672 Sine integral $\text{Si}(x) = \int_0^x \tfrac{\sin t}{t}\,dt$. 642 673 643 :code:`soure = ["lib/Si.c", ...]` 644 645 sph_j1c(qr): 674 This function uses Taylor series for small and large arguments: 675 676 For large arguments, 677 678 .. math:: 679 680 \text{Si}(x) \sim \frac{\pi}{2} 681 - \frac{\cos(x)}{x}\left(1 - \frac{2!}{x^2} + \frac{4!}{x^4} - \frac{6!}{x^6} \right) 682 - \frac{\sin(x)}{x}\left(\frac{1}{x} - \frac{3!}{x^3} + \frac{5!}{x^5} - \frac{7!}{x^7}\right) 683 684 For small arguments, 685 686 .. math:: 687 688 \text{Si}(x) \sim x 689 - \frac{x^3}{3\times 3!} + \frac{x^5}{5 \times 5!} - \frac{x^7}{7 \times 7!} 690 + \frac{x^9}{9\times 9!} - \frac{x^{11}}{11\times 11!} 691 692 :code:`source = ["lib/Si.c", ...]` 693 (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/Si.c>`_) 694 695 sas_3j1x_x(x): 646 696 Spherical Bessel form 647 $F(qr) = 3 j_1(qr)/(qr) = 3 (\sin(qr) - qr \cos(qr))/{(qr)^3}$, 648 with a limiting value of 1 at $qr=0$. This function uses a Taylor 649 series for small $qr$ for numerical accuracy. 650 651 :code:`source = ["lib/sph_j1c.c", ...]` 652 653 sas_J1c(qr): 654 Bessel form $F(qr) = 2 J_1(qr)/{(qr)}$, with a limiting value of 1 at $qr=0$. 697 $\text{sph_j1c}(x) = 3 j_1(x)/x = 3 (\sin(x) - x \cos(x))/x^3$, 698 with a limiting value of 1 at $x=0$, where $j_1(x)$ is the spherical 699 Bessel function of the first kind and first order. 700 701 This function uses a Taylor series for small $x$ for numerical accuracy. 702 703 :code:`source = ["lib/sas_3j1x_x.c", ...]` 704 (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_3j1x_x.c>`_) 705 706 707 sas_2J1x_x(x): 708 Bessel form $\text{sas_J1c}(x) = 2 J_1(x)/x$, with a limiting value 709 of 1 at $x=0$, where $J_1(x)$ is the Bessel function of first kind 710 and first order. 655 711 656 712 :code:`source = ["lib/polevl.c", "lib/sas_J1.c", ...]` 657 658 Gauss76z[i], Gauss76Wt[i]: 659 Points $z_i$ and weights $w_i$ for 76-point Gaussian quadrature, 660 computing $\int_{-1}^1 f(z)\,dz \approx \sum_{i=1}^{76} w_i f(z_i)$. 661 Similar arrays are available in :code:`gauss20.c` for 20 point 662 quadrature and in :code:`gauss150.c` for 150 point quadrature. 663 664 :code:`source = ["gauss76.c", ...]` 713 (`link to Bessel form's code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_J1.c>`_) 714 715 716 Gauss76Z[i], Gauss76Wt[i]: 717 Points $z_i$ and weights $w_i$ for 76-point Gaussian quadrature, respectively, 718 computing $\int_{-1}^1 f(z)\,dz \approx \sum_{i=1}^{76} w_i\,f(z_i)$. 719 720 Similar arrays are available in :code:`gauss20.c` for 20-point 721 quadrature and in :code:`gauss150.c` for 150-point quadrature. 722 723 :code:`source = ["lib/gauss76.c", ...]` 724 (`link to code <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/gauss76.c>`_) 725 726 665 727 666 728 Problems with C models -
src/sas/sasgui/perspectives/fitting/media/sm_help.rst
r7805458 r27aabc1 20 20 ================== 21 21 22 Sometimes it will be necessary to correct reduced experimental data for the 23 physical effects of the instrumental geometry in use. This process is called 24 *desmearing*. However, calculated/simulated data - which by definition will be 25 perfect/exact - can be *smeared* to make it more representative of what might 26 actually be measured experimentally. 27 28 SasView provides the following three smearing algorithms: 22 Sometimes the instrumental geometry used to acquire the experimental data has 23 an impact on the clarity of features in the reduced scattering curve. For 24 example, peaks or fringes might be slightly broadened. This is known as 25 *Q resolution smearing*. To compensate for this effect one can either try and 26 remove the resolution contribution - a process called *desmearing* - or add the 27 resolution contribution into a model calculation/simulation (which by definition 28 will be exact) to make it more representative of what has been measured 29 experimentally - a process called *smearing*. SasView will do the latter. 30 31 Both smearing and desmearing rely on functions to describe the resolution 32 effect. SasView provides three smearing algorithms: 29 33 30 34 * *Slit Smearing* 31 35 * *Pinhole Smearing* 32 36 * *2D Smearing* 37 38 SasView also has an option to use Q resolution data (estimated at the time of 39 data reduction) supplied in a reduced data file: the *Use dQ data* radio button. 40 41 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 42 43 dQ Smearing 44 ----------- 45 46 If this option is checked, SasView will assume that the supplied dQ values 47 represent the standard deviations of Gaussian functions. 33 48 34 49 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ -
src/sas/sasgui/perspectives/fitting/model_thread.py
r286c757 rc1681ea 82 82 fn.set_model(self.model) 83 83 fn.set_index(index_model) 84 # Get necessary data from self.data and set the data for smearing85 fn.get_data()86 84 # Calculate smeared Intensity 87 85 #(by Gaussian averaging): DataLoader/smearing2d/Smearer2D() … … 89 87 else: 90 88 # calculation w/o smearing 91 value = self.model.evalDistribution(\ 92 [self.data.qx_data[index_model], 93 self.data.qy_data[index_model]]) 89 value = self.model.evalDistribution([ 90 self.data.qx_data[index_model], 91 self.data.qy_data[index_model] 92 ]) 94 93 output = numpy.zeros(len(self.data.qx_data)) 95 94 # output default is None … … 198 197 output[index] = self.model.evalDistribution(self.data.x[index]) 199 198 200 sq_model = None 201 pq_model = None 199 sq_values = None 200 pq_values = None 201 s_model = None 202 p_model = None 202 203 if isinstance(self.model, MultiplicationModel): 203 sq_model = numpy.zeros((len(self.data.x))) 204 pq_model = numpy.zeros((len(self.data.x))) 205 sq_model[index] = self.model.s_model.evalDistribution(self.data.x[index]) 206 pq_model[index] = self.model.p_model.evalDistribution(self.data.x[index]) 204 s_model = self.model.s_model 205 p_model = self.model.p_model 206 elif hasattr(self.model, "get_composition_models"): 207 p_model, s_model = self.model.get_composition_models() 208 209 if p_model is not None and s_model is not None: 210 sq_values = numpy.zeros((len(self.data.x))) 211 pq_values = numpy.zeros((len(self.data.x))) 212 sq_values[index] = s_model.evalDistribution(self.data.x[index]) 213 pq_values[index] = p_model.evalDistribution(self.data.x[index]) 207 214 208 215 elapsed = time.time() - self.starttime … … 221 228 unsmeared_data=unsmeared_data, 222 229 unsmeared_error=unsmeared_error, 223 pq_model=pq_ model,224 sq_model=sq_ model)230 pq_model=pq_values, 231 sq_model=sq_values) 225 232 226 233 def results(self): -
src/sas/sasgui/perspectives/fitting/models.py
r313c5c9 r11b094f 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 r71601312 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"], … … 271 276 # store value of chisqr 272 277 self.tcChi = None 278 self.version = (1,0,0) 273 279 274 280 def clone(self): … … 349 355 obj.cb1 = copy.deepcopy(self.cb1) 350 356 obj.smearer = copy.deepcopy(self.smearer) 357 obj.version = copy.deepcopy(self.version) 351 358 352 359 for name, state in self.saved_states.iteritems(): … … 355 362 obj.saved_states[copy_name] = copy_state 356 363 return obj 364 365 def _old_first_model(self): 366 """ 367 Handle save states from 4.0.1 and before where the first item in the 368 selection boxes of category, formfactor and structurefactor were not 369 saved. 370 :return: None 371 """ 372 if self.categorycombobox == CUSTOM_MODEL_OLD: 373 self.categorycombobox = CUSTOM_MODEL 374 if self.formfactorcombobox == '': 375 FIRST_FORM = { 376 'Shapes' : 'BCCrystalModel', 377 'Uncategorized' : 'LineModel', 378 'StructureFactor' : 'HardsphereStructure', 379 'Ellipsoid' : 'core_shell_ellipsoid', 380 'Lamellae' : 'lamellar', 381 'Paracrystal' : 'bcc_paracrystal', 382 'Parallelepiped' : 'core_shell_parallelepiped', 383 'Shape Independent' : 'be_polyelectrolyte', 384 'Sphere' : 'adsorbed_layer', 385 'Structure Factor' : 'hardsphere', 386 CUSTOM_MODEL : '' 387 } 388 if self.categorycombobox == '': 389 if len(self.parameters) == 3: 390 self.categorycombobox = "Shape-Independent" 391 self.formfactorcombobox = 'PowerLawAbsModel' 392 elif len(self.parameters) == 9: 393 self.categorycombobox = 'Cylinder' 394 self.formfactorcombobox = 'barbell' 395 else: 396 msg = "Save state does not have enough information to load" 397 msg += " the all of the data." 398 logging.warning(msg=msg) 399 else: 400 self.formfactorcombobox = FIRST_FORM[self.categorycombobox] 401 402 @staticmethod 403 def param_remap_to_sasmodels_convert(params, is_string=False): 404 """ 405 Remaps the parameters for sasmodels conversion 406 407 :param params: list of parameters (likely self.parameters) 408 :return: remapped dictionary of parameters 409 """ 410 p = dict() 411 for fittable, name, value, _, uncert, lower, upper, units in params: 412 if not value: 413 value = numpy.nan 414 if not uncert or uncert[1] == '' or uncert[1] == 'None': 415 uncert[0] = False 416 uncert[1] = numpy.nan 417 if not upper or upper[1] == '' or upper[1] == 'None': 418 upper[0] = False 419 upper[1] = numpy.nan 420 if not lower or lower[1] == '' or lower[1] == 'None': 421 lower[0] = False 422 lower[1] = numpy.nan 423 if is_string: 424 p[name] = str(value) 425 else: 426 p[name] = float(value) 427 p[name + ".fittable"] = bool(fittable) 428 p[name + ".std"] = float(uncert[1]) 429 p[name + ".upper"] = float(upper[1]) 430 p[name + ".lower"] = float(lower[1]) 431 p[name + ".units"] = units 432 return p 433 434 @staticmethod 435 def param_remap_from_sasmodels_convert(params): 436 """ 437 Converts {name : value} map back to [] param list 438 :param params: parameter map returned from sasmodels 439 :return: None 440 """ 441 p_map = [] 442 for name, info in params.iteritems(): 443 if ".fittable" in name or ".std" in name or ".upper" in name or \ 444 ".lower" in name or ".units" in name: 445 pass 446 else: 447 fittable = params.get(name + ".fittable", True) 448 std = params.get(name + ".std", '0.0') 449 upper = params.get(name + ".upper", 'inf') 450 lower = params.get(name + ".lower", '-inf') 451 units = params.get(name + ".units") 452 if std is not None and std is not numpy.nan: 453 std = [True, str(std)] 454 else: 455 std = [False, ''] 456 if lower is not None and lower is not numpy.nan: 457 lower = [True, str(lower)] 458 else: 459 lower = [True, '-inf'] 460 if upper is not None and upper is not numpy.nan: 461 upper = [True, str(upper)] 462 else: 463 upper = [True, 'inf'] 464 param_list = [bool(fittable), str(name), str(info), 465 "+/-", std, lower, upper, str(units)] 466 p_map.append(param_list) 467 return p_map 468 469 def _convert_to_sasmodels(self): 470 """ 471 Convert parameters to a form usable by sasmodels converter 472 473 :return: None 474 """ 475 # Create conversion dictionary to send to sasmodels 476 self._old_first_model() 477 p = self.param_remap_to_sasmodels_convert(self.parameters) 478 structurefactor, params = convert.convert_model(self.structurecombobox, 479 p, False, self.version) 480 formfactor, params = convert.convert_model(self.formfactorcombobox, 481 params, False, self.version) 482 if len(self.str_parameters) > 0: 483 str_pars = self.param_remap_to_sasmodels_convert( 484 self.str_parameters, True) 485 formfactor, str_params = convert.convert_model( 486 self.formfactorcombobox, str_pars, False, self.version) 487 for key, value in str_params.iteritems(): 488 params[key] = value 489 490 if self.formfactorcombobox == 'SphericalSLDModel': 491 self.multi_factor += 1 492 self.formfactorcombobox = formfactor 493 self.structurecombobox = structurefactor 494 self.parameters = [] 495 self.parameters = self.param_remap_from_sasmodels_convert(params) 357 496 358 497 def _repr_helper(self, list, rep): … … 682 821 683 822 attr = newdoc.createAttribute("version") 684 attr.nodeValue = '1.0' 823 import sasview 824 attr.nodeValue = sasview.__version__ 825 # attr.nodeValue = '1.0' 685 826 top_element.setAttributeNode(attr) 686 827 … … 875 1016 raise RuntimeError, msg 876 1017 877 if node.get('version') and node.get('version') == '1.0': 1018 if node.get('version'): 1019 # Get the version for model conversion purposes 1020 self.version = tuple(int(e) for e in 1021 str.split(node.get('version'), ".")) 1022 # The tuple must be at least 3 items long 1023 while len(self.version) < 3: 1024 ver_list = list(self.version) 1025 ver_list.append(0) 1026 self.version = tuple(ver_list) 878 1027 879 1028 # Get file name … … 1033 1182 if self.cansas: 1034 1183 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 1184 1281 1185 def _parse_state(self, entry): … … 1354 1258 """ 1355 1259 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 1260 return_value, _ = self._parse_entry(dom) 1261 return return_value, _ 1614 1262 1615 1263 def _read_cansas(self, path): … … 1692 1340 name = original_fname 1693 1341 state.data.group_id = name 1342 state.version = fitstate.version 1694 1343 # store state in fitting 1695 1344 self.call_back(state=state, … … 1745 1394 state.data.run_name[0] = state.data.name 1746 1395 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) 1396 data = state.data 1397 doc, sasentry = self._to_xml_doc(data) 1754 1398 1755 1399 if state is not None: -
src/sas/sasgui/perspectives/invariant/invariant_state.py
rcb93b40 rdb5294e 423 423 for item in DEFAULT_STATE: 424 424 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 = '' 426 429 if input_field is not None: 427 430 temp_state[item] = val … … 433 436 for item in DEFAULT_STATE: 434 437 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 = '' 436 442 if input_field is not None: 437 443 self.set_saved_state(name=item, value=val) -
src/sas/sasgui/perspectives/invariant/media/invariant_help.rst
rb64b87c r484141c 116 116 Academic Press, New York, 1982 117 117 118 http:// physchem.kfunigraz.ac.at/sm/118 http://web.archive.org/web/20110824105537/http://physchem.kfunigraz.ac.at/sm/Service/Glatter_Kratky_SAXS_1982.zip 119 119 120 120 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ -
src/sas/sasgui/perspectives/pr/media/pr_help.rst
r0391dae r1221196 10 10 ----------- 11 11 12 This tool calculates a real-space distance distribution function, *P(r)*, using 13 the inversion approach (Moore, 19 08).12 This tool calculates a real-space distance distribution function, *P(r)*, using 13 the inversion approach (Moore, 1980). 14 14 15 15 *P(r)* is set to be equal to an expansion of base functions of the type … … 24 24 25 25 \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 26 26 27 27 28 28 where $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. 29 the prediction from the Fourier transform of the *P(r)* expansion. 30 30 31 The $Reg\_term$ term is a regularization term set to the second derivative 31 The $Reg\_term$ term is a regularization term set to the second derivative 32 32 $d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 33 33 … … 40 40 41 41 * *Number of terms*: the number of base functions in the P(r) expansion. 42 42 43 43 * *Regularization constant*: a multiplicative constant to set the size of 44 44 the regularization term. -
src/sas/sasgui/plottools/PlotPanel.py
r1a8e2e8e r198fa76 452 452 """ 453 453 self.cusor_line(event) 454 if self.gotLegend == 1 :454 if self.gotLegend == 1 and self.leftdown: 455 455 self._on_legend_motion(event) 456 456 return -
src/sas/sasgui/plottools/plottables.py
r8abd96d ra9f579c 212 212 self.color += plottable.colors() 213 213 self.plottables[plottable] = self.color 214 plottable.custom_color = self.color 214 215 215 216 def changed(self): … … 1022 1023 """ 1023 1024 1024 def __init__(self, x, y, dx=None, dy=None ):1025 def __init__(self, x, y, dx=None, dy=None, lam=None, dlam=None): 1025 1026 """ 1026 1027 Draw points specified by x[i],y[i] in the current color/symbol. … … 1036 1037 self.x = x 1037 1038 self.y = y 1039 self.lam = lam 1038 1040 self.dx = dx 1039 1041 self.dy = dy 1042 self.dlam = dlam 1040 1043 self.source = None 1041 1044 self.detector = None -
src/sas/sasgui/guiframe/data_panel.py
rc8e1996 rcb1e9a5 520 520 Add a listcrtl in the panel 521 521 """ 522 tree_ctrl_label = wx.StaticText(self, -1, "Data") 523 tree_ctrl_label.SetForegroundColour('blue') 524 self.tree_ctrl = DataTreeCtrl(parent=self, style=wx.SUNKEN_BORDER) 522 # Add splitter 523 w, h = self.parent.GetSize() 524 splitter = wx.SplitterWindow(self) 525 splitter.SetMinimumPaneSize(50) 526 splitter.SetSashGravity(1.0) 527 528 file_sizer = wx.BoxSizer(wx.VERTICAL) 529 file_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 530 theory_sizer = wx.BoxSizer(wx.VERTICAL) 531 theory_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 532 533 self.tree_ctrl = DataTreeCtrl(parent=splitter, style=wx.SUNKEN_BORDER) 534 525 535 self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_CHECKING, self.on_check_item) 526 536 self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_MENU, self.on_right_click_data) … … 557 567 wx.EVT_MENU(self, self.editmask_id, self.on_edit_data) 558 568 559 tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory") 560 tree_ctrl_theory_label.SetForegroundColour('blue') 561 self.tree_ctrl_theory = DataTreeCtrl(parent=self, 569 self.tree_ctrl_theory = DataTreeCtrl(parent=splitter, 562 570 style=wx.SUNKEN_BORDER) 563 571 self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING, … … 565 573 self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU, 566 574 self.on_right_click_theory) 567 self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10) 568 self.sizer1.Add(self.tree_ctrl, 1, wx.EXPAND | wx.ALL, 10) 569 self.sizer1.Add(tree_ctrl_theory_label, 0, wx.LEFT, 10) 570 self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND | wx.ALL, 10) 575 self.tree_ctrl.InsertItem(self.tree_ctrl.root, -1, " Data") 576 self.tree_ctrl_theory.InsertItem(self.tree_ctrl_theory.root, 577 -1, " Theory") 578 splitter.SplitHorizontally(self.tree_ctrl, self.tree_ctrl_theory) 579 self.sizer1.Add(splitter, 1, wx.EXPAND | wx.ALL, 10) 571 580 572 581 def on_right_click_theory(self, event):
Note: See TracChangeset
for help on using the changeset viewer.