Changeset ef3e09b in sasview


Ignore:
Timestamp:
Oct 5, 2016 4:40:11 PM (2 years ago)
Author:
krzywon
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_Invariant, ESS_GUI_Pr_fixes, ESS_GUI_batch_fitting, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_ordering, SVCC-1, SasView-664, config-error, costrafo411, py37-all, py37-sascalc, py37-sasgui, pytest, release-4.1.1, release-4.1.2, setup_clean_up, simplify-c-build, ticket-1094-headless, ticket-1111, ticket-1205-fit-weights, ticket-1218, ticket-1220, ticket-818, ticket-933, ticket885, unittest-saveload, win64bit_conda_vm
Children:
e89aed5
Parents:
a95ae9a (diff), b9c94fa (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 'master' into wx_save_simfit

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • docs/sphinx-docs/source/user/opencl_installation.rst

    r6e0c7b2 r6673d2f  
    1414 
    1515    * Go to: Start -> Control Panel -> Administrative Tools 
    16     * Double Click on Computer Managment 
     16    * Double Click on Computer Management 
    1717    * Click on Device Manager 
    1818    * Click open Display Adapters 
     
    3232Windows 
    3333========= 
    34     Depeneding on the graphic card on your system, drivers 
     34    Depending on the graphic card on your system, drivers 
    3535    can be obtained from different sources: 
    3636 
  • docs/sphinx-docs/source/user/sasgui/guiframe/data_formats_help.rst

    r49148bb r756f288  
    33.. This is a port of the original SasView html help file to ReSTructured text 
    44.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
     5.. WG Bouwman, DUT, added during CodeCamp-V in Oct 2016 the SESANS data format 
    56 
    67.. _Formats: 
     
    910============ 
    1011 
    11 SasView reads several different 1D (I(Q) vs Q) and 2D (I(Qx,Qy) vs (Qx,Qy)) 
     12SasView reads several different 1D (I(Q) vs Q), 2D SANS(I(Qx,Qy) vs (Qx,Qy)) 
     13and SESANS (P(z) vs z) 
    1214data files. But please note that SasView does not at present load data where 
    1315the Q and I(Q) data are in separate files. 
    1416 
    15 1D Formats 
    16 ---------- 
     171D Formats SANS 
     18--------------- 
    1719 
    1820SasView will read files with 2 to 4 columns of numbers in the following order:  
     
    4648.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    4749 
    48 2D Formats 
    49 ---------- 
     502D Formats SANS 
     51--------------- 
    5052 
    5153SasView will only read files in the NIST 2D format with the extensions  
     
    6062.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    6163 
    62 .. note::  This help document was last changed by Steve King, 01May2015 
     64Format SESANS 
     65--------------- 
     66 
     67The current file extension is .ses or .sesans (not case sensitive). 
     68 
     69The file format is to have a list of name-value pairs as a header at the top of the file, detailing general experimental parameters necessary for fitting and analyzing data. This list should contain all information necessary for the file to be 'portable' between users. 
     70 
     71Following that is a 6 column list of instrument experimental variables: 
     72 
     73- Spin echo length (z, in Angstroms) 
     74- Spin echo length error (:math:`\Delta` z, in Angstroms) (experimental resolution) 
     75- neutron wavelength (:math:`\lambda`, in Angstroms) (essential for ToF instruments) 
     76- neutron wavelength error (:math:`\Delta \lambda`, in Angstroms) 
     77- Normalized polarization (:math:`P/P_0`, unitless) 
     78- Normalized polarization error (:math:`\Delta(P/P_0)`, unitless) (measurement error) 
     79 
     80 
     81.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     82 
     83.. note::  This help document was last changed by Wim Bouwman, 05Oct2016 
  • docs/sphinx-docs/source/user/user.rst

    r20a3c55 rbdae317  
    77   :maxdepth: 1 
    88 
    9    SasView Model Documentation <index> 
     9   Model Documentation <index> 
     10    
     11   Menu Bar <menu_bar> 
    1012 
    1113   Analysis <analysis> 
     
    1416          
    1517   Working with SasView <working> 
    16  
    17    Computations with GPU <gpu_computations> 
  • docs/sphinx-docs/source/user/working.rst

    r3a6b10d rc43953ef  
    1616       
    1717   Tutorial <tutorial.rst> 
     18    
     19   Computations with a GPU <gpu_computations> 
     20    
  • src/sas/sasgui/guiframe/gui_manager.py

    rc8a641e8 r3fac0df  
    13451345        self._help_menu.Append(wx_id, '&Documentation', '') 
    13461346        wx.EVT_MENU(self, wx_id, self._onSphinxDocs) 
     1347        self._help_menu.AppendSeparator() 
    13471348 
    13481349        if config._do_tutorial and (IS_WIN or sys.platform == 'darwin'): 
    1349             self._help_menu.AppendSeparator() 
    13501350            wx_id = wx.NewId() 
    13511351            self._help_menu.Append(wx_id, '&Tutorial', 'Software tutorial') 
    13521352            wx.EVT_MENU(self, wx_id, self._onTutorial) 
     1353            self._help_menu.AppendSeparator() 
     1354 
    13531355 
    13541356        if config._do_acknowledge: 
    1355             self._help_menu.AppendSeparator() 
    13561357            wx_id = wx.NewId() 
    13571358            self._help_menu.Append(wx_id, '&Acknowledge', 'Acknowledging SasView') 
    13581359            wx.EVT_MENU(self, wx_id, self._onAcknowledge) 
     1360            self._help_menu.AppendSeparator() 
     1361 
    13591362 
    13601363        if config._do_aboutbox: 
     1364            logging.info("Doing help menu") 
     1365            wx_id = wx.NewId() 
     1366            self._help_menu.Append(wx_id, '&About', 'Software information') 
     1367            wx.EVT_MENU(self, wx_id, self._onAbout) 
    13611368            self._help_menu.AppendSeparator() 
    1362             self._help_menu.Append(wx.ID_ABOUT, '&About', 'Software information') 
    1363             wx.EVT_MENU(self, wx.ID_ABOUT, self._onAbout) 
     1369 
    13641370 
    13651371        # Checking for updates 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r6c382da rc65a265  
    15211521                self.fitrange = False 
    15221522 
    1523             if not self.data.is_data: 
    1524                 is_modified = True 
    1525  
    15261523            ## if any value is modify draw model with new value 
    15271524            if not self.fitrange: 
     
    15391536                self._draw_model() 
    15401537                self.Refresh() 
     1538 
     1539        logging.info("is_modified flag set to %g",is_modified) 
    15411540        return is_modified 
    15421541 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r7673ecd rca4d985  
    313313        """ 
    314314        event_id = event.GetId() 
    315         self.update_custom_combo()         
     315        self.update_custom_combo() 
    316316 
    317317    def update_custom_combo(self): 
     
    342342                                page.formfactorbox.SetLabel(current_val) 
    343343        except: 
    344             pass 
    345  
     344            logging.error("update_custom_combo: %s", sys.exc_value) 
    346345 
    347346    def set_edit_menu(self, owner): 
     
    16661665        wx.PostEvent(self.parent, StatusEvent(status=msg, type="update")) 
    16671666 
     1667    def create_theory_1D(self, x, y, page_id, model, data, state, 
     1668                         data_description, data_id, dy=None): 
     1669        """ 
     1670            Create a theory object associate with an existing Data1D 
     1671            and add it to the data manager. 
     1672            @param x: x-values of the data 
     1673            @param y: y_values of the data 
     1674            @param page_id: fit page ID 
     1675            @param model: model used for fitting 
     1676            @param data: Data1D object to create the theory for 
     1677            @param state: model state 
     1678            @param data_description: title to use in the data manager 
     1679            @param data_id: unique data ID 
     1680        """ 
     1681        new_plot = Data1D(x=x, y=y) 
     1682        if dy is None: 
     1683            new_plot.is_data = False 
     1684            new_plot.dy = numpy.zeros(len(y)) 
     1685            # If this is a theory curve, pick the proper symbol to make it a curve 
     1686            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 
     1687        else: 
     1688            new_plot.is_data = True 
     1689            new_plot.dy = dy 
     1690        new_plot.interactive = True 
     1691        new_plot.dx = None 
     1692        new_plot.dxl = None 
     1693        new_plot.dxw = None 
     1694        _yaxis, _yunit = data.get_yaxis() 
     1695        _xaxis, _xunit = data.get_xaxis() 
     1696        new_plot.title = data.name 
     1697        new_plot.group_id = data.group_id 
     1698        if new_plot.group_id == None: 
     1699            new_plot.group_id = data.group_id 
     1700        new_plot.id = data_id 
     1701        # Find if this theory was already plotted and replace that plot given 
     1702        # the same id 
     1703        self.page_finder[page_id].get_theory_data(fid=data.id) 
     1704 
     1705        if data.is_data: 
     1706            data_name = str(data.name) 
     1707        else: 
     1708            data_name = str(model.__class__.__name__) 
     1709 
     1710        new_plot.name = data_description + " [" + data_name + "]" 
     1711        new_plot.xaxis(_xaxis, _xunit) 
     1712        new_plot.yaxis(_yaxis, _yunit) 
     1713        self.page_finder[page_id].set_theory_data(data=new_plot, 
     1714                                                  fid=data.id) 
     1715        self.parent.update_theory(data_id=data.id, theory=new_plot, 
     1716                                   state=state) 
     1717        return new_plot 
     1718 
    16681719    def _complete1D(self, x, y, page_id, elapsed, index, model, 
    16691720                    weight=None, fid=None, 
    16701721                    toggle_mode_on=False, state=None, 
    16711722                    data=None, update_chisqr=True, 
    1672                     source='model', plot_result=True): 
    1673         """ 
    1674         Complete plotting 1D data 
     1723                    source='model', plot_result=True, 
     1724                    unsmeared_model=None, unsmeared_data=None, 
     1725                    unsmeared_error=None, sq_model=None, pq_model=None): 
     1726        """ 
     1727            Complete plotting 1D data 
     1728            @param unsmeared_model: fit model, without smearing 
     1729            @param unsmeared_data: data, rescaled to unsmeared model 
     1730            @param unsmeared_error: data error, rescaled to unsmeared model 
    16751731        """ 
    16761732        try: 
    16771733            numpy.nan_to_num(y) 
    1678  
    1679             new_plot = Data1D(x=x, y=y) 
    1680             new_plot.is_data = False 
    1681             new_plot.dy = numpy.zeros(len(y)) 
    1682             new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 
    1683             _yaxis, _yunit = data.get_yaxis() 
    1684             _xaxis, _xunit = data.get_xaxis() 
    1685             new_plot.title = data.name 
    1686  
    1687             new_plot.group_id = data.group_id 
    1688             if new_plot.group_id == None: 
    1689                 new_plot.group_id = data.group_id 
    1690             new_plot.id = str(page_id) + " " + data.name 
    1691             #if new_plot.id in self.color_dict: 
    1692             #    new_plot.custom_color = self.color_dict[new_plot.id] 
    1693             #find if this theory was already plotted and replace that plot given 
    1694             #the same id 
    1695             self.page_finder[page_id].get_theory_data(fid=data.id) 
    1696  
    1697             if data.is_data: 
    1698                 data_name = str(data.name) 
    1699             else: 
    1700                 data_name = str(model.__class__.__name__) 
    1701  
    1702             new_plot.name = model.name + " [" + data_name + "]" 
    1703             new_plot.xaxis(_xaxis, _xunit) 
    1704             new_plot.yaxis(_yaxis, _yunit) 
    1705             self.page_finder[page_id].set_theory_data(data=new_plot, 
    1706                                                       fid=data.id) 
    1707             self.parent.update_theory(data_id=data.id, theory=new_plot, 
    1708                                        state=state) 
     1734            new_plot = self.create_theory_1D(x, y, page_id, model, data, state, 
     1735                                             data_description=model.name, 
     1736                                             data_id=str(page_id) + " " + data.name) 
     1737            if unsmeared_model is not None: 
     1738                self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 
     1739                                      data_description=model.name + " unsmeared", 
     1740                                      data_id=str(page_id) + " " + data.name + " unsmeared") 
     1741 
     1742                self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 
     1743                                      data_description="Data unsmeared", 
     1744                                      data_id="Data  " + data.name + " unsmeared", 
     1745                                      dy=unsmeared_error) 
     1746                 
     1747            if sq_model is not None and pq_model is not None: 
     1748                self.create_theory_1D(x, sq_model, page_id, model, data, state, 
     1749                                      data_description=model.name + " S(q)", 
     1750                                      data_id=str(page_id) + " " + data.name + " S(q)") 
     1751                self.create_theory_1D(x, pq_model, page_id, model, data, state, 
     1752                                      data_description=model.name + " P(q)", 
     1753                                      data_id=str(page_id) + " " + data.name + " P(q)") 
     1754 
     1755 
    17091756            current_pg = self.fit_panel.get_page_by_id(page_id) 
    17101757            title = new_plot.title 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    re925f61 rcbbb6a4  
    4848- If necessary use underscore to separate words (i.e. barbell not BarBell or 
    4949  broad_peak not BroadPeak) 
    50 - Do not include “model” in the name (i.e. barbell not BarBellModel) 
     50- Do not include “modelâ€ᅵ in the name (i.e. barbell not BarBellModel) 
    5151 
    5252 
     
    644644- a dictionary of parameter values. This can be {} using the default 
    645645  parameters, or filled with some parameters that will be different 
    646   from the default, such as {‘radius’:10.0, ‘sld’:4}. Unlisted parameters 
     646  from the default, such as {‘radius’:10.0, ‘sld’:4}. Unlisted parameters 
    647647  will be given the default values. 
    648648- the input $q$ value or tuple of $(q_x, q_y)$ values. 
     
    664664 
    665665If you are editing your model from the SasView GUI, you can test it 
    666 by selecting *Run > Compile* from the *Model Editor* menu bar. An 
     666by selecting *Run > Check Model* from the *Model Editor* menu bar. An 
    667667*Info* box will appear with the results of the compilation and a 
    668668check that the model runs. 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    r934ce649 rca4d985  
    77import math 
    88from sas.sascalc.data_util.calcthread import CalcThread 
     9from sas.sascalc.fit.MultiplicationModel import MultiplicationModel 
    910 
    1011class Calc2D(CalcThread): 
     
    166167        index = (self.qmin <= self.data.x) & (self.data.x <= self.qmax) 
    167168 
     169        # If we use a smearer, also return the unsmeared model 
     170        unsmeared_output = None 
     171        unsmeared_data = None 
     172        unsmeared_error = None 
    168173        ##smearer the ouput of the plot 
    169174        if self.smearer is not None: 
     
    171176                                                             self.qmax) 
    172177            mask = self.data.x[first_bin:last_bin+1] 
    173             output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
    174             output = self.smearer(output, first_bin, last_bin) 
     178            unsmeared_output = numpy.zeros((len(self.data.x))) 
     179            unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
     180            output = self.smearer(unsmeared_output, first_bin, last_bin) 
     181             
     182            # Rescale data to unsmeared model 
     183            unsmeared_data = numpy.zeros((len(self.data.x))) 
     184            unsmeared_error = numpy.zeros((len(self.data.x))) 
     185            unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\ 
     186                                                    * unsmeared_output[first_bin:last_bin+1]\ 
     187                                                    / output[first_bin:last_bin+1] 
     188            unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\ 
     189                                                    * unsmeared_output[first_bin:last_bin+1]\ 
     190                                                    / output[first_bin:last_bin+1] 
     191            unsmeared_output=unsmeared_output[index] 
     192            unsmeared_data=unsmeared_data[index] 
     193            unsmeared_error=unsmeared_error 
    175194        else: 
    176195            output[index] = self.model.evalDistribution(self.data.x[index]) 
     196 
     197        sq_model = None 
     198        pq_model = None 
     199        if isinstance(self.model, MultiplicationModel): 
     200            sq_model = numpy.zeros((len(self.data.x))) 
     201            pq_model = numpy.zeros((len(self.data.x))) 
     202            sq_model[index] = self.model.s_model.evalDistribution(self.data.x[index]) 
     203            pq_model[index] = self.model.p_model.evalDistribution(self.data.x[index]) 
    177204 
    178205        elapsed = time.time() - self.starttime 
     
    187214                      data=self.data, 
    188215                      update_chisqr=self.update_chisqr, 
    189                       source=self.source) 
     216                      source=self.source, 
     217                      unsmeared_model=unsmeared_output, 
     218                      unsmeared_data=unsmeared_data, 
     219                      unsmeared_error=unsmeared_error, 
     220                      pq_model=pq_model, 
     221                      sq_model=sq_model) 
    190222 
    191223    def results(self): 
  • 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/pagestate.py

    r6c382da ra95ae9a  
    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 
     
    9601011        self.cansas = cansas 
    9611012        self.state = None 
     1013        # batch fitting params for saving 
     1014        self.batchfit_params = [] 
    9621015 
    9631016    def get_state(self): 
     
    14761529        nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 
    14771530        if len(nodes) > 1: 
    1478             raise RuntimeError, "CanSAS reader is not compatible with multiple SASdata entries" 
     1531            raise RuntimeError, "CanSAS reader is not compatible with" + \ 
     1532                                " multiple SASdata entries" 
    14791533 
    14801534        for entry in nodes: 
     
    15161570        try: 
    15171571            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  
     1572                if ext in self.ext or ext == '.xml': 
    15241573                    tree = etree.parse(path, parser=etree.ETCompatXMLParser()) 
    15251574                    # Check the format version number 
    1526                     # Specifying the namespace will take care of the file format version 
     1575                    # Specifying the namespace will take care of the file 
     1576                    # format version 
    15271577                    root = tree.getroot() 
    15281578                    entry_list = root.xpath('ns:SASentry', 
     
    15351585                        fitstate = self._parse_state(entry) 
    15361586 
    1537                         #state could be None when .svs file is loaded 
    1538                         #in this case, skip appending to output 
    1539                         if fitstate != None: 
     1587                        # state could be None when .svs file is loaded 
     1588                        # in this case, skip appending to output 
     1589                        if fitstate is not None: 
    15401590                            sas_entry.meta_data['fitstate'] = fitstate 
    15411591                            sas_entry.filename = fitstate.file 
     
    15801630                        name = original_fname 
    15811631                    state.data.group_id = name 
    1582                     #store state in fitting 
     1632                    # store state in fitting 
    15831633                    self.call_back(state=state, 
    15841634                                   datainfo=output[ind], format=ext) 
     
    15991649        """ 
    16001650        # Sanity check 
    1601         if self.cansas == True: 
     1651        if self.cansas: 
    16021652            # Add fitting information to the XML document 
    16031653            doc = self.write_toXML(datainfo, fitstate) 
     
    16111661        fd.close() 
    16121662 
    1613     def write_toXML(self, datainfo=None, state=None): 
     1663    def write_toXML(self, datainfo=None, state=None, batchfit=None): 
    16141664        """ 
    16151665        Write toXML, a helper for write(), 
     
    16191669        """ 
    16201670 
    1621         if state.data is None: 
    1622             data = sas.sascalc.dataloader.data_info.Data1D(x=[], y=[]) 
     1671        self.batchfit_params = batchfit 
     1672        if state.data is None or not state.data.is_data: 
    16231673            return None 
    1624         elif not state.data.is_data: 
    1625             return None 
     1674        # make sure title and data run are filled. 
     1675        if state.data.title is None or state.data.title == '': 
     1676            state.data.title = state.data.name 
     1677        if state.data.run_name is None or state.data.run_name == {}: 
     1678            state.data.run = [str(state.data.name)] 
     1679            state.data.run_name[0] = state.data.name 
     1680 
     1681        if issubclass(state.data.__class__, 
     1682                      sas.sascalc.dataloader.data_info.Data1D): 
     1683            data = state.data 
     1684            doc, sasentry = self._to_xml_doc(data) 
    16261685        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) 
     1686            data = state.data 
     1687            doc, sasentry = self._data2d_to_xml_doc(data) 
    16411688 
    16421689        if state is not None: 
    1643             doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry) 
     1690            doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry, 
     1691                              batch_fit_state=self.batchfit_params) 
    16441692 
    16451693        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 ra95ae9a  
    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) 
     
    750774            for id, model in self.constraint_dict.iteritems(): 
    751775                nb_fit_param += len(self.page_finder[id].get_param2fit()) 
    752             ##Don't add anymore 
     776            # Don't add anymore 
    753777            if len(self.constraints_list) == nb_fit_param: 
    754778                msg = "Cannot add another constraint. Maximum of number " 
     
    756780                wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    757781                self.sizer_constraints.Layout() 
    758                 self.sizer2.Layout() 
     782                self.constraints_sizer.Layout() 
    759783                return 
    760         if len(self.model_toFit) < 1: 
     784        if len(self.model_to_fit) < 1: 
    761785            msg = "Select at least 1 model to add constraint " 
    762786            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    763787            self.sizer_constraints.Layout() 
    764             self.sizer2.Layout() 
     788            self.constraints_sizer.Layout() 
    765789            return 
    766790 
     
    771795        model_cbox.Clear() 
    772796        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 
     797            # check if all parameters have been selected for constraint 
     798            # then do not allow add constraint on parameters 
    775799            model_cbox.Append(str(model.name), model) 
    776800        wx.EVT_COMBOBOX(model_cbox, wx.ID_ANY, self._on_select_model) 
     
    789813        # Remove button 
    790814        #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() 
     815        bt_remove = wx.Button(self, self._ids.next(), 'Remove') 
     816        bt_remove.Bind(wx.EVT_BUTTON, self.on_remove, 
     817                      id=bt_remove.GetId()) 
     818        bt_remove.SetToolTipString("Remove constraint.") 
     819        bt_remove.Hide() 
    796820 
    797821        # Hid the add button, if it exists 
     
    804828        sizer_constraint.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 
    805829        sizer_constraint.Add(constraint, flag=wx.RIGHT | wx.EXPAND, border=10) 
    806         sizer_constraint.Add(btRemove, flag=wx.RIGHT | wx.EXPAND, border=10) 
     830        sizer_constraint.Add(bt_remove, flag=wx.RIGHT | wx.EXPAND, border=10) 
    807831 
    808832        self.sizer_constraints.Insert(before=self.nb_constraint, 
     
    810834                border=5) 
    811835        c = ConstraintLine(model_cbox, param_cbox, egal_txt, 
    812                            constraint, btRemove, sizer_constraint) 
     836                           constraint, bt_remove, sizer_constraint) 
    813837        self.constraints_list.append(c) 
    814838 
    815839        self.nb_constraint += 1 
    816840        self.sizer_constraints.Layout() 
    817         self.sizer2.Layout() 
    818         self.Layout 
     841        self.constraints_sizer.Layout() 
     842        self.Layout() 
    819843 
    820844    def _hide_constraint(self): 
     
    841865        self.sizer_constraints.Clear(True) 
    842866        self.sizer_constraints.Layout() 
    843         self.sizer2.Layout() 
    844         self.Layout 
     867        self.constraints_sizer.Layout() 
     868        self.Layout() 
    845869        self.FitInside() 
    846870 
     
    852876            return 
    853877 
    854         ##This way PC/MAC both work, instead of using event.GetClientData(). 
     878        # This way PC/MAC both work, instead of using event.GetClientData(). 
    855879        model_cbox = self.constraints_list[-1].model_cbox 
    856880        n = model_cbox.GetCurrentSelection() 
     
    867891        param_cbox = self.constraints_list[-1].param_cbox 
    868892        param_cbox.Clear() 
    869         ## insert only fittable paramaters 
     893        # insert only fittable paramaters 
    870894        for param in param_list: 
    871895            param_cbox.Append(str(param), model) 
    872896        param_cbox.Show(True) 
    873897 
    874         btRemove = self.constraints_list[-1].btRemove 
    875         btRemove.Show(True) 
     898        bt_remove = self.constraints_list[-1].btRemove 
     899        bt_remove.Show(True) 
    876900        self.btAdd.Show(True) 
    877901#        self.Layout() 
     
    882906        Store the appropriate constraint in the page_finder 
    883907        """ 
    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() 
     908        # This way PC/MAC both work, instead of using event.GetClientData(). 
     909        # n = self.param_cbox.GetCurrentSelection() 
     910        # model = self.param_cbox.GetClientData(n) 
     911        # param = event.GetString() 
    888912 
    889913        if self.constraints_list: 
     
    891915            self.constraints_list[-1].constraint.Show(True) 
    892916 
    893     def _onAdd_constraint(self, event): 
     917    def _on_add_constraint(self, event): 
    894918        """ 
    895919        Add another line for constraint 
     
    899923            wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    900924            return 
    901         ## check that a constraint is added 
     925        # check that a constraint is added 
    902926        # before allow to add another constraint 
    903927        for item in self.constraints_list: 
     
    913937                model = item.param_cbox.GetClientData( 
    914938                                        item.param_cbox.GetCurrentSelection()) 
    915                 if model != None: 
     939                if model is not None: 
    916940                    msg = " Enter a constraint for %s.%s! " % (model.name, 
    917941                                        item.param_cbox.GetString(0)) 
     
    920944                wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    921945                return 
    922         ## some model or parameters can be constrained 
     946        # some model or parameters can be constrained 
    923947        self._show_constraint() 
    924948        self.FitInside() 
     
    9801004    def on_set_focus(self, event=None): 
    9811005        """ 
    982         The  derivative class is on focus if implemented 
     1006        The derivative class is on focus if implemented 
    9831007        """ 
    9841008        if self.parent is not None: 
     
    9951019        cbox.Append(name, value) 
    9961020    cbox.SetStringSelection(selected) 
     1021 
     1022 
     1023class SimFitPageState: 
     1024    """ 
     1025    State of the simultaneous fit page for saving purposes 
     1026    """ 
     1027 
     1028    def __init__(self): 
     1029        # Sim Fit Page Number 
     1030        self.fit_page_no = None 
     1031        # Select all data 
     1032        self.select_all = False 
     1033        # Data sets sent to fit page 
     1034        self.model_list = [] 
     1035        # Data sets to be fit 
     1036        self.model_to_fit = [] 
     1037        # Number of constraints 
     1038        self.no_constraint = 0 
     1039        # Dictionary of constraints 
     1040        self.constraint_dict = {} 
     1041        # List of constraints 
     1042        self.constraints_list = [] 
Note: See TracChangeset for help on using the changeset viewer.