Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/MainWindow/DataExplorer.py

    ra3c59503 r6bc0840  
    233233        filename = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] 
    234234        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() 
    250274 
    251275    def saveProject(self): 
     
    261285        name_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs) 
    262286        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) 
    441294 
    442295    def deleteFile(self, event): 
     
    557410            retval = msgbox.exec_() 
    558411 
    559     def sendItemToPerspective(self, item): 
    560         """ 
    561         Send the passed item data to the current perspective and set the relevant notifiers 
    562         """ 
    563         # Set the signal handlers 
    564         self.communicator.updateModelFromPerspectiveSignal.connect(self.updateModelFromPerspective) 
    565         selected_items = [item] 
    566         # Notify the GuiManager about the send request 
    567         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_() 
    578412 
    579413    def freezeCheckedData(self): 
     
    14701304        self.manager.update_stored_data(deleted_names) 
    14711305 
     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 
    14721320    def closePlotsForItem(self, item): 
    14731321        """ 
     
    15601408        checkbox_item.setCheckable(True) 
    15611409        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)) 
    15641411 
    15651412        # Add the actual Data1D/Data2D object 
Note: See TracChangeset for help on using the changeset viewer.