Changeset 9be22cd in sasview for src/sas/sasgui


Ignore:
Timestamp:
Sep 27, 2017 10:50:02 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, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
fca1f50
Parents:
69a6897 (diff), 83db1cc (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 'ticket-887-reorg' into ticket-853-fit-gui-to-calc

Location:
src/sas/sasgui
Files:
1 added
2 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst

    rf80b416e rad476d1  
    99----------- 
    1010 
    11 This performs a correlation function analysis of one-dimensional 
    12 SAXS/SANS data, or generates a model-independent volume fraction 
    13 profile from the SANS from an adsorbed polymer/surfactant layer. 
     11This currently performs correlation function analysis on SAXS/SANS data,  
     12but in the the future is also planned to generate model-independent volume  
     13fraction profiles from the SANS from adsorbed polymer/surfactant layers.  
     14The two types of analyses differ in the mathematical transform that is  
     15applied to the data (Fourier vs Hilbert). However, both functions are  
     16returned in *real space*. 
    1417 
    1518A correlation function may be interpreted in terms of an imaginary rod moving 
    16 through the structure of the material. Γ\ :sub:`1D`\ (R) is the probability that 
    17 a rod of length R moving through the material has equal electron/neutron scattering 
    18 length density at either end. Hence a frequently occurring spacing within a structure 
    19 manifests itself as a peak. 
    20  
    21 A volume fraction profile :math:`\Phi`\ (z) describes how the density of polymer segments/surfactant molecules varies with distance from an (assumed locally flat) interface. 
    22  
    23 Both functions are returned in *real space*. 
    24  
    25 The analysis is performed in 3 stages: 
    26  
    27 *  Extrapolation of the scattering curve to :math:`Q = 0` and 
     19through the structure of the material. Γ(x) is the probability that a rod of  
     20length x has equal electron/neutron scattering length density at either end.  
     21Hence a frequently occurring spacing within a structure will manifest itself  
     22as a peak in Γ(x). *SasView* will return both the one-dimensional ( Γ\ :sub:`1`\ (x) )  
     23and three-dimensional ( Γ\ :sub:`3`\ (x) ) correlation functions, the difference  
     24being that the former is only averaged in the plane of the scattering vector. 
     25 
     26A volume fraction profile :math:`\Phi`\ (z) describes how the density of polymer  
     27segments/surfactant molecules varies with distance, z, normal to an (assumed  
     28locally flat) interface. The form of :math:`\Phi`\ (z) can provide information  
     29about the arrangement of polymer/surfactant molecules at the interface. The width  
     30of the profile provides measures of the layer thickness, and the area under  
     31the profile is related to the amount of material that is adsorbed. 
     32 
     33Both analyses are performed in 3 stages: 
     34 
     35*  Extrapolation of the scattering curve to :math:`Q = 0` and toward  
    2836   :math:`Q = \infty` 
    2937*  Smoothed merging of the two extrapolations into the original data 
    3038*  Fourier / Hilbert Transform of the smoothed data to give the correlation 
    31    function / volume fraction profile, respectively 
    32 *  (Optional) Interpretation of the 1D correlation function based on an ideal 
    33    lamellar morphology 
     39   function or volume fraction profile, respectively 
     40*  (Optional) Interpretation of Γ\ :sub:`1`\ (x) assuming the sample conforms  
     41   to an ideal lamellar morphology 
    3442 
    3543.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     44 
    3645 
    3746Extrapolation 
     
    4150................ 
    4251 
    43 The data are extrapolated to Q = 0 by fitting a Guinier model to the data 
    44 points in the low-Q range. 
     52The data are extrapolated to q = 0 by fitting a Guinier function to the data 
     53points in the low-q range. 
    4554 
    4655The equation used is: 
    4756 
    4857.. math:: 
    49     I(Q) = Ae^{Bq^2} 
    50  
    51 The Guinier model assumes that the small angle scattering arises from particles 
    52 and that parameter :math:`B` is related to the radius of gyration of those 
    53 particles. This has dubious applicability to polymer systems. However, the 
    54 correlation function is affected by the Guinier back-extrapolation to the 
    55 greatest extent at large values of R and so only has a 
    56 small effect on the final analysis. 
     58    I(q) = A e^{Bq^2} 
     59 
     60Where the parameter :math:`B` is related to the effective radius-of-gyration of  
     61a spherical object having the same small-angle scattering in this region. 
     62         
     63Note that as q tends to zero this function tends to a limiting value and is  
     64therefore less appropriate for use in systems where the form factor does not  
     65do likewise. However, because of the transform, the correlation functions are  
     66most affected by the Guinier back-extrapolation at *large* values of x where  
     67the impact on any extrapolated parameters will be least significant. 
    5768 
    5869To :math:`Q = \infty` 
    5970..................... 
    6071 
    61 The data are extrapolated to Q = :math:`\infty` by fitting a Porod model to 
    62 the data points in the high-Q range. 
     72The data are extrapolated towards q = :math:`\infty` by fitting a Porod model to 
     73the data points in the high-q range and then computing the extrapolation to 100  
     74times the maximum q value in the experimental dataset. This should be more than  
     75sufficient to ensure that on transformation any truncation artefacts introduced  
     76are at such small values of x that they can be safely ignored. 
    6377 
    6478The equation used is: 
    6579 
    6680.. math:: 
    67     I(Q) = K Q^{-4}e^{-Q^2\sigma^2} + Bg 
    68  
    69 Where :math:`Bg` is the background, :math:`K` is the Porod 
    70 constant, and :math:`\sigma` (which must be > 0) describes the width of the electron or neutron scattering length density profile at the interface between the crystalline and amorphous 
    71 regions as shown below. 
     81    I(q) = K q^{-4}e^{-q^2\sigma^2} + Bg 
     82 
     83Where :math:`Bg` is the background, :math:`K` is the Porod constant, and :math:`\sigma` (which  
     84must be > 0) describes the width of the electron/neutron scattering length density  
     85profile at the interface between the crystalline and amorphous regions as shown below. 
    7286 
    7387.. figure:: fig1.png 
     
    7892--------- 
    7993 
    80 The extrapolated data set consists of the Guinier back-extrapolation from Q~0 
    81 up to the lowest Q value in the original data, then the original scattering data, and the Porod tail-fit beyond this. The joins between the original data and the Guinier/Porod fits are smoothed using the algorithm below to avoid the formation of ripples in the transformed data. 
     94The extrapolated data set consists of the Guinier back-extrapolation from q ~ 0 
     95up to the lowest q value in the original data, then the original scattering data,  
     96and then the Porod tail-fit beyond this. The joins between the original data and  
     97the Guinier/Porod extrapolations are smoothed using the algorithm below to try  
     98and avoid the formation of truncation ripples in the transformed data: 
    8299 
    83100Functions :math:`f(x_i)` and :math:`g(x_i)` where :math:`x_i \in \left\{ 
     
    94111 
    95112 
    96 Transform 
    97 --------- 
     113Transformation 
     114-------------- 
    98115 
    99116Fourier 
    100117....... 
    101118 
    102 If "Fourier" is selected for the transform type, the analysis will perform a 
     119If "Fourier" is selected for the transform type, *SasView* will perform a 
    103120discrete cosine transform on the extrapolated data in order to calculate the 
    104 1D correlation function: 
    105  
    106 .. math:: 
    107     \Gamma _{1D}(R) = \frac{1}{Q^{*}} \int_{0}^{\infty }I(q) q^{2} cos(qR) dq 
    108  
    109 where Q\ :sup:`*` is the Scattering Invariant. 
     1211D correlation function as: 
     122 
     123.. math:: 
     124    \Gamma _{1}(x) = \frac{1}{Q^{*}} \int_{0}^{\infty }I(q) q^{2} cos(qx) dq 
     125 
     126where Q\ :sup:`*` is the Scattering (also called Porod) Invariant. 
    110127 
    111128The following algorithm is applied: 
     
    116133    N-1, N 
    117134 
    118 The 3D correlation function is also calculated: 
    119  
    120 .. math:: 
    121     \Gamma _{3D}(R) = \frac{1}{Q^{*}} \int_{0}^{\infty}I(q) q^{2} 
    122     \frac{sin(qR)}{qR} dq 
     135The 3D correlation function is calculated as: 
     136 
     137.. math:: 
     138    \Gamma _{3}(x) = \frac{1}{Q^{*}} \int_{0}^{\infty}I(q) q^{2} 
     139    \frac{sin(qx)}{qx} dq 
     140 
     141.. note:: It is always advisable to inspect Γ\ :sub:`1`\ (x) and Γ\ :sub:`3`\ (x)  
     142    for artefacts arising from the extrapolation and transformation processes: 
     143         
     144        - do they tend to zero as x tends to :math:`\infty`? 
     145        - do they smoothly curve onto the ordinate at x = 0? (if not check the value  
     146          of :math:`\sigma` is sensible) 
     147        - are there ripples at x values corresponding to (2 :math:`pi` over) the two  
     148          q values at which the extrapolated and experimental data are merged? 
     149        - are there any artefacts at x values corresponding to 2 :math:`pi` / q\ :sub:`max` in  
     150          the experimental data?  
     151        - and lastly, do the significant features/peaks in the correlation functions  
     152          actually correspond to anticpated spacings in the sample?!!! 
     153 
     154Finally, the program calculates the interface distribution function (IDF) g\ :sub:`1`\ (x) as  
     155the discrete cosine transform of: 
     156 
     157.. math:: 
     158    -q^{4} I(q) 
     159 
     160The IDF is proportional to the second derivative of Γ\ :sub:`1`\ (x). 
    123161 
    124162Hilbert 
    125163....... 
    126  
     164         
    127165If "Hilbert" is selected for the transform type, the analysis will perform a 
    128166Hilbert transform on the extrapolated data in order to calculate the Volume 
    129167Fraction Profile. 
    130168 
    131 .. note:: This functionality is not yet implemented in SasView. 
     169.. note:: The Hilbert transform functionality is not yet implemented in SasView. 
    132170 
    133171 
     
    138176.................... 
    139177 
    140 Once the correlation function has been calculated it may be interpreted by clicking the "Compute Parameters" button. 
    141  
    142 The correlation function is interpreted in terms of an ideal lamellar 
    143 morphology, and structural parameters are obtained from it as shown below. 
    144 It should be noted that a small beam size is assumed; ie, no de-smearing is 
    145 performed. 
     178Once the correlation functions have been calculated *SasView* can be asked to  
     179try and interpret Γ\ :sub:`1`\ (x) in terms of an ideal lamellar morphology  
     180as shown below. 
    146181 
    147182.. figure:: fig2.png 
    148183   :align: center 
    149184 
    150 The structural parameters obtained are: 
     185The structural parameters extracted are: 
    151186 
    152187*   Long Period :math:`= L_p` 
     
    160195....................... 
    161196 
    162 SasView does not provide any automatic interpretation of volume fraction profiles in the same way that it does for correlation functions. However, a number of structural parameters are obtainable by other means: 
     197SasView does not provide any automatic interpretation of volume fraction profiles  
     198in the same way that it does for correlation functions. However, a number of  
     199structural parameters are obtainable by other means: 
    163200 
    164201*   Surface Coverage :math:`=\theta` 
     
    175212   :align: center 
    176213 
     214The reader is directed to the references for information on these parameters. 
    177215 
    178216References 
    179217---------- 
    180218 
     219Correlation Function 
     220.................... 
     221 
    181222Strobl, G. R.; Schneider, M. *J. Polym. Sci.* (1980), 18, 1343-1359 
    182223 
     
    189230Baltá Calleja, F. J.; Vonk, C. G. *X-ray Scattering of Synthetic Poylmers*, Elsevier. Amsterdam (1989), 260-270 
    190231 
     232Göschel, U.; Urban, G. *Polymer* (1995), 36, 3633-3639 
     233 
     234Stribeck, N. *X-Ray Scattering of Soft Matter*, Springer. Berlin (2007), 138-161 
     235 
    191236:ref:`FDR` (PDF format) 
     237 
     238Volume Fraction Profile 
     239....................... 
     240 
     241Washington, C.; King, S. M. *J. Phys. Chem.*, (1996), 100, 7603-7609 
     242 
     243Cosgrove, T.; King, S. M.; Griffiths, P. C. *Colloid-Polymer Interactions: From Fundamentals to Practice*, Wiley. New York (1999), 193-204 
     244 
     245King, S. M.; Griffiths, P. C.; Cosgrove, T. *Applications of Neutron Scattering to Soft Condensed Matter*, Gordon & Breach. Amsterdam (2000), 77-105 
     246 
     247King, S.; Griffiths, P.; Hone, J.; Cosgrove, T. *Macromol. Symp.* (2002), 190, 33-42 
    192248 
    193249.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    198254Upon sending data for correlation function analysis, it will be plotted (minus 
    199255the background value), along with a *red* bar indicating the *upper end of the 
    200 low-Q range* (used for back-extrapolation), and 2 *purple* bars indicating the range to be used for forward-extrapolation. These bars may be moved my clicking and 
    201 dragging, or by entering appropriate values in the Q range input boxes. 
     256low-Q range* (used for Guinier back-extrapolation), and 2 *purple* bars indicating  
     257the range to be used for Porod forward-extrapolation. These bars may be moved by  
     258grabbing and dragging, or by entering appropriate values in the Q range input boxes. 
    202259 
    203260.. figure:: tutorial1.png 
    204261   :align: center 
    205262 
    206 Once the Q ranges have been set, click the "Calculate" button to determine the background level. Alternatively, enter your own value into the field. If the box turns yellow this indicates that background subtraction has resulted in some negative intensities. 
    207  
    208 Click the "Extrapolate" button to extrapolate the data and plot the extrapolation in the same figure. The values of the parameters used for the Guinier and Porod models will also be shown in the "Extrapolation Parameters" section of the window. 
     263Once the Q ranges have been set, click the "Calculate Bg" button to determine the  
     264background level. Alternatively, enter your own value into the box. If the box turns  
     265yellow this indicates that background subtraction has created some negative intensities. 
     266 
     267Now click the "Extrapolate" button to extrapolate the data. The graph window will update  
     268to show the extrapolated data, and the values of the parameters used for the Guinier and  
     269Porod extrapolations will appear in the "Extrapolation Parameters" section of the SasView  
     270GUI. 
    209271 
    210272.. figure:: tutorial2.png 
     
    214276buttons: 
    215277 
    216 *   **Fourier** Perform a Fourier Transform to calculate the correlation 
    217     function 
    218 *   **Hilbert** Perform a Hilbert Transform to calculate the volume fraction 
     278*   **Fourier**: to perform a Fourier Transform to calculate the correlation 
     279    functions 
     280*   **Hilbert**: to perform a Hilbert Transform to calculate the volume fraction 
    219281    profile 
    220282 
    221 Click the "Transform" button to perform the selected transform and plot 
    222 the result in a new graph window. 
    223  
    224 If a Fourier Transform was performed, the "Compute Parameters" button can now be clicked to interpret the correlation function as described earlier. 
     283and click the "Transform" button to perform the selected transform and plot 
     284the results. 
    225285 
    226286 .. figure:: tutorial3.png 
    227287    :align: center 
    228288 
     289If a Fourier Transform was performed, the "Compute Parameters" button can now be  
     290clicked to interpret the correlation function as described earlier. The parameters  
     291will appear in the "Output Parameters" section of the SasView GUI. 
     292 
     293 .. figure:: tutorial4.png 
     294    :align: center 
     295 
    229296 
    230297.. note:: 
    231     This help document was last changed by Steve King, 08Oct2016 
     298    This help document was last changed by Steve King, 26Sep2017 
  • src/sas/sasgui/__init__.py

    rc6bdb3b rb963b20  
    1 import sys 
    2 import os 
    3 from os.path import exists, expanduser, dirname, realpath, join as joinpath 
    4  
    5  
    6 def dirn(path, n): 
    7     path = realpath(path) 
    8     for _ in range(n): 
    9         path = dirname(path) 
    10     return path 
    11  
    12 # Set up config directories 
    13 def make_user_folder(): 
    14     path = joinpath(expanduser("~"),'.sasview') 
    15     if not exists(path): 
    16         os.mkdir(path) 
    17     return path 
    18  
    19  
    20 def find_app_folder(): 
    21     # We are starting out with the following info: 
    22     #     __file__ = .../sas/sasgui/__init__.pyc 
    23     # Check if the sister path .../sas/sasview exists, and use it as the 
    24     # app directory.  This will only be the case if the app is not frozen. 
    25     path = joinpath(dirn(__file__, 2), 'sasview') 
    26     if exists(path): 
    27         return path 
    28  
    29     # If we are running frozen, then root is a parent directory 
    30     if sys.platform == 'darwin': 
    31         # Here is the path to the file on the mac: 
    32         #     .../Sasview.app/Contents/Resources/lib/python2.7/site-packages.zip/sas/sasgui/__init__.pyc 
    33         # We want the path to the Resources directory. 
    34         path = dirn(__file__, 6) 
    35     elif os.name == 'nt': 
    36         # Here is the path to the file on windows: 
    37         #     ../Sasview/library.zip/sas/sasgui/__init__.pyc 
    38         # We want the path to the Sasview directory. 
    39         path = dirn(__file__, 4) 
    40     else: 
    41         raise RuntimeError("Couldn't find the app directory") 
    42     return path 
    43  
    44 USER_FOLDER = make_user_folder() 
    45 APP_FOLDER = find_app_folder() 
    46  
    47  
    48 def get_app_dir(): 
    49     return APP_FOLDER 
    50  
    51 def get_user_dir(): 
    52     return USER_FOLDER 
    53  
    54 def get_custom_config_path(): 
    55     dirname = os.path.join(get_user_dir(), 'config') 
    56     # If the directory doesn't exist, create it 
    57     if not os.path.exists(dirname): 
    58         os.makedirs(dirname) 
    59     path = os.path.join(dirname, "custom_config.py") 
    60     return path 
    61  
    62 _config_cache = None 
    63 def get_local_config(): 
    64     global _config_cache 
    65     if not _config_cache: 
    66         _config_cache = _load_config() 
    67     return _config_cache 
    68  
    69 def _load_config(): 
    70     import os 
    71     import sys 
    72     import logging 
    73     from sasmodels.custom import load_module_from_path 
    74  
    75     logger = logging.getLogger(__name__) 
    76     dirname = get_app_dir() 
    77     filename = 'local_config.py' 
    78     path = os.path.join(dirname, filename) 
    79     try: 
    80         module = load_module_from_path('sas.sasgui.local_config', path) 
    81         logger.info("GuiManager loaded %s", path) 
    82         return module 
    83     except Exception as exc: 
    84         logger.critical("Error loading %s: %s", path, exc) 
    85         sys.exit() 
  • src/sas/sasgui/guiframe/CategoryInstaller.py

    r6e50a8d rb963b20  
    1515from collections import defaultdict, OrderedDict 
    1616 
    17 from sas.sasgui import get_user_dir 
     17from sas import get_user_dir 
    1818 
    1919USER_FILE = 'categories.json' 
     
    2727    Note - class is entirely static! 
    2828    """ 
     29 
     30    @staticmethod 
     31    def _get_installed_model_dir(): 
     32        """ 
     33        returns the dir where installed_models.txt should be 
     34        """ 
     35        from sas.sascalc.dataloader.readers import get_data_path 
     36        return get_data_path() 
     37 
     38    @staticmethod 
     39    def _get_default_cat_file_dir(): 
     40        """ 
     41        returns the dir where default_cat.j should be 
     42        """ 
     43        # The default categories file is usually found with the code, except 
     44        # when deploying using py2app (it will be in Contents/Resources), or 
     45        # py2exe (it will be in the exec dir). 
     46        import sas.sasview 
     47        cat_file = "default_categories.json" 
     48 
     49        possible_cat_file_paths = [ 
     50            os.path.join(os.path.split(sas.sasview.__file__)[0], cat_file),           # Source 
     51            os.path.join(os.path.dirname(sys.executable), '..', 'Resources', cat_file), # Mac 
     52            os.path.join(os.path.dirname(sys.executable), cat_file)                     # Windows 
     53        ] 
     54 
     55        for path in possible_cat_file_paths: 
     56            if os.path.isfile(path): 
     57                return os.path.dirname(path) 
     58 
     59        raise RuntimeError('CategoryInstaller: Could not find folder containing default categories') 
     60 
     61    @staticmethod 
     62    def _get_home_dir(): 
     63        """ 
     64        returns the users sasview config dir 
     65        """ 
     66        return os.path.join(os.path.expanduser("~"), ".sasview") 
    2967 
    3068    @staticmethod 
     
    81119               which are user supplied. 
    82120        """ 
    83         _model_dict = { model.name: model for model in model_list} 
     121        _model_dict = {model.name: model for model in model_list} 
    84122        _model_list = _model_dict.keys() 
    85123 
     
    107145                        by_model_dict.pop(model_name) 
    108146                        model_enabled_dict.pop(model_name) 
    109                     except: 
     147                    except Exception: 
    110148                        logger.error("CategoryInstaller: %s", sys.exc_value) 
    111149                else: 
     
    113151        if del_name or (len(add_list) > 0): 
    114152            for model in add_list: 
    115                 model_enabled_dict[model]= True 
    116                 if _model_dict[model].category is None or len(str(_model_dict[model].category.capitalize())) == 0: 
     153                model_enabled_dict[model] = True 
     154                # TODO: should be:  not _model_dict[model].category 
     155                if (_model_dict[model].category is None 
     156                        or len(str(_model_dict[model].category.capitalize())) == 0): 
    117157                    by_model_dict[model].append('Uncategorized') 
    118158                else: 
  • src/sas/sasgui/guiframe/aboutbox.py

    r724af06 rb963b20  
    2525import os 
    2626 
    27 from sas.sasgui import get_local_config 
     27from sas import get_local_config 
    2828config = get_local_config() 
    2929 
  • src/sas/sasgui/guiframe/acknowledgebox.py

    r914ba0a rb963b20  
    1313from wx.lib.expando import ExpandoTextCtrl 
    1414 
    15 from sas.sasgui import get_local_config 
     15from sas import get_local_config 
    1616config = get_local_config() 
    1717 
  • src/sas/sasgui/guiframe/config.py

    r724af06 rb963b20  
    145145UPDATE_TIMEOUT = 2 
    146146 
    147 #OpenCL option 
    148 SAS_OPENCL = None 
    149  
    150147# Time out for updating sasview 
    151148UPDATE_TIMEOUT = 2 
  • src/sas/sasgui/guiframe/data_panel.py

    rc6bdb3b rb963b20  
    3333from sas.sasgui.guiframe.local_perspectives.plotting.SimplePlot \ 
    3434    import PlotFrame as QucikPlotDialog 
    35 from sas.sasgui import get_local_config 
     35from sas import get_local_config 
    3636 
    3737config = get_local_config() 
  • src/sas/sasgui/guiframe/documentation_window.py

    r724af06 rb963b20  
    2727    WX_SUPPORTS_HTML2 = False 
    2828 
    29 from sas.sasgui import get_app_dir 
     29from sas import get_app_dir 
    3030 
    3131# Don't use wx html renderer on windows. 
  • src/sas/sasgui/guiframe/gui_manager.py

    r914ba0a rb963b20  
    2828from matplotlib import _pylab_helpers 
    2929 
    30 from sas.sasgui import get_local_config, get_app_dir, get_user_dir 
     30from sas import get_local_config, get_custom_config, get_app_dir, get_user_dir 
    3131from sas.sasgui.guiframe.events import EVT_CATEGORY 
    3232from sas.sasgui.guiframe.events import EVT_STATUS 
     
    4747from sas.sascalc.dataloader.loader import Loader 
    4848from sas.sasgui.guiframe.proxy import Connection 
    49 from sas.sasgui.guiframe.customdir import setup_custom_config 
    5049 
    5150logger = logging.getLogger(__name__) 
     
    5352 
    5453config = get_local_config() 
    55 custom_config = setup_custom_config() 
     54custom_config = get_custom_config() 
    5655 
    5756# read some constants from config 
     
    6362SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT 
    6463SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME 
    65 SAS_OPENCL = config.SAS_OPENCL 
    6664if not WELCOME_PANEL_ON: 
    6765    WELCOME_PANEL_SHOW = False 
     
    138136        PARENT_FRAME = wx.Frame 
    139137        CHILD_FRAME = wx.Frame 
    140  
    141 #Initiliaze enviromental variable with custom setting but only if variable not set 
    142 if SAS_OPENCL and not "SAS_OPENCL" in os.environ: 
    143     os.environ["SAS_OPENCL"] = SAS_OPENCL 
    144138 
    145139class ViewerFrame(PARENT_FRAME): 
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    r759a8ab rb963b20  
    1010logger = logging.getLogger(__name__) 
    1111 
     12from sas import get_local_config 
     13 
    1214from sas.sascalc.dataloader.loader import Loader 
    1315from sas.sascalc.dataloader.loader_exceptions import NoKnownLoaderException 
    1416 
    15 from sas.sasgui import get_local_config 
    1617from sas.sasgui.guiframe.plugin_base import PluginBase 
    1718from sas.sasgui.guiframe.events import StatusEvent 
  • src/sas/sasgui/guiframe/report_dialog.py

    r463e7ffc r69a6897  
    1313if sys.platform == "win32": 
    1414    _STATICBOX_WIDTH = 450 
    15     PANEL_WIDTH = 500  
     15    PANEL_WIDTH = 500 
    1616    PANEL_HEIGHT = 700 
    1717    FONT_VARIANT = 0 
     
    2626 
    2727class BaseReportDialog(wx.Dialog): 
    28      
     28 
    2929    def __init__(self, report_list, *args, **kwds): 
    3030        """ 
    3131        Initialization. The parameters added to Dialog are: 
    32          
     32 
    3333        :param report_list: list of html_str, text_str, image for report 
    3434        """ 
     
    4848        self.report_list = report_list 
    4949        # wild card 
    50         # pdf supporting only on MAC 
    51         if self.is_pdf: 
    52             self.wild_card = ' PDF files (*.pdf)|*.pdf|' 
     50        if self.is_pdf:  # pdf writer is available 
     51            self.wild_card = 'PDF files (*.pdf)|*.pdf|' 
    5352            self.index_offset = 0 
    5453        else: 
     
    6362        """ 
    6463        hbox = wx.BoxSizer(wx.HORIZONTAL) 
    65          
     64 
    6665        # buttons 
    6766        button_close = wx.Button(self, wx.ID_OK, "Close") 
     
    7574                          id=button_print.GetId()) 
    7675        hbox.Add(button_print) 
    77          
     76 
    7877        button_save = wx.Button(self, wx.NewId(), "Save") 
    7978        button_save.SetToolTipString("Save this report.") 
    8079        button_save.Bind(wx.EVT_BUTTON, self.onSave, id=button_save.GetId()) 
    8180        hbox.Add(button_save) 
    82          
     81 
    8382        # panel for report page 
    8483        vbox = wx.BoxSizer(wx.VERTICAL) 
     
    8786        # set the html page with the report string 
    8887        self.hwindow.SetPage(self.report_html) 
    89          
     88 
    9089        # add panels to boxsizers 
    9190        vbox.Add(hbox) 
     
    103102        previewh = html.HtmlEasyPrinting(name="Printing", parentWindow=self) 
    104103        previewh.PreviewText(self.report_html) 
    105          
     104 
    106105    def onPrint(self, event=None): 
    107106        """ 
     
    118117        """ 
    119118        self.Close() 
    120      
     119 
    121120    def HTML2PDF(self, data, filename): 
    122121        """ 
    123122        Create a PDF file from html source string. 
    124         Returns True is the file creation was successful.  
     123        Returns True is the file creation was successful. 
    125124        : data: html string 
    126125        : filename: name of file to be saved 
     
    136135            self.Update() 
    137136            return pisaStatus.err 
    138         except: 
     137        except Exception: 
    139138            logger.error("Error creating pdf: %s" % sys.exc_value) 
    140139        return False 
    141  
  • src/sas/sasgui/guiframe/startup_configuration.py

    r914ba0a rb963b20  
    1313import wx 
    1414 
    15 from sas.sasgui import get_custom_config_path 
     15from sas import make_custom_config_path 
    1616from sas.sasgui.guiframe.events import StatusEvent 
    1717from sas.sasgui.guiframe.gui_style import GUIFRAME 
     
    194194        Write custom configuration 
    195195        """ 
    196         path = get_custom_config_path() 
     196        path = make_custom_config_path() 
    197197        with open(path, 'w') as out_f: 
    198198            out_f.write("#Application appearance custom configuration\n") 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    r23359ccb r69363c7  
    3131import re 
    3232import logging 
     33import datetime 
     34 
    3335from wx.py.editwindow import EditWindow 
     36 
    3437from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     38 
    3539from .pyconsole import show_model_output, check_model 
    3640 
    3741logger = logging.getLogger(__name__) 
    38  
    3942 
    4043if sys.platform.count("win32") > 0: 
     
    7881    a Modal Dialog. 
    7982 
    80     :TODO the build in compiler currently balks at when it tries to import 
     83    :TODO the built in compiler currently balks at when it tries to import 
    8184    a model whose name contains spaces or symbols (such as + ... underscore 
    8285    should be fine).  Have fixed so the editor cannot save such a file name 
     
    335338            list_fnames = os.listdir(self.plugin_dir) 
    336339            # fake existing regular model name list 
    337             m_list = [model + ".py" for model in self.model_list] 
     340            m_list = [model.name + ".py" for model in self.model_list] 
    338341            list_fnames.append(m_list) 
    339342            if t_fname in list_fnames and title != mname: 
     
    533536            desc_line = "\nmodel_info.description = '{}'".format(description) 
    534537        name = os.path.splitext(os.path.basename(self.fname))[0] 
    535         output = SUM_TEMPLATE.format(name=name, model1=model1_name,  
     538        output = SUM_TEMPLATE.format(name=name, model1=model1_name, 
    536539            model2=model2_name, operator=self._operator, desc_line=desc_line) 
    537540        with open(self.fname, 'w') as out_f: 
     
    789792                    exec "float(math.%s)" % item 
    790793                    self.math_combo.Append(str(item)) 
    791                 except: 
     794                except Exception: 
    792795                    self.math_combo.Append(str(item) + "()") 
    793796        self.math_combo.Bind(wx.EVT_COMBOBOX, self._on_math_select) 
     
    914917            msg = "Name exists already." 
    915918 
    916         # Prepare the messagebox 
     919        # 
    917920        if self.base is not None and not msg: 
    918921            self.base.update_custom_combo() 
    919             # Passed exception in import test as it will fail for sasmodels.sasview_model class 
    920             # Should add similar test for new style? 
    921             Model = None 
    922             try: 
    923                 exec "from %s import Model" % name 
    924             except: 
    925                 logger.error(sys.exc_value) 
    926922 
    927923        # Prepare the messagebox 
     
    956952        :param func_str: content of func; Strings 
    957953        """ 
    958         try: 
    959             out_f = open(fname, 'w') 
    960         except: 
    961             raise 
    962         # Prepare the content of the function 
    963         lines = CUSTOM_TEMPLATE.split('\n') 
    964  
    965         has_scipy = func_str.count("scipy.") 
    966         if has_scipy: 
    967             lines.insert(0, 'import scipy') 
    968  
    969         # Think about 2D later 
    970         #self.is_2d = func_str.count("#self.ndim = 2") 
    971         #line_2d = '' 
    972         #if self.is_2d: 
    973         #    line_2d = CUSTOM_2D_TEMP.split('\n') 
    974  
    975         # Also think about test later 
    976         #line_test = TEST_TEMPLATE.split('\n') 
    977         #local_params = '' 
    978         #spaces = '        '#8spaces 
    979         spaces4  = ' '*4 
    980         spaces13 = ' '*13 
    981         spaces16 = ' '*16 
     954        out_f = open(fname, 'w') 
     955 
     956        out_f.write(CUSTOM_TEMPLATE % { 
     957            'name': name, 
     958            'title': 'User model for ' + name, 
     959            'description': desc_str, 
     960            'date': datetime.datetime.now().strftime('%YYYY-%mm-%dd'), 
     961        }) 
     962 
     963        # Write out parameters 
    982964        param_names = []    # to store parameter names 
    983         has_scipy = func_str.count("scipy.") 
    984         if has_scipy: 
    985             lines.insert(0, 'import scipy') 
    986  
    987         # write function here 
    988         for line in lines: 
    989             # The location where to put the strings is 
    990             # hard-coded in the template as shown below. 
    991             out_f.write(line + '\n') 
    992             if line.count('#name'): 
    993                 out_f.write('name = "%s" \n' % name) 
    994             elif line.count('#title'): 
    995                 out_f.write('title = "User model for %s"\n' % name) 
    996             elif line.count('#description'): 
    997                 out_f.write('description = "%s"\n' % desc_str) 
    998             elif line.count('#parameters'): 
    999                 out_f.write('parameters = [ \n') 
    1000                 for param_line in param_str.split('\n'): 
    1001                     p_line = param_line.lstrip().rstrip() 
    1002                     if p_line: 
    1003                         pname, pvalue, desc = self.get_param_helper(p_line) 
    1004                         param_names.append(pname) 
    1005                         out_f.write("%s['%s', '', %s, [-numpy.inf, numpy.inf], '', '%s'],\n" % (spaces16, pname, pvalue, desc)) 
    1006                 for param_line in pd_param_str.split('\n'): 
    1007                     p_line = param_line.lstrip().rstrip() 
    1008                     if p_line: 
    1009                         pname, pvalue, desc = self.get_param_helper(p_line) 
    1010                         param_names.append(pname) 
    1011                         out_f.write("%s['%s', '', %s, [-numpy.inf, numpy.inf], 'volume', '%s'],\n" % (spaces16, pname, pvalue, desc)) 
    1012                 out_f.write('%s]\n' % spaces13) 
    1013  
    1014         # No form_volume or ER available in simple model editor 
    1015         out_f.write('def form_volume(*arg): \n') 
    1016         out_f.write('    return 1.0 \n') 
    1017         out_f.write('\n') 
    1018         out_f.write('def ER(*arg): \n') 
    1019         out_f.write('    return 1.0 \n') 
    1020  
    1021         # function to compute 
    1022         out_f.write('\n') 
    1023         out_f.write('def Iq(x ') 
    1024         for name in param_names: 
    1025             out_f.write(', %s' % name) 
    1026         out_f.write('):\n') 
     965        pd_params = [] 
     966        out_f.write('parameters = [ \n') 
     967        out_f.write('#   ["name", "units", default, [lower, upper], "type", "description"],\n') 
     968        for pname, pvalue, desc in self.get_param_helper(param_str): 
     969            param_names.append(pname) 
     970            out_f.write("    ['%s', '', %s, [-inf, inf], '', '%s'],\n" 
     971                        % (pname, pvalue, desc)) 
     972        for pname, pvalue, desc in self.get_param_helper(pd_param_str): 
     973            param_names.append(pname) 
     974            pd_params.append(pname) 
     975            out_f.write("    ['%s', '', %s, [-inf, inf], 'volume', '%s'],\n" 
     976                        % (pname, pvalue, desc)) 
     977        out_f.write('    ]\n') 
     978 
     979        # Write out function definition 
     980        out_f.write('def Iq(%s):\n' % ', '.join(['x'] + param_names)) 
     981        out_f.write('    """Absolute scattering"""\n') 
     982        if "scipy." in func_str: 
     983            out_f.write('    import scipy') 
     984        if "numpy." in func_str: 
     985            out_f.write('    import numpy') 
     986        if "np." in func_str: 
     987            out_f.write('    import numpy as np') 
    1027988        for func_line in func_str.split('\n'): 
    1028989            out_f.write('%s%s\n' % (spaces4, func_line)) 
    1029  
    1030         Iqxy_string = 'return Iq(numpy.sqrt(x**2+y**2) ' 
    1031  
     990        out_f.write('## uncomment the following if Iq works for vector x\n') 
     991        out_f.write('#Iq.vectorized = True\n') 
     992 
     993        # If polydisperse, create place holders for form_volume, ER and VR 
     994        if pd_params: 
     995            out_f.write('\n') 
     996            out_f.write(CUSTOM_TEMPLATE_PD % {'args': ', '.join(pd_params)}) 
     997 
     998        # Create place holder for Iqxy 
    1032999        out_f.write('\n') 
    1033         out_f.write('def Iqxy(x, y ') 
    1034         for name in param_names: 
    1035             out_f.write(', %s' % name) 
    1036             Iqxy_string += ', ' + name 
    1037         out_f.write('):\n') 
    1038         Iqxy_string += ')' 
    1039         out_f.write('%s%s\n' % (spaces4, Iqxy_string)) 
     1000        out_f.write('#def Iqxy(%s):\n' % ', '.join(["x", "y"] + param_names)) 
     1001        out_f.write('#    """Absolute scattering of oriented particles."""\n') 
     1002        out_f.write('#    ...\n') 
     1003        out_f.write('#    return oriented_form(x, y, args)\n') 
     1004        out_f.write('## uncomment the following if Iqxy works for vector x, y\n') 
     1005        out_f.write('#Iqxy.vectorized = True\n') 
    10401006 
    10411007        out_f.close() 
    10421008 
    1043     def get_param_helper(self, line): 
    1044         """ 
    1045         Get string in line to define the params dictionary 
    1046  
    1047         :param line: one line of string got from the param_str 
    1048         """ 
    1049         items = line.split(";") 
    1050         for item in items: 
    1051             name = item.split("=")[0].strip() 
    1052             description = "" 
    1053             try: 
    1054                 value = item.split("=")[1].strip() 
    1055                 if value.count("#"): 
    1056                     # If line ends in a comment, remove it before parsing float 
    1057                     index = value.index("#") 
    1058                     description = value[(index + 1):].strip() 
    1059                     value = value[:value.index("#")].strip() 
    1060                 float(value) 
    1061             except ValueError: 
    1062                 value = 1.0 # default 
    1063  
    1064         return name, value, description 
     1009    def get_param_helper(self, param_str): 
     1010        """ 
     1011        yield a sequence of name, value pairs for the parameters in param_str 
     1012 
     1013        Parameters can be defined by one per line by name=value, or multiple 
     1014        on the same line by separating the pairs by semicolon or comma.  The 
     1015        value is optional and defaults to "1.0". 
     1016        """ 
     1017        for line in param_str.replace(';', ',').split('\n'): 
     1018            for item in line.split(','): 
     1019                defn, desc = item.split('#', 1) if '#' in item else (item, '') 
     1020                name, value = defn.split('=', 1) if '=' in defn else (defn, '1.0') 
     1021                if name: 
     1022                    yield [v.strip() for v in (name, value, desc)] 
    10651023 
    10661024    def set_function_helper(self, line): 
     
    10961054        running "file:///...." 
    10971055 
    1098     :param evt: Triggers on clicking the help button 
    1099     """ 
     1056        :param evt: Triggers on clicking the help button 
     1057        """ 
    11001058 
    11011059        _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 
     
    11401098## Templates for plugin models 
    11411099 
    1142 CUSTOM_TEMPLATE = """ 
     1100CUSTOM_TEMPLATE = '''\ 
     1101r""" 
     1102Definition 
     1103---------- 
     1104 
     1105Calculates %(name)s. 
     1106 
     1107%(description)s 
     1108 
     1109References 
     1110---------- 
     1111 
     1112Authorship and Verification 
     1113--------------------------- 
     1114 
     1115* **Author:** --- **Date:** %(date)s 
     1116* **Last Modified by:** --- **Date:** %(date)s 
     1117* **Last Reviewed by:** --- **Date:** %(date)s 
     1118""" 
     1119 
    11431120from math import * 
    1144 import os 
    1145 import sys 
    1146 import numpy 
    1147  
    1148 #name 
    1149  
    1150 #title 
    1151  
    1152 #description 
    1153  
    1154 #parameters 
    1155  
    1156 """ 
    1157  
    1158 CUSTOM_2D_TEMP = """ 
    1159     def run(self, x=0.0, y=0.0): 
    1160         if x.__class__.__name__ == 'list': 
    1161             x_val = x[0] 
    1162             y_val = y[0]*0.0 
    1163             return self.function(x_val, y_val) 
    1164         elif x.__class__.__name__ == 'tuple': 
    1165             msg = "Tuples are not allowed as input to BaseComponent models" 
    1166             raise ValueError, msg 
    1167         else: 
    1168             return self.function(x, 0.0) 
    1169     def runXY(self, x=0.0, y=0.0): 
    1170         if x.__class__.__name__ == 'list': 
    1171             return self.function(x, y) 
    1172         elif x.__class__.__name__ == 'tuple': 
    1173             msg = "Tuples are not allowed as input to BaseComponent models" 
    1174             raise ValueError, msg 
    1175         else: 
    1176             return self.function(x, y) 
    1177     def evalDistribution(self, qdist): 
    1178         if qdist.__class__.__name__ == 'list': 
    1179             msg = "evalDistribution expects a list of 2 ndarrays" 
    1180             if len(qdist)!=2: 
    1181                 raise RuntimeError, msg 
    1182             if qdist[0].__class__.__name__ != 'ndarray': 
    1183                 raise RuntimeError, msg 
    1184             if qdist[1].__class__.__name__ != 'ndarray': 
    1185                 raise RuntimeError, msg 
    1186             v_model = numpy.vectorize(self.runXY, otypes=[float]) 
    1187             iq_array = v_model(qdist[0], qdist[1]) 
    1188             return iq_array 
    1189         elif qdist.__class__.__name__ == 'ndarray': 
    1190             v_model = numpy.vectorize(self.runXY, otypes=[float]) 
    1191             iq_array = v_model(qdist) 
    1192             return iq_array 
    1193 """ 
    1194 TEST_TEMPLATE = """ 
    1195 ###################################################################### 
    1196 ## THIS IS FOR TEST. DO NOT MODIFY THE FOLLOWING LINES!!!!!!!!!!!!!!!! 
    1197 if __name__ == "__main__": 
    1198     m= Model() 
    1199     out1 = m.runXY(0.0) 
    1200     out2 = m.runXY(0.01) 
    1201     isfine1 = numpy.isfinite(out1) 
    1202     isfine2 = numpy.isfinite(out2) 
    1203     print "Testing the value at Q = 0.0:" 
    1204     print out1, " : finite? ", isfine1 
    1205     print "Testing the value at Q = 0.01:" 
    1206     print out2, " : finite? ", isfine2 
    1207     if isfine1 and isfine2: 
    1208         print "===> Simple Test: Passed!" 
    1209     else: 
    1210         print "===> Simple Test: Failed!" 
    1211 """ 
     1121from numpy import inf 
     1122 
     1123name = "%(name)s" 
     1124title = "%(title)s" 
     1125description = """%(description)s""" 
     1126 
     1127''' 
     1128 
     1129CUSTOM_TEMPLATE_PD = '''\ 
     1130def form_volume(%(args)s): 
     1131    """ 
     1132    Volume of the particles used to compute absolute scattering intensity 
     1133    and to weight polydisperse parameter contributions. 
     1134    """ 
     1135    return 0.0 
     1136 
     1137def ER(%(args)s): 
     1138    """ 
     1139    Effective radius of particles to be used when computing structure factors. 
     1140 
     1141    Input parameters are vectors ranging over the mesh of polydispersity values. 
     1142    """ 
     1143    return 0.0 
     1144 
     1145def VR(%(args)s): 
     1146    """ 
     1147    Volume ratio of particles to be used when computing structure factors. 
     1148 
     1149    Input parameters are vectors ranging over the mesh of polydispersity values. 
     1150    """ 
     1151    return 1.0 
     1152''' 
     1153 
    12121154SUM_TEMPLATE = """ 
    12131155from sasmodels.core import load_model_info 
     
    12191161""" 
    12201162if __name__ == "__main__": 
    1221 #    app = wx.PySimpleApp() 
    12221163    main_app = wx.App() 
    12231164    main_frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"], 
    1224                        plugin_dir='../fitting/plugin_models') 
     1165                            plugin_dir='../fitting/plugin_models') 
    12251166    main_frame.ShowModal() 
    12261167    main_app.MainLoop() 
    1227  
    1228 #if __name__ == "__main__": 
    1229 #    from sas.sasgui.perspectives.fitting import models 
    1230 #    dir_path = models.find_plugins_dir() 
    1231 #    app = wx.App() 
    1232 #    window = EditorWindow(parent=None, base=None, path=dir_path, title="Editor") 
    1233 #    app.MainLoop() 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r53b8266 rd3b0c77  
    66import sys 
    77import os 
    8 import wx 
    9 import numpy as np 
    108import time 
    119import copy 
     
    1412import logging 
    1513import traceback 
    16  
    1714from Queue import Queue 
    1815from threading import Thread 
    1916from collections import defaultdict 
     17 
     18import numpy as np 
     19 
     20import wx 
    2021from wx.lib.scrolledpanel import ScrolledPanel 
    2122 
     23from sasmodels.sasview_model import MultiplicationModel 
    2224from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
     25from sasmodels.weights import GaussianDispersion 
     26 
     27from sas.sascalc.dataloader.data_info import Detector 
     28from sas.sascalc.dataloader.data_info import Source 
     29from sas.sascalc.fit.pagestate import PageState 
     30from sas.sascalc.fit.models import PLUGIN_NAME_BASE 
    2331 
    2432from sas.sasgui.guiframe.panel_base import PanelBase 
     
    3240from sas.sasgui.guiframe.dataFitting import check_data_validity 
    3341from sas.sasgui.guiframe.gui_style import GUIFRAME_ID 
    34 from sas.sascalc.dataloader.data_info import Detector 
    35 from sas.sascalc.dataloader.data_info import Source 
    36 from sas.sasgui.perspectives.fitting.pagestate import PageState 
    3742from sas.sasgui.guiframe.CategoryInstaller import CategoryInstaller 
    3843from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     44 
     45from .report_dialog import ReportDialog 
     46from .utils import get_weight 
    3947 
    4048logger = logging.getLogger(__name__) 
     
    155163        self.disp_cb_dict = {} 
    156164 
    157         # self.state = PageState(parent=parent) 
     165        # self.state = PageState() 
    158166        # dictionary containing list of models 
    159167        self.model_list_box = {} 
     
    202210        self.fitrange = True 
    203211        # Create memento to save the current state 
    204         self.state = PageState(parent=self.parent, 
    205                                model=self.model, data=self.data) 
     212        self.state = PageState(model=self.model, data=self.data) 
    206213        # flag to determine if state has change 
    207214        self.state_change = False 
     
    295302        """ 
    296303        x = np.linspace(start=self.qmin_x, stop=self.qmax_x, 
    297                            num=self.npts_x, endpoint=True) 
     304                        num=self.npts_x, endpoint=True) 
    298305        self.data = Data1D(x=x) 
    299306        self.data.xaxis('\\rm{Q}', "A^{-1}") 
     
    321328 
    322329        x = np.logspace(start=qmin, stop=qmax, 
    323                            num=self.npts_x, endpoint=True, base=10.0) 
     330                        num=self.npts_x, endpoint=True, base=10.0) 
    324331        self.data = Data1D(x=x) 
    325332        self.data.xaxis('\\rm{Q}', "A^{-1}") 
     
    510517        self.state.manager = manager 
    511518 
    512     def populate_box(self, model_dict): 
     519    def populate_box(self, model_list_box): 
    513520        """ 
    514521        Store list of model 
    515522 
    516         :param model_dict: dictionary containing list of models 
    517  
    518         """ 
    519         self.model_list_box = model_dict 
    520         self.state.model_list_box = self.model_list_box 
     523        :param model_list_box: dictionary containing categorized models 
     524        """ 
     525        self.model_list_box = model_list_box 
    521526        self.initialize_combox() 
    522527 
    523     def set_model_dictionary(self, model_dict): 
     528    def set_model_dictionary(self, model_dictionary): 
    524529        """ 
    525530        Store a dictionary linking model name -> model object 
    526531 
    527         :param model_dict: dictionary containing list of models 
    528         """ 
    529         self.model_dict = model_dict 
     532        :param model_dictionary: dictionary containing all models 
     533        """ 
     534        self.model_dictionary = model_dictionary 
    530535 
    531536    def initialize_combox(self): 
     
    533538        put default value in the combo box 
    534539        """ 
    535         if self.model_list_box is not None and len(self.model_list_box) > 0: 
     540        if self.model_list_box: 
    536541            self._populate_box(self.structurebox, 
    537542                               self.model_list_box["Structure Factors"]) 
     
    632637        # Get plot image from plotpanel 
    633638        images, canvases = self.get_images() 
    634         # get the report dialog 
    635         self.state.report(images, canvases) 
     639        imgRAM, images, refs = self._build_plots_for_report(images, canvases) 
     640 
     641        # get the strings for report 
     642        report_str, text_str = self.state.report(fig_urls=refs) 
     643 
     644        # Show the dialog 
     645        report_list = [report_str, text_str, images] 
     646        dialog = ReportDialog(report_list, None, wx.ID_ANY, "") 
     647        dialog.Show() 
     648 
     649    def _build_plots_for_report(self, figs, canvases): 
     650        """ 
     651        Build image state that wx.html understand 
     652        by plotting, putting it into wx.FileSystem image object 
     653        """ 
     654        images = [] 
     655        refs = [] 
     656 
     657        # For no figures in the list, prepare empty plot 
     658        if figs is None or len(figs) == 0: 
     659            figs = [None] 
     660 
     661        # Loop over the list of figures 
     662        # use wx.MemoryFSHandler 
     663        imgRAM = wx.MemoryFSHandler() 
     664        for fig in figs: 
     665            if fig is not None: 
     666                ind = figs.index(fig) 
     667                canvas = canvases[ind] 
     668 
     669            # store the image in wx.FileSystem Object 
     670            wx.FileSystem.AddHandler(wx.MemoryFSHandler()) 
     671 
     672            # index of the fig 
     673            ind = figs.index(fig) 
     674 
     675            # AddFile, image can be retrieved with 'memory:filename' 
     676            name = 'img_fit%s.png' % ind 
     677            refs.append('memory:' + name) 
     678            imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG) 
     679 
     680            # append figs 
     681            images.append(fig) 
     682 
     683        return imgRAM, images, refs 
     684 
    636685 
    637686    def on_save(self, event): 
     
    855904            self.state.disable_disp = self.disable_disp.GetValue() 
    856905 
    857         self.state.smearer = copy.deepcopy(self.current_smearer) 
    858906        if hasattr(self, "enable_smearer"): 
    859907            self.state.enable_smearer = \ 
     
    871919        if len(self._disp_obj_dict) > 0: 
    872920            for k, v in self._disp_obj_dict.iteritems(): 
    873                 self.state._disp_obj_dict[k] = v.type 
     921                self.state.disp_obj_dict[k] = v.type 
    874922 
    875923            self.state.values = copy.deepcopy(self.values) 
     
    889937                                    self.state.str_parameters) 
    890938        self._copy_parameters_state(self.orientation_params, 
    891                                      self.state.orientation_params) 
     939                                    self.state.orientation_params) 
    892940        self._copy_parameters_state(self.orientation_params_disp, 
    893941                                    self.state.orientation_params_disp) 
     
    920968            self.state.disable_disp = self.disable_disp.GetValue() 
    921969 
    922         self.state.smearer = copy.deepcopy(self.current_smearer) 
    923970        if hasattr(self, "enable_smearer"): 
    924971            self.state.enable_smearer = \ 
     
    944991                        try: 
    945992                            self.state.disp_cb_dict[k] = v.GetValue() 
    946                         except: 
     993                        except Exception: 
    947994                            self.state.disp_cb_dict[k] = None 
    948995            if len(self._disp_obj_dict) > 0: 
    949996                for k, v in self._disp_obj_dict.iteritems(): 
    950                     self.state._disp_obj_dict[k] = v.type 
     997                    self.state.disp_obj_dict[k] = v.type 
    951998 
    952999            self.state.values = copy.deepcopy(self.values) 
     
    9901037            # to support older version 
    9911038            category_pos = int(state.categorycombobox) 
    992         except: 
     1039        except Exception: 
    9931040            category_pos = 0 
    9941041            for ind_cat in range(self.categorybox.GetCount()): 
     
    10021049            # to support older version 
    10031050            formfactor_pos = int(state.formfactorcombobox) 
    1004         except: 
     1051        except Exception: 
    10051052            formfactor_pos = 0 
    10061053            for ind_form in range(self.formfactorbox.GetCount()): 
     
    10151062            # to support older version 
    10161063            structfactor_pos = int(state.structurecombobox) 
    1017         except: 
     1064        except Exception: 
    10181065            structfactor_pos = 0 
    10191066            for ind_struct in range(self.structurebox.GetCount()): 
     
    11821229        self.categorybox.Select(category_pos) 
    11831230        self._show_combox(None) 
    1184         from models import PLUGIN_NAME_BASE 
    1185         if self.categorybox.GetValue() == CUSTOM_MODEL \ 
    1186                 and PLUGIN_NAME_BASE not in state.formfactorcombobox: 
     1231        if (self.categorybox.GetValue() == CUSTOM_MODEL 
     1232                and PLUGIN_NAME_BASE not in state.formfactorcombobox): 
    11871233            state.formfactorcombobox = \ 
    11881234                PLUGIN_NAME_BASE + state.formfactorcombobox 
    11891235        formfactor_pos = 0 
    11901236        for ind_form in range(self.formfactorbox.GetCount()): 
    1191             if self.formfactorbox.GetString(ind_form) == \ 
    1192                                                 (state.formfactorcombobox): 
     1237            if (self.formfactorbox.GetString(ind_form) 
     1238                    == state.formfactorcombobox): 
    11931239                formfactor_pos = int(ind_form) 
    11941240                break 
     
    12001246            state.structurecombobox = unicode(state.structurecombobox) 
    12011247            for ind_struct in range(self.structurebox.GetCount()): 
    1202                 if self.structurebox.GetString(ind_struct) == \ 
    1203                                                 (state.structurecombobox): 
     1248                if (self.structurebox.GetString(ind_struct) 
     1249                        == state.structurecombobox): 
    12041250                    structfactor_pos = int(ind_struct) 
    12051251                    break 
     
    12521298            self.dI_sqrdata.SetValue(state.dI_sqrdata) 
    12531299            self.dI_idata.SetValue(state.dI_idata) 
    1254         except: 
     1300        except Exception: 
    12551301            # to support older state file formats 
    12561302            self.dI_noweight.SetValue(False) 
     
    13081354        self.weights = copy.deepcopy(state.weights) 
    13091355 
    1310         for key, disp_type in state._disp_obj_dict.iteritems(): 
     1356        for key, disp_type in state.disp_obj_dict.iteritems(): 
    13111357            # disp_model = disp 
    13121358            disp_model = POLYDISPERSITY_MODELS[disp_type]() 
     
    15421588                        try: 
    15431589                            self.npts_x = float(self.Npts_total.GetValue()) 
    1544                         except: 
     1590                        except Exception: 
    15451591                            flag = False 
    15461592                            return flag 
     
    15831629            return 
    15841630 
    1585         for j in range(len(listtorestore)): 
     1631        for item_page in listtorestore: 
    15861632            for param in statelist: 
    1587                 if param[1] == listtorestore[j][1]: 
    1588                     item_page = listtorestore[j] 
     1633                if param[1] == item_page[1]: 
    15891634                    item_page_info = param 
    15901635                    if (item_page_info[1] == "theta" or item_page_info[1] == 
     
    16321677        listtorestore = copy.deepcopy(statelist) 
    16331678 
    1634         for j in range(len(listtorestore)): 
    1635             item_page = listtorestore[j] 
    1636             item_page_info = statelist[j] 
     1679        for item_page, item_page_info in zip(listtorestore, statelist): 
    16371680            # change the state of the check box for simple parameters 
    1638  
    16391681            if item_page[0] is not None: 
    16401682                item_page[0].SetValue(format_number(item_page_info[0], True)) 
     
    17411783                    temp_smear = self.current_smearer 
    17421784            # compute weight for the current data 
    1743             from sas.sasgui.perspectives.fitting.utils import get_weight 
    17441785            flag = self.get_weight_flag() 
    17451786            weight = get_weight(data=self.data, is2d=self._is_2D(), flag=flag) 
     
    17681809 
    17691810        from sas.sasgui.plottools import Data1D as pf_data1d 
    1770         # from sas.sasgui.perspectives.theory.profile_dialog import SLDPanel 
    17711811        from sas.sasgui.guiframe.local_perspectives.plotting.profile_dialog \ 
    17721812            import SLDPanel 
     
    18291869            if mod_cat == CUSTOM_MODEL: 
    18301870                for model in self.model_list_box[mod_cat]: 
    1831                     m_list.append(self.model_dict[model.name]) 
     1871                    m_list.append(self.model_dictionary[model.name]) 
    18321872            else: 
    18331873                cat_dic = self.master_category_dict[mod_cat] 
    1834                 for (model, enabled) in cat_dic: 
     1874                for model, enabled in cat_dic: 
    18351875                    if enabled: 
    1836                         m_list.append(self.model_dict[model]) 
     1876                        m_list.append(self.model_dictionary[model]) 
    18371877        except Exception: 
    18381878            msg = traceback.format_exc() 
     
    19061946                    wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    19071947                    return 
    1908             except: 
     1948            except Exception: 
    19091949                tcrtl.SetBackgroundColour("pink") 
    19101950                msg = "Model Error: wrong value entered: %s" % sys.exc_info()[1] 
     
    19632003                    wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    19642004                    return 
    1965             except: 
     2005            except Exception: 
    19662006                tcrtl.SetBackgroundColour("pink") 
    19672007                msg = "Model Error: wrong value entered: %s" % sys.exc_info()[1] 
     
    20632103 
    20642104        if struct_factor is not None: 
    2065             from sasmodels.sasview_model import MultiplicationModel 
    20662105            self.model = MultiplicationModel(form_factor(self.multi_factor), 
    20672106                                             struct_factor()) 
     
    21412180            # q value from qx and qy 
    21422181            radius = np.sqrt(data.qx_data * data.qx_data + 
    2143                                 data.qy_data * data.qy_data) 
     2182                             data.qy_data * data.qy_data) 
    21442183            # get unmasked index 
    21452184            index_data = (float(self.qmin.GetValue()) <= radius) & \ 
     
    23702409        put gaussian dispersity into current model 
    23712410        """ 
    2372         if len(self.param_toFit) > 0: 
     2411        if self.param_toFit: 
    23732412            for item in self.fittable_param: 
    23742413                if item in self.param_toFit: 
     
    23852424        self.weights = {} 
    23862425 
    2387         # from sas.models.dispersion_models import GaussianDispersion 
    2388         from sasmodels.weights import GaussianDispersion 
    2389         if len(self.disp_cb_dict) == 0: 
    2390             self.save_current_state() 
     2426        if not self.disp_cb_dict: 
    23912427            self.sizer4_4.Clear(True) 
    2392             self.Layout() 
    2393             return 
    2394         if (len(self.disp_cb_dict) > 0): 
     2428        else: 
    23952429            for p in self.disp_cb_dict: 
    23962430                # The parameter was un-selected. 
     
    24652499                self._disp_obj_dict[name1] = disp_model 
    24662500                self.model.set_dispersion(param_name, disp_model) 
    2467                 self.state._disp_obj_dict[name1] = disp_model.type 
     2501                self.state.disp_obj_dict[name1] = disp_model.type 
    24682502 
    24692503                value1 = str(format_number(self.model.getParam(name1), True)) 
     
    25802614        self._disp_obj_dict[name] = disp 
    25812615        self.model.set_dispersion(name.split('.')[0], disp) 
    2582         self.state._disp_obj_dict[name] = disp.type 
     2616        self.state.disp_obj_dict[name] = disp.type 
    25832617        self.values[name] = values 
    25842618        self.weights[name] = weights 
     
    29382972            # go through the parameters 
    29392973            strings = self._get_copy_helper(self.parameters, 
    2940                                            self.orientation_params) 
     2974                                            self.orientation_params) 
    29412975            content += strings 
    29422976 
    29432977            # go through the fittables 
    29442978            strings = self._get_copy_helper(self.fittable_param, 
    2945                                            self.orientation_params_disp) 
     2979                                            self.orientation_params_disp) 
    29462980            content += strings 
    29472981 
    29482982            # go through the fixed params 
    29492983            strings = self._get_copy_helper(self.fixed_param, 
    2950                                            self.orientation_params_disp) 
     2984                                            self.orientation_params_disp) 
    29512985            content += strings 
    29522986 
    29532987            # go through the str params 
    29542988            strings = self._get_copy_helper(self.str_parameters, 
    2955                                            self.orientation_params) 
     2989                                            self.orientation_params) 
    29562990            content += strings 
    29572991            return content 
     
    29663000        the names of parameters that have been fitted 
    29673001 
    2968         :returns: all_params - A list of all parameters, in the format of  
     3002        :returns: all_params - A list of all parameters, in the format of 
    29693003        self.parameters 
    29703004        :returns: fitted_par_names - A list of the names of parameters that have 
     
    30433077                # Only print errors for fitted parameters 
    30443078                content += param[4].GetValue() 
    3045                 content += tab  
     3079                content += tab 
    30463080 
    30473081        return content 
     
    30633097            # Do nothing if self.parameters doesn't exist 
    30643098            return False 
    3065          
    3066         content = '\\begin{table}' 
    3067         content += '\\begin{tabular}[h]' 
     3099 
     3100        content = r'\begin{table}' 
     3101        content += r'\begin{tabular}[h]' 
    30683102 
    30693103        crlf = chr(13) + chr(10) 
     
    30753109        for param in all_params: 
    30763110            content += 'l|l|' 
    3077         content += '}\hline' 
     3111        content += r'}\hline' 
    30783112        content += crlf 
    30793113 
     
    30813115        for index, param in enumerate(all_params): 
    30823116            name = param[1] # Parameter name 
    3083             content += name.replace('_', '\_')  # Escape underscores 
     3117            content += name.replace('_', r'\_')  # Escape underscores 
    30843118            if name in fitted_param_names: 
    30853119                # Only print errors for fitted parameters 
    30863120                content += ' & ' 
    3087                 content += name.replace('_', '\_') + "\_err" 
     3121                content += name.replace('_', r'\_') + r"\_err" 
    30883122            if index < len(all_params) - 1: 
    30893123                content += ' & ' 
    30903124 
    3091         content += '\\\\ \\hline' 
     3125        content += r'\\ \hline' 
    30923126        content += crlf 
    30933127 
     
    31083142            if index < len(all_params) - 1: 
    31093143                content += ' & ' 
    3110          
    3111         content += '\\\\ \\hline' 
     3144 
     3145        content += r'\\ \hline' 
    31123146        content += crlf 
    3113         content += '\\end{tabular}' 
    3114         content += '\\end{table}' 
     3147        content += r'\end{tabular}' 
     3148        content += r'\end{table}' 
    31153149 
    31163150        return content 
     
    33693403                                if name.endswith('.npts'): 
    33703404                                    pd = int(pd) 
    3371                             except: 
     3405                            except Exception: 
    33723406                                # continue 
    33733407                                if not pd and pd != '': 
     
    34553489                self._disp_obj_dict[name] = disp_model 
    34563490                self.model.set_dispersion(param_name, disp_model) 
    3457                 self.state._disp_obj_dict[name] = disp_model.type 
     3491                self.state.disp_obj_dict[name] = disp_model.type 
    34583492                # TODO: It's not an array, why update values and weights? 
    34593493                self.model._persistency_dict[param_name] = \ 
     
    35553589        self.model_box.Clear() 
    35563590 
    3557         if category == 'Plugin Models': 
     3591        if category == CUSTOM_MODEL: 
    35583592            for model in self.model_list_box[category]: 
    35593593                str_m = str(model).split(".")[0] 
     
    35613595 
    35623596        else: 
    3563             for (model, enabled) in sorted(self.master_category_dict[category], 
    3564                                            key=lambda name: name[0]): 
    3565                 if(enabled): 
     3597            for model, enabled in sorted(self.master_category_dict[category], 
     3598                                         key=lambda name: name[0]): 
     3599                if enabled: 
    35663600                    self.model_box.Append(model) 
    35673601 
     
    38043838        self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus) 
    38053839        self.Bind(wx.EVT_KILL_FOCUS, self._silent_kill_focus 
    3806         if kill_focus_callback is None else kill_focus_callback) 
     3840                  if kill_focus_callback is None else kill_focus_callback) 
    38073841        self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter 
    3808         if text_enter_callback is None else text_enter_callback) 
     3842                  if text_enter_callback is None else text_enter_callback) 
    38093843        if not ON_MAC: 
    38103844            self.Bind(wx.EVT_LEFT_UP, self._highlight_text 
    3811             if mouse_up_callback is None else mouse_up_callback) 
     3845                      if mouse_up_callback is None else mouse_up_callback) 
    38123846 
    38133847    def _on_set_focus(self, event): 
  • src/sas/sasgui/perspectives/fitting/batchfitpage.py

    r7432acb r50fcb09  
    55import wx.lib.newevent 
    66import math 
     7 
     8from sas.sascalc.fit.qsmearing import smear_selection 
     9 
    710from sas.sasgui.guiframe.events import StatusEvent 
    811from sas.sasgui.guiframe.events import NewPlotEvent 
     12from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent 
     13from sas.sasgui.perspectives.fitting.fitpage import FitPage 
     14from sas.sasgui.perspectives.fitting.fitpage import check_data_validity 
    915 
    1016(Chi2UpdateEvent, EVT_CHI2_UPDATE) = wx.lib.newevent.NewEvent() 
     
    1319SMEAR_SIZE_L = 0.00 
    1420SMEAR_SIZE_H = 0.00 
    15  
    16 from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent 
    17 from sas.sascalc.data_util.qsmearing import smear_selection 
    18 from sas.sasgui.perspectives.fitting.fitpage import FitPage 
    19 from sas.sasgui.perspectives.fitting.fitpage import check_data_validity 
    2021 
    2122class BatchFitPage(FitPage): 
     
    7677#         """ 
    7778#         is_2Ddata = False 
    78 #          
     79# 
    7980#         # Check if data is 2D 
    8081#         if self.data.__class__.__name__ ==  "Data2D" or \ 
    8182#                         self.enable2D: 
    8283#             is_2Ddata = True 
    83 #              
    84 #         title = "Fitting"      
     84# 
     85#         title = "Fitting" 
    8586#         self._get_smear_info() 
    86 #          
     87# 
    8788#         #Sizers 
    8889#         box_description_range = wx.StaticBox(self, wx.ID_ANY, str(title)) 
    89 #         boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)       
     90#         boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL) 
    9091#         self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL) 
    9192#         #sizer_smearer = wx.BoxSizer(wx.HORIZONTAL) 
     
    9394#         self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL) 
    9495#         sizer_chi2 = wx.BoxSizer(wx.VERTICAL) 
    95 #  
     96# 
    9697#         sizer_fit = wx.GridSizer(2, 4, 2, 6) 
    9798#         #Fit button 
     
    100101#         self.btFit.Bind(wx.EVT_BUTTON, self._onFit, id= self.btFit.GetId()) 
    101102#         self.btFit.SetToolTipString("Start fitting.") 
    102 #  
     103# 
    103104#         # Update and Draw button 
    104105#         self.draw_button = wx.Button(self, self._ids.next(), 'Compute', size=(88, 24)) 
    105106#         self.draw_button.Bind(wx.EVT_BUTTON, \ 
    106107#                               self._onDraw,id=self.draw_button.GetId()) 
    107 #         self.draw_button.SetToolTipString("Compute and Draw.")   
     108#         self.draw_button.SetToolTipString("Compute and Draw.") 
    108109#         sizer_fit.Add(self.draw_button, 0, 0) 
    109 #         sizer_fit.Add(self.btFit, 0, 0)  
     110#         sizer_fit.Add(self.btFit, 0, 0) 
    110111#         sizer_chi2.Add((-1, 5)) 
    111112#         # get smear_selection 
     
    114115#          #2D data? default 
    115116#         is_2Ddata = False 
    116 #          
     117# 
    117118#         #check if it is 2D data 
    118119#         if self.data.__class__.__name__ ==  "Data2D" or \ 
    119120#                         self.enable2D: 
    120121#             is_2Ddata = True 
    121 #              
     122# 
    122123#         self.sizer5.Clear(True) 
    123 #       
     124# 
    124125#         self.qmin  = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20), 
    125 #                                           style=wx.TE_PROCESS_ENTER,  
     126#                                           style=wx.TE_PROCESS_ENTER, 
    126127#                                     text_enter_callback = self._onQrangeEnter) 
    127128#         self.qmin.SetValue(str(self.qmin_x)) 
    128129#         self.qmin.SetToolTipString("Minimun value of Q in linear scale.") 
    129 #       
     130# 
    130131#         self.qmax  = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20), 
    131 #                                           style=wx.TE_PROCESS_ENTER,  
     132#                                           style=wx.TE_PROCESS_ENTER, 
    132133#                                         text_enter_callback=self._onQrangeEnter) 
    133134#         self.qmax.SetValue(str(self.qmax_x)) 
    134135#         self.qmax.SetToolTipString("Maximum value of Q in linear scale.") 
    135 #          
     136# 
    136137#         id = self._ids.next() 
    137138#         self.reset_qrange =wx.Button(self, id, 'Reset', size=(77, 20)) 
    138 #        
     139# 
    139140#         self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked, id=id) 
    140141#         self.reset_qrange.SetToolTipString(\ 
    141142#                                     "Reset Q range to the default values") 
    142 #       
     143# 
    143144#         sizer_horizontal = wx.BoxSizer(wx.HORIZONTAL) 
    144145#         sizer = wx.GridSizer(2, 4, 2, 6) 
    145 #  
     146# 
    146147#         self.btEditMask = wx.Button(self, self._ids.next(),'Editor', size=(88, 23)) 
    147 #         self.btEditMask.Bind(wx.EVT_BUTTON,  
     148#         self.btEditMask.Bind(wx.EVT_BUTTON, 
    148149#                              self._onMask,id=self.btEditMask.GetId()) 
    149150#         self.btEditMask.SetToolTipString("Edit Mask.") 
    150151#         self.EditMask_title = wx.StaticText(self, wx.ID_ANY, ' Masking(2D)') 
    151 #  
     152# 
    152153#         sizer.Add(wx.StaticText(self, wx.ID_ANY, 'Q range')) 
    153154#         sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Min[1/A]')) 
    154155#         sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Max[1/A]')) 
    155156#         sizer.Add(self.EditMask_title) 
    156 #   
    157 #         sizer.Add(self.reset_qrange)    
     157# 
     158#         sizer.Add(self.reset_qrange) 
    158159#         sizer.Add(self.qmin) 
    159160#         sizer.Add(self.qmax) 
    160 #  
     161# 
    161162#         sizer.Add(self.btEditMask) 
    162 #         boxsizer_range.Add(sizer_chi2)  
     163#         boxsizer_range.Add(sizer_chi2) 
    163164#         boxsizer_range.Add((10, 10)) 
    164165#         boxsizer_range.Add(sizer) 
    165 #          
     166# 
    166167#         boxsizer_range.Add((10, 15)) 
    167168#         boxsizer_range.Add(sizer_fit) 
    168169#         if is_2Ddata: 
    169 #             self.btEditMask.Enable()   
    170 #             self.EditMask_title.Enable()  
     170#             self.btEditMask.Enable() 
     171#             self.EditMask_title.Enable() 
    171172#         else: 
    172 #             self.btEditMask.Disable()   
     173#             self.btEditMask.Disable() 
    173174#             self.EditMask_title.Disable() 
    174 #  
     175# 
    175176#         ## save state 
    176177#         #self.save_current_state() 
    177 #  
     178# 
    178179#         self.sizer5.Add(boxsizer_range, 0, wx.EXPAND | wx.ALL, 10) 
    179180#         self.sizer5.Layout() 
    180 #         
    181 #     def _on_select_model(self, event=None):  
     181# 
     182#     def _on_select_model(self, event=None): 
    182183#         """ 
    183184#         call back for model selection 
    184 #         """   
    185 #          
    186 #         self.Show(False)     
    187 #         self._on_select_model_helper()  
    188 #         self.set_model_param_sizer(self.model)                    
     185#         """ 
     186# 
     187#         self.Show(False) 
     188#         self._on_select_model_helper() 
     189#         self.set_model_param_sizer(self.model) 
    189190#         if self.model is None: 
    190191#             self._set_bookmark_flag(False) 
     
    199200#         self.state.structurecombobox = self.structurebox.GetCurrentSelection() 
    200201#         self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection() 
    201 #        
     202# 
    202203#         if self.model is not None: 
    203204#             self._set_copy_flag(True) 
     
    206207#                 self._set_bookmark_flag(False) 
    207208#                 self._keep.Enable(False) 
    208 #                  
     209# 
    209210#             temp_smear = None 
    210211#             ## event to post model to fit to fitting plugins 
    211212#             (ModelEventbox, _) = wx.lib.newevent.NewEvent() 
    212 #           
    213 #             ## set smearing value whether or not  
     213# 
     214#             ## set smearing value whether or not 
    214215#             #    the data contain the smearing info 
    215 #             evt = ModelEventbox(model=self.model,  
    216 #                                         smearer=temp_smear,  
     216#             evt = ModelEventbox(model=self.model, 
     217#                                         smearer=temp_smear, 
    217218#                                         qmin=float(self.qmin_x), 
    218219#                                         uid=self.uid, 
    219 #                                      qmax=float(self.qmax_x))  
    220 #     
     220#                                      qmax=float(self.qmax_x)) 
     221# 
    221222#             self._manager._on_model_panel(evt=evt) 
    222223#             self.mbox_description.SetLabel("Model [%s]" % str(self.model.name)) 
    223224#             self.state.model = self.model.clone() 
    224225#             self.state.model.name = self.model.name 
    225 #  
    226 #              
     226# 
     227# 
    227228#         if event is not None: 
    228229#             ## post state to fit panel 
    229230#             new_event = PageInfoEvent(page = self) 
    230 #             wx.PostEvent(self.parent, new_event)  
     231#             wx.PostEvent(self.parent, new_event) 
    231232#             #update list of plugins if new plugin is available 
    232233#             if self.plugin_rbutton.GetValue(): 
     
    243244#             self._draw_model() 
    244245#         self.SetupScrolling() 
    245 #         self.Show(True)    
    246 #          
     246#         self.Show(True) 
     247# 
    247248#     def _update_paramv_on_fit(self): 
    248249#         """ 
     
    253254#         self.fitrange = True 
    254255#         is_modified = False 
    255 #  
     256# 
    256257#         if self.model is not None: 
    257258#             ##Check the values 
     
    259260#             self._check_value_enter( self.fixed_param) 
    260261#             self._check_value_enter( self.parameters) 
    261 #  
    262 #             # If qmin and qmax have been modified, update qmin and qmax and  
     262# 
     263#             # If qmin and qmax have been modified, update qmin and qmax and 
    263264#              # Here we should check whether the boundaries have been modified. 
    264 #             # If qmin and qmax have been modified, update qmin and qmax and  
     265#             # If qmin and qmax have been modified, update qmin and qmax and 
    265266#             # set the is_modified flag to True 
    266267#             self.fitrange = self._validate_qrange(self.qmin, self.qmax) 
     
    273274#                     self.qmax_x = tempmax 
    274275#                 if tempmax == tempmin: 
    275 #                     flag = False     
     276#                     flag = False 
    276277#                 #temp_smearer = None 
    277278#                 if self._is_2D(): 
    278 #                     # only 2D case set mask   
     279#                     # only 2D case set mask 
    279280#                     flag = self._validate_Npts() 
    280281#                     if not flag: 
    281282#                         return flag 
    282283#             else: flag = False 
    283 #         else:  
     284#         else: 
    284285#             flag = False 
    285 #  
    286 #         #For invalid q range, disable the mask editor and fit button, vs.     
     286# 
     287#         #For invalid q range, disable the mask editor and fit button, vs. 
    287288#         if not self.fitrange: 
    288289#             #self.btFit.Disable() 
     
    293294#             if self._is_2D() and  self.data is not None: 
    294295#                 self.btEditMask.Enable(True) 
    295 #  
     296# 
    296297#         if not flag: 
    297298#             msg = "Cannot Plot or Fit :Must select a " 
    298299#             msg += " model or Fitting range is not valid!!!  " 
    299300#             wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
    300 #          
     301# 
    301302#         self.save_current_state() 
    302 #     
    303 #         return flag   
     303# 
     304#         return flag 
    304305#     def save_current_state(self): 
    305306#         """ 
    306307#         Currently no save option implemented for batch page 
    307308#         """ 
    308 #         pass  
     309#         pass 
    309310#     def save_current_state_fit(self): 
    310311#         """ 
     
    314315#     def set_data(self, data): 
    315316#         """ 
    316 #         reset the current data  
     317#         reset the current data 
    317318#         """ 
    318319#         #id = None 
     
    340341#             self._set_save_flag(False) 
    341342#             self._set_preview_flag(True) 
    342 #    
     343# 
    343344#             self.formfactorbox.Enable() 
    344345#             self.structurebox.Enable() 
     
    346347#             #set maximum range for x in linear scale 
    347348#             if not hasattr(self.data,"data"): #Display only for 1D data fit 
    348 #                 # Minimum value of data    
     349#                 # Minimum value of data 
    349350#                 data_min = min(self.data.x) 
    350 #                 # Maximum value of data   
     351#                 # Maximum value of data 
    351352#                 data_max = max(self.data.x) 
    352 #                 self.btEditMask.Disable()   
     353#                 self.btEditMask.Disable() 
    353354#                 self.EditMask_title.Disable() 
    354355#             else: 
    355 #                  
    356 #                 ## Minimum value of data  
     356# 
     357#                 ## Minimum value of data 
    357358#                 data_min = 0 
    358 #                 x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax))  
     359#                 x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
    359360#                 y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax)) 
    360 #                 ## Maximum value of data   
     361#                 ## Maximum value of data 
    361362#                 data_max = math.sqrt(x*x + y*y) 
    362 #                 self.btEditMask.Enable()   
    363 #                 self.EditMask_title.Enable()  
    364 #  
     363#                 self.btEditMask.Enable() 
     364#                 self.EditMask_title.Enable() 
     365# 
    365366#         self.dataSource.SetValue(data_name) 
    366367#         self.qmin_x = data_min 
     
    375376#         self.state.qmin = self.qmin_x 
    376377#         self.state.qmax = self.qmax_x 
    377 #          
     378# 
    378379#         #update model plot with new data information 
    379380#         if flag: 
     
    385386#                 self.enable2D = False 
    386387#                 self.model_view.SetLabel("1D Mode") 
    387 #                  
     388# 
    388389#             self.model_view.Disable() 
    389 #              
    390 #             wx.PostEvent(self._manager.parent,  
     390# 
     391#             wx.PostEvent(self._manager.parent, 
    391392#                              NewPlotEvent(group_id=group_id, 
    392393#                                                action="delete")) 
    393394#             #plot the current selected data 
    394 #             wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data,  
     395#             wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, 
    395396#                                                     title=str(self.data.title))) 
    396397#             self._manager.store_data(uid=self.uid, data=data, 
  • src/sas/sasgui/perspectives/fitting/fit_thread.py

    r959eb01 rba8d326  
    2929                 worktime=0.03, 
    3030                 reset_flag=False): 
    31         CalcThread.__init__(self, 
    32                  completefn, 
    33                  updatefn, 
    34                  yieldtime, 
    35                  worktime) 
     31        CalcThread.__init__(self, completefn, updatefn, yieldtime, worktime) 
    3632        self.handler = handler 
    3733        self.fitter = fn 
     
    9389            # Real code should not print, but this is an example... 
    9490            #print "keyboard exception" 
    95             #Stop on exception during fitting. Todo: need to put  
     91            #Stop on exception during fitting. Todo: need to put 
    9692            #some mssg and reset progress bar. 
    9793 
     
    10096            if self.handler is not None: 
    10197                self.handler.stop(msg=msg) 
    102         except: 
     98        except:  # catch-all: show every exception which stops the thread 
    10399            import traceback 
    104100            if self.handler is not None: 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r48154abb r0315b63  
    1414from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
    1515 
     16from sas.sascalc.fit.qsmearing import smear_selection 
     17 
    1618from sas.sasgui.guiframe.events import StatusEvent, NewPlotEvent, \ 
    1719    PlotQrangeEvent 
     
    2325from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent as \ 
    2426    PageInfoEvent 
    25 from sas.sascalc.data_util.qsmearing import smear_selection 
    2627from .basepage import ModelTextCtrl 
    2728 
     
    11421143            self.model.name = "M" + str(self.index_model) 
    11431144 
    1144     def _on_select_model(self, event=None): 
     1145    def _on_select_model(self, event=None, keep_pars=False): 
    11451146        """ 
    11461147        call back for model selection 
    11471148        """ 
    11481149        self.Show(False) 
    1149         copy_flag = False 
    1150         is_poly_enabled = None 
    11511150        if event is not None: 
    1152             if (event.GetEventObject() == self.formfactorbox 
    1153                     and self.structurebox.GetLabel() != 'None')\ 
    1154                     or event.GetEventObject() == self.structurebox\ 
    1155                     or event.GetEventObject() == self.multifactorbox: 
    1156                 copy_flag = self.get_copy_params() 
    1157                 is_poly_enabled = self.enable_disp.GetValue() 
     1151            control = event.GetEventObject() 
     1152            if ((control == self.formfactorbox 
     1153                 and self.structurebox.GetLabel() != 'None') 
     1154                    or control == self.structurebox 
     1155                    or control == self.multifactorbox): 
     1156                keep_pars = True 
     1157 
     1158        if keep_pars: 
     1159            saved_pars = self.get_copy_params() 
     1160            is_poly_enabled = self.enable_disp.GetValue() 
     1161        else: 
     1162            saved_pars = None 
     1163            is_poly_enabled = None 
     1164 
    11581165        try: 
    11591166            self._on_select_model_helper() 
     
    11771184        try: 
    11781185            self.set_dispers_sizer() 
    1179         except: 
     1186        except Exception: 
    11801187            pass 
    11811188        self.state.enable_disp = self.enable_disp.GetValue() 
     
    12381245            self.state.model.name = self.model.name 
    12391246 
     1247        # when select a model only from guictr/button 
     1248        if is_poly_enabled is not None: 
     1249            self.enable_disp.SetValue(is_poly_enabled) 
     1250            self.disable_disp.SetValue(not is_poly_enabled) 
     1251            self._set_dipers_Param(event=None) 
     1252            self.state.enable_disp = self.enable_disp.GetValue() 
     1253            self.state.disable_disp = self.disable_disp.GetValue() 
     1254 
     1255        # Keep the previous param values 
     1256        if saved_pars: 
     1257            self.get_paste_params(saved_pars) 
     1258 
    12401259        if event is not None: 
     1260            # update list of plugins if new plugin is available 
     1261            # mod_cat = self.categorybox.GetStringSelection() 
     1262            # if mod_cat == CUSTOM_MODEL: 
     1263            #     temp = self.parent.update_model_list() 
     1264            #     for v in self.parent.model_dictionary.values(): 
     1265            #         if v.id == self.model.id: 
     1266            #             self.model = v() 
     1267            #             break 
     1268            #     if temp: 
     1269            #         self.model_list_box = temp 
     1270            #         current_val = self.formfactorbox.GetLabel() 
     1271            #         pos = self.formfactorbox.GetSelection() 
     1272            #         self._show_combox_helper() 
     1273            #         self.formfactorbox.SetStringSelection(current_val) 
     1274            #         self.formfactorbox.SetValue(current_val) 
    12411275            # post state to fit panel 
    12421276            new_event = PageInfoEvent(page=self) 
    12431277            wx.PostEvent(self.parent, new_event) 
    1244             # update list of plugins if new plugin is available 
    1245             mod_cat = self.categorybox.GetStringSelection() 
    1246             if mod_cat == CUSTOM_MODEL: 
    1247                 temp_id = self.model.id 
    1248                 temp = self.parent.update_model_list() 
    1249                 for v in self.parent.model_dictionary.values(): 
    1250                     if v.id == temp_id: 
    1251                         self.model = v() 
    1252                         break 
    1253                 if temp: 
    1254                     self.model_list_box = temp 
    1255                     current_val = self.formfactorbox.GetLabel() 
    1256                     pos = self.formfactorbox.GetSelection() 
    1257                     self._show_combox_helper() 
    1258                     self.formfactorbox.SetSelection(pos) 
    1259                     self.formfactorbox.SetValue(current_val) 
    1260             # when select a model only from guictr/button 
    1261             if is_poly_enabled is not None: 
    1262                 self.enable_disp.SetValue(is_poly_enabled) 
    1263                 self.disable_disp.SetValue(not is_poly_enabled) 
    1264                 self._set_dipers_Param(event=None) 
    1265                 self.state.enable_disp = self.enable_disp.GetValue() 
    1266                 self.state.disable_disp = self.disable_disp.GetValue() 
    1267  
    1268             # Keep the previous param values 
    1269             if copy_flag: 
    1270                 self.get_paste_params(copy_flag) 
    12711278            wx.CallAfter(self._onDraw, None) 
    12721279 
     
    17261733        ind = 0 
    17271734        while(ind < len(list)): 
    1728             for key, val in list.iteritems(): 
    1729                 if (val == ind): 
     1735            for key, val in list.items(): 
     1736                if val == ind: 
    17301737                    fun_box.Append(key, val) 
    17311738                    break 
  • src/sas/sasgui/perspectives/fitting/fitpanel.py

    r13374be r69363c7  
    99from wx.aui import AuiNotebook as nb 
    1010 
     11from sas.sascalc.fit.models import ModelManager 
     12 
    1113from sas.sasgui.guiframe.panel_base import PanelBase 
    1214from sas.sasgui.guiframe.events import PanelOnFocusEvent, StatusEvent 
    1315from sas.sasgui.guiframe.dataFitting import check_data_validity 
    14 from sas.sasgui.perspectives.fitting.simfitpage import SimultaneousFitPage 
    15  
    16 import basepage 
    17 import models 
     16 
     17 
     18from . import basepage 
     19from .fitpage import FitPage 
     20from .simfitpage import SimultaneousFitPage 
     21from .batchfitpage import BatchFitPage 
     22from .fitting_widgets import BatchDataDialog 
     23 
    1824_BOX_WIDTH = 80 
    1925 
     
    4652        self.event_owner = None 
    4753        # dictionary of miodel {model class name, model class} 
    48         self.menu_mng = models.ModelManager() 
     54        self.menu_mng = ModelManager() 
    4955        self.model_list_box = self.menu_mng.get_model_list() 
    5056        # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING 
     
    114120        """ 
    115121        temp = self.menu_mng.update() 
    116         if len(temp): 
     122        if temp: 
    117123            self.model_list_box = temp 
    118124        return temp 
     
    121127        """ 
    122128        """ 
    123         temp = self.menu_mng.plugins_reset() 
    124         if len(temp): 
    125             self.model_list_box = temp 
    126         return temp 
     129        self.model_list_box = self.menu_mng.plugins_reset() 
     130        return self.model_list_box 
    127131 
    128132    def get_page_by_id(self, uid): 
     
    298302        self.model_list_box = dict 
    299303 
    300     def set_model_dict(self, m_dict): 
     304    def set_model_dictionary(self, model_dictionary): 
    301305        """ 
    302306        copy a dictionary of model name -> model object 
    303307 
    304         :param m_dict: dictionary linking model name -> model object 
     308        :param model_dictionary: dictionary linking model name -> model object 
    305309        """ 
    306310 
     
    316320        Add the simultaneous fit page 
    317321        """ 
    318         from simfitpage import SimultaneousFitPage 
    319322        page_finder = self._manager.get_page_finder() 
    320323        if caption == "Const & Simul Fit": 
     
    344347        """ 
    345348        if self.batch_on: 
    346             from batchfitpage import BatchFitPage 
    347349            panel = BatchFitPage(parent=self) 
    348350            self.batch_page_index += 1 
     
    351353        else: 
    352354            # Increment index of fit page 
    353             from fitpage import FitPage 
    354355            panel = FitPage(parent=self) 
    355356            self.fit_page_index += 1 
     
    359360        panel._set_save_flag(not panel.batch_on) 
    360361        panel.set_model_dictionary(self.model_dictionary) 
    361         panel.populate_box(model_dict=self.model_list_box) 
     362        panel.populate_box(model_list_box=self.model_list_box) 
    362363        panel.formfactor_combo_init() 
    363364        panel.set_manager(self._manager) 
     
    445446        if data_1d_list and data_2d_list: 
    446447            # need to warning the user that this batch is a special case 
    447             from sas.sasgui.perspectives.fitting.fitting_widgets import \ 
    448                 BatchDataDialog 
    449448            dlg = BatchDataDialog(self) 
    450449            if dlg.ShowModal() == wx.ID_OK: 
  • src/sas/sasgui/perspectives/fitting/fitproblem.py

    r959eb01 r251ef684  
    1414################################################################################ 
    1515import copy 
    16 from sas.sascalc.data_util.qsmearing import smear_selection 
    17  
    18 class FitProblemComponent(object): 
     16 
     17from sas.sascalc.fit.qsmearing import smear_selection 
     18 
     19class FitProblem(object): 
    1920    """ 
    20     Inferface containing information to store data, model, range of data, etc... 
    21     and retreive this information. This is an inferface 
    22     for a fitProblem i.e relationship between data and model. 
     21    Define the relationship between data and model, including range, weights, 
     22    etc. 
    2323    """ 
     24    def __init__(self): 
     25        """ 
     26        contains information about data and model to fit 
     27        """ 
     28        ## data used for fitting 
     29        self.fit_data = None 
     30        self.theory_data = None 
     31        self.residuals = None 
     32        # original data: should not be modified 
     33        self.original_data = None 
     34        ## the current model 
     35        self.model = None 
     36        ## if 1 this fit problem will be selected to fit , if 0 
     37        ## it will not be selected for fit 
     38        self.schedule = 0 
     39        ##list containing parameter name and value 
     40        self.list_param = [] 
     41        self.list_param2fit = [] 
     42        ## smear object to smear or not data1D 
     43        self.smearer_computed = False 
     44        self.smearer_enable = False 
     45        self.smearer_computer_value = None 
     46        ## fitting range 
     47        self.qmin = None 
     48        self.qmax = None 
     49        # fit weight 
     50        self.weight = None 
     51        self.result = None 
     52        self.fit_tab_caption = None 
     53        self.name_per_page = None 
     54 
    2455    def enable_smearing(self, flag=False): 
    2556        """ 
     
    2758            flag is 0 ingore smear value. 
    2859        """ 
     60        self.smearer_enable = flag 
     61 
     62    def set_smearer(self, smearer): 
     63        """ 
     64        save reference of  smear object on fitdata 
     65 
     66        :param smear: smear object from DataLoader 
     67 
     68        """ 
     69        self.smearer_computer_value = smearer 
    2970 
    3071    def get_smearer(self): 
     
    3273        return smear object 
    3374        """ 
     75        if not self.smearer_enable: 
     76            return None 
     77        if not self.smearer_computed: 
     78            #smeari_selection should be call only once per fitproblem 
     79            self.smearer_computer_value = smear_selection(self.fit_data, 
     80                                                          self.model) 
     81            self.smearer_computed = True 
     82        return self.smearer_computer_value 
     83 
    3484    def save_model_name(self, name): 
    3585        """ 
    3686        """ 
     87        self.name_per_page = name 
    3788 
    3889    def get_name(self): 
    3990        """ 
    4091        """ 
     92        return self.name_per_page 
    4193 
    4294    def set_model(self, model): 
     
    4698        :param name: name created for model 
    4799        """ 
     100        self.model = model 
     101        self.smearer_computer_value = smear_selection(self.fit_data, 
     102                                                      self.model) 
     103        self.smearer_computed = True 
    48104 
    49105    def get_model(self): 
     
    51107        :return: saved model 
    52108        """ 
     109        return self.model 
    53110 
    54111    def set_residuals(self, residuals): 
     
    57114        :param data: data selected 
    58115        """ 
     116        self.residuals = residuals 
    59117 
    60118    def get_residuals(self): 
     
    62120        :return: residuals 
    63121        """ 
     122        return self.residuals 
    64123 
    65124    def set_theory_data(self, data): 
    66125        """ 
    67126        save a copy of the data select to fit 
     127 
    68128        :param data: data selected 
    69         """ 
     129 
     130        """ 
     131        self.theory_data = copy.deepcopy(data) 
    70132 
    71133    def get_theory_data(self): 
    72134        """ 
    73         :return: list of data dList 
    74         """ 
     135        :return: theory generated with the current model and data of this class 
     136        """ 
     137        return self.theory_data 
    75138 
    76139    def set_fit_data(self, data): 
    77140        """ 
    78         Store of list of data and create  by create new fitproblem of each data 
    79         id, if there was existing information about model, this information 
    80         get copy to the new fitproblem 
     141        Store data associated with this class 
    81142        :param data: list of data selected 
    82143        """ 
     144        self.original_data = None 
     145        self.fit_data = None 
     146        # original data: should not be modified 
     147        self.original_data = data 
     148        # fit data: used for fit and can be modified for convenience 
     149        self.fit_data = copy.deepcopy(data) 
     150        self.smearer_computer_value = smear_selection(self.fit_data, self.model) 
     151        self.smearer_computed = True 
     152        self.result = None 
    83153 
    84154    def get_fit_data(self): 
    85155        """ 
    86         """ 
     156        :return: data associate with this class 
     157        """ 
     158        return self.fit_data 
     159 
     160    def get_origin_data(self): 
     161        """ 
     162        """ 
     163        return self.original_data 
     164 
     165    def set_weight(self, is2d, flag=None): 
     166        """ 
     167        Received flag and compute error on data. 
     168        :param flag: flag to transform error of data. 
     169        :param is2d: flag to distinguish 1D to 2D Data 
     170        """ 
     171        from sas.sasgui.perspectives.fitting.utils import get_weight 
     172        # send original data for weighting 
     173        self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag) 
     174        if is2d: 
     175            self.fit_data.err_data = self.weight 
     176        else: 
     177            self.fit_data.dy = self.weight 
     178 
     179    def get_weight(self): 
     180        """ 
     181        returns weight array 
     182        """ 
     183        return self.weight 
     184 
     185    def set_param2fit(self, list): 
     186        """ 
     187        Store param names to fit (checked) 
     188        :param list: list of the param names 
     189        """ 
     190        self.list_param2fit = list 
     191 
     192    def get_param2fit(self): 
     193        """ 
     194        return the list param names to fit 
     195        """ 
     196        return self.list_param2fit 
    87197 
    88198    def set_model_param(self, name, value=None): 
     
    92202        :param value: value of that parameter 
    93203        """ 
    94  
    95     def set_param2fit(self, list): 
    96         """ 
    97         Store param names to fit (checked) 
    98         :param list: list of the param names 
    99         """ 
    100  
    101     def get_param2fit(self): 
    102         """ 
    103         return the list param names to fit 
    104         """ 
     204        self.list_param.append([name, value]) 
    105205 
    106206    def get_model_param(self): 
     
    108208        return list of couple of parameter name and value 
    109209        """ 
     210        return self.list_param 
    110211 
    111212    def schedule_tofit(self, schedule=0): 
     
    113214        set schedule to true to decide if this fit  must be performed 
    114215        """ 
     216        self.schedule = schedule 
    115217 
    116218    def get_scheduled(self): 
     
    118220        return true or false if a problem as being schedule for fitting 
    119221        """ 
     222        return self.schedule 
    120223 
    121224    def set_range(self, qmin=None, qmax=None): 
    122225        """ 
    123226        set fitting range 
    124         """ 
     227        :param qmin: minimum value to consider for the fit range 
     228        :param qmax: maximum value to consider for the fit range 
     229        """ 
     230        self.qmin = qmin 
     231        self.qmax = qmax 
    125232 
    126233    def get_range(self): 
    127234        """ 
    128235        :return: fitting range 
    129         """ 
    130  
    131     def set_weight(self, flag=None): 
    132         """ 
    133         set fitting range 
    134         """ 
    135  
    136     def get_weight(self): 
    137         """ 
    138         get fitting weight 
    139         """ 
     236 
     237        """ 
     238        return self.qmin, self.qmax 
    140239 
    141240    def clear_model_param(self): 
     
    143242        clear constraint info 
    144243        """ 
     244        self.list_param = [] 
    145245 
    146246    def set_fit_tab_caption(self, caption): 
    147247        """ 
    148         store the caption of the page associated with object 
    149         """ 
     248        """ 
     249        self.fit_tab_caption = str(caption) 
    150250 
    151251    def get_fit_tab_caption(self): 
    152252        """ 
    153         Return the caption of the page associated with object 
    154         """ 
     253        """ 
     254        return self.fit_tab_caption 
    155255 
    156256    def set_graph_id(self, id): 
     
    158258        Set graph id (from data_group_id at the time the graph produced) 
    159259        """ 
     260        self.graph_id = id 
    160261 
    161262    def get_graph_id(self): 
     
    163264        Get graph_id 
    164265        """ 
     266        return self.graph_id 
    165267 
    166268    def set_result(self, result): 
    167269        """ 
    168270        """ 
     271        self.result = result 
    169272 
    170273    def get_result(self): 
     
    172275        get result 
    173276        """ 
    174  
    175  
    176 class FitProblemDictionary(FitProblemComponent, dict): 
     277        return self.result 
     278 
     279 
     280class FitProblemDictionary(dict): 
    177281    """ 
    178282    This module implements a dictionary of fitproblem objects 
    179283    """ 
    180284    def __init__(self): 
    181         FitProblemComponent.__init__(self) 
    182285        dict.__init__(self) 
    183286        ## the current model 
     
    206309        self._smear_on = flag 
    207310        if fid is None: 
    208             for value in self.itervalues(): 
     311            for value in self.values(): 
    209312                value.enable_smearing(flag) 
    210         else: 
    211             if fid in self.iterkeys(): 
    212                 self[fid].enable_smearing(flag) 
     313        elif fid in self: 
     314            self[fid].enable_smearing(flag) 
    213315 
    214316    def set_smearer(self, smearer, fid=None): 
     
    218320        """ 
    219321        if fid is None: 
    220             for value in self.itervalues(): 
     322            for value in self.values(): 
    221323                value.set_smearer(smearer) 
    222         else: 
    223             if fid in self.iterkeys(): 
    224                 self[fid].set_smearer(smearer) 
     324        elif fid in self: 
     325            self[fid].set_smearer(smearer) 
    225326 
    226327    def get_smearer(self, fid=None): 
     
    228329        return smear object 
    229330        """ 
    230         if fid in self.iterkeys(): 
     331        if fid in self: 
    231332            return self[fid].get_smearer() 
    232333 
     
    235336        """ 
    236337        if fid is None: 
    237             for value in self.itervalues(): 
     338            for value in self.values(): 
    238339                value.save_model_name(name) 
    239         else: 
    240             if fid in self.iterkeys(): 
    241                 self[fid].save_model_name(name) 
     340        elif fid in self: 
     341            self[fid].save_model_name(name) 
    242342 
    243343    def get_name(self, fid=None): 
     
    246346        result = [] 
    247347        if fid is None: 
    248             for value in self.itervalues(): 
     348            for value in self.values(): 
    249349                result.append(value.get_name()) 
    250         else: 
    251             if fid in self.iterkeys(): 
    252                 result.append(self[fid].get_name()) 
     350        elif fid in self: 
     351            result.append(self[fid].get_name()) 
    253352        return result 
    254353 
     
    261360        self.model = model 
    262361        if fid is None: 
    263             for value in self.itervalues(): 
     362            for value in self.values(): 
    264363                value.set_model(self.model) 
    265         else: 
    266             if fid in self.iterkeys(): 
    267                 self[fid].set_model(self.model) 
     364        elif fid in self: 
     365            self[fid].set_model(self.model) 
    268366 
    269367    def get_model(self, fid): 
     
    271369        :return: saved model 
    272370        """ 
    273         if fid in self.iterkeys(): 
     371        if fid in self: 
    274372            return self[fid].get_model() 
    275373 
     
    291389        :param data: data selected 
    292390        """ 
    293         if fid in self.iterkeys(): 
     391        if fid in self: 
    294392            self[fid].set_residuals(residuals) 
    295393 
     
    298396        :return: residuals 
    299397        """ 
    300         if fid in self.iterkeys(): 
     398        if fid in self: 
    301399            return self[fid].get_residuals() 
    302400 
     
    306404        :param data: data selected 
    307405        """ 
    308         if fid in self.iterkeys(): 
     406        if fid in self: 
    309407            self[fid].set_theory_data(data) 
    310408 
     
    313411        :return: list of data dList 
    314412        """ 
    315         if fid in self.iterkeys(): 
     413        if fid in self: 
    316414            return self[fid].get_theory_data() 
    317415 
     
    322420        :note: only data changes in the fit problem 
    323421        """ 
    324         if data.id not in self.iterkeys(): 
     422        if data.id not in self: 
    325423            self[data.id] = FitProblem() 
    326424        self[data.id].set_fit_data(data) 
     
    336434            data = [] 
    337435        for d in data: 
    338             if (d is not None): 
    339                 if (d.id not in self.iterkeys()): 
     436            if d is not None: 
     437                if d.id not in self: 
    340438                    self[d.id] = FitProblem() 
    341439                self[d.id].set_fit_data(d) 
     
    348446        :param fid: key representing a fitproblem, usually extract from data id 
    349447        """ 
    350         if fid in self.iterkeys(): 
     448        if fid in self: 
    351449            return self[fid].get_fit_data() 
    352450 
     
    358456        """ 
    359457        if fid is None: 
    360             for value in self.itervalues(): 
     458            for value in self.values(): 
    361459                value.set_model_param(name, value) 
    362         else: 
    363             if fid in self.iterkeys(): 
    364                 self[fid].set_model_param(name, value) 
     460        elif fid in self: 
     461            self[fid].set_model_param(name, value) 
    365462 
    366463    def get_model_param(self, fid): 
     
    368465        return list of couple of parameter name and value 
    369466        """ 
    370         if fid in self.iterkeys(): 
     467        if fid in self: 
    371468            return self[fid].get_model_param() 
    372469 
     
    389486        """ 
    390487        self.scheduled = schedule 
    391         for value in self.itervalues(): 
     488        for value in self.values(): 
    392489            value.schedule_tofit(schedule) 
    393490 
     
    405502        self.qmax = qmax 
    406503        if fid is None: 
    407             for value in self.itervalues(): 
     504            for value in self.values(): 
    408505                value.set_range(self.qmin, self.qmax) 
    409         else: 
    410             if fid in self.iterkeys(): 
    411                 self[fid].value.set_range(self.qmin, self.qmax) 
     506        elif fid in self: 
     507            self[fid].value.set_range(self.qmin, self.qmax) 
    412508 
    413509    def get_range(self, fid): 
     
    415511        :return: fitting range 
    416512        """ 
    417         if fid in self.iterkeys(): 
     513        if fid in self: 
    418514            return self[fid].get_range() 
    419515 
     
    423519        """ 
    424520        if fid is None: 
    425             for value in self.itervalues(): 
     521            for value in self.values(): 
    426522                value.set_weight(flag=flag, is2d=is2d) 
    427         else: 
    428             if fid in self.iterkeys(): 
    429                 self[fid].set_weight(flag=flag, is2d=is2d) 
     523        elif fid in self: 
     524            self[fid].set_weight(flag=flag, is2d=is2d) 
    430525 
    431526    def get_weight(self, fid=None): 
     
    433528        return fit weight 
    434529        """ 
    435         if fid in self.iterkeys(): 
     530        if fid in self: 
    436531            return self[fid].get_weight() 
    437532 
     
    441536        """ 
    442537        if fid is None: 
    443             for value in self.itervalues(): 
     538            for value in self.values(): 
    444539                value.clear_model_param() 
    445         else: 
    446             if fid in self.iterkeys(): 
    447                 self[fid].clear_model_param() 
     540        elif fid in self: 
     541            self[fid].clear_model_param() 
    448542 
    449543    def get_fit_problem(self): 
     
    451545        return fitproblem contained in this dictionary 
    452546        """ 
    453         return self.itervalues() 
     547        return self.values() 
    454548 
    455549    def set_result(self, result, fid): 
    456550        """ 
    457551        """ 
    458         if fid in self.iterkeys(): 
     552        if fid in self: 
    459553            self[fid].set_result(result) 
    460554 
     
    470564        get result 
    471565        """ 
    472         if fid in self.iterkeys(): 
     566        if fid in self: 
    473567            return self[fid].get_result() 
    474568 
     
    490584        """ 
    491585        return self.graph_id 
    492  
    493  
    494 class FitProblem(FitProblemComponent): 
    495     """ 
    496     FitProblem class allows to link a model with the new name created in _on_model, 
    497     a name theory created with that model  and the data fitted with the model. 
    498     FitProblem is mostly used  as value of the dictionary by fitting module. 
    499     """ 
    500     def __init__(self): 
    501         FitProblemComponent.__init__(self) 
    502         """ 
    503         contains information about data and model to fit 
    504         """ 
    505         ## data used for fitting 
    506         self.fit_data = None 
    507         self.theory_data = None 
    508         self.residuals = None 
    509         # original data: should not be modified 
    510         self.original_data = None 
    511         ## the current model 
    512         self.model = None 
    513         ## if 1 this fit problem will be selected to fit , if 0 
    514         ## it will not be selected for fit 
    515         self.schedule = 0 
    516         ##list containing parameter name and value 
    517         self.list_param = [] 
    518         ## smear object to smear or not data1D 
    519         self.smearer_computed = False 
    520         self.smearer_enable = False 
    521         self.smearer_computer_value = None 
    522         ## fitting range 
    523         self.qmin = None 
    524         self.qmax = None 
    525         # fit weight 
    526         self.weight = None 
    527         self.result = None 
    528  
    529     def enable_smearing(self, flag=False): 
    530         """ 
    531         :param flag: bool.When flag is 1 get the computer smear value. When 
    532             flag is 0 ingore smear value. 
    533         """ 
    534         self.smearer_enable = flag 
    535  
    536     def set_smearer(self, smearer): 
    537         """ 
    538         save reference of  smear object on fitdata 
    539  
    540         :param smear: smear object from DataLoader 
    541  
    542         """ 
    543         self.smearer_computer_value = smearer 
    544  
    545     def get_smearer(self): 
    546         """ 
    547         return smear object 
    548         """ 
    549         if not self.smearer_enable: 
    550             return None 
    551         if not self.smearer_computed: 
    552             #smeari_selection should be call only once per fitproblem 
    553             self.smearer_computer_value = smear_selection(self.fit_data, 
    554                                                            self.model) 
    555             self.smearer_computed = True 
    556         return self.smearer_computer_value 
    557  
    558     def save_model_name(self, name): 
    559         """ 
    560         """ 
    561         self.name_per_page = name 
    562  
    563     def get_name(self): 
    564         """ 
    565         """ 
    566         return self.name_per_page 
    567  
    568     def set_model(self, model): 
    569         """ 
    570         associates each model with its new created name 
    571         :param model: model selected 
    572         :param name: name created for model 
    573         """ 
    574         self.model = model 
    575         self.smearer_computer_value = smear_selection(self.fit_data, 
    576                                                            self.model) 
    577         self.smearer_computed = True 
    578  
    579     def get_model(self): 
    580         """ 
    581         :return: saved model 
    582         """ 
    583         return self.model 
    584  
    585     def set_residuals(self, residuals): 
    586         """ 
    587         save a copy of residual 
    588         :param data: data selected 
    589         """ 
    590         self.residuals = residuals 
    591  
    592     def get_residuals(self): 
    593         """ 
    594         :return: residuals 
    595         """ 
    596         return self.residuals 
    597  
    598     def set_theory_data(self, data): 
    599         """ 
    600         save a copy of the data select to fit 
    601  
    602         :param data: data selected 
    603  
    604         """ 
    605         self.theory_data = copy.deepcopy(data) 
    606  
    607     def get_theory_data(self): 
    608         """ 
    609         :return: theory generated with the current model and data of this class 
    610         """ 
    611         return self.theory_data 
    612  
    613     def set_fit_data(self, data): 
    614         """ 
    615         Store data associated with this class 
    616         :param data: list of data selected 
    617         """ 
    618         self.original_data = None 
    619         self.fit_data = None 
    620         # original data: should not be modified 
    621         self.original_data = data 
    622         # fit data: used for fit and can be modified for convenience 
    623         self.fit_data = copy.deepcopy(data) 
    624         self.smearer_computer_value = smear_selection(self.fit_data, 
    625                                                            self.model) 
    626         self.smearer_computed = True 
    627         self.result = None 
    628  
    629     def get_fit_data(self): 
    630         """ 
    631         :return: data associate with this class 
    632         """ 
    633         return self.fit_data 
    634  
    635     def get_origin_data(self): 
    636         """ 
    637         """ 
    638         return self.original_data 
    639  
    640     def set_weight(self, is2d, flag=None): 
    641         """ 
    642         Received flag and compute error on data. 
    643         :param flag: flag to transform error of data. 
    644         :param is2d: flag to distinguish 1D to 2D Data 
    645         """ 
    646         from sas.sasgui.perspectives.fitting.utils import get_weight 
    647         # send original data for weighting 
    648         self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag) 
    649         if is2d: 
    650             self.fit_data.err_data = self.weight 
    651         else: 
    652             self.fit_data.dy = self.weight 
    653  
    654     def get_weight(self): 
    655         """ 
    656         returns weight array 
    657         """ 
    658         return self.weight 
    659  
    660     def set_param2fit(self, list): 
    661         """ 
    662         Store param names to fit (checked) 
    663         :param list: list of the param names 
    664         """ 
    665         self.list_param2fit = list 
    666  
    667     def get_param2fit(self): 
    668         """ 
    669         return the list param names to fit 
    670         """ 
    671         return self.list_param2fit 
    672  
    673     def set_model_param(self, name, value=None): 
    674         """ 
    675         Store the name and value of a parameter of this fitproblem's model 
    676         :param name: name of the given parameter 
    677         :param value: value of that parameter 
    678         """ 
    679         self.list_param.append([name, value]) 
    680  
    681     def get_model_param(self): 
    682         """ 
    683         return list of couple of parameter name and value 
    684         """ 
    685         return self.list_param 
    686  
    687     def schedule_tofit(self, schedule=0): 
    688         """ 
    689         set schedule to true to decide if this fit  must be performed 
    690         """ 
    691         self.schedule = schedule 
    692  
    693     def get_scheduled(self): 
    694         """ 
    695         return true or false if a problem as being schedule for fitting 
    696         """ 
    697         return self.schedule 
    698  
    699     def set_range(self, qmin=None, qmax=None): 
    700         """ 
    701         set fitting range 
    702         :param qmin: minimum value to consider for the fit range 
    703         :param qmax: maximum value to consider for the fit range 
    704         """ 
    705         self.qmin = qmin 
    706         self.qmax = qmax 
    707  
    708     def get_range(self): 
    709         """ 
    710         :return: fitting range 
    711  
    712         """ 
    713         return self.qmin, self.qmax 
    714  
    715     def clear_model_param(self): 
    716         """ 
    717         clear constraint info 
    718         """ 
    719         self.list_param = [] 
    720  
    721     def set_fit_tab_caption(self, caption): 
    722         """ 
    723         """ 
    724         self.fit_tab_caption = str(caption) 
    725  
    726     def get_fit_tab_caption(self): 
    727         """ 
    728         """ 
    729         return self.fit_tab_caption 
    730  
    731     def set_graph_id(self, id): 
    732         """ 
    733         Set graph id (from data_group_id at the time the graph produced) 
    734         """ 
    735         self.graph_id = id 
    736  
    737     def get_graph_id(self): 
    738         """ 
    739         Get graph_id 
    740         """ 
    741         return self.graph_id 
    742  
    743     def set_result(self, result): 
    744         """ 
    745         """ 
    746         self.result = result 
    747  
    748     def get_result(self): 
    749         """ 
    750         get result 
    751         """ 
    752         return self.result 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r66acafe r9706d88  
    2323import traceback 
    2424 
     25import bumps.options 
     26from bumps.gui.fit_dialog import show_fit_config 
     27try: 
     28    from bumps.gui.fit_dialog import EVT_FITTER_CHANGED 
     29except ImportError: 
     30    # CRUFT: bumps 0.7.5.8 and below 
     31    EVT_FITTER_CHANGED = None  # type: wx.PyCommandEvent 
     32 
    2533from sas.sascalc.dataloader.loader import Loader 
     34from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit 
     35from sas.sascalc.fit.pagestate import Reader, PageState, SimFitPageState 
     36from sas.sascalc.fit import models 
     37 
    2638from sas.sasgui.guiframe.dataFitting import Data2D 
    2739from sas.sasgui.guiframe.dataFitting import Data1D 
     
    3446from sas.sasgui.guiframe.plugin_base import PluginBase 
    3547from sas.sasgui.guiframe.data_processor import BatchCell 
    36 from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit 
    37 from sas.sasgui.perspectives.fitting.console import ConsoleUpdate 
    38 from sas.sasgui.perspectives.fitting.fitproblem import FitProblemDictionary 
    39 from sas.sasgui.perspectives.fitting.fitpanel import FitPanel 
    40 from sas.sasgui.perspectives.fitting.resultpanel import ResultPanel, PlotResultEvent 
    41  
    42 from sas.sasgui.perspectives.fitting.fit_thread import FitThread 
    43 from sas.sasgui.perspectives.fitting.pagestate import Reader 
    44 from sas.sasgui.perspectives.fitting.fitpage import Chi2UpdateEvent 
     48from sas.sasgui.guiframe.gui_manager import MDIFrame 
     49from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     50 
    4551from sas.sasgui.perspectives.calculator.model_editor import TextDialog 
    4652from sas.sasgui.perspectives.calculator.model_editor import EditorWindow 
    47 from sas.sasgui.guiframe.gui_manager import MDIFrame 
    48 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
    49 from sas.sasgui.perspectives.fitting.gpu_options import GpuOptions 
    50  
    51 from . import models 
     53from sas.sasgui.perspectives.calculator.pyconsole import PyConsole 
     54 
     55from .fitting_widgets import DataDialog 
     56from .fit_thread import FitThread 
     57from .fitpage import Chi2UpdateEvent 
     58from .console import ConsoleUpdate 
     59from .fitproblem import FitProblemDictionary 
     60from .fitpanel import FitPanel 
     61from .model_thread import Calc1D, Calc2D 
     62from .resultpanel import ResultPanel, PlotResultEvent 
     63from .gpu_options import GpuOptions 
    5264 
    5365logger = logging.getLogger(__name__) 
     
    6375    ON_MAC = True 
    6476 
    65 import bumps.options 
    66 from bumps.gui.fit_dialog import show_fit_config 
    67 try: 
    68     from bumps.gui.fit_dialog import EVT_FITTER_CHANGED 
    69 except ImportError: 
    70     # CRUFT: bumps 0.7.5.8 and below 
    71     EVT_FITTER_CHANGED = None  # type: wx.PyCommandEvent 
    7277 
    7378class Plugin(PluginBase): 
     
    240245        event_id = event.GetId() 
    241246        label = self.edit_menu.GetLabel(event_id) 
    242         from sas.sasgui.perspectives.calculator.pyconsole import PyConsole 
    243247        filename = os.path.join(models.find_plugins_dir(), label) 
    244248        frame = PyConsole(parent=self.parent, manager=self, 
     
    290294                        break 
    291295        except Exception: 
    292             import traceback; traceback.print_exc() 
     296            traceback.print_exc() 
    293297            msg = 'Delete Error: \nCould not delete the file; Check if in use.' 
    294298            wx.MessageBox(msg, 'Error') 
     
    300304        event_id = event.GetId() 
    301305        model_manager = models.ModelManager() 
    302         model_list = model_manager.get_model_name_list() 
     306        model_list = model_manager.composable_models() 
    303307        plug_dir = models.find_plugins_dir() 
    304308        textdial = TextDialog(None, self, wx.ID_ANY, 'Easy Sum/Multi(p1, p2) Editor', 
     
    340344            self.set_edit_menu_helper(self.parent, self.edit_custom_model) 
    341345            self.set_edit_menu_helper(self.parent, self.delete_custom_model) 
    342             temp = self.fit_panel.reset_pmodel_list() 
    343             if temp: 
    344                 # Set the new plugin model list for all fit pages 
    345                 for uid, page in self.fit_panel.opened_pages.iteritems(): 
    346                     if hasattr(page, "formfactorbox"): 
    347                         page.model_list_box = temp 
    348                         current_val = page.formfactorbox.GetLabel() 
    349                         #if page.plugin_rbutton.GetValue(): 
    350                         mod_cat = page.categorybox.GetStringSelection() 
    351                         if mod_cat == custom_model: 
    352                             #pos = page.formfactorbox.GetSelection() 
    353                             page._show_combox_helper() 
    354                             new_val = page.formfactorbox.GetLabel() 
    355                             if current_val != new_val and new_val != '': 
    356                                 page.formfactorbox.SetLabel(new_val) 
    357                             else: 
    358                                 page.formfactorbox.SetLabel(current_val) 
    359                         if hasattr(page, 'structurebox'): 
    360                             selected_name = page.structurebox.GetStringSelection() 
    361  
    362                             page.structurebox.Clear() 
    363                             page.initialize_combox() 
    364  
    365                             index = page.structurebox.FindString(selected_name) 
    366                             if index == -1: 
    367                                 index = 0 
    368                             page.structurebox.SetSelection(index) 
    369                             page._on_select_model() 
    370         except: 
     346            new_pmodel_list = self.fit_panel.reset_pmodel_list() 
     347            if not new_pmodel_list: 
     348                return 
     349            # Set the new plugin model list for all fit pages 
     350            for uid, page in self.fit_panel.opened_pages.iteritems(): 
     351                if hasattr(page, "formfactorbox"): 
     352                    page.model_list_box = new_pmodel_list 
     353                    mod_cat = page.categorybox.GetStringSelection() 
     354                    if mod_cat == custom_model: 
     355                        box = page.formfactorbox 
     356                        model_name = box.GetValue() 
     357                        model = (box.GetClientData(box.GetCurrentSelection()) 
     358                                 if model_name else None) 
     359                        page._show_combox_helper() 
     360                        new_index = box.FindString(model_name) 
     361                        new_model = (box.GetClientData(new_index) 
     362                                     if new_index >= 0 else None) 
     363                        if new_index >= 0: 
     364                            box.SetStringSelection(model_name) 
     365                        else: 
     366                            box.SetStringSelection('') 
     367                        if model and new_model != model: 
     368                            page._on_select_model(keep_pars=True) 
     369                    if hasattr(page, "structurebox"): 
     370                        selected_name = page.structurebox.GetStringSelection() 
     371 
     372                        page.structurebox.Clear() 
     373                        page.initialize_combox() 
     374 
     375                        index = page.structurebox.FindString(selected_name) 
     376                        if index == -1: 
     377                            index = 0 
     378                        page.structurebox.SetSelection(index) 
     379                        page._on_select_model() 
     380        except Exception: 
    371381            logger.error("update_custom_combo: %s", sys.exc_value) 
    372382 
     
    378388        #new_model_menu = wx.Menu() 
    379389        self.edit_model_menu.Append(wx_id, 'New Plugin Model', 
    380                                    'Add a new model function') 
     390                                    'Add a new model function') 
    381391        wx.EVT_MENU(owner, wx_id, self.make_new_model) 
    382392 
     
    575585        else: 
    576586            if len(data_list) > MAX_NBR_DATA: 
    577                 from fitting_widgets import DataDialog 
    578587                dlg = DataDialog(data_list=data_list, nb_data=MAX_NBR_DATA) 
    579588                if dlg.ShowModal() == wx.ID_OK: 
     
    620629        : param datainfo: data 
    621630        """ 
    622         from pagestate import PageState 
    623         from simfitpage import SimFitPageState 
    624631        if isinstance(state, PageState): 
    625632            state = state.clone() 
    626633            self.temp_state.append(state) 
    627634        elif isinstance(state, SimFitPageState): 
    628             state.load_from_save_state(self) 
     635            if self.fit_panel.sim_page is None: 
     636                self.fit_panel.add_sim_page() 
     637            self.fit_panel.sim_page.load_from_save_state(state) 
    629638        else: 
    630639            self.temp_state = [] 
     
    661670                self.parent.add_data(data_list={data.id: data}) 
    662671                wx.PostEvent(self.parent, NewPlotEvent(plot=data, 
    663                                         title=data.title)) 
     672                             title=data.title)) 
    664673                #need to be fix later make sure we are sendind guiframe.data 
    665674                #to panel 
     
    672681                self.parent.add_data(data_list={data.id: data}) 
    673682                wx.PostEvent(self.parent, NewPlotEvent(plot=data, 
    674                                         title=data.title)) 
     683                             title=data.title)) 
    675684                page = self.add_fit_page([data]) 
    676685                caption = page.window_caption 
    677686                self.store_data(uid=page.uid, data_list=page.get_data_list(), 
    678                         caption=caption) 
     687                                caption=caption) 
    679688                self.mypanels.append(page) 
    680689 
     
    793802        """ 
    794803        if item.find(".") >= 0: 
    795             param_names = re.split("\.", item) 
     804            param_names = re.split(r"\.", item) 
    796805            model_name = param_names[0] 
    797806            ##Assume max len is 3; eg., M0.radius.width 
     
    896905 
    897906            self.draw_model(model=model, data=data, page_id=uid, smearer=smear, 
    898                 enable1D=enable1D, enable2D=enable2D, 
    899                 qmin=qmin, qmax=qmax, weight=weight) 
     907                            enable1D=enable1D, enable2D=enable2D, 
     908                            qmin=qmin, qmax=qmax, weight=weight) 
    900909 
    901910    def draw_model(self, model, page_id, data=None, smearer=None, 
     
    940949            ## draw model 2D with no initial data 
    941950            self._draw_model2D(model=model, 
    942                                 page_id=page_id, 
    943                                 data=data, 
    944                                 enable2D=enable2D, 
    945                                 smearer=smearer, 
    946                                 qmin=qmin, 
    947                                 qmax=qmax, 
    948                                 fid=fid, 
    949                                 weight=weight, 
    950                                 state=state, 
    951                                 toggle_mode_on=toggle_mode_on, 
    952                                 update_chisqr=update_chisqr, 
    953                                 source=source) 
     951                               page_id=page_id, 
     952                               data=data, 
     953                               enable2D=enable2D, 
     954                               smearer=smearer, 
     955                               qmin=qmin, 
     956                               qmax=qmax, 
     957                               fid=fid, 
     958                               weight=weight, 
     959                               state=state, 
     960                               toggle_mode_on=toggle_mode_on, 
     961                               update_chisqr=update_chisqr, 
     962                               source=source) 
    954963 
    955964    def onFit(self, uid): 
     
    960969        :param uid: id related to the panel currently calling this fit function. 
    961970        """ 
    962         if uid is None: raise RuntimeError("no page to fit") # Should never happen 
     971        if uid is None: 
     972            raise RuntimeError("no page to fit") # Should never happen 
    963973 
    964974        sim_page_uid = getattr(self.sim_page, 'uid', None) 
     
    9941004                    page = self.fit_panel.get_page_by_id(page_id) 
    9951005                    self.set_fit_weight(uid=page.uid, 
    996                                      flag=page.get_weight_flag(), 
    997                                      is2d=page._is_2D()) 
     1006                                        flag=page.get_weight_flag(), 
     1007                                        is2d=page._is_2D()) 
    9981008                    if not page.param_toFit: 
    9991009                        msg = "No fitting parameters for %s" % page.window_caption 
     
    10191029                            fitter = sim_fitter 
    10201030                        self._add_problem_to_fit(fitproblem=fitproblem, 
    1021                                              pars=pars, 
    1022                                              fitter=fitter, 
    1023                                              fit_id=fit_id) 
     1031                                                 pars=pars, 
     1032                                                 fitter=fitter, 
     1033                                                 fit_id=fit_id) 
    10241034                        fit_id += 1 
    10251035                    list_page_id.append(page_id) 
     
    10681078            ## Perform more than 1 fit at the time 
    10691079            calc_fit = FitThread(handler=handler, 
    1070                                     fn=fitter_list, 
    1071                                     batch_inputs=batch_inputs, 
    1072                                     batch_outputs=batch_outputs, 
    1073                                     page_id=list_page_id, 
    1074                                     updatefn=handler.update_fit, 
    1075                                     completefn=self._fit_completed) 
     1080                                 fn=fitter_list, 
     1081                                 batch_inputs=batch_inputs, 
     1082                                 batch_outputs=batch_outputs, 
     1083                                 page_id=list_page_id, 
     1084                                 updatefn=handler.update_fit, 
     1085                                 completefn=self._fit_completed) 
    10761086        #self.fit_thread_list[current_page_id] = calc_fit 
    10771087        self.fit_thread_list[uid] = calc_fit 
     
    11341144                evt = StatusEvent(status=msg, info="warning") 
    11351145                wx.PostEvent(self.parent, evt) 
    1136         except: 
     1146        except Exception: 
    11371147            msg = "Creating Fit page: %s" % sys.exc_value 
    11381148            wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 
     
    11581168                    group_id = str(page.uid) + " Model1D" 
    11591169                    wx.PostEvent(self.parent, 
    1160                              NewPlotEvent(group_id=group_id, 
    1161                                                action="delete")) 
     1170                                 NewPlotEvent(group_id=group_id, 
     1171                                              action="delete")) 
    11621172                    self.parent.update_data(prev_data=theory_data, 
    1163                                              new_data=data) 
     1173                                            new_data=data) 
    11641174            else: 
    11651175                if theory_data is not None: 
     
    11671177                    data.group_id = theory_data.group_id 
    11681178                    wx.PostEvent(self.parent, 
    1169                              NewPlotEvent(group_id=group_id, 
    1170                                                action="delete")) 
     1179                                 NewPlotEvent(group_id=group_id, 
     1180                                              action="delete")) 
    11711181                    self.parent.update_data(prev_data=theory_data, 
    1172                                              new_data=data) 
     1182                                            new_data=data) 
    11731183        self.store_data(uid=page.uid, data_list=page.get_data_list(), 
    11741184                        caption=page.window_caption) 
     
    14791489        if "Data" not in batch_outputs.keys(): 
    14801490            batch_outputs["Data"] = [] 
    1481         from sas.sasgui.guiframe.data_processor import BatchCell 
    14821491        cell = BatchCell() 
    14831492        cell.label = data.name 
     
    15791588                    except KeyboardInterrupt: 
    15801589                        fit_msg += "\nSingular point: Fitting stopped." 
    1581                     except: 
     1590                    except Exception: 
    15821591                        fit_msg += "\nSingular point: Fitting error occurred." 
    15831592                if fit_msg: 
    1584                    evt = StatusEvent(status=fit_msg, info="warning", type="stop") 
    1585                    wx.PostEvent(self.parent, evt) 
    1586  
    1587         except: 
     1593                    evt = StatusEvent(status=fit_msg, info="warning", type="stop") 
     1594                    wx.PostEvent(self.parent, evt) 
     1595 
     1596        except Exception: 
    15881597            msg = ("Fit completed but the following error occurred: %s" 
    15891598                   % sys.exc_value) 
    1590             #import traceback; msg = "\n".join((traceback.format_exc(), msg)) 
     1599            #msg = "\n".join((traceback.format_exc(), msg)) 
    15911600            evt = StatusEvent(status=msg, info="warning", type="stop") 
    15921601            wx.PostEvent(self.parent, evt) 
     
    17431752                                                  fid=data.id) 
    17441753        self.parent.update_theory(data_id=data.id, theory=new_plot, 
    1745                                    state=state) 
     1754                                  state=state) 
    17461755        return new_plot 
    17471756 
     
    17671776        # Create the new theories 
    17681777        if unsmeared_model is not None: 
    1769             unsmeared_model_plot = self.create_theory_1D(x, unsmeared_model,  
     1778            unsmeared_model_plot = self.create_theory_1D(x, unsmeared_model, 
    17701779                                  page_id, model, data, state, 
    17711780                                  data_description=model.name + " unsmeared", 
     
    17741783 
    17751784            if unsmeared_data is not None and unsmeared_error is not None: 
    1776                 unsmeared_data_plot = self.create_theory_1D(x, unsmeared_data,  
     1785                unsmeared_data_plot = self.create_theory_1D(x, unsmeared_data, 
    17771786                                      page_id, model, data, state, 
    17781787                                      data_description="Data unsmeared", 
     
    17921801            plots_to_update.append(pq_plot) 
    17931802        # Update the P(Q), S(Q) and unsmeared theory plots if they exist 
    1794         wx.PostEvent(self.parent, NewPlotEvent(plots=plots_to_update,  
     1803        wx.PostEvent(self.parent, NewPlotEvent(plots=plots_to_update, 
    17951804                                              action='update')) 
    17961805 
     
    18081817 
    18091818        self.page_finder[page_id].set_theory_data(data=new_plot, 
    1810                                                       fid=data.id) 
     1819                                                  fid=data.id) 
    18111820        if toggle_mode_on: 
    18121821            wx.PostEvent(self.parent, 
    18131822                         NewPlotEvent(group_id=str(page_id) + " Model2D", 
    1814                                           action="Hide")) 
     1823                                      action="Hide")) 
    18151824        else: 
    18161825            if update_chisqr: 
    1817                 wx.PostEvent(current_pg, 
    1818                              Chi2UpdateEvent(output=self._cal_chisqr( 
    1819                                                                 data=data, 
    1820                                                                 fid=fid, 
    1821                                                                 weight=weight, 
    1822                                                                 page_id=page_id, 
    1823                                                                 index=index))) 
     1826                output = self._cal_chisqr(data=data, 
     1827                                          fid=fid, 
     1828                                          weight=weight, 
     1829                                          page_id=page_id, 
     1830                                          index=index) 
     1831                wx.PostEvent(current_pg, Chi2UpdateEvent(output=output)) 
    18241832            else: 
    18251833                self._plot_residuals(page_id=page_id, data=data, fid=fid, 
     
    18291837            logger.error("Using the present parameters the model does not return any finite value. ") 
    18301838            msg = "Computing Error: Model did not return any finite value." 
    1831             wx.PostEvent(self.parent, StatusEvent(status = msg, info="error")) 
     1839            wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 
    18321840        else: 
    18331841            msg = "Computation  completed!" 
     
    18541862 
    18551863    def _complete2D(self, image, data, model, page_id, elapsed, index, qmin, 
    1856                 qmax, fid=None, weight=None, toggle_mode_on=False, state=None, 
    1857                      update_chisqr=True, source='model', plot_result=True): 
     1864                    qmax, fid=None, weight=None, toggle_mode_on=False, state=None, 
     1865                    update_chisqr=True, source='model', plot_result=True): 
    18581866        """ 
    18591867        Complete get the result of modelthread and create model 2D 
     
    18961904                                                  fid=data.id) 
    18971905        self.parent.update_theory(data_id=data.id, 
    1898                                        theory=new_plot, 
    1899                                        state=state) 
     1906                                  theory=new_plot, 
     1907                                  state=state) 
    19001908        current_pg = self.fit_panel.get_page_by_id(page_id) 
    19011909        title = new_plot.title 
    19021910        if not source == 'fit' and plot_result: 
    1903             wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 
    1904                                                title=title)) 
     1911            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title)) 
    19051912        if toggle_mode_on: 
    19061913            wx.PostEvent(self.parent, 
    1907                              NewPlotEvent(group_id=str(page_id) + " Model1D", 
    1908                                                action="Hide")) 
     1914                         NewPlotEvent(group_id=str(page_id) + " Model1D", 
     1915                                      action="Hide")) 
    19091916        else: 
    19101917            # Chisqr in fitpage 
    19111918            if update_chisqr: 
    1912                 wx.PostEvent(current_pg, 
    1913                              Chi2UpdateEvent(output=self._cal_chisqr(data=data, 
    1914                                                                     weight=weight, 
    1915                                                                     fid=fid, 
    1916                                                          page_id=page_id, 
    1917                                                          index=index))) 
     1919                output = self._cal_chisqr(data=data, 
     1920                                          weight=weight, 
     1921                                          fid=fid, 
     1922                                          page_id=page_id, 
     1923                                          index=index) 
     1924                wx.PostEvent(current_pg, Chi2UpdateEvent(output=output)) 
    19181925            else: 
    19191926                self._plot_residuals(page_id=page_id, data=data, fid=fid, 
    1920                                       index=index, weight=weight) 
     1927                                     index=index, weight=weight) 
    19211928 
    19221929        if not number_finite: 
    19231930            logger.error("Using the present parameters the model does not return any finite value. ") 
    19241931            msg = "Computing Error: Model did not return any finite value." 
    1925             wx.PostEvent(self.parent, StatusEvent(status = msg, info="error")) 
     1932            wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 
    19261933        else: 
    19271934            msg = "Computation  completed!" 
     
    19391946                      weight=None, 
    19401947                      toggle_mode_on=False, 
    1941                        update_chisqr=True, source='model'): 
     1948                      update_chisqr=True, source='model'): 
    19421949        """ 
    19431950        draw model in 2D 
     
    19541961            return None 
    19551962        try: 
    1956             from model_thread import Calc2D 
    19571963            ## If a thread is already started, stop it 
    19581964            if (self.calc_2D is not None) and self.calc_2D.isrunning(): 
     
    19861992    def _draw_model1D(self, model, page_id, data, 
    19871993                      qmin, qmax, smearer=None, 
    1988                 state=None, 
    1989                 weight=None, 
    1990                 fid=None, 
    1991                 toggle_mode_on=False, update_chisqr=True, source='model', 
    1992                 enable1D=True): 
     1994                      state=None, weight=None, fid=None, 
     1995                      toggle_mode_on=False, update_chisqr=True, source='model', 
     1996                      enable1D=True): 
    19931997        """ 
    19941998        Draw model 1D from loaded data1D 
     
    20012005            return 
    20022006        try: 
    2003             from model_thread import Calc1D 
    20042007            ## If a thread is already started, stop it 
    20052008            if (self.calc_1D is not None) and self.calc_1D.isrunning(): 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    r0f9ea1c r69363c7  
    11""" 
    2     Calculation thread for modeling 
     2Calculation thread for modeling 
    33""" 
    44 
    55import time 
     6import math 
     7 
    68import numpy as np 
    7 import math 
     9 
    810from sas.sascalc.data_util.calcthread import CalcThread 
    911from sas.sascalc.fit.MultiplicationModel import MultiplicationModel 
     
    2830                 worktime=0.04, 
    2931                 exception_handler=None, 
    30                  ): 
     32                ): 
    3133        CalcThread.__init__(self, completefn, updatefn, yieldtime, worktime, 
    3234                            exception_handler=exception_handler) 
     
    5759        if self.qmax is None: 
    5860            if self.data is not None: 
    59                 newx = math.pow(max(math.fabs(self.data.xmax), 
    60                                    math.fabs(self.data.xmin)), 2) 
    61                 newy = math.pow(max(math.fabs(self.data.ymax), 
    62                                    math.fabs(self.data.ymin)), 2) 
    63                 self.qmax = math.sqrt(newx + newy) 
     61                newx = max(math.fabs(self.data.xmax), math.fabs(self.data.xmin)) 
     62                newy = max(math.fabs(self.data.ymax), math.fabs(self.data.ymin)) 
     63                self.qmax = math.sqrt(newx**2 + newy**2) 
    6464 
    6565        if self.data is None: 
     
    6868 
    6969        # Define matrix where data will be plotted 
    70         radius = np.sqrt((self.data.qx_data * self.data.qx_data) + \ 
    71                     (self.data.qy_data * self.data.qy_data)) 
     70        radius = np.sqrt(self.data.qx_data**2 + self.data.qy_data**2) 
    7271 
    7372        # For theory, qmax is based on 1d qmax 
    7473        # so that must be mulitified by sqrt(2) to get actual max for 2d 
    7574        index_model = (self.qmin <= radius) & (radius <= self.qmax) 
    76         index_model = index_model & self.data.mask 
    77         index_model = index_model & np.isfinite(self.data.data) 
     75        index_model &= self.data.mask 
     76        index_model &= np.isfinite(self.data.data) 
    7877 
    7978        if self.smearer is not None: 
     
    101100        elapsed = time.time() - self.starttime 
    102101        self.complete(image=output, 
    103                        data=self.data, 
    104                        page_id=self.page_id, 
    105                        model=self.model, 
    106                        state=self.state, 
    107                        toggle_mode_on=self.toggle_mode_on, 
    108                        elapsed=elapsed, 
    109                        index=index_model, 
    110                        fid=self.fid, 
    111                        qmin=self.qmin, 
    112                        qmax=self.qmax, 
    113                        weight=self.weight, 
    114                        #qstep=self.qstep, 
    115                        update_chisqr=self.update_chisqr, 
    116                        source=self.source) 
     102                      data=self.data, 
     103                      page_id=self.page_id, 
     104                      model=self.model, 
     105                      state=self.state, 
     106                      toggle_mode_on=self.toggle_mode_on, 
     107                      elapsed=elapsed, 
     108                      index=index_model, 
     109                      fid=self.fid, 
     110                      qmin=self.qmin, 
     111                      qmax=self.qmax, 
     112                      weight=self.weight, 
     113                      #qstep=self.qstep, 
     114                      update_chisqr=self.update_chisqr, 
     115                      source=self.source) 
    117116 
    118117 
     
    138137                 worktime=0.01, 
    139138                 exception_handler=None, 
    140                  ): 
     139                ): 
    141140        """ 
    142141        """ 
     
    193192                                                        * unsmeared_output[first_bin:last_bin+1]\ 
    194193                                                        / output[first_bin:last_bin+1] 
    195                 unsmeared_output=unsmeared_output[index] 
    196                 unsmeared_data=unsmeared_data[index] 
    197                 unsmeared_error=unsmeared_error 
     194                unsmeared_output = unsmeared_output[index] 
     195                unsmeared_data = unsmeared_data[index] 
     196                unsmeared_error = unsmeared_error 
    198197        else: 
    199198            output[index] = self.model.evalDistribution(self.data.x[index]) 
     
    243242    class CalcCommandline: 
    244243        def __init__(self, n=20000): 
    245             #print thread.get_ident() 
    246             from sas.models.CylinderModel import CylinderModel 
    247  
    248             model = CylinderModel() 
    249  
    250  
    251             print model.runXY([0.01, 0.02]) 
     244            #print(thread.get_ident()) 
     245 
     246            from sasmodels.sasview_model import _make_standard_model 
     247            cylinder = _make_standard_model('cylinder') 
     248            model = cylinder() 
     249 
     250            print(model.runXY([0.01, 0.02])) 
    252251 
    253252            qmax = 0.01 
     
    258257            y = numpy.arange(-qmax, qmax+qstep*0.01, qstep) 
    259258 
    260  
    261259            calc_thread_2D = Calc2D(x, y, None, model.clone(),None, 
    262260                                    -qmax, qmax,qstep, 
    263                                             completefn=self.complete, 
    264                                             updatefn=self.update , 
    265                                             yieldtime=0.0) 
     261                                    completefn=self.complete, 
     262                                    updatefn=self.update , 
     263                                    yieldtime=0.0) 
    266264 
    267265            calc_thread_2D.queue() 
     
    272270 
    273271        def update(self,output): 
    274             print "update" 
     272            print("update") 
    275273 
    276274        def complete(self, image, data, model, elapsed, qmin, qmax,index, qstep ): 
    277             print "complete" 
     275            print("complete") 
    278276            self.done = True 
    279277 
  • src/sas/sasgui/perspectives/fitting/report_dialog.py

    r7432acb r69a6897  
    3838        # number of images of plot 
    3939        self.nimages = len(self.report_list[2]) 
    40  
    41         if self.report_list[2] is not None: 
    42             # put image path in the report string 
    43             if len(self.report_list[2]) == 1: 
    44                 self.report_html = self.report_list[0] % \ 
    45                                     "memory:img_fit0.png" 
    46             elif len(self.report_list[2]) == 2: 
    47                 self.report_html = self.report_list[0] % \ 
    48                                     ("memory:img_fit0.png", 
    49                                      "memory:img_fit1.png") 
    50             # allows up to three images 
    51             else: 
    52                 self.report_html = self.report_list[0] % \ 
    53                                     ("memory:img_fit0.png", 
    54                                      "memory:img_fit1.png", 
    55                                      "memory:img_fit2.png") 
    56         else: 
    57             self.report_html = self.report_list[0] 
     40        self.report_html = self.report_list[0] 
    5841        # layout 
    5942        self._setup_layout() 
     
    7457 
    7558        fName = dlg.GetPath() 
     59        basename = os.path.splitext(fName)[0] 
    7660        ext_num = dlg.GetFilterIndex() 
     61        dlg.Destroy() 
     62 
     63        if ext_num == 0 and self.index_offset == 0:  # has pdf 
     64            ext = ".pdf" 
     65        elif ext_num == 1 - self.index_offset: 
     66            ext = ".html" 
     67        elif ext_num == 2 - self.index_offset: 
     68            ext = ".txt" 
     69        else: 
     70            logger.warn("unknown export format in report dialog") 
     71            return 
     72        filename = basename + ext 
     73 
     74        # save figures 
     75        pictures = [] 
     76        for num in range(self.nimages): 
     77            pic_name = basename + '_img%s.png' % num 
     78            # save the image for use with pdf writer 
     79            self.report_list[2][num].savefig(pic_name) 
     80            pictures.append(pic_name) 
     81 
     82        # translate png references int html from in-memory name to on-disk name 
     83        html = self.report_html.replace("memory:img_fit", basename+'_img') 
    7784 
    7885        #set file extensions 
    7986        img_ext = [] 
    80         pic_fname = [] 
    81         #PDF 
    82         if ext_num == (0 + 2 * self.index_offset): 
    83             # TODO: Sort this case out 
    84             ext = '.pdf' 
     87        if ext == ".pdf": 
     88            # write pdf as a pdf file 
     89            pdf = self.HTML2PDF(data=html, filename=filename) 
    8590 
    86             fName = os.path.splitext(fName)[0] + ext 
    87             dlg.Destroy() 
    88             #pic (png) file path/name 
    89             for num in range(self.nimages): 
    90                 im_ext = '_img%s.png' % num 
    91                 #img_ext.append(im_ext) 
    92                 pic_name = os.path.splitext(fName)[0] + im_ext 
    93                 pic_fname.append(pic_name) 
    94                 # save the image for use with pdf writer 
    95                 self.report_list[2][num].savefig(pic_name) 
     91            # delete images used to create the pdf 
     92            for pic_name in pictures: 
     93                os.remove(pic_name) 
    9694 
    97             #put the image path in html string 
    98             report_frame = self.report_list[0] 
    99             #put image name strings into the html file 
    100             #Note:The str for pic_fname shouldn't be removed. 
    101             if self.nimages == 1: 
    102                 html = report_frame % str(pic_fname[0]) 
    103             elif self.nimages == 2: 
    104                 html = report_frame % (str(pic_fname[0]), str(pic_fname[1])) 
    105             elif self.nimages == 3: 
    106                 html = report_frame % (str(pic_fname[0]), str(pic_fname[1]), 
    107                                           str(pic_fname[2])) 
    108  
    109             # make/open file in case of absence 
    110             f = open(fName, 'w') 
    111             f.close() 
    112             # write pdf as a pdf file 
    113             pdf = self.HTML2PDF(data=html, filename=fName) 
    114  
    115             #open pdf 
     95            #open pdf viewer 
    11696            if pdf: 
    11797                try: 
    118                     #Windows 
    119                     os.startfile(str(fName)) 
    120                 except: 
    121                     try: 
    122                         #Mac 
     98                    if os.name == 'nt':  # Windows 
     99                        os.startfile(fName) 
     100                    elif sys.platform == "darwin":  # Mac 
    123101                        os.system("open %s" % fName) 
    124                     except: 
    125                         #DO not open 
    126                         pass 
    127             #delete image file 
    128             for num in range(self.nimages): 
    129                 os.remove(pic_fname[num]) 
    130             return 
    131         #HTML + png(graph) 
    132         elif ext_num == (1 - self.index_offset): 
    133             ext = '.html' 
    134             for num in range(self.nimages): 
    135                 img_ext.append('_img4html%s.png' % num) 
    136             report_frame = self.report_list[0] 
    137         #TEXT + pdf(graph) 
    138         elif ext_num == (2 - self.index_offset): 
    139             ext = '.txt' 
    140             # changing the image extension actually changes the image 
    141             # format on saving 
    142             for num in range(self.nimages): 
    143                 img_ext.append('_img4txt%s.pdf' % num) 
    144             report = self.report_list[1] 
    145         else: 
    146             return 
     102                except Exception as exc: 
     103                    # cannot open pdf 
     104                    logging.error(str(exc)) 
    147105 
    148         #file name 
    149         fName = os.path.splitext(fName)[0] + ext 
    150         dlg.Destroy() 
     106        elif ext == ".html": 
     107            with open(filename, 'w') as f: 
     108                f.write(html) 
    151109 
    152         #pic (png) file path/name 
    153         for num in range(self.nimages): 
    154             pic_name = os.path.splitext(fName)[0] + img_ext[num] 
    155             pic_fname.append(pic_name) 
    156         #put the image path in html string 
    157         if ext_num == (1 - self.index_offset): 
    158             if self.nimages == 1: 
    159                 report = report_frame % os.path.basename(pic_fname[0]) 
    160             elif self.nimages == 2: 
    161                 report = report_frame % (os.path.basename(pic_fname[0]), 
    162                                          os.path.basename(pic_fname[1])) 
    163             elif self.nimages == 3: 
    164                 report = report_frame % (os.path.basename(pic_fname[0]), 
    165                                          os.path.basename(pic_fname[1]), 
    166                                          os.path.basename(pic_fname[2])) 
    167         f = open(fName, 'w') 
    168         f.write(report) 
    169         f.close() 
     110        elif ext == ".txt": 
     111            with open(filename, 'w') as f: 
     112                f.write(self.report_list[1]) 
     113 
    170114        self.Update() 
    171         #save png file using pic_fname 
    172         for num in range(self.nimages): 
    173             self.report_list[2][num].savefig(pic_fname[num]) 
  • src/sas/sasgui/perspectives/fitting/simfitpage.py

    r9804394 r24d9e84  
    22    Simultaneous or Batch fit page 
    33""" 
    4 # Note that this is used for both Simultaneous/Constrained fit AND for  
     4# Note that this is used for both Simultaneous/Constrained fit AND for 
    55# 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  
     6# There are the a half dozen or so places where an if statement is used as in 
    77# if not batch_on: 
    88#     xxxx 
     
    1111# This is just wrong but dont have time to fix this go. Proper approach would be 
    1212# 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  
     13# level class from which a contrained/simultaneous fit page and a combined 
    1414# batch page inherit. 
    1515# 
     
    2323from wx.lib.scrolledpanel import ScrolledPanel 
    2424 
     25from sas.sascalc.fit.pagestate import SimFitPageState 
    2526from sas.sasgui.guiframe.events import StatusEvent, PanelOnFocusEvent 
    2627from sas.sasgui.guiframe.panel_base import PanelBase 
     
    6061 
    6162    return fittable_param 
    62  
    6363 
    6464class SimultaneousFitPage(ScrolledPanel, PanelBase): 
     
    157157        return self.state 
    158158 
     159    def load_from_save_state(self, sim_state): 
     160        """ 
     161        Load in a simultaneous/constrained fit from a save state 
     162        :param fit: Fitpanel object 
     163        :return: None 
     164        """ 
     165        init_map = {} 
     166        final_map = {} 
     167        # Process each model and associate old M# with new M# 
     168        i = 0 
     169        for model in self.model_list: 
     170            model_id = self._format_id(model[1].keys()[0]) 
     171            for saved_model in sim_state.model_list: 
     172                save_id = saved_model.pop('name') 
     173                saved_model['name'] = save_id 
     174                save_id = self._format_id(save_id) 
     175                if save_id == model_id: 
     176                    model_map[saved_model.pop('fit_page_source')] = \ 
     177                        model[3].name 
     178                    check = bool(saved_model.pop('checked')) 
     179                    self.model_list[i][0].SetValue(check) 
     180                    inter_id = str(i)*5 
     181                    init_map[saved_model.pop('fit_page_source')] = inter_id 
     182                    final_map[inter_id] = model[3].name 
     183                    check = bool(saved_model.pop('checked')) 
     184                    self.model_list[i][0].SetValue(check) 
     185                    break 
     186            i += 1 
     187 
     188        self.check_model_name(None) 
     189 
     190        if len(sim_state.constraints_list) > 0: 
     191            self.hide_constraint.SetValue(False) 
     192            self.show_constraint.SetValue(True) 
     193            self._display_constraint(None) 
     194 
     195        for index, item in enumerate(sim_state.constraints_list): 
     196            model_cbox = item.pop('model_cbox') 
     197            if model_cbox != "": 
     198                constraint_value = item.pop('constraint') 
     199                param = item.pop('param_cbox') 
     200                equality = item.pop('egal_txt') 
     201                for key, value in init_map.items(): 
     202                    model_cbox = model_cbox.replace(key, value) 
     203                    constraint_value = constraint_value.replace(key, value) 
     204                for key, value in final_map.items(): 
     205                    model_cbox = model_cbox.replace(key, value) 
     206                    constraint_value = constraint_value.replace(key, value) 
     207 
     208                self.constraints_list[index][0].SetValue(model_cbox) 
     209                self._on_select_model(None) 
     210                self.constraints_list[index][1].SetValue(param) 
     211                self.constraints_list[index][2].SetLabel(equality) 
     212                self.constraints_list[index][3].SetValue(constraint_value) 
     213                self._on_add_constraint(None) 
     214                self._manager.sim_page = self 
     215 
     216    def _format_id(self, original_id): 
     217        original_id = original_id.rstrip('1234567890.') 
     218        new_id_list = original_id.split() 
     219        new_id = ' '.join(new_id_list) 
     220        return new_id 
     221 
     222 
     223 
    159224    def draw_page(self): 
    160225        """ 
    161226        Construct the Simultaneous/Constrained fit page. fills the first 
    162         region (sizer1) with the list of available fit page pairs of data  
     227        region (sizer1) with the list of available fit page pairs of data 
    163228        and models.  Then fills sizer2 with the checkbox for adding 
    164229        constraints, and finally fills sizer3 with the fit button and 
     
    10431108        cbox.Append(name, value) 
    10441109    cbox.SetStringSelection(selected) 
    1045  
    1046  
    1047 class SimFitPageState: 
    1048     """ 
    1049     State of the simultaneous fit page for saving purposes 
    1050     """ 
    1051  
    1052     def __init__(self): 
    1053         # Sim Fit Page Number 
    1054         self.fit_page_no = None 
    1055         # Select all data 
    1056         self.select_all = False 
    1057         # Data sets sent to fit page 
    1058         self.model_list = [] 
    1059         # Data sets to be fit 
    1060         self.model_to_fit = [] 
    1061         # Number of constraints 
    1062         self.no_constraint = 0 
    1063         # Dictionary of constraints 
    1064         self.constraint_dict = {} 
    1065         # List of constraints 
    1066         self.constraints_list = [] 
    1067  
    1068     def load_from_save_state(self, fit): 
    1069         """ 
    1070         Load in a simultaneous/constrained fit from a save state 
    1071         :param fit: Fitpanel object 
    1072         :return: None 
    1073         """ 
    1074  
    1075         init_map = {} 
    1076         final_map = {} 
    1077         if fit.fit_panel.sim_page is None: 
    1078             fit.fit_panel.add_sim_page() 
    1079         sim_page = fit.fit_panel.sim_page 
    1080  
    1081         # Process each model and associate old M# with new M# 
    1082         i = 0 
    1083         for model in sim_page.model_list: 
    1084             model_id = self._format_id(model[1].keys()[0]) 
    1085             for saved_model in self.model_list: 
    1086                 save_id = saved_model.pop('name') 
    1087                 saved_model['name'] = save_id 
    1088                 save_id = self._format_id(save_id) 
    1089                 if save_id == model_id: 
    1090                     inter_id = str(i) + str(i) + str(i) + str(i) + str(i) 
    1091                     init_map[saved_model.pop('fit_page_source')] = inter_id 
    1092                     final_map[inter_id] = model[3].name 
    1093                     check = bool(saved_model.pop('checked')) 
    1094                     sim_page.model_list[i][0].SetValue(check) 
    1095                     break 
    1096             i += 1 
    1097         sim_page.check_model_name(None) 
    1098  
    1099         if len(self.constraints_list) > 0: 
    1100             sim_page.hide_constraint.SetValue(False) 
    1101             sim_page.show_constraint.SetValue(True) 
    1102             sim_page._display_constraint(None) 
    1103  
    1104         for index, item in enumerate(self.constraints_list): 
    1105             model_cbox = item.pop('model_cbox') 
    1106             if model_cbox != "": 
    1107                 constraint_value = item.pop('constraint') 
    1108                 param = item.pop('param_cbox') 
    1109                 equality = item.pop('egal_txt') 
    1110                 for key, value in init_map.items(): 
    1111                     model_cbox = model_cbox.replace(key, value) 
    1112                     constraint_value = constraint_value.replace(key, value) 
    1113                 for key, value in final_map.items(): 
    1114                     model_cbox = model_cbox.replace(key, value) 
    1115                     constraint_value = constraint_value.replace(key, value) 
    1116  
    1117                 sim_page.constraints_list[index][0].SetValue(model_cbox) 
    1118                 sim_page._on_select_model(None) 
    1119                 sim_page.constraints_list[index][1].SetValue(param) 
    1120                 sim_page.constraints_list[index][2].SetLabel(equality) 
    1121                 sim_page.constraints_list[index][3].SetValue(constraint_value) 
    1122                 sim_page._on_add_constraint(None) 
    1123                 sim_page._manager.sim_page = sim_page 
    1124  
    1125     def _format_id(self, original_id): 
    1126         original_id = original_id.rstrip('1234567890.') 
    1127         new_id_list = original_id.split() 
    1128         new_id = ' '.join(new_id_list) 
    1129         return new_id 
Note: See TracChangeset for help on using the changeset viewer.