Changes in / [5dd7499:cb823f0] in sasview


Ignore:
Location:
src/sas/sasgui/perspectives/fitting
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/fitting/fitpanel.py

    r05228b0 ra95ae9a  
    1313from sas.sasgui.guiframe.events import StatusEvent 
    1414from sas.sasgui.guiframe.dataFitting import check_data_validity 
     15from sas.sasgui.perspectives.fitting.simfitpage import SimultaneousFitPage 
    1516 
    1617import basepage 
     
    1819_BOX_WIDTH = 80 
    1920 
     21 
    2022class FitPanel(nb, PanelBase): 
    2123    """ 
     
    2628 
    2729    """ 
    28     ## Internal name for the AUI manager 
     30    # Internal name for the AUI manager 
    2931    window_name = "Fit panel" 
    30     ## Title to appear on top of the window 
     32    # Title to appear on top of the window 
    3133    window_caption = "Fit Panel " 
    3234    CENTER_PANE = True 
     
    4042                    wx.CLIP_CHILDREN) 
    4143        PanelBase.__init__(self, parent) 
    42         #self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS) 
     44        # self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS) 
    4345        self._manager = manager 
    4446        self.parent = parent 
    4547        self.event_owner = None 
    46         #dictionary of miodel {model class name, model class} 
     48        # dictionary of miodel {model class name, model class} 
    4749        self.menu_mng = models.ModelManager() 
    4850        self.model_list_box = self.menu_mng.get_model_list() 
    49         #pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING 
     51        # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING 
    5052        self.model_dictionary = self.menu_mng.get_model_dictionary() 
    5153        self.pageClosedEvent = wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE 
    5254 
    5355        self.Bind(self.pageClosedEvent, self.on_close_page) 
    54         ## save the title of the last page tab added 
     56        # save the title of the last page tab added 
    5557        self.fit_page_name = {} 
    56         ## list of existing fit page 
     58        # list of existing fit page 
    5759        self.opened_pages = {} 
    58         #index of fit page 
     60        # index of fit page 
    5961        self.fit_page_index = 0 
    60         #index of batch page 
     62        # index of batch page 
    6163        self.batch_page_index = 0 
    62         #page of simultaneous fit 
     64        # page of simultaneous fit 
    6365        self.sim_page = None 
    6466        self.batch_page = None 
    65         ## get the state of a page 
     67        # get the state of a page 
    6668        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate) 
    6769        self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo) 
     
    8082        """ 
    8183        return an xml node containing state of the panel 
    82          that guiframe can write to file 
    83         """ 
    84         msg = "" 
     84        that guiframe can write to file 
     85        """ 
     86        # Iterate through all pages and check for batch fitting 
     87        batch_state = None 
     88        if self.sim_page is not None: 
     89            batch_state = self.sim_page.set_state() 
     90 
    8591        for uid, page in self.opened_pages.iteritems(): 
    86             if page.batch_on: 
    87                 pos = self.GetPageIndex(page) 
    88                 if pos != -1 and page not in [self.sim_page, self.batch_page]: 
    89                     msg += "%s .\n" % str(self.GetPageText(pos)) 
    90             else: 
    91                 data = page.get_data() 
    92                 # state must be cloned 
    93                 state = page.get_state().clone() 
    94                 if data is not None and page.model is not None: 
    95                     new_doc = self._manager.state_reader.write_toXML(data, 
    96                                                                      state) 
    97                     if doc != None and hasattr(doc, "firstChild"): 
    98                         child = new_doc.firstChild.firstChild 
    99                         doc.firstChild.appendChild(child) 
    100                     else: 
    101                         doc = new_doc 
    102         if msg.strip() != "": 
    103             temp = "Save Project is not supported for Batch page.\n" 
    104             temp += "The following pages will not be save:\n" 
    105             message = temp + msg 
    106             wx.PostEvent(self._manager.parent, StatusEvent(status=message, 
    107                                                             info="warning")) 
     92            data = page.get_data() 
     93            # state must be cloned 
     94            state = page.get_state().clone() 
     95            if data is not None or page.model is not None: 
     96                new_doc = self._manager.state_reader.write_toXML(data, 
     97                                                                 state, 
     98                                                                 batch_state) 
     99                if doc is not None and hasattr(doc, "firstChild"): 
     100                    child = new_doc.firstChild.firstChild 
     101                    doc.firstChild.appendChild(child) 
     102                else: 
     103                    doc = new_doc 
     104 
    108105        return doc 
    109106 
     
    363360            panel.set_index_model(self.batch_page_index) 
    364361        else: 
    365             #Increment index of fit page 
     362            # Increment index of fit page 
    366363            panel = FitPage(parent=self) 
    367364            self.fit_page_index += 1 
     
    526523                    self.SetSelection(pos) 
    527524                    return page 
    528         #create new page and add data 
     525        # create new page and add data 
    529526        page = self.add_empty_page() 
    530527        pos = self.GetPageIndex(page) 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    rca4d985 re89aed5  
    593593        : param datainfo: data 
    594594        """ 
    595         #state = self.state_reader.get_state() 
    596         if state != None: 
     595        from pagestate import PageState 
     596        from simfitpage import SimFitPageState 
     597        if isinstance(state, PageState): 
    597598            state = state.clone() 
    598             # store fitting state in temp_state 
    599599            self.temp_state.append(state) 
     600        elif isinstance(state, SimFitPageState): 
     601            state.load_from_save_state(self) 
    600602        else: 
    601603            self.temp_state = [] 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    r6c382da re89aed5  
    22    Class that holds a fit page state 
    33""" 
    4 #TODO: Refactor code so we don't need to use getattr/setattr 
     4# TODO: Refactor code so we don't need to use getattr/setattr 
    55################################################################################ 
    6 #This software was developed by the University of Tennessee as part of the 
    7 #Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    8 #project funded by the US National Science Foundation. 
     6# This software was developed by the University of Tennessee as part of the 
     7# Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
     8# project funded by the US National Science Foundation. 
    99# 
    10 #See the license text in license.txt 
     10# See the license text in license.txt 
    1111# 
    12 #copyright 2009, University of Tennessee 
     12# copyright 2009, University of Tennessee 
    1313################################################################################ 
    1414import time 
     
    3030from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader 
    3131from sas.sascalc.dataloader.readers.cansas_reader import get_content, write_node 
    32 from sas.sascalc.dataloader.data_info import Data2D 
    33 from sas.sascalc.dataloader.data_info import Collimation 
    34 from sas.sascalc.dataloader.data_info import Detector 
    35 from sas.sascalc.dataloader.data_info import Process 
    36 from sas.sascalc.dataloader.data_info import Aperture 
    37 #Information to read/write state as xml 
     32from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 
     33from sas.sascalc.dataloader.data_info import Process, Aperture 
     34# Information to read/write state as xml 
    3835FITTING_NODE_NAME = 'fitting_plug_in' 
    3936CANSAS_NS = "cansas1d/1.0" 
     
    123120            try: 
    124121                return node.get(item[0]).strip() == "True" 
    125  
    126122            except: 
    127123                return None 
     
    146142        """ 
    147143        self.file = None 
    148         #Time of state creation 
     144        # Time of state creation 
    149145        self.timestamp = time.time() 
    150         ## Data member to store the dispersion object created 
     146        # Data member to store the dispersion object created 
    151147        self._disp_obj_dict = {} 
    152         #------------------------ 
    153         #Data used for fitting 
     148        # ------------------------ 
     149        # Data used for fitting 
    154150        self.data = data 
    155151        # model data 
    156152        self.theory_data = None 
    157         #Is 2D 
     153        # Is 2D 
    158154        self.is_2D = False 
    159155        self.images = None 
    160156 
    161         #save additional information on data that dataloader.reader does not read 
     157        # save additional information on data that dataloader.reader 
     158        # does not read 
    162159        self.is_data = None 
    163160        self.data_name = "" 
     
    172169            self.data_group_id = self.data.group_id 
    173170 
    174         ## reset True change the state of exsiting button 
     171        # reset True change the state of existing button 
    175172        self.reset = False 
    176173 
     
    180177        self.model = model 
    181178        self.m_name = None 
    182         #list of process done to model 
     179        # list of process done to model 
    183180        self.process = [] 
    184         #fit page manager 
     181        # fit page manager 
    185182        self.manager = None 
    186         #Store the parent of this panel parent 
     183        # Store the parent of this panel parent 
    187184        # For this application fitpanel is the parent 
    188185        self.parent = parent 
    189186        # Event_owner is the owner of model event 
    190187        self.event_owner = None 
    191         ##page name 
     188        # page name 
    192189        self.page_name = "" 
    193190        # Contains link between model, all its parameters, and panel organization 
     
    196193        self.str_parameters = [] 
    197194        # Contains list of parameters that cannot be fitted and reference to 
    198         #panel objects 
     195        # panel objects 
    199196        self.fixed_param = [] 
    200197        # Contains list of parameters with dispersity and reference to 
    201         #panel objects 
     198        # panel objects 
    202199        self.fittable_param = [] 
    203         ## orientation parameters 
     200        # orientation parameters 
    204201        self.orientation_params = [] 
    205         ## orientation parameters for gaussian dispersity 
     202        # orientation parameters for gaussian dispersity 
    206203        self.orientation_params_disp = [] 
    207         ## smearer info 
     204        # smearer info 
    208205        self.smearer = None 
    209206        self.smear_type = None 
     
    214211        self.dxl = None 
    215212        self.dxw = None 
    216         #list of dispersion parameters 
     213        # list of dispersion parameters 
    217214        self.disp_list = [] 
    218215        if self.model is not None: 
     
    223220        self.weights = {} 
    224221 
    225         #contains link between a model and selected parameters to fit 
     222        # contains link between a model and selected parameters to fit 
    226223        self.param_toFit = [] 
    227         ##dictionary of model type and model class 
     224        # dictionary of model type and model class 
    228225        self.model_list_box = None 
    229         ## save the state of the context menu 
     226        # save the state of the context menu 
    230227        self.saved_states = {} 
    231         ## save selection of combobox 
     228        # save selection of combobox 
    232229        self.formfactorcombobox = None 
    233230        self.categorycombobox = None 
    234231        self.structurecombobox = None 
    235232 
    236         ## radio box to select type of model 
    237         #self.shape_rbutton = False 
    238         #self.shape_indep_rbutton = False 
    239         #self.struct_rbutton = False 
    240         #self.plugin_rbutton = False 
    241         ## the indice of the current selection 
     233        # radio box to select type of model 
     234        # self.shape_rbutton = False 
     235        # self.shape_indep_rbutton = False 
     236        # self.struct_rbutton = False 
     237        # self.plugin_rbutton = False 
     238        # the indice of the current selection 
    242239        self.disp_box = 0 
    243         ## Qrange 
    244         ## Q range 
     240        # Qrange 
     241        # Q range 
    245242        self.qmin = 0.001 
    246243        self.qmax = 0.1 
    247         #reset data range 
     244        # reset data range 
    248245        self.qmax_x = None 
    249246        self.qmin_x = None 
     
    253250        self.multi_factor = None 
    254251        self.magnetic_on = False 
    255         ## enable smearering state 
     252        # enable smearering state 
    256253        self.enable_smearer = False 
    257254        self.disable_smearer = True 
     
    263260        self.dI_sqrdata = False 
    264261        self.dI_idata = False 
    265         ## disperity selection 
     262        # disperity selection 
    266263        self.enable_disp = False 
    267264        self.disable_disp = True 
    268265 
    269         ## state of selected all check button 
     266        # state of selected all check button 
    270267        self.cb1 = False 
    271         ## store value of chisqr 
     268        # store value of chisqr 
    272269        self.tcChi = None 
    273270 
     
    293290        obj.structurecombobox = self.structurecombobox 
    294291 
    295         #obj.shape_rbutton = self.shape_rbutton 
    296         #obj.shape_indep_rbutton = self.shape_indep_rbutton 
    297         #obj.struct_rbutton = self.struct_rbutton 
    298         #obj.plugin_rbutton = self.plugin_rbutton 
     292        # obj.shape_rbutton = self.shape_rbutton 
     293        # obj.shape_indep_rbutton = self.shape_indep_rbutton 
     294        # obj.struct_rbutton = self.struct_rbutton 
     295        # obj.plugin_rbutton = self.plugin_rbutton 
    299296 
    300297        obj.manager = self.manager 
     
    386383        rep += "data's name : %s\n" % self.data_name 
    387384        rep += "data's id : %s\n" % self.data_id 
    388         if self.model != None: 
     385        if self.model is not None: 
    389386            m_name = self.model.__class__.__name__ 
    390387            if m_name == 'Model': 
     
    397394        rep += "model type (Category) selected: %s\n" % self.categorycombobox 
    398395        rep += "data : %s\n" % str(self.data) 
    399         rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % (str(self.qmin), 
    400                                                                   str(self.qmax), str(self.npts)) 
     396        rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % \ 
     397               (str(self.qmin),str(self.qmax), str(self.npts)) 
    401398        rep += "Dispersion selection : %s\n" % str(self.disp_box) 
    402399        rep += "Smearing enable : %s\n" % str(self.enable_smearer) 
     
    414411 
    415412        rep += "2D enable : %s\n" % str(self.enable2D) 
    416         rep += "All parameters checkbox selected: %s\n" % (self.cb1) 
     413        rep += "All parameters checkbox selected: %s\n" % str(self.cb1) 
    417414        rep += "Value of Chisqr : %s\n" % str(self.tcChi) 
    418415        rep += "Smear object : %s\n" % str(self.smearer) 
    419         rep += "Smear type : %s\n" % (self.smear_type) 
     416        rep += "Smear type : %s\n" % str(self.smear_type) 
    420417        rep += "dq_l  : %s\n" % self.dq_l 
    421418        rep += "dq_r  : %s\n" % self.dq_r 
     
    434431            if not self.is_2D: 
    435432                for item in self.parameters: 
    436                     if not item in self.orientation_params: 
     433                    if item not in self.orientation_params: 
    437434                        temp_parameters.append(item) 
    438435                for item in self.fittable_param: 
    439                     if not item in self.orientation_params_disp: 
     436                    if item not in self.orientation_params_disp: 
    440437                        temp_fittable_param.append(item) 
    441438            else: 
     
    443440                temp_fittable_param = self.fittable_param 
    444441 
    445             rep += "number parameters(self.parameters): %s\n" % len(temp_parameters) 
     442            rep += "number parameters(self.parameters): %s\n" % \ 
     443                   len(temp_parameters) 
    446444            rep = self._repr_helper(list=temp_parameters, rep=rep) 
    447             rep += "number str_parameters(self.str_parameters): %s\n" % len(self.str_parameters) 
     445            rep += "number str_parameters(self.str_parameters): %s\n" % \ 
     446                   len(self.str_parameters) 
    448447            rep = self._repr_helper(list=self.str_parameters, rep=rep) 
    449             rep += "number fittable_param(self.fittable_param): %s\n" % len(temp_fittable_param) 
     448            rep += "number fittable_param(self.fittable_param): %s\n" % \ 
     449                   len(temp_fittable_param) 
    450450            rep = self._repr_helper(list=temp_fittable_param, rep=rep) 
    451451        return rep 
     
    551551                    paramval_string += CENTRE % param + "\n" 
    552552 
    553         text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % (title, file, q_name, chi2, paramval) 
     553        text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % \ 
     554                      (title, file, q_name, chi2, paramval) 
    554555 
    555556        title_name = self._check_html_format(title_name) 
     
    632633            element.appendChild(sub_element) 
    633634 
    634     def toXML(self, file="fitting_state.fitv", doc=None, entry_node=None): 
    635         """ 
    636         Writes the state of the InversionControl panel to file, as XML. 
     635    def toXML(self, file="fitting_state.fitv", doc=None, 
     636              entry_node=None, batch_fit_state=None): 
     637        """ 
     638        Writes the state of the fit panel to file, as XML. 
    637639 
    638640        Compatible with standalone writing, or appending to an 
     
    691693        element.setAttributeNode(attr) 
    692694        top_element.appendChild(element) 
     695 
    693696        # Inputs 
    694697        inputs = newdoc.createElement("Attributes") 
     
    743746            self._toXML_helper(thelist=getattr(self, item[1]), element=element, newdoc=newdoc) 
    744747            inputs.appendChild(element) 
     748 
     749        # Combined and Simultaneous Fit Parameters 
     750        if batch_fit_state is not None: 
     751            batch_combo = newdoc.createElement('simultaneous_fit') 
     752            top_element.appendChild(batch_combo) 
     753 
     754            # Simultaneous Fit Number For Linking Later 
     755            element = newdoc.createElement('sim_fit_number') 
     756            element.setAttribute('fit_number', str(batch_fit_state.fit_page_no)) 
     757            batch_combo.appendChild(element) 
     758 
     759            # Save constraints 
     760            constraints = newdoc.createElement('constraints') 
     761            batch_combo.appendChild(constraints) 
     762            for constraint in batch_fit_state.constraints_list: 
     763                # model_cbox, param_cbox, egal_txt, constraint, btRemove, sizer 
     764                doc_cons = newdoc.createElement('constraint') 
     765                doc_cons.setAttribute('model_cbox', 
     766                                      str(constraint.model_cbox.GetValue())) 
     767                doc_cons.setAttribute('param_cbox', 
     768                                      str(constraint.param_cbox.GetValue())) 
     769                doc_cons.setAttribute('egal_txt', 
     770                                      str(constraint.egal_txt.GetLabel())) 
     771                doc_cons.setAttribute('constraint', 
     772                                      str(constraint.constraint.GetValue())) 
     773                constraints.appendChild(doc_cons) 
     774 
     775            # Save all models 
     776            models = newdoc.createElement('model_list') 
     777            batch_combo.appendChild(models) 
     778            for model in batch_fit_state.model_list: 
     779                doc_model = newdoc.createElement('model_list_item') 
     780                doc_model.setAttribute('checked', str(model[0].GetValue())) 
     781                keys = model[1].keys() 
     782                doc_model.setAttribute('name', str(keys[0])) 
     783                values = model[1].get(keys[0]) 
     784                doc_model.setAttribute('fit_number', str(model[2])) 
     785                doc_model.setAttribute('fit_page_source', str(model[3])) 
     786                doc_model.setAttribute('model_name', str(values.model.id)) 
     787                models.appendChild(doc_model) 
     788 
     789            # Select All Checkbox 
     790            element = newdoc.createElement('select_all') 
     791            if batch_fit_state.select_all: 
     792                element.setAttribute('checked', 'True') 
     793            else: 
     794                element.setAttribute('checked', 'False') 
     795            batch_combo.appendChild(element) 
    745796 
    746797        # Save the file 
     
    809860        :param file: .fitv file 
    810861        :param node: node of a XML document to read from 
    811  
    812862        """ 
    813863        if file is not None: 
     
    816866            raise RuntimeError, msg 
    817867 
    818         if node.get('version')and node.get('version') == '1.0': 
     868        if node.get('version') and node.get('version') == '1.0': 
    819869 
    820870            # Get file name 
     
    9601010        self.cansas = cansas 
    9611011        self.state = None 
     1012        # batch fitting params for saving 
     1013        self.batchfit_params = [] 
    9621014 
    9631015    def get_state(self): 
     
    12191271 
    12201272        :param entry: XML node to read from 
    1221  
    12221273        :return: PageState object 
    12231274        """ 
     
    12281279            nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 
    12291280                                namespaces={'ns': CANSAS_NS}) 
    1230             if nodes != []: 
     1281            if nodes: 
    12311282                # Create an empty state 
    12321283                state = PageState() 
     
    12381289 
    12391290        return state 
     1291 
     1292    def _parse_simfit_state(self, entry): 
     1293        """ 
     1294        Parses the saved data for a simultaneous fit 
     1295        :param entry: XML object to read from 
     1296        :return: XML object for a simultaneous fit or None 
     1297        """ 
     1298        nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 
     1299                            namespaces={'ns': CANSAS_NS}) 
     1300        if nodes: 
     1301            simfitstate = nodes[0].xpath('ns:simultaneous_fit', 
     1302                                         namespaces={'ns': CANSAS_NS}) 
     1303            if simfitstate: 
     1304                from simfitpage import SimFitPageState 
     1305                sim_fit_state = SimFitPageState() 
     1306                simfitstate_0 = simfitstate[0] 
     1307                all = simfitstate_0.xpath('ns:select_all', 
     1308                                        namespaces={'ns': CANSAS_NS}) 
     1309                atts = all[0].attrib 
     1310                checked = atts.get('checked') 
     1311                sim_fit_state.select_all = bool(checked) 
     1312                model_list = simfitstate_0.xpath('ns:model_list', 
     1313                                               namespaces={'ns': CANSAS_NS}) 
     1314                model_list_items = model_list[0].xpath('ns:model_list_item', 
     1315                                                       namespaces={'ns': CANSAS_NS}) 
     1316                for model in model_list_items: 
     1317                    attrs = model.attrib 
     1318                    sim_fit_state.model_list.append(attrs) 
     1319                constraints = simfitstate_0.xpath('ns:constraints', 
     1320                                                namespaces={'ns': CANSAS_NS}) 
     1321                constraint_list = constraints[0].xpath('ns:constraint', 
     1322                                                       namespaces={'ns': CANSAS_NS}) 
     1323                for constraint in constraint_list: 
     1324                    attrs = constraint.attrib 
     1325                    sim_fit_state.constraints_list.append(attrs) 
     1326 
     1327                return sim_fit_state 
     1328            else: 
     1329                return None 
    12401330 
    12411331    def _parse_save_state_entry(self, dom): 
     
    14761566        nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 
    14771567        if len(nodes) > 1: 
    1478             raise RuntimeError, "CanSAS reader is not compatible with multiple SASdata entries" 
     1568            raise RuntimeError, "CanSAS reader is not compatible with" + \ 
     1569                                " multiple SASdata entries" 
    14791570 
    14801571        for entry in nodes: 
     
    14981589    def _read_cansas(self, path): 
    14991590        """ 
    1500         Load data and P(r) information from a CanSAS XML file. 
     1591        Load data and fitting information from a CanSAS XML file. 
    15011592 
    15021593        :param path: file path 
    1503  
    15041594        :return: Data1D object if a single SASentry was found, 
    15051595                    or a list of Data1D objects if multiple entries were found, 
    15061596                    or None of nothing was found 
    1507  
    15081597        :raise RuntimeError: when the file can't be opened 
    15091598        :raise ValueError: when the length of the data vectors are inconsistent 
    1510  
    15111599        """ 
    15121600        output = [] 
     1601        simfitstate = None 
    15131602        basename = os.path.basename(path) 
    15141603        root, extension = os.path.splitext(basename) 
     
    15161605        try: 
    15171606            if os.path.isfile(path): 
    1518  
    1519                 #TODO: eventually remove the check for .xml once 
    1520                 # the P(r) writer/reader is truly complete. 
    1521                 if  ext in self.ext or \ 
    1522                     ext == '.xml': 
    1523  
     1607                if ext in self.ext or ext == '.xml': 
    15241608                    tree = etree.parse(path, parser=etree.ETCompatXMLParser()) 
    15251609                    # Check the format version number 
    1526                     # Specifying the namespace will take care of the file format version 
     1610                    # Specifying the namespace will take care of the file 
     1611                    # format version 
    15271612                    root = tree.getroot() 
    15281613                    entry_list = root.xpath('ns:SASentry', 
     
    15341619                            raise 
    15351620                        fitstate = self._parse_state(entry) 
    1536  
    1537                         #state could be None when .svs file is loaded 
    1538                         #in this case, skip appending to output 
    1539                         if fitstate != None: 
     1621                        simfitstate = self._parse_simfit_state(entry) 
     1622 
     1623                        # state could be None when .svs file is loaded 
     1624                        # in this case, skip appending to output 
     1625                        if fitstate is not None: 
    15401626                            sas_entry.meta_data['fitstate'] = fitstate 
    15411627                            sas_entry.filename = fitstate.file 
    15421628                            output.append(sas_entry) 
     1629 
    15431630            else: 
    15441631                self.call_back(format=ext) 
     
    15801667                        name = original_fname 
    15811668                    state.data.group_id = name 
    1582                     #store state in fitting 
     1669                    # store state in fitting 
    15831670                    self.call_back(state=state, 
    15841671                                   datainfo=output[ind], format=ext) 
    15851672                    self.state = state 
     1673                if simfitstate is not None: 
     1674                    self.call_back(state=simfitstate) 
     1675 
    15861676                return output 
    15871677        except: 
     
    15991689        """ 
    16001690        # Sanity check 
    1601         if self.cansas == True: 
     1691        if self.cansas: 
    16021692            # Add fitting information to the XML document 
    16031693            doc = self.write_toXML(datainfo, fitstate) 
     
    16111701        fd.close() 
    16121702 
    1613     def write_toXML(self, datainfo=None, state=None): 
     1703    def write_toXML(self, datainfo=None, state=None, batchfit=None): 
    16141704        """ 
    16151705        Write toXML, a helper for write(), 
     
    16191709        """ 
    16201710 
    1621         if state.data is None: 
    1622             data = sas.sascalc.dataloader.data_info.Data1D(x=[], y=[]) 
     1711        self.batchfit_params = batchfit 
     1712        if state.data is None or not state.data.is_data: 
    16231713            return None 
    1624         elif not state.data.is_data: 
    1625             return None 
     1714        # make sure title and data run are filled. 
     1715        if state.data.title is None or state.data.title == '': 
     1716            state.data.title = state.data.name 
     1717        if state.data.run_name is None or state.data.run_name == {}: 
     1718            state.data.run = [str(state.data.name)] 
     1719            state.data.run_name[0] = state.data.name 
     1720 
     1721        if issubclass(state.data.__class__, 
     1722                      sas.sascalc.dataloader.data_info.Data1D): 
     1723            data = state.data 
     1724            doc, sasentry = self._to_xml_doc(data) 
    16261725        else: 
    1627             #make sure title and data run is filled up. 
    1628             if state.data.title == None or state.data.title == '': 
    1629                 state.data.title = state.data.name 
    1630             if state.data.run_name == None or state.data.run_name == {}: 
    1631                 state.data.run = [str(state.data.name)] 
    1632                 state.data.run_name[0] = state.data.name 
    1633  
    1634             if issubclass(state.data.__class__, 
    1635                           sas.sascalc.dataloader.data_info.Data1D): 
    1636                 data = state.data 
    1637                 doc, sasentry = self._to_xml_doc(data) 
    1638             else: 
    1639                 data = state.data 
    1640                 doc, sasentry = self._data2d_to_xml_doc(data) 
     1726            data = state.data 
     1727            doc, sasentry = self._data2d_to_xml_doc(data) 
    16411728 
    16421729        if state is not None: 
    1643             doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry) 
     1730            doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry, 
     1731                              batch_fit_state=self.batchfit_params) 
    16441732 
    16451733        return doc 
    1646  
    1647 # Simple html report templet 
    1648 HEADER = "<html>\n" 
    1649 HEADER += "<head>\n" 
    1650 HEADER += "<meta http-equiv=Content-Type content='text/html; " 
    1651 HEADER += "charset=windows-1252'> \n" 
    1652 HEADER += "<meta name=Generator >\n" 
    1653 HEADER += "</head>\n" 
    1654 HEADER += "<body lang=EN-US>\n" 
    1655 HEADER += "<div class=WordSection1>\n" 
    1656 HEADER += "<p class=MsoNormal><b><span ><center><font size='4' >" 
    1657 HEADER += "%s</font></center></span></center></b></p>" 
    1658 HEADER += "<p class=MsoNormal>&nbsp;</p>" 
    1659 PARA = "<p class=MsoNormal><font size='4' > %s \n" 
    1660 PARA += "</font></p>" 
    1661 CENTRE = "<p class=MsoNormal><center><font size='4' > %s \n" 
    1662 CENTRE += "</font></center></p>" 
    1663 FEET_1 = \ 
    1664 """ 
    1665 <p class=MsoNormal>&nbsp;</p> 
    1666 <br> 
    1667 <p class=MsoNormal><b><span ><center> <font size='4' > Graph 
    1668 </font></span></center></b></p> 
    1669 <p class=MsoNormal>&nbsp;</p> 
    1670 <center> 
    1671 <br><font size='4' >Model Computation</font> 
    1672 <br><font size='4' >Data: "%s"</font><br> 
    1673 """ 
    1674 FEET_2 = \ 
    1675 """ 
    1676 <img src="%s" > 
    1677 </img> 
    1678 """ 
    1679 FEET_3 = \ 
    1680 """ 
    1681 </center> 
    1682 </div> 
    1683 </body> 
    1684 </html> 
    1685 """ 
    1686 ELINE = "<p class=MsoNormal>&nbsp;</p>" 
    1687  
    1688 if __name__ == "__main__": 
    1689     state = PageState(parent=None) 
    1690     #state.toXML() 
    1691     """ 
    1692  
    1693     file = open("test_state", "w") 
    1694     pickle.dump(state, file) 
    1695     print pickle.dumps(state) 
    1696     state.data_name = "hello---->" 
    1697     pickle.dump(state, file) 
    1698     file = open("test_state", "r") 
    1699     new_state= pickle.load(file) 
    1700     print "new state", new_state 
    1701     new_state= pickle.load(file) 
    1702     print "new state", new_state 
    1703     #print "state", state 
    1704     """ 
    1705     import bsddb 
    1706     import pickle 
    1707     db = bsddb.btopen('file_state.db', 'c') 
    1708     val = (pickle.dumps(state), "hello", "hi") 
    1709     db['state1'] = pickle.dumps(val) 
    1710     print pickle.loads(db['state1']) 
    1711     state.data_name = "hello---->22" 
    1712     db['state2'] = pickle.dumps(state) 
    1713     state.data_name = "hello---->2" 
    1714     db['state3'] = pickle.dumps(state) 
    1715     del db['state3'] 
    1716     state.data_name = "hello---->3" 
    1717     db['state4'] = pickle.dumps(state) 
    1718     new_state = pickle.loads(db['state1']) 
    1719     #print db.last() 
    1720     db.set_location('state2') 
    1721     state.data_name = "hello---->5" 
    1722     db['aastate5'] = pickle.dumps(state) 
    1723     db.keys().sort() 
    1724     print pickle.loads(db['state2']) 
    1725  
    1726     db.close() 
  • src/sas/sasgui/perspectives/fitting/simfitpage.py

    r4cafdff r4fea1df  
    99from wx.lib.scrolledpanel import ScrolledPanel 
    1010 
    11 from sas.sasgui.guiframe.events import StatusEvent 
     11from sas.sasgui.guiframe.events import StatusEvent, PanelOnFocusEvent 
    1212from sas.sasgui.guiframe.panel_base import PanelBase 
    13 from sas.sasgui.guiframe.events import PanelOnFocusEvent 
    1413from sas.sasgui.guiframe.utils import IdList 
    1514from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
    1615 
    17 #Control panel width  
     16# Control panel width 
    1817if sys.platform.count("darwin") == 0: 
    1918    PANEL_WID = 420 
     
    2928        'model_cbox param_cbox egal_txt constraint btRemove sizer') 
    3029 
     30 
    3131def get_fittableParam(model): 
    3232    """ 
     
    4747    return fittable_param 
    4848 
     49 
    4950class SimultaneousFitPage(ScrolledPanel, PanelBase): 
    5051    """ 
     
    5354    two data members window_name and window_caption 
    5455    """ 
    55     ## Internal name for the AUI manager 
    56     window_name = "simultaneous Fit page" 
    57     ## Title to appear on top of the window 
     56    # Internal name for the AUI manager 
     57    window_name = "Simultaneous Fit Page" 
     58    # Title to appear on top of the window 
    5859    window_caption = "Simultaneous Fit Page" 
    5960    ID_DOC = wx.NewId() 
     
    7475        self._ids = iter(self._id_pool) 
    7576        self.SetupScrolling() 
    76         ##Font size 
     77        # Font size 
    7778        self.SetWindowVariant(variant=FONT_VARIANT) 
    7879        self.uid = wx.NewId() 
    7980        self.parent = parent 
    8081        self.batch_on = batch_on 
    81         ## store page_finder 
     82        # store page_finder 
    8283        self.page_finder = page_finder 
    83         ## list containing info to set constraint 
    84         ## look like self.constraint_dict[page_id]= page 
     84        # list containing info to set constraint 
     85        # look like self.constraint_dict[page_id]= page 
    8586        self.constraint_dict = {} 
    86         ## item list 
    87         ## self.constraints_list=[combobox1, combobox2,=,textcrtl, button ] 
     87        # item list 
     88        # self.constraints_list=[combobox1, combobox2,=,textcrtl, button ] 
    8889        self.constraints_list = [] 
    89         ## list of current model 
     90        # list of current model 
    9091        self.model_list = [] 
    91         ## selected mdoel to fit 
    92         self.model_toFit = [] 
    93         ## Control the fit state 
     92        # selected model to fit 
     93        self.model_to_fit = [] 
     94        # Control the fit state 
    9495        self.fit_started = False 
    95         ## number of constraint 
     96        # number of constraint 
    9697        self.nb_constraint = 0 
     98        self.state = SimFitPageState() 
    9799        self.model_cbox_left = None 
    98100        self.model_cbox_right = None 
    99         ## draw page 
     101        # draw page 
    100102        self.define_page_structure() 
    101103        self.draw_page() 
     
    107109        """ 
    108110        self.vbox = wx.BoxSizer(wx.VERTICAL) 
    109         self.sizer1 = wx.BoxSizer(wx.VERTICAL) 
    110         self.sizer2 = wx.BoxSizer(wx.VERTICAL) 
    111         self.sizer3 = wx.BoxSizer(wx.VERTICAL) 
    112  
    113         self.sizer1.SetMinSize((PANEL_WID, -1)) 
    114         self.sizer2.SetMinSize((PANEL_WID, -1)) 
    115         self.sizer3.SetMinSize((PANEL_WID, -1)) 
    116         self.vbox.Add(self.sizer1) 
    117         self.vbox.Add(self.sizer2) 
    118         self.vbox.Add(self.sizer3) 
     111        self.data_selection_sizer = wx.BoxSizer(wx.VERTICAL) 
     112        self.constraints_sizer = wx.BoxSizer(wx.VERTICAL) 
     113        self.run_fit_sizer = wx.BoxSizer(wx.VERTICAL) 
     114 
     115        self.data_selection_sizer.SetMinSize((PANEL_WID, -1)) 
     116        self.constraints_sizer.SetMinSize((PANEL_WID, -1)) 
     117        self.run_fit_sizer.SetMinSize((PANEL_WID, -1)) 
     118        self.vbox.Add(self.data_selection_sizer) 
     119        self.vbox.Add(self.constraints_sizer) 
     120        self.vbox.Add(self.run_fit_sizer) 
    119121        self.SetSizer(self.vbox) 
    120122        self.Centre() 
     123 
     124    def set_state(self): 
     125        """ 
     126        Define a set of state parameters for saving simultaneous fits. 
     127        """ 
     128        self._set_constraint() 
     129        self.state.fit_page_no = self.uid 
     130        self.state.select_all = self.cb1.GetValue() 
     131        self.state.model_list = self.model_list 
     132        self.state.model_to_fit = self.model_to_fit 
     133        self.state.no_constraint = self.nb_constraint 
     134        self.state.constraint_dict = self.constraint_dict 
     135        self.state.constraints_list = self.constraints_list 
     136        return self.get_state() 
     137 
     138    def get_state(self): 
     139        """ 
     140        Return the state of the current page 
     141        :return: self.state 
     142        """ 
     143        return self.state 
    121144 
    122145    def draw_page(self): 
     
    131154        # create blank list of constraints 
    132155        self.model_list = [] 
    133         self.model_toFit = [] 
     156        self.model_to_fit = [] 
    134157        self.constraints_list = [] 
    135158        self.constraint_dict = {} 
     
    144167 
    145168        #------------------------------------------------------- 
    146         ## setup sizer1 (which fitpages to include) 
    147         self.sizer1.Clear(True) 
     169        # setup sizer1 (which fitpages to include) 
     170        self.data_selection_sizer.Clear(True) 
    148171        box_description = wx.StaticBox(self, wx.ID_ANY, "Fit Combinations") 
    149172        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 
     
    151174        sizer_couples = wx.GridBagSizer(5, 5) 
    152175 
    153         #This if statement should be obsolete and can be removed in version 4 
    154         #Leave it here for now as no time to thoroughly test.  However if no 
    155         #fit page is found the menu item that calls this page is inactive  
    156         # Nov. 22 2015  --PDB 
     176        # The wx GUI has a flag to enable a menu item, but can still be 
     177        # reached via scripting. There is no guearantee future GUI 
     178        # implementations force this check, either. 
     179        # IMHO, this if statement should stay -- JRK 2016-OCT-05 
    157180        if len(self.page_finder) == 0: 
    158181            msg = " No fit combinations are found! \n\n" 
     
    161184            sizer_title.Add(wx.StaticText(self, wx.ID_ANY, msg)) 
    162185        else: 
    163             ## store model 
     186            # store model 
    164187            self._store_model() 
    165188 
     
    171194                wx.TOP | wx.BOTTOM | wx.EXPAND | wx.ADJUST_MINSIZE, border=5) 
    172195            sizer_title.Add(self.cb1, 0, 
    173                 wx.TOP | wx.BOTTOM | wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, border=5) 
    174  
    175             ## draw list of model and data names 
     196                wx.TOP | wx.BOTTOM | wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 
     197                border=5) 
     198 
     199            # draw list of model and data names 
    176200            self._fill_sizer_model_list(sizer_couples) 
    177201 
    178202        boxsizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=5) 
    179203        boxsizer1.Add(sizer_couples, 1, flag=wx.TOP | wx.BOTTOM, border=5) 
    180         self.sizer1.Add(boxsizer1, 1, wx.EXPAND | wx.ALL, 10) 
    181 #        self.sizer1.Layout() 
     204        self.data_selection_sizer.Add(boxsizer1, 1, wx.EXPAND | wx.ALL, 10) 
     205        # self.sizer1.Layout() 
    182206 
    183207        #-------------------------------------------------------- 
    184         ## set up the other 2 sizers: the constraints list and the 
    185         ## buttons (fit, help etc) sizer at the bottom of the page. 
    186         ## Note: the if statement should be removed along with the above 
    187         ## if statement as soon as it can be properly tested. 
    188         ## Nov. 22 2015  --PDB 
     208        # set up the other 2 sizers: the constraints list and the 
     209        # buttons (fit, help etc) sizer at the bottom of the page. 
     210        # Note: the if statement should be removed along with the above 
     211        # if statement as soon as it can be properly tested. 
     212        # Nov. 22 2015  --PDB 
     213        # As above, this page can be accessed through other means than the 
     214        # base SasView GUI. 
     215        # Oct. 5, 2016 --JRK 
    189216        if len(self.page_finder) > 0: 
    190             ## draw the sizer containing constraint info 
     217            # draw the sizer containing constraint info 
    191218            if not self.batch_on: 
    192219                self._fill_sizer_constraint() 
    193             ## draw fit button sizer 
     220            # draw fit button sizer 
    194221            self._fill_sizer_fit() 
    195  
    196222 
    197223    def _fill_sizer_model_list(self, sizer): 
     
    201227        ix = 0 
    202228        iy = 0 
    203         list = [] 
    204229        sizer.Clear(True) 
    205230 
     
    209234        new_name.SetForegroundColour(wx.WHITE) 
    210235        sizer.Add(new_name, (iy, ix), (1, 1), 
    211                             wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
     236                  wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
    212237        ix += 2 
    213238        model_type = wx.StaticText(self, wx.ID_ANY, '  Model ') 
     
    215240        model_type.SetForegroundColour(wx.WHITE) 
    216241        sizer.Add(model_type, (iy, ix), (1, 1), 
    217                             wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
     242                  wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    218243        ix += 1 
    219244        data_used = wx.StaticText(self, wx.ID_ANY, '  Data ') 
     
    221246        data_used.SetForegroundColour(wx.WHITE) 
    222247        sizer.Add(data_used, (iy, ix), (1, 1), 
    223                             wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
     248                  wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    224249        ix += 1 
    225250        tab_used = wx.StaticText(self, wx.ID_ANY, '  FitPage ') 
     
    302327        wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    303328 
    304         self.sizer2.Clear(True) 
     329        self.constraints_sizer.Clear(True) 
    305330        if self.batch_on: 
    306             if self.sizer2.IsShown(): 
    307                 self.sizer2.Show(False) 
     331            if self.constraints_sizer.IsShown(): 
     332                self.constraints_sizer.Show(False) 
    308333            return 
    309334        box_description = wx.StaticBox(self, wx.ID_ANY, "Fit Constraints") 
    310         boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 
     335        box_sizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 
    311336        sizer_title = wx.BoxSizer(wx.HORIZONTAL) 
    312337        self.sizer_all_constraints = wx.BoxSizer(wx.HORIZONTAL) 
     
    338363 
    339364        self.btAdd = wx.Button(self, self.ID_ADD, 'Add') 
    340         self.btAdd.Bind(wx.EVT_BUTTON, self._onAdd_constraint, 
     365        self.btAdd.Bind(wx.EVT_BUTTON, self._on_add_constraint, 
    341366                        id=self.btAdd.GetId()) 
    342367        self.btAdd.SetToolTipString("Add another constraint?") 
     
    344369 
    345370        text_hint = wx.StaticText(self, wx.ID_ANY, 
    346                                   "Example: [M0][paramter] = M1.parameter") 
     371                                  "Example: [M0][parameter] = M1.parameter") 
    347372        sizer_button.Add(text_hint, 0, 
    348373                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 10) 
     
    350375                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 10) 
    351376 
    352         boxsizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=10) 
    353         boxsizer1.Add(self.sizer_all_constraints, flag=wx.TOP | wx.BOTTOM, 
    354                       border=10) 
    355         boxsizer1.Add(self.sizer_constraints, flag=wx.TOP | wx.BOTTOM, 
    356                       border=10) 
    357         boxsizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 
    358  
    359         self.sizer2.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10) 
    360  
     377        box_sizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=10) 
     378        box_sizer1.Add(self.sizer_all_constraints, flag=wx.TOP | wx.BOTTOM, 
     379                       border=10) 
     380        box_sizer1.Add(self.sizer_constraints, flag=wx.TOP | wx.BOTTOM, 
     381                       border=10) 
     382        box_sizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 
     383 
     384        self.constraints_sizer.Add(box_sizer1, 0, wx.EXPAND | wx.ALL, 10) 
    361385 
    362386    def _fill_sizer_fit(self): 
     
    364388        Draw fit button 
    365389        """ 
    366         self.sizer3.Clear(True) 
     390        self.run_fit_sizer.Clear(True) 
    367391        box_description = wx.StaticBox(self, wx.ID_ANY, "Fit ") 
    368392        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 
    369393        sizer_button = wx.BoxSizer(wx.HORIZONTAL) 
    370394 
    371         #Fit button 
     395        # Fit button 
    372396        self.btFit = wx.Button(self, self.ID_FIT, 'Fit', size=wx.DefaultSize) 
    373         self.btFit.Bind(wx.EVT_BUTTON, self.onFit, id=self.btFit.GetId()) 
     397        self.btFit.Bind(wx.EVT_BUTTON, self.on_fit, id=self.btFit.GetId()) 
    374398        self.btFit.SetToolTipString("Perform fit.") 
    375399 
    376         #General Help button 
     400        # General Help button 
    377401        self.btHelp = wx.Button(self, wx.ID_HELP, 'HELP') 
    378402        self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 
    379         self.btHelp.Bind(wx.EVT_BUTTON, self._onHelp) 
    380  
    381         #hint text on button line 
     403        self.btHelp.Bind(wx.EVT_BUTTON, self._on_help) 
     404 
     405        # hint text on button line 
    382406        if self.batch_on: 
    383407            text = " Fit in Parallel all Data sets\n" 
     
    393417 
    394418        boxsizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 
    395         self.sizer3.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10) 
    396  
    397     def onRemove(self, event): 
     419        self.run_fit_sizer.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10) 
     420 
     421    def on_remove(self, event): 
    398422        """ 
    399423        Remove constraint fields 
     
    406430            return 
    407431        wx.CallAfter(self._remove_after, event.GetId()) 
    408         #self._onAdd_constraint(None) 
     432        # self._onAdd_constraint(None) 
    409433 
    410434    def _remove_after(self, id): 
     
    416440                self.constraints_list.remove(item) 
    417441                self.nb_constraint -= 1 
    418                 self.sizer2.Layout() 
     442                self.constraints_sizer.Layout() 
    419443                self.FitInside() 
    420444                break 
    421445 
    422     def onFit(self, event): 
     446    def on_fit(self, event): 
    423447        """ 
    424448        signal for fitting 
     
    435459            flag = (self._manager.sim_page.uid == self.uid) 
    436460 
    437         ## making sure all parameters content a constraint 
     461        # making sure all parameters content a constraint 
    438462        if not self.batch_on and self.show_constraint.GetValue(): 
    439463            if not self._set_constraint(): 
    440464                return 
    441         ## model was actually selected from this page to be fit 
    442         if len(self.model_toFit) >= 1: 
     465        # model was actually selected from this page to be fit 
     466        if len(self.model_to_fit) >= 1: 
    443467            self.manager._reset_schedule_problem(value=0) 
    444468            for item in self.model_list: 
     
    456480            msg = "Select at least one model check box to fit " 
    457481            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
     482        self.set_state() 
    458483 
    459484    def _on_fit_complete(self): 
     
    467492        """ 
    468493        Attempt to stop the fitting thread 
    469         """ 
    470         if event != None: 
     494 
     495        :param event: Event handler when stop fit is clicked 
     496        """ 
     497        if event is not None: 
    471498            event.Skip() 
    472499        self.manager.stop_fit(self.uid) 
     
    485512        self.btFit.Enable(True) 
    486513 
    487     def _onHelp(self, event): 
     514    def _on_help(self, event): 
    488515        """ 
    489516        Bring up the simultaneous Fitting Documentation whenever the HELP 
     
    494521        versions of Wx (before 2.9) and thus not the release version of 
    495522        installers, the help comes up at the top level of the file as 
    496         webbrowser does not pass anything past the # to the browser when it is 
     523        web browser does not pass anything past the # to the browser when it is 
    497524        running "file:///...." 
    498525 
    499     :param evt: Triggers on clicking the help button 
     526    :param event: Triggers on clicking the help button 
    500527    """ 
    501528        _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 
     
    510537 
    511538        :param manager: instance of plugin fitting 
    512  
    513539        """ 
    514540        self.manager = manager 
     
    518544        check all models names 
    519545        """ 
    520         self.model_toFit = [] 
    521         if self.cb1.GetValue() == True: 
     546        self.model_to_fit = [] 
     547        if self.cb1.GetValue(): 
    522548            for item in self.model_list: 
    523549                if item[0].IsEnabled(): 
    524550                    item[0].SetValue(True) 
    525                     self.model_toFit.append(item) 
    526  
    527             ## constraint info 
     551                    self.model_to_fit.append(item) 
     552 
     553            # constraint info 
    528554            self._store_model() 
    529555            if not self.batch_on: 
    530                 ## display constraint fields 
     556                # display constraint fields 
    531557                if (self.show_constraint.GetValue() and 
    532558                                 len(self.constraints_list) == 0): 
     
    538564 
    539565            if not self.batch_on: 
    540                 ##constraint info 
     566                # constraint info 
    541567                self._hide_constraint() 
    542568 
     
    544570        self.FitInside() 
    545571 
    546  
    547572    def check_model_name(self, event): 
    548573        """ 
    549574        Save information related to checkbox and their states 
    550575        """ 
    551         self.model_toFit = [] 
    552         cbox = event.GetEventObject() 
     576        self.model_to_fit = [] 
    553577        for item in self.model_list: 
    554             if item[0].GetValue() == True: 
    555                 self.model_toFit.append(item) 
     578            if item[0].GetValue(): 
     579                self.model_to_fit.append(item) 
    556580            else: 
    557                 if item in self.model_toFit: 
    558                     self.model_toFit.remove(item) 
     581                if item in self.model_to_fit: 
     582                    self.model_to_fit.remove(item) 
    559583                    self.cb1.SetValue(False) 
    560584 
    561         ## display constraint fields 
    562         if len(self.model_toFit) >= 1: 
     585        # display constraint fields 
     586        if len(self.model_to_fit) >= 1: 
    563587            self._store_model() 
    564588            if not self.batch_on and self.show_constraint.GetValue() and\ 
     
    567591                self._show_constraint() 
    568592 
    569         elif len(self.model_toFit) < 1: 
    570             ##constraint info 
     593        elif len(self.model_to_fit) < 1: 
     594            # constraint info 
    571595            self._hide_constraint() 
    572596 
    573597        self._update_easy_setup_cb() 
    574         ## set the value of the main check button 
    575         if len(self.model_list) == len(self.model_toFit): 
     598        # set the value of the main check button 
     599        if len(self.model_list) == len(self.model_to_fit): 
    576600            self.cb1.SetValue(True) 
    577601            self.FitInside() 
     
    585609        Update easy setup combobox on selecting a model 
    586610        """ 
    587         if self.model_cbox_left == None or self.model_cbox_right == None: 
    588             return 
    589  
    590         models = [(item[3].name, item[3]) for item in self.model_toFit] 
     611        if self.model_cbox_left is None or self.model_cbox_right is None: 
     612            return 
     613 
     614        models = [(item[3].name, item[3]) for item in self.model_to_fit] 
    591615        setComboBoxItems(self.model_cbox_left, models) 
    592616        setComboBoxItems(self.model_cbox_right, models) 
     
    595619        if self.model_cbox_left.GetSelection() == wx.NOT_FOUND: 
    596620            self.model_cbox_left.SetSelection(0) 
    597         self.sizer2.Layout() 
     621        self.constraints_sizer.Layout() 
    598622 
    599623    def _store_model(self): 
     
    601625         Store selected model 
    602626        """ 
    603         if len(self.model_toFit) < 1: 
    604             return 
    605         for item in self.model_toFit: 
     627        if len(self.model_to_fit) < 1: 
     628            return 
     629        for item in self.model_to_fit: 
    606630            model = item[3] 
    607631            page_id = item[2] 
     
    612636        Show fields to add constraint 
    613637        """ 
    614         if len(self.model_toFit) < 1: 
     638        if len(self.model_to_fit) < 1: 
    615639            msg = "Select at least 1 model to add constraint " 
    616640            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    617             ## hide button 
     641            # hide button 
    618642            self._hide_constraint() 
    619643            return 
     
    632656        """ 
    633657        box_description = wx.StaticBox(self, wx.ID_ANY, "Easy Setup ") 
    634         boxsizer = wx.StaticBoxSizer(box_description, wx.HORIZONTAL) 
     658        box_sizer = wx.StaticBoxSizer(box_description, wx.HORIZONTAL) 
    635659        sizer_constraint = wx.BoxSizer(wx.HORIZONTAL) 
    636660        self.model_cbox_left = wx.ComboBox(self, wx.ID_ANY, style=wx.CB_READONLY) 
     
    650674 
    651675        for id, model in self.constraint_dict.iteritems(): 
    652             ## check if all parameters have been selected for constraint 
    653             ## then do not allow add constraint on parameters 
     676            # check if all parameters have been selected for constraint 
     677            # then do not allow add constraint on parameters 
    654678            self.model_cbox_left.Append(str(model.name), model) 
    655679        self.model_cbox_left.Select(0) 
    656680        for id, model in self.constraint_dict.iteritems(): 
    657             ## check if all parameters have been selected for constraint 
    658             ## then do not allow add constraint on parameters 
     681            # check if all parameters have been selected for constraint 
     682            # then do not allow add constraint on parameters 
    659683            self.model_cbox_right.Append(str(model.name), model) 
    660         boxsizer.Add(self.model_cbox_left, 
     684        box_sizer.Add(self.model_cbox_left, 
    661685                             flag=wx.RIGHT | wx.EXPAND, border=10) 
    662         #boxsizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 
     686        # box_sizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 
    663687        #                     flag=wx.RIGHT | wx.EXPAND, border=5) 
    664         boxsizer.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 
    665         boxsizer.Add(self.model_cbox_right, 
     688        box_sizer.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 
     689        box_sizer.Add(self.model_cbox_right, 
    666690                             flag=wx.RIGHT | wx.EXPAND, border=10) 
    667         #boxsizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 
     691        # box_sizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 
    668692        #                     flag=wx.RIGHT | wx.EXPAND, border=5) 
    669         boxsizer.Add((20, -1)) 
    670         boxsizer.Add(self.set_button, flag=wx.RIGHT | wx.EXPAND, border=5) 
    671         sizer_constraint.Add(boxsizer, flag=wx.RIGHT | wx.EXPAND, border=5) 
     693        box_sizer.Add((20, -1)) 
     694        box_sizer.Add(self.set_button, flag=wx.RIGHT | wx.EXPAND, border=5) 
     695        sizer_constraint.Add(box_sizer, flag=wx.RIGHT | wx.EXPAND, border=5) 
    672696        self.sizer_all_constraints.Insert(before=0, 
    673697                             item=sizer_constraint, 
     
    699723            return 
    700724        param_list = [] 
    701         param_listB = [] 
     725        param_list_b = [] 
    702726        selection = self.model_cbox_left.GetCurrentSelection() 
    703727        model_left = self.model_cbox_left.GetValue() 
    704728        model = self.model_cbox_left.GetClientData(selection) 
    705         selectionB = self.model_cbox_right.GetCurrentSelection() 
     729        selection_b = self.model_cbox_right.GetCurrentSelection() 
    706730        model_right = self.model_cbox_right.GetValue() 
    707         modelB = self.model_cbox_right.GetClientData(selectionB) 
     731        model_b = self.model_cbox_right.GetClientData(selection_b) 
    708732        for id, dic_model in self.constraint_dict.iteritems(): 
    709733            if model == dic_model: 
    710734                param_list = self.page_finder[id].get_param2fit() 
    711             if modelB == dic_model: 
    712                 param_listB = self.page_finder[id].get_param2fit() 
    713             if len(param_list) > 0 and len(param_listB) > 0: 
     735            if model_b == dic_model: 
     736                param_list_b = self.page_finder[id].get_param2fit() 
     737            if len(param_list) > 0 and len(param_list_b) > 0: 
    714738                break 
    715739        num_cbox = 0 
     
    717741        for param in param_list: 
    718742            num_cbox += 1 
    719             if param in param_listB: 
     743            if param in param_list_b: 
    720744                item = self.constraints_list[-1] 
    721745                item.model_cbox.SetStringSelection(model_left) 
     
    744768        """ 
    745769        Show constraint fields 
     770        :param dict: dictionary mapping constraint values 
    746771        """ 
    747772        self.btAdd.Show(True) 
     
    750775            for id, model in self.constraint_dict.iteritems(): 
    751776                nb_fit_param += len(self.page_finder[id].get_param2fit()) 
    752             ##Don't add anymore 
     777            # Don't add anymore 
    753778            if len(self.constraints_list) == nb_fit_param: 
    754779                msg = "Cannot add another constraint. Maximum of number " 
     
    756781                wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    757782                self.sizer_constraints.Layout() 
    758                 self.sizer2.Layout() 
     783                self.constraints_sizer.Layout() 
    759784                return 
    760         if len(self.model_toFit) < 1: 
     785        if len(self.model_to_fit) < 1: 
    761786            msg = "Select at least 1 model to add constraint " 
    762787            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    763788            self.sizer_constraints.Layout() 
    764             self.sizer2.Layout() 
     789            self.constraints_sizer.Layout() 
    765790            return 
    766791 
     
    771796        model_cbox.Clear() 
    772797        for id, model in self.constraint_dict.iteritems(): 
    773             ## check if all parameters have been selected for constraint 
    774             ## then do not allow add constraint on parameters 
     798            # check if all parameters have been selected for constraint 
     799            # then do not allow add constraint on parameters 
    775800            model_cbox.Append(str(model.name), model) 
    776801        wx.EVT_COMBOBOX(model_cbox, wx.ID_ANY, self._on_select_model) 
     
    789814        # Remove button 
    790815        #btRemove = wx.Button(self, self.ID_REMOVE, 'Remove') 
    791         btRemove = wx.Button(self, self._ids.next(), 'Remove') 
    792         btRemove.Bind(wx.EVT_BUTTON, self.onRemove, 
    793                       id=btRemove.GetId()) 
    794         btRemove.SetToolTipString("Remove constraint.") 
    795         btRemove.Hide() 
     816        bt_remove = wx.Button(self, self._ids.next(), 'Remove') 
     817        bt_remove.Bind(wx.EVT_BUTTON, self.on_remove, 
     818                      id=bt_remove.GetId()) 
     819        bt_remove.SetToolTipString("Remove constraint.") 
     820        bt_remove.Hide() 
    796821 
    797822        # Hid the add button, if it exists 
     
    804829        sizer_constraint.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 
    805830        sizer_constraint.Add(constraint, flag=wx.RIGHT | wx.EXPAND, border=10) 
    806         sizer_constraint.Add(btRemove, flag=wx.RIGHT | wx.EXPAND, border=10) 
     831        sizer_constraint.Add(bt_remove, flag=wx.RIGHT | wx.EXPAND, border=10) 
    807832 
    808833        self.sizer_constraints.Insert(before=self.nb_constraint, 
     
    810835                border=5) 
    811836        c = ConstraintLine(model_cbox, param_cbox, egal_txt, 
    812                            constraint, btRemove, sizer_constraint) 
     837                           constraint, bt_remove, sizer_constraint) 
    813838        self.constraints_list.append(c) 
    814839 
    815840        self.nb_constraint += 1 
    816841        self.sizer_constraints.Layout() 
    817         self.sizer2.Layout() 
    818         self.Layout 
     842        self.constraints_sizer.Layout() 
     843        self.Layout() 
    819844 
    820845    def _hide_constraint(self): 
     
    841866        self.sizer_constraints.Clear(True) 
    842867        self.sizer_constraints.Layout() 
    843         self.sizer2.Layout() 
    844         self.Layout 
     868        self.constraints_sizer.Layout() 
     869        self.Layout() 
    845870        self.FitInside() 
    846871 
    847872    def _on_select_model(self, event): 
    848873        """ 
    849         fill combox box with list of parameters 
     874        fill combo box with list of parameters 
    850875        """ 
    851876        if not self.constraints_list: 
    852877            return 
    853878 
    854         ##This way PC/MAC both work, instead of using event.GetClientData(). 
     879        # This way PC/MAC both work, instead of using event.GetClientData(). 
    855880        model_cbox = self.constraints_list[-1].model_cbox 
    856881        n = model_cbox.GetCurrentSelection() 
     
    867892        param_cbox = self.constraints_list[-1].param_cbox 
    868893        param_cbox.Clear() 
    869         ## insert only fittable paramaters 
     894        # insert only fittable paramaters 
    870895        for param in param_list: 
    871896            param_cbox.Append(str(param), model) 
    872897        param_cbox.Show(True) 
    873898 
    874         btRemove = self.constraints_list[-1].btRemove 
    875         btRemove.Show(True) 
     899        bt_remove = self.constraints_list[-1].btRemove 
     900        bt_remove.Show(True) 
    876901        self.btAdd.Show(True) 
    877902#        self.Layout() 
     
    882907        Store the appropriate constraint in the page_finder 
    883908        """ 
    884         ##This way PC/MAC both work, instead of using event.GetClientData(). 
    885         #n = self.param_cbox.GetCurrentSelection() 
    886         #model = self.param_cbox.GetClientData(n) 
    887         #param = event.GetString() 
     909        # This way PC/MAC both work, instead of using event.GetClientData(). 
     910        # n = self.param_cbox.GetCurrentSelection() 
     911        # model = self.param_cbox.GetClientData(n) 
     912        # param = event.GetString() 
    888913 
    889914        if self.constraints_list: 
     
    891916            self.constraints_list[-1].constraint.Show(True) 
    892917 
    893     def _onAdd_constraint(self, event): 
     918    def _on_add_constraint(self, event): 
    894919        """ 
    895920        Add another line for constraint 
     
    899924            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    900925            return 
    901         ## check that a constraint is added 
     926        # check that a constraint is added 
    902927        # before allow to add another constraint 
    903928        for item in self.constraints_list: 
     
    913938                model = item.param_cbox.GetClientData( 
    914939                                        item.param_cbox.GetCurrentSelection()) 
    915                 if model != None: 
     940                if model is not None: 
    916941                    msg = " Enter a constraint for %s.%s! " % (model.name, 
    917942                                        item.param_cbox.GetString(0)) 
     
    920945                wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    921946                return 
    922         ## some model or parameters can be constrained 
     947        # some model or parameters can be constrained 
    923948        self._show_constraint() 
    924949        self.FitInside() 
     
    9801005    def on_set_focus(self, event=None): 
    9811006        """ 
    982         The  derivative class is on focus if implemented 
     1007        The derivative class is on focus if implemented 
    9831008        """ 
    9841009        if self.parent is not None: 
     
    9951020        cbox.Append(name, value) 
    9961021    cbox.SetStringSelection(selected) 
     1022 
     1023 
     1024class SimFitPageState: 
     1025    """ 
     1026    State of the simultaneous fit page for saving purposes 
     1027    """ 
     1028 
     1029    def __init__(self): 
     1030        # Sim Fit Page Number 
     1031        self.fit_page_no = None 
     1032        # Select all data 
     1033        self.select_all = False 
     1034        # Data sets sent to fit page 
     1035        self.model_list = [] 
     1036        # Data sets to be fit 
     1037        self.model_to_fit = [] 
     1038        # Number of constraints 
     1039        self.no_constraint = 0 
     1040        # Dictionary of constraints 
     1041        self.constraint_dict = {} 
     1042        # List of constraints 
     1043        self.constraints_list = [] 
     1044 
     1045    def load_from_save_state(self, fit): 
     1046        """ 
     1047        Load in a simultaneous/constrained fit from a save state 
     1048        :param fit: Fitpanel object 
     1049        :return: None 
     1050        """ 
     1051 
     1052        # FIXME: Not tracking data set name on loading ==> NECESSARY! 
     1053        model_map = {} 
     1054        if fit.fit_panel.sim_page is None: 
     1055            fit.fit_panel.add_sim_page() 
     1056        sim_page = fit.fit_panel.sim_page 
     1057 
     1058        # Process each model and associate old M# with new M# 
     1059        i = 0 
     1060        for model in sim_page.model_list: 
     1061            model_id = self._format_id(model[1].keys()[0]) 
     1062            for saved_model in self.model_list: 
     1063                save_id = saved_model.pop('name') 
     1064                saved_model['name'] = save_id 
     1065                save_id = self._format_id(save_id) 
     1066                if save_id == model_id: 
     1067                    model_map[saved_model.pop('fit_page_source')] = \ 
     1068                        model[3].name 
     1069                    check = bool(saved_model.pop('checked')) 
     1070                    sim_page.model_list[i][0].SetValue(check) 
     1071                    continue 
     1072            i += 1 
     1073        sim_page.check_model_name(None) 
     1074 
     1075        if len(self.constraints_list) > 0: 
     1076            sim_page.hide_constraint.SetValue(False) 
     1077            sim_page.show_constraint.SetValue(True) 
     1078            sim_page._display_constraint(None) 
     1079 
     1080        for index, item in enumerate(self.constraints_list): 
     1081            model_cbox = item.pop('model_cbox') 
     1082            constraint_value = item.pop('constraint') 
     1083            param = item.pop('param_cbox') 
     1084            equality = item.pop('egal_txt') 
     1085            for key, value in model_map.iteritems(): 
     1086                model_cbox.replace(key, value) 
     1087                constraint_value.replace(key, value) 
     1088 
     1089            sim_page.constraints_list[index][0].SetValue(model_cbox) 
     1090            sim_page._on_select_model(None) 
     1091            sim_page.constraints_list[index][1].SetValue(param) 
     1092            sim_page.constraints_list[index][2].SetLabel(equality) 
     1093            sim_page.constraints_list[index][3].SetValue(constraint_value) 
     1094            sim_page._on_add_constraint(None) 
     1095 
     1096    def _format_id(self, original_id): 
     1097        original_id = original_id.rstrip('1234567890.') 
     1098        new_id_list = original_id.split() 
     1099        new_id = ' '.join(new_id_list) 
     1100        return new_id 
Note: See TracChangeset for help on using the changeset viewer.