Changeset 6fab3a0 in sasview for src/sas/sasgui/perspectives/fitting


Ignore:
Timestamp:
Aug 17, 2017 10:15:23 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
e32c98a
Parents:
14ecc24e (diff), a06ee7e (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 ticket-597

Location:
src/sas/sasgui/perspectives/fitting
Files:
3 added
5 edited

Legend:

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

    ra1b8fee r914c49d5  
    254254        if not hasattr(self, "model_view"): 
    255255            return 
    256         toggle_mode_on = self.model_view.IsEnabled() 
     256        toggle_mode_on = self.model_view.IsEnabled() or self.data is None 
    257257        if toggle_mode_on: 
    258258            if self.enable2D and not check_data_validity(self.data): 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    ra1b8fee r489f53a  
    257257        toks = os.path.splitext(label) 
    258258        path = os.path.join(models.find_plugins_dir(), toks[0]) 
     259        message = "Are you sure you want to delete the file {}?".format(path) 
     260        dlg = wx.MessageDialog(self.frame, message, '', wx.YES_NO | wx.ICON_QUESTION) 
     261        if not dlg.ShowModal() == wx.ID_YES: 
     262            return 
    259263        try: 
    260264            for ext in ['.py', '.pyc']: 
    261265                p_path = path + ext 
     266                if ext == '.pyc' and not os.path.isfile(path + ext): 
     267                    # If model is invalid, .pyc file may not exist as model has 
     268                    # never been compiled. Don't try and delete it 
     269                    continue 
    262270                os.remove(p_path) 
    263271            self.update_custom_combo() 
     
    361369                                   'Add a new model function') 
    362370        wx.EVT_MENU(owner, wx_id, self.make_new_model) 
    363          
     371 
    364372        wx_id = wx.NewId() 
    365373        self.edit_model_menu.Append(wx_id, 'Sum|Multi(p1, p2)', 
     
    383391          '(Re)Load all models present in user plugin_models folder') 
    384392        wx.EVT_MENU(owner, wx_id, self.load_plugin_models) 
    385                  
     393 
    386394    def set_edit_menu_helper(self, owner=None, menu=None): 
    387395        """ 
     
    17341742            @param unsmeared_error: data error, rescaled to unsmeared model 
    17351743        """ 
    1736         try: 
    1737             np.nan_to_num(y) 
    1738             new_plot = self.create_theory_1D(x, y, page_id, model, data, state, 
    1739                                              data_description=model.name, 
    1740                                              data_id=str(page_id) + " " + data.name) 
    1741             if unsmeared_model is not None: 
    1742                 self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 
    1743                                       data_description=model.name + " unsmeared", 
    1744                                       data_id=str(page_id) + " " + data.name + " unsmeared") 
    1745  
    1746                 if unsmeared_data is not None and unsmeared_error is not None: 
    1747                     self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 
    1748                                           data_description="Data unsmeared", 
    1749                                           data_id="Data  " + data.name + " unsmeared", 
    1750                                           dy=unsmeared_error) 
    1751             # Comment this out until we can get P*S models with correctly populated parameters 
    1752             #if sq_model is not None and pq_model is not None: 
    1753             #    self.create_theory_1D(x, sq_model, page_id, model, data, state, 
    1754             #                          data_description=model.name + " S(q)", 
    1755             #                          data_id=str(page_id) + " " + data.name + " S(q)") 
    1756             #    self.create_theory_1D(x, pq_model, page_id, model, data, state, 
    1757             #                          data_description=model.name + " P(q)", 
    1758             #                          data_id=str(page_id) + " " + data.name + " P(q)") 
    1759  
    1760             current_pg = self.fit_panel.get_page_by_id(page_id) 
    1761             title = new_plot.title 
    1762             batch_on = self.fit_panel.get_page_by_id(page_id).batch_on 
    1763             if not batch_on: 
    1764                 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 
    1765                                             title=str(title))) 
    1766             elif plot_result: 
    1767                 top_data_id = self.fit_panel.get_page_by_id(page_id).data.id 
    1768                 if data.id == top_data_id: 
    1769                     wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 
    1770                                             title=str(title))) 
    1771             caption = current_pg.window_caption 
    1772             self.page_finder[page_id].set_fit_tab_caption(caption=caption) 
    1773  
    1774             self.page_finder[page_id].set_theory_data(data=new_plot, 
     1744 
     1745        number_finite = np.count_nonzero(np.isfinite(y)) 
     1746        np.nan_to_num(y) 
     1747        new_plot = self.create_theory_1D(x, y, page_id, model, data, state, 
     1748                                         data_description=model.name, 
     1749                                         data_id=str(page_id) + " " + data.name) 
     1750        if unsmeared_model is not None: 
     1751            self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 
     1752                                  data_description=model.name + " unsmeared", 
     1753                                  data_id=str(page_id) + " " + data.name + " unsmeared") 
     1754 
     1755            if unsmeared_data is not None and unsmeared_error is not None: 
     1756                self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 
     1757                                      data_description="Data unsmeared", 
     1758                                      data_id="Data  " + data.name + " unsmeared", 
     1759                                      dy=unsmeared_error) 
     1760        # Comment this out until we can get P*S models with correctly populated parameters 
     1761        #if sq_model is not None and pq_model is not None: 
     1762        #    self.create_theory_1D(x, sq_model, page_id, model, data, state, 
     1763        #                          data_description=model.name + " S(q)", 
     1764        #                          data_id=str(page_id) + " " + data.name + " S(q)") 
     1765        #    self.create_theory_1D(x, pq_model, page_id, model, data, state, 
     1766        #                          data_description=model.name + " P(q)", 
     1767        #                          data_id=str(page_id) + " " + data.name + " P(q)") 
     1768 
     1769        current_pg = self.fit_panel.get_page_by_id(page_id) 
     1770        title = new_plot.title 
     1771        batch_on = self.fit_panel.get_page_by_id(page_id).batch_on 
     1772        if not batch_on: 
     1773            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=str(title))) 
     1774        elif plot_result: 
     1775            top_data_id = self.fit_panel.get_page_by_id(page_id).data.id 
     1776            if data.id == top_data_id: 
     1777                wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=str(title))) 
     1778        caption = current_pg.window_caption 
     1779        self.page_finder[page_id].set_fit_tab_caption(caption=caption) 
     1780 
     1781        self.page_finder[page_id].set_theory_data(data=new_plot, 
    17751782                                                      fid=data.id) 
    1776             if toggle_mode_on: 
    1777                 wx.PostEvent(self.parent, 
    1778                              NewPlotEvent(group_id=str(page_id) + " Model2D", 
     1783        if toggle_mode_on: 
     1784            wx.PostEvent(self.parent, 
     1785                         NewPlotEvent(group_id=str(page_id) + " Model2D", 
    17791786                                          action="Hide")) 
    1780             else: 
    1781                 if update_chisqr: 
    1782                     wx.PostEvent(current_pg, 
    1783                                  Chi2UpdateEvent(output=self._cal_chisqr( 
     1787        else: 
     1788            if update_chisqr: 
     1789                wx.PostEvent(current_pg, 
     1790                             Chi2UpdateEvent(output=self._cal_chisqr( 
    17841791                                                                data=data, 
    17851792                                                                fid=fid, 
    17861793                                                                weight=weight, 
    1787                                                             page_id=page_id, 
    1788                                                             index=index))) 
    1789                 else: 
    1790                     self._plot_residuals(page_id=page_id, data=data, fid=fid, 
    1791                                          index=index, weight=weight) 
    1792  
     1794                                                                page_id=page_id, 
     1795                                                                index=index))) 
     1796            else: 
     1797                self._plot_residuals(page_id=page_id, data=data, fid=fid, 
     1798                                     index=index, weight=weight) 
     1799 
     1800        if not number_finite: 
     1801            logger.error("Using the present parameters the model does not return any finite value. ") 
     1802            msg = "Computing Error: Model did not return any finite value." 
     1803            wx.PostEvent(self.parent, StatusEvent(status = msg, info="error")) 
     1804        else: 
    17931805            msg = "Computation  completed!" 
     1806            if number_finite != y.size: 
     1807                msg += ' PROBLEM: For some Q values the model returns non finite intensities!' 
     1808                logger.error("For some Q values the model returns non finite intensities.") 
    17941809            wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop")) 
    1795         except: 
    1796             raise 
    17971810 
    17981811    def _calc_exception(self, etype, value, tb): 
     
    18191832        that can be plot. 
    18201833        """ 
     1834        number_finite = np.count_nonzero(np.isfinite(image)) 
    18211835        np.nan_to_num(image) 
    18221836        new_plot = Data2D(image=image, err_image=data.err_data) 
     
    18771891                self._plot_residuals(page_id=page_id, data=data, fid=fid, 
    18781892                                      index=index, weight=weight) 
    1879         msg = "Computation  completed!" 
    1880         wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop")) 
     1893 
     1894        if not number_finite: 
     1895            logger.error("Using the present parameters the model does not return any finite value. ") 
     1896            msg = "Computing Error: Model did not return any finite value." 
     1897            wx.PostEvent(self.parent, StatusEvent(status = msg, info="error")) 
     1898        else: 
     1899            msg = "Computation  completed!" 
     1900            if number_finite != image.size: 
     1901                msg += ' PROBLEM: For some Qx,Qy values the model returns non finite intensities!' 
     1902                logger.error("For some Qx,Qy values the model returns non finite intensities.") 
     1903            wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop")) 
    18811904 
    18821905    def _draw_model2D(self, model, page_id, qmin, 
     
    19121935                ## and may be the cause of other noted instabilities 
    19131936                ## 
    1914                 ##    -PDB August 12, 2014  
     1937                ##    -PDB August 12, 2014 
    19151938                while self.calc_2D.isrunning(): 
    19161939                    time.sleep(0.1) 
     
    19541977            if (self.calc_1D is not None) and self.calc_1D.isrunning(): 
    19551978                self.calc_1D.stop() 
    1956                 ## stop just raises the flag -- the thread is supposed to  
     1979                ## stop just raises the flag -- the thread is supposed to 
    19571980                ## then kill itself but cannot.  Paul Kienzle came up with 
    19581981                ## this fix to prevent threads from stepping on each other 
     
    19661989                ## a request to stop the computation. 
    19671990                ## It seems thus that the whole thread approach used here 
    1968                 ## May need rethinking   
     1991                ## May need rethinking 
    19691992                ## 
    19701993                ##    -PDB August 12, 2014 
     
    21312154            residuals.dxw = None 
    21322155            residuals.ytransform = 'y' 
    2133             # For latter scale changes  
     2156            # For latter scale changes 
    21342157            residuals.xaxis('\\rm{Q} ', 'A^{-1}') 
    21352158            residuals.yaxis('\\rm{Residuals} ', 'normalized') 
  • src/sas/sasgui/perspectives/fitting/models.py

    ra1b8fee rb1c2011  
    156156    try: 
    157157        import compileall 
    158         compileall.compile_dir(dir=dir, ddir=dir, force=1, 
     158        compileall.compile_dir(dir=dir, ddir=dir, force=0, 
    159159                               quiet=report_problem) 
    160160    except: 
     
    163163 
    164164 
    165 def _findModels(dir): 
     165def _find_models(): 
    166166    """ 
    167167    Find custom models 
    168168    """ 
    169169    # List of plugin objects 
    170     dir = find_plugins_dir() 
     170    directory = find_plugins_dir() 
    171171    # Go through files in plug-in directory 
    172     if not os.path.isdir(dir): 
    173         msg = "SasView couldn't locate Model plugin folder %r." % dir 
     172    if not os.path.isdir(directory): 
     173        msg = "SasView couldn't locate Model plugin folder %r." % directory 
    174174        logger.warning(msg) 
    175175        return {} 
    176176 
    177     plugin_log("looking for models in: %s" % str(dir)) 
    178     #compile_file(dir)  #always recompile the folder plugin 
    179     logger.info("plugin model dir: %s" % str(dir)) 
     177    plugin_log("looking for models in: %s" % str(directory)) 
     178    # compile_file(directory)  #always recompile the folder plugin 
     179    logger.info("plugin model dir: %s" % str(directory)) 
    180180 
    181181    plugins = {} 
    182     for filename in os.listdir(dir): 
     182    for filename in os.listdir(directory): 
    183183        name, ext = os.path.splitext(filename) 
    184184        if ext == '.py' and not name == '__init__': 
    185             path = os.path.abspath(os.path.join(dir, filename)) 
     185            path = os.path.abspath(os.path.join(directory, filename)) 
    186186            try: 
    187187                model = load_custom_model(path) 
    188                 model.name = PLUGIN_NAME_BASE + model.name 
     188                if not model.name.count(PLUGIN_NAME_BASE): 
     189                    model.name = PLUGIN_NAME_BASE + model.name 
    189190                plugins[model.name] = model 
    190191            except Exception: 
     
    193194                plugin_log(msg) 
    194195                logger.warning("Failed to load plugin %r. See %s for details" 
    195                                 % (path, PLUGIN_LOG)) 
    196              
     196                               % (path, PLUGIN_LOG)) 
     197 
    197198    return plugins 
    198199 
     
    264265        temp = {} 
    265266        if self.is_changed(): 
    266             return  _findModels(dir) 
     267            return  _find_models() 
    267268        logger.info("plugin model : %s" % str(temp)) 
    268269        return temp 
     
    297298        for name, plug in self.stored_plugins.iteritems(): 
    298299            self.model_dictionary[name] = plug 
    299          
     300 
    300301        self._get_multifunc_models() 
    301302 
     
    339340        """ 
    340341        self.plugins = [] 
    341         new_plugins = _findModels(dir) 
     342        new_plugins = _find_models() 
    342343        for name, plug in  new_plugins.iteritems(): 
    343344            for stored_name, stored_plug in self.stored_plugins.iteritems(): 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r5295cf5 r9d93c37  
    636636 
    637637     Example: radius [2 : 5] , radius [10 : 25] 
    638  
    639 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    640  
    641 .. note::  This help document was last changed by Steve King, 10Oct2016 
     638      
     639.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     640 
     641Combined Batch Fit Mode 
     642----------------------- 
     643 
     644Batch mode does not allow for multiple models.  In other words in batch mode 
     645all the data sets must be fit with single model and set of parameter.  At times 
     646there may be a shape change occuring in the series that requires changing the 
     647model part way through the series.  In this case set up two batch fit pages 
     648following the instructions in :ref:`Batch Fit Mode`.  However *be careful!* each 
     649time a batch fit panel runs fit it will overwrite the table of values. 
     650 
     651However there may be occassion when one wants to run these two (or more) batch 
     652fits and then plot one of the common parameters (e.g. radius of shere and 
     653eventually cylinder).  In this case the Combined Batch Fit can be used. 
     654Similarly to the Simultaneous Fit page a new page will appear.  In this case, 
     655instead of a check box for each fitpage model there will be a check box for each 
     656batchpage.  Clicking the Fit button will run each batch fit *in sequence*.  
     657 
     658.. image:: combine_batch_page.png 
     659 
     660The batch table will then pop up at the end as before with the following 
     661caveats: 
     662 
     663.. note:: 
     664   The order matters.  The parameters in the table will be taken from the model 
     665   used in the first batch page of the list.  Any parameters from the 
     666   second and on batch pages that have the same name as a parameter in the first 
     667   will show up allowing for plotting of that parameter across the models. 
     668.. note:: 
     669   a corralary of the above is that currently models created as a sum|multiply 
     670   model will not work as desired because the generated model parameters have a 
     671   p#_ appended to the beginning and thus radius and p1_radius will not be 
     672   recognized as the same parameter. 
     673    
     674.. image:: combine_batch_grid.png 
     675 
     676In this case the series is a time series.  Unfortunately the time is not listed 
     677in the file but the file name contains the information.  A column can be added 
     678manually, in this case called time.  Clicking on the top of a column will select 
     679it. Clicking next on the Add button next to the x or y row will add the cell 
     680information to use in a plot.  The axis labels will be automatically populated 
     681from the top row information.  Units can be specified as well using text and a 
     682subset of in line Latex.  Once this is set up, in this case using the peak 
     683position from the two different models for the y axis and time on the x axis, 
     684one clicks the Plot button.   
     685 
     686.. image:: combine_batch_plot.png 
     687 
     688Note the discontinuity in the peak position.  This 
     689is due to the fact that the Guassian fit is actually pretty bad and is not 
     690actually finding the peak. 
     691 
     692.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     693 
     694.. note::  This help document was last changed by Paul Butler, 06April2017 
  • src/sas/sasgui/perspectives/fitting/simfitpage.py

    r959eb01 ra9f9ca4  
    11""" 
    2     Simultaneous fit page 
     2    Simultaneous or Batch fit page 
    33""" 
     4# Note that this is used for both Simultaneous/Constrained fit AND for  
     5# combined batch fit.  This is done through setting of the batch_on parameter. 
     6# There are the a half dozen or so places where an if statement is used as in  
     7# if not batch_on: 
     8#     xxxx 
     9# else: 
     10#     xxxx 
     11# This is just wrong but dont have time to fix this go. Proper approach would be 
     12# to strip all parts of the code that depend on batch_on and create the top 
     13# level class from which a contrained/simultaneous fit page and a combined  
     14# batch page inherit. 
     15# 
     16#            04/09/2017   --PDB 
     17 
    418import sys 
    519from collections import namedtuple 
     
    400414        # General Help button 
    401415        self.btHelp = wx.Button(self, wx.ID_HELP, 'HELP') 
    402         self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 
     416        if self.batch_on: 
     417            self.btHelp.SetToolTipString("Combined Batch Fitting help.") 
     418        else: 
     419            self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 
    403420        self.btHelp.Bind(wx.EVT_BUTTON, self._on_help) 
    404421 
     
    527544    """ 
    528545        _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 
    529         _PageAnchor = "#simultaneous-fit-mode" 
    530         _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation, 
     546        if not self.batch_on: 
     547            _PageAnchor = "#simultaneous-fit-mode" 
     548            _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation, 
    531549                                          _PageAnchor, 
    532550                                          "Simultaneous/Constrained Fitting Help") 
     551        else: 
     552            _PageAnchor = "#combined-batch-fit-mode" 
     553            _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation, 
     554                                          _PageAnchor, 
     555                                          "Combined Batch Fit Help") 
    533556 
    534557    def set_manager(self, manager): 
Note: See TracChangeset for help on using the changeset viewer.