Changes in src/sas/qtgui/MainWindow/DataExplorer.py [a3c59503:6bc0840] in sasview
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/MainWindow/DataExplorer.py
ra3c59503 r6bc0840 233 233 filename = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] 234 234 if filename: 235 self.readProject(filename) 236 237 def loadAnalysis(self): 238 """ 239 Called when the "Open Analysis" menu item chosen. 240 """ 241 kwargs = { 242 'parent' : self, 243 'caption' : 'Open Analysis', 244 'filter' : 'Project (*.fitv);;All files (*.*)', 245 'options' : QtWidgets.QFileDialog.DontUseNativeDialog 246 } 247 filename = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] 248 if filename: 249 self.readAnalysis(filename) 235 load_thread = threads.deferToThread(self.readProject, filename) 236 load_thread.addCallback(self.readProjectComplete) 237 load_thread.addErrback(self.readProjectFailed) 238 239 def loadFailed(self, reason): 240 """ 241 """ 242 print("file load FAILED: ", reason) 243 pass 244 245 def readProjectFailed(self, reason): 246 """ 247 """ 248 print("readProjectFailed FAILED: ", reason) 249 pass 250 251 def readProject(self, filename): 252 self.communicator.statusBarUpdateSignal.emit("Loading Project... %s" % os.path.basename(filename)) 253 try: 254 manager = DataManager() 255 with open(filename, 'r') as infile: 256 manager.load_from_readable(infile) 257 258 self.communicator.statusBarUpdateSignal.emit("Loaded Project: %s" % os.path.basename(filename)) 259 return manager 260 261 except: 262 self.communicator.statusBarUpdateSignal.emit("Failed: %s" % os.path.basename(filename)) 263 raise 264 265 def readProjectComplete(self, manager): 266 self.model.clear() 267 268 self.manager.assign(manager) 269 self.model.beginResetModel() 270 for id, item in self.manager.get_all_data().items(): 271 self.updateModel(item.data, item.path) 272 273 self.model.endResetModel() 250 274 251 275 def saveProject(self): … … 261 285 name_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs) 262 286 filename = name_tuple[0] 263 if not filename: 264 return 265 _, extension = os.path.splitext(filename) 266 if not extension: 267 filename = '.'.join((filename, 'json')) 268 self.communicator.statusBarUpdateSignal.emit("Saving Project... %s\n" % os.path.basename(filename)) 269 270 return filename 271 272 def saveAsAnalysisFile(self, tab_id=1): 273 """ 274 Show the save as... dialog and return the chosen filepath 275 """ 276 default_name = "FitPage"+str(tab_id)+".fitv" 277 278 wildcard = "fitv files (*.fitv)" 279 kwargs = { 280 'caption' : 'Save As', 281 'directory' : default_name, 282 'filter' : wildcard, 283 'parent' : None, 284 } 285 # Query user for filename. 286 filename_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs) 287 filename = filename_tuple[0] 288 return filename 289 290 def saveAnalysis(self, data, tab_id=1): 291 """ 292 Called when the "Save Analysis" menu item chosen. 293 """ 294 filename = self.saveAsAnalysisFile(tab_id) 295 if not filename: 296 return 297 _, extension = os.path.splitext(filename) 298 if not extension: 299 filename = '.'.join((filename, 'fitv')) 300 self.communicator.statusBarUpdateSignal.emit("Saving analysis... %s\n" % os.path.basename(filename)) 301 302 with open(filename, 'w') as outfile: 303 GuiUtils.saveData(outfile, data) 304 305 self.communicator.statusBarUpdateSignal.emit('Analysis saved.') 306 307 def allDataForModel(self, model): 308 # data model 309 all_data = {} 310 for i in range(model.rowCount()): 311 properties = {} 312 item = model.item(i) 313 data = GuiUtils.dataFromItem(item) 314 if data is None: continue 315 # Now, all plots under this item 316 filename = data.filename 317 is_checked = item.checkState() 318 properties['checked'] = is_checked 319 other_datas = [] 320 # no need to save other_datas - things will be refit on read 321 #other_datas = GuiUtils.plotsFromFilename(filename, model) 322 # skip the main plot 323 #other_datas = list(other_datas.values())[1:] 324 all_data[data.id] = [data, properties, other_datas] 325 return all_data 326 327 def getDataForID(self, id): 328 # return the dataset with the given ID 329 all_data = [] 330 for model in (self.model, self.theory_model): 331 for i in range(model.rowCount()): 332 properties = {} 333 item = model.item(i) 334 data = GuiUtils.dataFromItem(item) 335 if data is None: continue 336 if data.id != id: continue 337 # We found the dataset - save it. 338 filename = data.filename 339 is_checked = item.checkState() 340 properties['checked'] = is_checked 341 other_datas = GuiUtils.plotsFromFilename(filename, model) 342 # skip the main plot 343 other_datas = list(other_datas.values())[1:] 344 all_data = [data, properties, other_datas] 345 break 346 return all_data 347 348 def getAllData(self): 349 """ 350 converts all datasets into serializable dictionary 351 """ 352 data = self.allDataForModel(self.model) 353 theory = self.allDataForModel(self.theory_model) 354 355 all_data = {} 356 for key, value in data.items(): 357 all_data[key] = value 358 for key, value in theory.items(): 359 if key in all_data: 360 raise ValueError("Inconsistent data in Project file.") 361 all_data[key] = value 362 return all_data 363 364 def saveDataToFile(self, outfile): 365 """ 366 Save every dataset to a json file 367 """ 368 all_data = self.getAllData() 369 # save datas 370 GuiUtils.saveData(outfile, all_data) 371 372 def readProject(self, filename): 373 """ 374 Read out datasets and fitpages from file 375 """ 376 with open(filename, 'r') as infile: 377 all_data = GuiUtils.readDataFromFile(infile) 378 379 for key, value in all_data.items(): 380 data_dict = {key:value['fit_data']} 381 items = self.updateModelFromData(data_dict) 382 # send newly created item to its perspective 383 if 'fit_params' in value: 384 self.sendItemToPerspective(items[0]) 385 # Make the perspective read the rest of the read data 386 self._perspective().updateFromParameters(value['fit_params']) 387 388 pass # debugger 389 390 def readAnalysis(self, filename): 391 """ 392 Read out a single dataset and fitpage from file 393 """ 394 with open(filename, 'r') as infile: 395 all_data = GuiUtils.readDataFromFile(infile) 396 # simulate full project structure 397 all_data_dict = {1:all_data['fit_data']} 398 items = self.updateModelFromData(all_data_dict) 399 # TODO: allow other perspectives 400 # send newly created item to its perspective 401 if len(items) > 0: 402 self.sendItemToPerspective(items[0]) 403 # Make the perspective read the rest of the read data 404 self._perspective().updateFromParameters(all_data['fit_params']) 405 406 pass 407 408 def updateModelFromData(self, data): 409 """ 410 Given data from analysis/project file, 411 create indices and populate data/theory models 412 """ 413 # model items for top level datasets 414 items = [] 415 #self.model.beginResetModel() 416 for key, value in data.items(): 417 # key - cardinal number of dataset 418 # value - main dataset, [dependant filesets] 419 # add the main index 420 if not value: continue 421 new_data = value[0] 422 assert isinstance(new_data, (Data1D, Data2D)) 423 properties = value[1] 424 is_checked = properties['checked'] 425 new_item = GuiUtils.createModelItemWithPlot(new_data, new_data.filename) 426 new_item.setCheckState(is_checked) 427 items.append(new_item) 428 model = self.theory_model 429 if new_data.is_data: 430 model = self.model 431 model.appendRow(new_item) 432 self.manager.add_data(data_list={new_data.id:new_data}) 433 434 # Add the underlying data 435 if not value[2]: 436 continue 437 for plot in value[2]: 438 assert isinstance(plot, (Data1D, Data2D)) 439 GuiUtils.updateModelItemWithPlot(new_item, plot, plot.name) 440 return items 287 if filename: 288 _, extension = os.path.splitext(filename) 289 if not extension: 290 filename = '.'.join((filename, 'json')) 291 self.communicator.statusBarUpdateSignal.emit("Saving Project... %s\n" % os.path.basename(filename)) 292 with open(filename, 'w') as outfile: 293 self.manager.save_to_writable(outfile) 441 294 442 295 def deleteFile(self, event): … … 557 410 retval = msgbox.exec_() 558 411 559 def sendItemToPerspective(self, item):560 """561 Send the passed item data to the current perspective and set the relevant notifiers562 """563 # Set the signal handlers564 self.communicator.updateModelFromPerspectiveSignal.connect(self.updateModelFromPerspective)565 selected_items = [item]566 # Notify the GuiManager about the send request567 try:568 self._perspective().setData(data_item=selected_items, is_batch=False)569 except Exception as ex:570 msg = "%s perspective returned the following message: \n%s\n" %(self._perspective().name, str(ex))571 logging.error(msg)572 msg = str(ex)573 msgbox = QtWidgets.QMessageBox()574 msgbox.setIcon(QtWidgets.QMessageBox.Critical)575 msgbox.setText(msg)576 msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)577 retval = msgbox.exec_()578 412 579 413 def freezeCheckedData(self): … … 1470 1304 self.manager.update_stored_data(deleted_names) 1471 1305 1306 def closeAllPlots(self): 1307 """ 1308 Close all currently displayed plots 1309 """ 1310 1311 for plot_id in PlotHelper.currentPlots(): 1312 try: 1313 plotter = PlotHelper.plotById(plot_id) 1314 plotter.close() 1315 self.plot_widgets[plot_id].close() 1316 self.plot_widgets.pop(plot_id, None) 1317 except AttributeError as ex: 1318 logging.error("Closing of %s failed:\n %s" % (plot_id, str(ex))) 1319 1472 1320 def closePlotsForItem(self, item): 1473 1321 """ … … 1560 1408 checkbox_item.setCheckable(True) 1561 1409 checkbox_item.setCheckState(QtCore.Qt.Checked) 1562 if p_file is not None: 1563 checkbox_item.setText(os.path.basename(p_file)) 1410 checkbox_item.setText(os.path.basename(p_file)) 1564 1411 1565 1412 # Add the actual Data1D/Data2D object
Note: See TracChangeset
for help on using the changeset viewer.