Changeset 21e71f1 in sasview for src/sas/qtgui/Utilities
- Timestamp:
- Nov 21, 2018 6:39:24 AM (6 years ago)
- Branches:
- ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- f2e199e
- Parents:
- 44c15fc (diff), fb39f28 (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/qtgui/Utilities
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Utilities/GuiUtils.py
r67346f9 r133812c7 11 11 import webbrowser 12 12 import urllib.parse 13 import json 14 from io import BytesIO 13 15 14 16 import numpy as np … … 26 28 from sas.qtgui.Plotting.PlotterData import Data1D 27 29 from sas.qtgui.Plotting.PlotterData import Data2D 30 from sas.qtgui.Plotting.Plottables import Plottable 31 from sas.sascalc.dataloader.data_info import Sample, Source, Vector 32 from sas.qtgui.Plotting.Plottables import View 33 from sas.qtgui.Plotting.Plottables import PlottableTheory1D 34 from sas.qtgui.Plotting.Plottables import PlottableFit1D 35 from sas.qtgui.Plotting.Plottables import Text 36 from sas.qtgui.Plotting.Plottables import Chisq 37 from sas.qtgui.MainWindow.DataState import DataState 38 28 39 from sas.sascalc.dataloader.loader import Loader 29 40 from sas.qtgui.Utilities import CustomDir … … 259 270 sendDataToGridSignal = QtCore.pyqtSignal(list) 260 271 261 # Action Save Analysis triggered262 saveAnalysisSignal = QtCore.pyqtSignal()263 264 272 # Mask Editor requested 265 273 maskEditorSignal = QtCore.pyqtSignal(Data2D) … … 292 300 forcePlotDisplaySignal = QtCore.pyqtSignal(list) 293 301 294 def updateModelItemWithPlot(item, update_data, name="" ):302 def updateModelItemWithPlot(item, update_data, name="", checkbox_state=None): 295 303 """ 296 304 Adds a checkboxed row named "name" to QStandardItem … … 317 325 # Force redisplay 318 326 return 319 320 327 # Create the new item 321 328 checkbox_item = createModelItemWithPlot(update_data, name) 322 329 330 if checkbox_state is not None: 331 checkbox_item.setCheckState(checkbox_state) 323 332 # Append the new row to the main item 324 333 item.appendRow(checkbox_item) … … 571 580 if isinstance(data.process, list) and data.process: 572 581 for process in data.process: 582 if process is None: 583 continue 573 584 process_date = process.date 574 585 process_date_item = QtGui.QStandardItem("Date: " + process_date) … … 1145 1156 return result 1146 1157 1158 def saveData(fp, data): 1159 """ 1160 save content of data to fp (a .write()-supporting file-like object) 1161 """ 1162 1163 def add_type(dict, type): 1164 dict['__type__'] = type.__name__ 1165 return dict 1166 1167 def jdefault(o): 1168 """ 1169 objects that can't otherwise be serialized need to be converted 1170 """ 1171 # tuples and sets (TODO: default JSONEncoder converts tuples to lists, create custom Encoder that preserves tuples) 1172 if isinstance(o, (tuple, set)): 1173 content = { 'data': list(o) } 1174 return add_type(content, type(o)) 1175 1176 # "simple" types 1177 if isinstance(o, (Sample, Source, Vector)): 1178 return add_type(o.__dict__, type(o)) 1179 if isinstance(o, (Plottable, View)): 1180 return add_type(o.__dict__, type(o)) 1181 1182 # DataState 1183 if isinstance(o, (Data1D, Data2D)): 1184 # don't store parent 1185 content = o.__dict__.copy() 1186 #content.pop('parent') 1187 return add_type(content, type(o)) 1188 1189 # ndarray 1190 if isinstance(o, np.ndarray): 1191 buffer = BytesIO() 1192 np.save(buffer, o) 1193 buffer.seek(0) 1194 content = { 'data': buffer.read().decode('latin-1') } 1195 return add_type(content, type(o)) 1196 1197 # not supported 1198 logging.info("data cannot be serialized to json: %s" % type(o)) 1199 return None 1200 1201 json.dump(data, fp, indent=2, sort_keys=True, default=jdefault) 1202 1203 def readDataFromFile(fp): 1204 ''' 1205 Reads in Data1D/Data2 datasets from the file. 1206 Datasets are stored in the JSON format. 1207 ''' 1208 supported = [ 1209 tuple, set, 1210 Sample, Source, Vector, 1211 Plottable, Data1D, Data2D, PlottableTheory1D, PlottableFit1D, Text, Chisq, View, 1212 DataState, np.ndarray] 1213 1214 lookup = dict((cls.__name__, cls) for cls in supported) 1215 1216 class TooComplexException(Exception): 1217 pass 1218 1219 def simple_type(cls, data, level): 1220 class Empty(object): 1221 def __init__(self): 1222 for key, value in data.items(): 1223 setattr(self, key, generate(value, level)) 1224 1225 # create target object 1226 o = Empty() 1227 o.__class__ = cls 1228 1229 return o 1230 1231 def construct(type, data, level): 1232 try: 1233 cls = lookup[type] 1234 except KeyError: 1235 logging.info('unknown type: %s' % type) 1236 return None 1237 1238 # tuples and sets 1239 if cls in (tuple, set): 1240 # convert list to tuple/set 1241 return cls(generate(data['data'], level)) 1242 1243 # "simple" types 1244 if cls in (Sample, Source, Vector): 1245 return simple_type(cls, data, level) 1246 if issubclass(cls, Plottable) or (cls == View): 1247 return simple_type(cls, data, level) 1248 1249 # DataState 1250 if cls == DataState: 1251 o = simple_type(cls, data, level) 1252 o.parent = None # TODO: set to ??? 1253 return o 1254 1255 # ndarray 1256 if cls == np.ndarray: 1257 buffer = BytesIO() 1258 buffer.write(data['data'].encode('latin-1')) 1259 buffer.seek(0) 1260 return np.load(buffer) 1261 1262 logging.info('not implemented: %s, %s' % (type, cls)) 1263 return None 1264 1265 def generate(data, level): 1266 if level > 16: # recursion limit (arbitrary number) 1267 raise TooComplexException() 1268 else: 1269 level += 1 1270 1271 if isinstance(data, dict): 1272 try: 1273 type = data['__type__'] 1274 except KeyError: 1275 # if dictionary doesn't have __type__ then it is assumed to be just an ordinary dictionary 1276 o = {} 1277 for key, value in data.items(): 1278 o[key] = generate(value, level) 1279 return o 1280 1281 return construct(type, data, level) 1282 1283 if isinstance(data, list): 1284 return [generate(item, level) for item in data] 1285 1286 return data 1287 1288 new_stored_data = {} 1289 for id, data in json.load(fp).items(): 1290 try: 1291 new_stored_data[id] = generate(data, 0) 1292 except TooComplexException: 1293 logging.info('unable to load %s' % id) 1294 1295 return new_stored_data 1296 1297 def readProjectFromSVS(filepath): 1298 """ 1299 Read old SVS file and convert to the project dictionary 1300 """ 1301 from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader 1302 from sas.sascalc.fit.pagestate import Reader 1303 1304 loader = Loader() 1305 loader.associate_file_reader('.svs', Reader) 1306 temp = loader.load(filepath) 1307 state_reader = Reader() 1308 data_svs, state_svs = state_reader.read(filepath) 1309 1310 output = [] 1311 if isinstance(temp, list) and isinstance(state_svs, list): 1312 for item, state in zip(temp, state_svs): 1313 output.append([item, state]) 1314 else: 1315 output[temp, state_svs] 1316 return output 1317 1318 def convertFromSVS(datasets): 1319 """ 1320 Read in properties from SVS and convert into a simple dict 1321 """ 1322 content = {} 1323 for dataset in datasets: 1324 # we already have data - interested only in properties 1325 #[[item_1, state_1], [item_2, state_2],...] 1326 data = dataset[0] 1327 params = dataset[1] 1328 content[params.data_id] = {} 1329 content[params.data_id]['fit_data'] = [data, {'checked': 2}, []] 1330 param_dict = {} 1331 param_dict['fitpage_category'] = [params.categorycombobox] 1332 param_dict['fitpage_model'] = [params.formfactorcombobox] 1333 param_dict['fitpage_structure'] = [params.structurecombobox] 1334 param_dict['2D_params'] = [str(params.is_2D)] 1335 param_dict['chainfit_params'] = ["False"] 1336 param_dict['data_id'] = [params.data_id] 1337 param_dict['data_name'] = [params.data_name] 1338 param_dict['is_data'] = [str(params.is_data)] 1339 param_dict['magnetic_params'] = [str(params.magnetic_on)] 1340 param_dict['model_name'] = [params.formfactorcombobox] 1341 param_dict['polydisperse_params'] = [str(params.enable_disp)] 1342 param_dict['q_range_max'] = [str(params.qmax)] 1343 param_dict['q_range_min'] = [str(params.qmin)] 1344 # Smearing is a bit trickier. 4.x has multiple keywords, 1345 # one for each combobox option 1346 if params.enable_smearer: 1347 if params.slit_smearer: 1348 w = 1 1349 elif params.pinhole_smearer: 1350 w = 2 1351 else: 1352 w = 0 1353 param_dict['smearing'] = [str(w)] 1354 # weighting is also tricky. 4.x has multiple keywords, 1355 # one for each radio box. 1356 if params.dI_noweight: 1357 w = 2 1358 elif params.dI_didata: 1359 w = 3 1360 elif params.dI_sqrdata: 1361 w = 4 1362 elif params.dI_idata: 1363 w = 5 1364 else: 1365 w = 2 1366 param_dict['weighting'] = [str(w)] 1367 1368 # 4.x multi_factor is really the multiplicity 1369 if params.multi_factor is not None: 1370 param_dict['multiplicity'] = [str(int(params.multi_factor))] 1371 1372 # playing with titles 1373 data.filename = params.file 1374 data.title = params.data_name 1375 data.name = params.data_name 1376 1377 # main parameters 1378 for p in params.parameters: 1379 p_name = p[1] 1380 param_dict[p_name] = [str(p[0]), str(p[2]), None, str(p[5][1]), str(p[6][1])] 1381 # orientation parameters 1382 if params.is_2D: 1383 for p in params.orientation_params: 1384 p_name = p[1] 1385 p_min = "-360.0" 1386 p_max = "360.0" 1387 if p[5][1] != "": 1388 p_min = p[5][1] 1389 if p[6][1] != "": 1390 p_max = p[6][1] 1391 param_dict[p_name] = [str(p[0]), str(p[2]), None, p_min, p_max] 1392 1393 # disperse parameters 1394 if params.enable_disp: 1395 for p in params.fittable_param: 1396 p_name = p[1] 1397 p_opt = str(p[0]) 1398 p_err = "0" 1399 p_width = str(p[2]) 1400 p_min = str(0) 1401 p_max = "inf" 1402 param_npts = p_name.replace('.width','.npts') 1403 param_nsigmas = p_name.replace('.width', '.nsigmas') 1404 if params.is_2D and p_name in params.disp_obj_dict: 1405 lookup = params.orientation_params_disp 1406 p_min = "-360.0" 1407 p_max = "360.0" 1408 else: 1409 lookup = params.fixed_param 1410 p_npts = [s[2] for s in lookup if s[1] == param_npts][0] 1411 p_nsigmas = [s[2] for s in lookup if s[1] == param_nsigmas][0] 1412 if p_name in params.disp_obj_dict: 1413 p_disp = params.disp_obj_dict[p_name] 1414 else: 1415 p_disp = "gaussian" 1416 param_dict[p_name] = [p_opt, p_width, p_min, p_max, p_npts, p_nsigmas, p_disp] 1417 1418 content[params.data_id]['fit_params'] = param_dict 1419 return content 1147 1420 1148 1421 def enum(*sequential, **named): -
src/sas/qtgui/Utilities/GridPanel.py
r75906a1 rc4c4957 126 126 return 127 127 128 def addTabPage(self ):128 def addTabPage(self, name=None): 129 129 """ 130 130 Add new tab page with QTableWidget … … 141 141 # However, some models have LONG names, which doesn't look well on the tab bar. 142 142 self.tab_number += 1 143 tab_name = "Tab " + str(self.tab_number) 143 if name is not None: 144 tab_name = name 145 else: 146 tab_name = "Tab " + str(self.tab_number) 144 147 # each table needs separate slots. 145 148 tab_widget.customContextMenuRequested.connect(self.showContextMenu) … … 153 156 Create a new tab with batch fitting results 154 157 """ 158 # pull out page name from results 159 page_name = None 160 if len(results)>=2: 161 if isinstance(results[-1], str): 162 page_name = results[-1] 163 _ = results.pop(-1) 164 155 165 if self.has_data: 156 self.addTabPage() 166 self.addTabPage(name=page_name) 167 else: 168 self.tabWidget.setTabText(0, page_name) 157 169 # Update the new widget 158 170 # Fill in the table from input data in the last/newest page
Note: See TracChangeset
for help on using the changeset viewer.