Changeset 10d57f6 in sasview


Ignore:
Timestamp:
Oct 18, 2018 3:43:11 AM (5 years ago)
Author:
Piotr Rozyczko <piotr.rozyczko@…>
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:
2eeda93
Parents:
b95d748 (diff), 9a42ea1 (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.
Message:

Merge branch 'ESS_GUI' into ESS_GUI_project_save

Location:
src/sas/qtgui
Files:
6 edited

Legend:

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

    refaf022 r6040cd7  
    444444        """ 
    445445        # disable not yet fully implemented actions 
    446         self._workspace.actionOpen_Analysis.setVisible(False) 
     446        #self._workspace.actionOpen_Analysis.setVisible(False) 
    447447        self._workspace.actionUndo.setVisible(False) 
    448448        self._workspace.actionRedo.setVisible(False) 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    rdd545d1 r9a42ea1  
    567567        self.communicate.customModelDirectoryChanged.connect(self.onCustomModelChange) 
    568568        self.communicate.saveAnalysisSignal.connect(self.savePageState) 
     569        #self.communicate.loadAnalysisSignal.connect(self.loadPageState) 
    569570        self.smearing_widget.smearingChangedSignal.connect(self.onSmearingOptionsUpdate) 
    570571 
     
    33693370        Create and serialize local PageState 
    33703371        """ 
    3371         from sas.sascalc.fit.pagestate import Reader 
    3372         model = self.kernel_module 
    3373  
    3374         # Old style PageState object 
    3375         state = PageState(model=model, data=self.data) 
    3376  
    3377         # Add parameter data to the state 
    3378         self.getCurrentFitState(state) 
    3379  
    3380         # Create the filewriter, aptly named 'Reader' 
    3381         state_reader = Reader(self.loadPageStateCallback) 
    33823372        filepath = self.saveAsAnalysisFile() 
    33833373        if filepath is None or filepath == "": 
    33843374            return 
    3385         state_reader.write(filename=filepath, fitstate=state) 
    3386         pass 
     3375 
     3376        fitpage_state = self.getFitPage() 
     3377        fitpage_state += self.getFitModel() 
     3378 
     3379        with open(filepath, 'w') as statefile: 
     3380            for line in fitpage_state: 
     3381                statefile.write(str(line)) 
     3382 
     3383        self.communicate.statusBarUpdateSignal.emit('Analysis saved.') 
    33873384 
    33883385    def saveAsAnalysisFile(self): 
     
    34173414        Load the PageState object and update the current widget 
    34183415        """ 
     3416        filepath = self.loadAnalysisFile() 
     3417        if filepath is None or filepath == "": 
     3418            return 
     3419 
     3420        with open(filepath, 'r') as statefile: 
     3421            #column_data = [line.rstrip().split() for line in statefile.readlines()] 
     3422            lines = statefile.readlines() 
     3423 
     3424        # convert into list of lists 
    34193425        pass 
    34203426 
    3421     def getCurrentFitState(self, state=None): 
    3422         """ 
    3423         Store current state for fit_page 
    3424         """ 
    3425         # save model option 
    3426         #if self.model is not None: 
    3427         #    self.disp_list = self.getDispParamList() 
    3428         #    state.disp_list = copy.deepcopy(self.disp_list) 
    3429         #    #state.model = self.model.clone() 
    3430  
    3431         # Comboboxes 
    3432         state.categorycombobox = self.cbCategory.currentText() 
    3433         state.formfactorcombobox = self.cbModel.currentText() 
    3434         if self.cbStructureFactor.isEnabled(): 
    3435             state.structurecombobox = self.cbStructureFactor.currentText() 
    3436         state.tcChi = self.chi2 
    3437  
    3438         state.enable2D = self.is2D 
    3439  
    3440         #state.weights = copy.deepcopy(self.weights) 
    3441         # save data 
    3442         state.data = copy.deepcopy(self.data) 
    3443  
    3444         # save plotting range 
    3445         state.qmin = self.q_range_min 
    3446         state.qmax = self.q_range_max 
    3447         state.npts = self.npts 
    3448  
    3449         #    self.state.enable_disp = self.enable_disp.GetValue() 
    3450         #    self.state.disable_disp = self.disable_disp.GetValue() 
    3451  
    3452         #    self.state.enable_smearer = \ 
    3453         #                        copy.deepcopy(self.enable_smearer.GetValue()) 
    3454         #    self.state.disable_smearer = \ 
    3455         #                        copy.deepcopy(self.disable_smearer.GetValue()) 
    3456  
    3457         #self.state.pinhole_smearer = \ 
    3458         #                        copy.deepcopy(self.pinhole_smearer.GetValue()) 
    3459         #self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
    3460         #self.state.dI_noweight = copy.deepcopy(self.dI_noweight.GetValue()) 
    3461         #self.state.dI_didata = copy.deepcopy(self.dI_didata.GetValue()) 
    3462         #self.state.dI_sqrdata = copy.deepcopy(self.dI_sqrdata.GetValue()) 
    3463         #self.state.dI_idata = copy.deepcopy(self.dI_idata.GetValue()) 
    3464  
    3465         p = self.model_parameters 
    3466         # save checkbutton state and txtcrtl values 
    3467         state.parameters = FittingUtilities.getStandardParam(self._model_model) 
    3468         state.orientation_params_disp = FittingUtilities.getOrientationParam(self.kernel_module) 
    3469  
    3470         #self._copy_parameters_state(self.orientation_params_disp, self.state.orientation_params_disp) 
    3471         #self._copy_parameters_state(self.parameters, self.state.parameters) 
    3472         #self._copy_parameters_state(self.fittable_param, self.state.fittable_param) 
    3473         #self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 
     3427    def loadAnalysisFile(self): 
     3428        """ 
     3429        Called when the "Open Project" menu item chosen. 
     3430        """ 
     3431        default_name = "FitPage"+str(self.tab_id)+".fitv" 
     3432        wildcard = "fitv files (*.fitv)" 
     3433        kwargs = { 
     3434            'caption'   : 'Open Analysis', 
     3435            'directory' : default_name, 
     3436            'filter'    : wildcard, 
     3437            'parent'    : self, 
     3438        } 
     3439        filename = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] 
     3440        return filename 
    34743441 
    34753442    def onCopyToClipboard(self, format=None): 
     
    34813448        param_list = self.getFitParameters() 
    34823449        if format=="": 
     3450            param_list = self.getFitPage() 
     3451            param_list += self.getFitModel() 
    34833452            formatted_output = FittingUtilities.formatParameters(param_list) 
    34843453        elif format == "Excel": 
     
    34933462        cb.setText(formatted_output) 
    34943463 
    3495     def getFitParameters(self, format=None): 
    3496         """ 
    3497         Copy current parameters into the clipboard 
     3464    def getFitModel(self): 
     3465        """ 
     3466        serializes combobox state 
     3467        """ 
     3468        param_list = [] 
     3469        model = str(self.cbModel.currentText()) 
     3470        category = str(self.cbCategory.currentText()) 
     3471        structure = str(self.cbStructureFactor.currentText()) 
     3472        param_list.append(['fitpage_category', category]) 
     3473        param_list.append(['fitpage_model', model]) 
     3474        param_list.append(['fitpage_structure', structure]) 
     3475 
     3476        return param_list 
     3477 
     3478    def getFitPage(self): 
     3479        """ 
     3480        serializes full state of this fit page 
    34983481        """ 
    34993482        # run a loop over all parameters and pull out 
    35003483        # first - regular params 
     3484        param_list = self.getFitParameters() 
     3485 
     3486        param_list.append(['is_data', str(self.data_is_loaded)]) 
     3487        if self.data_is_loaded: 
     3488            param_list.append(['data_id', str(self.logic.data.id)]) 
     3489            param_list.append(['data_name', str(self.logic.data.filename)]) 
     3490 
     3491        # option tab 
     3492        param_list.append(['q_range_min', str(self.q_range_min)]) 
     3493        param_list.append(['q_range_max', str(self.q_range_max)]) 
     3494        param_list.append(['q_weighting', str(self.weighting)]) 
     3495        param_list.append(['weighting', str(self.options_widget.weighting)]) 
     3496 
     3497        # resolution 
     3498        smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
     3499        index = self.smearing_widget.cbSmearing.currentIndex() 
     3500        param_list.append(['smearing', str(index)]) 
     3501        param_list.append(['smearing_min', str(smearing_min)]) 
     3502        param_list.append(['smearing_max', str(smearing_max)]) 
     3503 
     3504        # checkboxes, if required 
     3505        has_polydisp = self.chkPolydispersity.isChecked() 
     3506        has_magnetism = self.chkMagnetism.isChecked() 
     3507        has_chain = self.chkChainFit.isChecked() 
     3508        has_2D = self.chk2DView.isChecked() 
     3509        param_list.append(['polydisperse_params', str(has_polydisp)]) 
     3510        param_list.append(['magnetic_params', str(has_magnetism)]) 
     3511        param_list.append(['chainfit_params', str(has_chain)]) 
     3512        param_list.append(['2D_params', str(has_2D)]) 
     3513 
     3514        return param_list 
     3515 
     3516    def getFitParameters(self): 
     3517        """ 
     3518        serializes current parameters 
     3519        """ 
    35013520        param_list = [] 
    35023521        param_list.append(['model_name', str(self.cbModel.currentText())]) 
     
    35333552            if self.has_error_column: 
    35343553                column_offset = 1 
     3554                param_error = str(self._model_model.item(row, 1+column_offset).text()) 
    35353555            try: 
    35363556                param_min = str(self._model_model.item(row, 2+column_offset).text()) 
     
    35393559                pass 
    35403560 
    3541             param_list.append([param_name, param_checked, param_value, param_min, param_max]) 
     3561            param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 
    35423562 
    35433563        def gatherPolyParams(row): 
     
    35523572            if self.has_poly_error_column: 
    35533573                column_offset = 1 
     3574                param_error = str(self._poly_model.item(row, 1+column_offset).text()) 
    35543575            param_min   = str(self._poly_model.item(row, 2+column_offset).text()) 
    35553576            param_max   = str(self._poly_model.item(row, 3+column_offset).text()) 
     
    35633584            # width 
    35643585            name = param_name+".width" 
    3565             param_list.append([name, param_checked, param_value, param_min, param_max, 
    3566                                 param_npts, param_nsigs, param_fun]) 
     3586            param_list.append([name, param_checked, param_value, param_error, 
     3587                               param_min, param_max, param_npts, param_nsigs, param_fun]) 
    35673588 
    35683589        def gatherMagnetParams(row): 
     
    35773598            if self.has_magnet_error_column: 
    35783599                column_offset = 1 
     3600                param_error = str(self._magnet_model.item(row, 1+column_offset).text()) 
    35793601            param_min = str(self._magnet_model.item(row, 2+column_offset).text()) 
    35803602            param_max = str(self._magnet_model.item(row, 3+column_offset).text()) 
    3581             param_list.append([param_name, param_checked, param_value, param_min, param_max]) 
     3603            param_list.append([param_name, param_checked, param_value, 
     3604                               param_error, param_min, param_max]) 
    35823605 
    35833606        self.iterateOverModel(gatherParams) 
     
    35893612        if self.kernel_module.is_multiplicity_model: 
    35903613            param_list.append(['multiplicity', str(self.kernel_module.multiplicity)]) 
    3591  
    3592         # option tab 
    3593         param_list.append(['q_range_min', str(self.q_range_min)]) 
    3594         param_list.append(['q_range_max', str(self.q_range_max)]) 
    3595         param_list.append(['q_weighting', str(self.weighting)]) 
    3596  
    3597         # resolution 
    3598         smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
    3599         index = self.smearing_widget.cbSmearing.currentIndex() 
    3600         param_list.append(['smearing', str(index)]) 
    3601         param_list.append(['smearing_min', str(smearing_min)]) 
    3602         param_list.append(['smearing_max', str(smearing_max)]) 
    3603  
    3604         # checkboxes, if required 
    3605         has_polydisp = self.chkPolydispersity.isChecked() 
    3606         has_magnetism = self.chkMagnetism.isChecked() 
    3607         has_chain = self.chkChainFit.isChecked() 
    3608         has_2D = self.chk2DView.isChecked() 
    3609         param_list.append(['polydisperse_params', str(has_polydisp)]) 
    3610         param_list.append(['magnetic_params', str(has_magnetism)]) 
    3611         param_list.append(['chainfit_params', str(has_chain)]) 
    3612         param_list.append(['2D_params', str(has_2D)]) 
    36133614 
    36143615        return param_list 
     
    36973698                pass 
    36983699        self.options_widget.updateQRange(self.q_range_min, self.q_range_max, self.npts) 
     3700        try: 
     3701            button_id = int(line_dict['weighting'][0]) 
     3702            for button in self.options_widget.weightingGroup.buttons(): 
     3703                if abs(self.options_widget.weightingGroup.id(button)) == button_id+2: 
     3704                    button.setChecked(True) 
     3705                    break 
     3706        except ValueError: 
     3707            pass 
    36993708 
    37003709        self.updateFullModel(context) 
     
    37593768            # Potentially the error column 
    37603769            ioffset = 0 
    3761             if len(param_dict[param_name])>4 and self.has_error_column: 
     3770            joffset = 0 
     3771            if len(param_dict[param_name])>3: 
    37623772                # error values are not editable - no need to update 
    37633773                ioffset = 1 
     3774            if self.has_error_column: 
     3775                joffset = 1 
    37643776            # min/max 
    37653777            try: 
    37663778                param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 
    3767                 self._model_model.item(row, 2+ioffset).setText(param_repr) 
     3779                self._model_model.item(row, 2+joffset).setText(param_repr) 
    37683780                param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 
    3769                 self._model_model.item(row, 3+ioffset).setText(param_repr) 
     3781                self._model_model.item(row, 3+joffset).setText(param_repr) 
    37703782            except: 
    37713783                pass 
     
    38013813            # Potentially the error column 
    38023814            ioffset = 0 
    3803             if len(param_dict[param_name])>4 and self.has_poly_error_column: 
     3815            joffset = 0 
     3816            if len(param_dict[param_name])>3: 
    38043817                ioffset = 1 
     3818            if self.has_poly_error_column: 
     3819                joffset = 1 
    38053820            # min 
    38063821            param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 
    3807             self._poly_model.item(row, 2+ioffset).setText(param_repr) 
     3822            self._poly_model.item(row, 2+joffset).setText(param_repr) 
    38083823            # max 
    38093824            param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 
    3810             self._poly_model.item(row, 3+ioffset).setText(param_repr) 
     3825            self._poly_model.item(row, 3+joffset).setText(param_repr) 
    38113826            # Npts 
    38123827            param_repr = GuiUtils.formatNumber(param_dict[param_name][4+ioffset], high=True) 
    3813             self._poly_model.item(row, 4+ioffset).setText(param_repr) 
     3828            self._poly_model.item(row, 4+joffset).setText(param_repr) 
    38143829            # Nsigs 
    38153830            param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 
    3816             self._poly_model.item(row, 5+ioffset).setText(param_repr) 
    3817  
    3818             param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 
    3819             self._poly_model.item(row, 5+ioffset).setText(param_repr) 
     3831            self._poly_model.item(row, 5+joffset).setText(param_repr) 
     3832 
    38203833            self.setFocus() 
    38213834 
     
    38483861            # Potentially the error column 
    38493862            ioffset = 0 
    3850             if len(param_dict[param_name])>4 and self.has_magnet_error_column: 
     3863            joffset = 0 
     3864            if len(param_dict[param_name])>3: 
    38513865                ioffset = 1 
     3866            if self.has_magnet_error_column: 
     3867                joffset = 1 
    38523868            # min 
    38533869            param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 
    3854             self._magnet_model.item(row, 2+ioffset).setText(param_repr) 
     3870            self._magnet_model.item(row, 2+joffset).setText(param_repr) 
    38553871            # max 
    38563872            param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 
    3857             self._magnet_model.item(row, 3+ioffset).setText(param_repr) 
     3873            self._magnet_model.item(row, 3+joffset).setText(param_repr) 
    38583874 
    38593875        self.iterateOverMagnetModel(updateFittedValues) 
     3876 
     3877    def getCurrentFitState(self, state=None): 
     3878        """ 
     3879        Store current state for fit_page 
     3880        """ 
     3881        # save model option 
     3882        #if self.model is not None: 
     3883        #    self.disp_list = self.getDispParamList() 
     3884        #    state.disp_list = copy.deepcopy(self.disp_list) 
     3885        #    #state.model = self.model.clone() 
     3886 
     3887        # Comboboxes 
     3888        state.categorycombobox = self.cbCategory.currentText() 
     3889        state.formfactorcombobox = self.cbModel.currentText() 
     3890        if self.cbStructureFactor.isEnabled(): 
     3891            state.structurecombobox = self.cbStructureFactor.currentText() 
     3892        state.tcChi = self.chi2 
     3893 
     3894        state.enable2D = self.is2D 
     3895 
     3896        #state.weights = copy.deepcopy(self.weights) 
     3897        # save data 
     3898        state.data = copy.deepcopy(self.data) 
     3899 
     3900        # save plotting range 
     3901        state.qmin = self.q_range_min 
     3902        state.qmax = self.q_range_max 
     3903        state.npts = self.npts 
     3904 
     3905        #    self.state.enable_disp = self.enable_disp.GetValue() 
     3906        #    self.state.disable_disp = self.disable_disp.GetValue() 
     3907 
     3908        #    self.state.enable_smearer = \ 
     3909        #                        copy.deepcopy(self.enable_smearer.GetValue()) 
     3910        #    self.state.disable_smearer = \ 
     3911        #                        copy.deepcopy(self.disable_smearer.GetValue()) 
     3912 
     3913        #self.state.pinhole_smearer = \ 
     3914        #                        copy.deepcopy(self.pinhole_smearer.GetValue()) 
     3915        #self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
     3916        #self.state.dI_noweight = copy.deepcopy(self.dI_noweight.GetValue()) 
     3917        #self.state.dI_didata = copy.deepcopy(self.dI_didata.GetValue()) 
     3918        #self.state.dI_sqrdata = copy.deepcopy(self.dI_sqrdata.GetValue()) 
     3919        #self.state.dI_idata = copy.deepcopy(self.dI_idata.GetValue()) 
     3920 
     3921        p = self.model_parameters 
     3922        # save checkbutton state and txtcrtl values 
     3923        state.parameters = FittingUtilities.getStandardParam(self._model_model) 
     3924        state.orientation_params_disp = FittingUtilities.getOrientationParam(self.kernel_module) 
     3925 
     3926        #self._copy_parameters_state(self.orientation_params_disp, self.state.orientation_params_disp) 
     3927        #self._copy_parameters_state(self.parameters, self.state.parameters) 
     3928        #self._copy_parameters_state(self.fittable_param, self.state.fittable_param) 
     3929        #self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 
     3930 
  • src/sas/qtgui/MainWindow/DataExplorer.py

    r3b95b3b r345b3b3  
    233233        filename = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] 
    234234        if 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() 
     235            self.readProject(filename) 
    274236 
    275237    def saveProject(self): 
     
    285247        name_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs) 
    286248        filename = name_tuple[0] 
    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) 
     249        if not filename: 
     250            return 
     251        _, extension = os.path.splitext(filename) 
     252        if not extension: 
     253            filename = '.'.join((filename, 'json')) 
     254        self.communicator.statusBarUpdateSignal.emit("Saving Project... %s\n" % os.path.basename(filename)) 
     255 
     256        with open(filename, 'w') as outfile: 
     257            self.saveDataToFile(outfile) 
     258 
     259    def allDataForModel(self, model): 
     260        # data model 
     261        all_data = {} 
     262        for i in range(model.rowCount()): 
     263            properties = {} 
     264            item = model.item(i) 
     265            data = GuiUtils.dataFromItem(item) 
     266            if data is None: continue 
     267            # Now, all plots under this item 
     268            filename = data.filename 
     269            is_checked = item.checkState() 
     270            properties['checked'] = is_checked 
     271            other_datas = GuiUtils.plotsFromFilename(filename, model) 
     272            # skip the main plot 
     273            other_datas = list(other_datas.values())[1:] 
     274            all_data[data.id] = [data, properties, other_datas] 
     275        return all_data 
     276 
     277    def saveDataToFile(self, outfile): 
     278        """ 
     279        Save every dataset to a json file 
     280        """ 
     281        data = self.allDataForModel(self.model) 
     282        theory = self.allDataForModel(self.theory_model) 
     283 
     284        all_data = {} 
     285        for key, value in data.items(): 
     286            all_data[key] = value 
     287        for key, value in theory.items(): 
     288            if key in all_data: 
     289                raise ValueError("Inconsistent data in Project file.") 
     290            all_data[key] = value 
     291 
     292        # perspectives 
     293        current_perspective = self._perspective() 
     294        try: 
     295            perspective_dump = current_perspective.getCurrentStateAsXml() 
     296        except Exception: 
     297            ex = "State of " + current_perspective.windowTitle() + \ 
     298                " cannot be saved." 
     299            logging.error(ex) 
     300        if perspective_dump is not None: 
     301            assert(isinstance(perspective_dump, dict)) 
     302            all_data['perspective'] = perspective_dump 
     303        # save datas 
     304        GuiUtils.saveData(outfile, all_data) 
     305        return 
     306 
     307    def readProject(self, filename): 
     308        """ 
     309        Read out datasets and fitpages from file 
     310        """ 
     311        with open(filename, 'r') as infile: 
     312            all_data = GuiUtils.readDataFromFile(infile) 
     313        # clear the model 
     314        self.model.clear() 
     315 
     316        #self.model.beginResetModel() 
     317        for key, value in all_data.items(): 
     318            # key - cardinal number of dataset 
     319            # value - main dataset, [dependant filesets] 
     320            # add the main index 
     321            new_data = value[0] 
     322            assert isinstance(new_data, (Data1D, Data2D)) 
     323            properties = value[1] 
     324            is_checked = properties['checked'] 
     325            new_item = GuiUtils.createModelItemWithPlot(new_data, new_data.filename) 
     326            new_item.setCheckState(is_checked) 
     327            model = self.theory_model 
     328            if new_data.is_data: 
     329                model = self.model 
     330            model.appendRow(new_item) 
     331            self.manager.add_data(data_list={new_data.id:new_data}) 
     332 
     333            # Add the underlying data 
     334            if not value[2]: 
     335                continue 
     336            for plot in value[2]: 
     337                assert isinstance(plot, (Data1D, Data2D)) 
     338                GuiUtils.updateModelItemWithPlot(new_item, plot, plot.name) 
    294339 
    295340    def deleteFile(self, event): 
     
    13941439        checkbox_item.setCheckable(True) 
    13951440        checkbox_item.setCheckState(QtCore.Qt.Checked) 
    1396         checkbox_item.setText(os.path.basename(p_file)) 
     1441        if p_file is not None: 
     1442            checkbox_item.setText(os.path.basename(p_file)) 
    13971443 
    13981444        # Add the actual Data1D/Data2D object 
  • src/sas/qtgui/MainWindow/DataManager.py

    re2e5f3d r345b3b3  
    2929from sas.qtgui.Plotting.PlotterData import Data1D 
    3030from sas.qtgui.Plotting.PlotterData import Data2D 
    31 from sas.qtgui.Plotting.Plottables import Plottable 
    3231from sas.qtgui.Plotting.Plottables import PlottableTheory1D 
    3332from sas.qtgui.Plotting.Plottables import PlottableFit1D 
  • src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py

    rd2007a8 rb95d748  
    337337        pass 
    338338 
     339    def getCurrentStateAsXml(self): 
     340        """ 
     341        Returns an XML version of the current state 
     342        """ 
     343        state = {} 
     344        for tab in self.tabs: 
     345            pass 
     346        return state 
     347 
    339348    @property 
    340349    def currentTab(self): 
  • src/sas/qtgui/Utilities/GuiUtils.py

    r63467b6 r345b3b3  
    1111import webbrowser 
    1212import urllib.parse 
     13import json 
     14from io import BytesIO 
    1315 
    1416import numpy as np 
     
    2628from sas.qtgui.Plotting.PlotterData import Data1D 
    2729from sas.qtgui.Plotting.PlotterData import Data2D 
     30from sas.qtgui.Plotting.Plottables import Plottable 
     31from sas.sascalc.dataloader.data_info import Sample, Source, Vector 
     32from sas.qtgui.Plotting.Plottables import View 
     33from sas.qtgui.Plotting.Plottables import PlottableTheory1D 
     34from sas.qtgui.Plotting.Plottables import PlottableFit1D 
     35from sas.qtgui.Plotting.Plottables import Text 
     36from sas.qtgui.Plotting.Plottables import Chisq 
     37from sas.qtgui.MainWindow.DataState import DataState 
     38 
    2839from sas.sascalc.dataloader.loader import Loader 
    2940from sas.qtgui.Utilities import CustomDir 
     
    286297    changeDataExplorerTabSignal = QtCore.pyqtSignal(int) 
    287298 
    288 def updateModelItemWithPlot(item, update_data, name=""): 
     299def updateModelItemWithPlot(item, update_data, name="", checkbox_state=None): 
    289300    """ 
    290301    Adds a checkboxed row named "name" to QStandardItem 
     
    311322            # Force redisplay 
    312323            return 
    313  
    314324    # Create the new item 
    315325    checkbox_item = createModelItemWithPlot(update_data, name) 
    316326 
     327    if checkbox_state is not None: 
     328        checkbox_item.setCheckState(checkbox_state) 
    317329    # Append the new row to the main item 
    318330    item.appendRow(checkbox_item) 
     
    11391151    return result 
    11401152 
     1153def saveData(fp, data): 
     1154    """ 
     1155    save content of data to fp (a .write()-supporting file-like object) 
     1156    """ 
     1157 
     1158    def add_type(dict, type): 
     1159        dict['__type__'] = type.__name__ 
     1160        return dict 
     1161 
     1162    def jdefault(o): 
     1163        """ 
     1164        objects that can't otherwise be serialized need to be converted 
     1165        """ 
     1166        # tuples and sets (TODO: default JSONEncoder converts tuples to lists, create custom Encoder that preserves tuples) 
     1167        if isinstance(o, (tuple, set)): 
     1168            content = { 'data': list(o) } 
     1169            return add_type(content, type(o)) 
     1170 
     1171        # "simple" types 
     1172        if isinstance(o, (Sample, Source, Vector)): 
     1173            return add_type(o.__dict__, type(o)) 
     1174        if isinstance(o, (Plottable, View)): 
     1175            return add_type(o.__dict__, type(o)) 
     1176 
     1177        # DataState 
     1178        if isinstance(o, (Data1D, Data2D)): 
     1179            # don't store parent 
     1180            content = o.__dict__.copy() 
     1181            #content.pop('parent') 
     1182            return add_type(content, type(o)) 
     1183 
     1184        # ndarray 
     1185        if isinstance(o, np.ndarray): 
     1186            buffer = BytesIO() 
     1187            np.save(buffer, o) 
     1188            buffer.seek(0) 
     1189            content = { 'data': buffer.read().decode('latin-1') } 
     1190            return add_type(content, type(o)) 
     1191 
     1192        # not supported 
     1193        logging.info("data cannot be serialized to json: %s" % type(o)) 
     1194        return None 
     1195 
     1196    json.dump(data, fp, indent=2, sort_keys=True, default=jdefault) 
     1197 
     1198def readDataFromFile(fp): 
     1199    ''' 
     1200    ''' 
     1201    supported = [ 
     1202        tuple, set, 
     1203        Sample, Source, Vector, 
     1204        Plottable, Data1D, Data2D, PlottableTheory1D, PlottableFit1D, Text, Chisq, View, 
     1205        DataState, np.ndarray] 
     1206 
     1207    lookup = dict((cls.__name__, cls) for cls in supported) 
     1208 
     1209    class TooComplexException(Exception): 
     1210        pass 
     1211 
     1212    def simple_type(cls, data, level): 
     1213        class Empty(object): 
     1214            def __init__(self): 
     1215                for key, value in data.items(): 
     1216                    setattr(self, key, generate(value, level)) 
     1217 
     1218        # create target object 
     1219        o = Empty() 
     1220        o.__class__ = cls 
     1221 
     1222        return o 
     1223 
     1224    def construct(type, data, level): 
     1225        try: 
     1226            cls = lookup[type] 
     1227        except KeyError: 
     1228            logging.info('unknown type: %s' % type) 
     1229            return None 
     1230 
     1231        # tuples and sets 
     1232        if cls in (tuple, set): 
     1233            # convert list to tuple/set 
     1234            return cls(generate(data['data'], level)) 
     1235 
     1236        # "simple" types 
     1237        if cls in (Sample, Source, Vector): 
     1238            return simple_type(cls, data, level) 
     1239        if issubclass(cls, Plottable) or (cls == View): 
     1240            return simple_type(cls, data, level) 
     1241 
     1242        # DataState 
     1243        if cls == DataState: 
     1244            o = simple_type(cls, data, level) 
     1245            o.parent = None # TODO: set to ??? 
     1246            return o 
     1247 
     1248        # ndarray 
     1249        if cls == np.ndarray: 
     1250            buffer = BytesIO() 
     1251            buffer.write(data['data'].encode('latin-1')) 
     1252            buffer.seek(0) 
     1253            return np.load(buffer) 
     1254 
     1255        logging.info('not implemented: %s, %s' % (type, cls)) 
     1256        return None 
     1257 
     1258    def generate(data, level): 
     1259        if level > 16: # recursion limit (arbitrary number) 
     1260            raise TooComplexException() 
     1261        else: 
     1262            level += 1 
     1263 
     1264        if isinstance(data, dict): 
     1265            try: 
     1266                type = data['__type__'] 
     1267            except KeyError: 
     1268                # if dictionary doesn't have __type__ then it is assumed to be just an ordinary dictionary 
     1269                o = {} 
     1270                for key, value in data.items(): 
     1271                    o[key] = generate(value, level) 
     1272                return o 
     1273 
     1274            return construct(type, data, level) 
     1275 
     1276        if isinstance(data, list): 
     1277            return [generate(item, level) for item in data] 
     1278 
     1279        return data 
     1280 
     1281    new_stored_data = {} 
     1282    for id, data in json.load(fp).items(): 
     1283        try: 
     1284            new_stored_data[id] = generate(data, 0) 
     1285        except TooComplexException: 
     1286            logging.info('unable to load %s' % id) 
     1287 
     1288    return new_stored_data 
     1289 
    11411290 
    11421291def enum(*sequential, **named): 
Note: See TracChangeset for help on using the changeset viewer.