Changeset 9be22cd in sasview


Ignore:
Timestamp:
Sep 27, 2017 10:50:02 AM (5 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

Files:
3 added
2 deleted
37 edited
2 moved

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/corfunc/corfunc_calculator.py

    ra859f99 r92eee84  
    124124 
    125125        params, s2 = self._fit_data(q, iq) 
     126        # Extrapolate to 100*Qmax in experimental data 
    126127        qs = np.arange(0, q[-1]*100, (q[1]-q[0])) 
    127128        iqs = s2(qs) 
  • 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 
  • installers/setup_exe.py

    r92df9cbd rb963b20  
    4646sys.path.insert(0, build_path) 
    4747 
    48 from sas.sasview import local_config 
    4948from installer_generator import generate_installer 
    5049 
     
    7473          sys.exc_value) 
    7574 
     75from sas import get_local_config 
     76local_config = get_local_config() 
    7677 
    7778# Solution taken from here: http://www.py2exe.org/index.cgi/win32com.shell 
  • installers/setup_mac.py

    r67d8b1b rb963b20  
    4545import macholib_patch 
    4646 
    47 from sas.sasview import local_config 
     47from sas import get_local_config 
     48local_config = get_local_config() 
    4849 
    4950ICON = local_config.SetupIconFile_mac 
  • src/sas/__init__.py

    r79492222 rb963b20  
     1__all__ = ['get_app_dir', 'get_user_dir', 
     2           'get_local_config', 'get_custom_config'] 
     3 
     4_APP_DIR = None 
     5def get_app_dir(): 
     6    """ 
     7    The directory where the sasview application is found. 
     8 
     9    Returns the path to sasview if running in place or installed with setup. 
     10    If the application is frozen, returns the parent directory of the 
     11    application resources such as test files and images. 
     12    """ 
     13    global _APP_DIR 
     14    if not _APP_DIR: 
     15        from ._config import find_app_dir 
     16        _APP_DIR = find_app_dir() 
     17    return _APP_DIR 
     18 
     19_USER_DIR = None 
     20def get_user_dir(): 
     21    """ 
     22    The directory where the per-user configuration is stored. 
     23 
     24    Returns ~/.sasview, creating it if it does not already exist. 
     25    """ 
     26    global _USER_DIR 
     27    if not _USER_DIR: 
     28        from ._config import make_user_dir 
     29        _USER_DIR = make_user_dir() 
     30    return _USER_DIR 
     31 
     32def make_custom_config_path(): 
     33    from ._config import make_custom_config_path as _make_path 
     34    return _make_path(get_user_dir()) 
     35 
     36_CUSTOM_CONFIG = None 
     37def get_custom_config(): 
     38    """ 
     39    Setup the custom config dir and cat file 
     40    """ 
     41    global _CUSTOM_CONFIG 
     42    if not _CUSTOM_CONFIG: 
     43        from ._config import setup_custom_config 
     44        _CUSTOM_CONFIG = setup_custom_config(get_app_dir(), get_user_dir()) 
     45    return _CUSTOM_CONFIG 
     46 
     47 
     48_LOCAL_CONFIG = None 
     49def get_local_config(): 
     50    """ 
     51    Loads the local config file. 
     52    """ 
     53    global _LOCAL_CONFIG 
     54    if not _LOCAL_CONFIG: 
     55        from ._config import load_local_config 
     56        _LOCAL_CONFIG = load_local_config(get_app_dir()) 
     57    return _LOCAL_CONFIG 
  • src/sas/sascalc/fit/AbstractFitEngine.py

    ra1b8fee r50fcb09  
    137137               that will smear the theory data (slit smearing or resolution 
    138138               smearing) when set. 
    139              
     139 
    140140            The proper way to set the smearing object would be to 
    141141            do the following: :: 
    142              
    143                 from sas.sascalc.data_util.qsmearing import smear_selection 
     142 
     143                from sas.sascalc.fit.qsmearing import smear_selection 
    144144                smearer = smear_selection(some_data) 
    145145                fitdata1d = FitData1D( x= [1,3,..,], 
     
    147147                                        dx=None, 
    148148                                        dy=[1,2...], smearer= smearer) 
    149             
     149 
    150150            :Note: that some_data _HAS_ to be of 
    151151                class DataLoader.data_info.Data1D 
    152152                Setting it back to None will turn smearing off. 
    153                  
     153 
    154154        """ 
    155155        Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy, lam=lam, dlam=dlam) 
     
    176176        ## Max Q-value 
    177177        self.qmax = max(self.x) 
    178          
     178 
    179179        # Range used for input to smearing 
    180180        self._qmin_unsmeared = self.qmin 
     
    184184        self.idx_unsmeared = (self.x >= self._qmin_unsmeared) \ 
    185185                            & (self.x <= self._qmax_unsmeared) 
    186    
     186 
    187187    def set_fit_range(self, qmin=None, qmax=None): 
    188188        """ to set the fit range""" 
     
    199199        self._qmin_unsmeared = self.qmin 
    200200        self._qmax_unsmeared = self.qmax 
    201          
     201 
    202202        self._first_unsmeared_bin = 0 
    203203        self._last_unsmeared_bin = len(self.x) - 1 
    204          
     204 
    205205        if self.smearer is not None: 
    206206            self._first_unsmeared_bin, self._last_unsmeared_bin = \ 
     
    208208            self._qmin_unsmeared = self.x[self._first_unsmeared_bin] 
    209209            self._qmax_unsmeared = self.x[self._last_unsmeared_bin] 
    210              
     210 
    211211        # Identify the bin range for the unsmeared and smeared spaces 
    212212        self.idx = (self.x >= self.qmin) & (self.x <= self.qmax) 
     
    231231        """ 
    232232            Compute residuals. 
    233              
     233 
    234234            If self.smearer has been set, use if to smear 
    235235            the data before computing chi squared. 
    236              
     236 
    237237            :param fn: function that return model value 
    238              
     238 
    239239            :return: residuals 
    240240        """ 
     
    242242        fx = np.zeros(len(self.x)) 
    243243        fx[self.idx_unsmeared] = fn(self.x[self.idx_unsmeared]) 
    244         
     244 
    245245        ## Smear theory data 
    246246        if self.smearer is not None: 
     
    253253            raise RuntimeError, msg 
    254254        return (self.y[self.idx] - fx[self.idx]) / self.dy[self.idx], fx[self.idx] 
    255              
     255 
    256256    def residuals_deriv(self, model, pars=[]): 
    257257        """ 
    258258            :return: residuals derivatives . 
    259              
    260             :note: in this case just return empty array  
     259 
     260            :note: in this case just return empty array 
    261261        """ 
    262262        return [] 
     
    293293        x_max = max(math.fabs(sas_data2d.xmin), math.fabs(sas_data2d.xmax)) 
    294294        y_max = max(math.fabs(sas_data2d.ymin), math.fabs(sas_data2d.ymax)) 
    295          
     295 
    296296        ## fitting range 
    297297        if qmin is None: 
     
    305305            self.res_err_data = copy.deepcopy(self.err_data) 
    306306        #self.res_err_data[self.res_err_data==0]=1 
    307          
     307 
    308308        self.radius = np.sqrt(self.qx_data**2 + self.qy_data**2) 
    309          
     309 
    310310        # Note: mask = True: for MASK while mask = False for NOT to mask 
    311311        self.idx = ((self.qmin <= self.radius) &\ 
     
    368368 
    369369        return res, gn 
    370          
     370 
    371371    def residuals_deriv(self, model, pars=[]): 
    372372        """ 
    373373        :return: residuals derivatives . 
    374          
     374 
    375375        :note: in this case just return empty array 
    376          
     376 
    377377        """ 
    378378        return [] 
    379      
    380      
     379 
     380 
    381381class FitAbort(Exception): 
    382382    """ 
     
    396396        self.fit_arrange_dict = {} 
    397397        self.fitter_id = None 
    398          
     398 
    399399    def set_model(self, model, id, pars=[], constraints=[], data=None): 
    400400        """ 
    401401        set a model on a given  in the fit engine. 
    402          
    403         :param model: sas.models type  
     402 
     403        :param model: sas.models type 
    404404        :param id: is the key of the fitArrange dictionary where model is saved as a value 
    405         :param pars: the list of parameters to fit  
    406         :param constraints: list of  
     405        :param pars: the list of parameters to fit 
     406        :param constraints: list of 
    407407            tuple (name of parameter, value of parameters) 
    408408            the value of parameter must be a string to constraint 2 different 
    409409            parameters. 
    410             Example:   
     410            Example: 
    411411            we want to fit 2 model M1 and M2 both have parameters A and B. 
    412412            constraints can be ``constraints = [(M1.A, M2.B+2), (M1.B= M2.A *5),...,]`` 
    413              
    414               
     413 
     414 
    415415        :note: pars must contains only name of existing model's parameters 
    416          
     416 
    417417        """ 
    418418        if not pars: 
     
    445445        in a FitArrange object and adds that object in a dictionary 
    446446        with key id. 
    447          
     447 
    448448        :param data: data added 
    449449        :param id: unique key corresponding to a fitArrange object with data 
     
    456456                                 dx=data.dx, dy=data.dy, smearer=smearer) 
    457457        fitdata.sas_data = data 
    458         
     458 
    459459        fitdata.set_fit_range(qmin=qmin, qmax=qmax) 
    460460        #A fitArrange is already created but contains model only at id 
     
    466466            fitproblem.add_data(fitdata) 
    467467            self.fit_arrange_dict[id] = fitproblem 
    468     
     468 
    469469    def get_model(self, id): 
    470470        """ 
    471471        :param id: id is key in the dictionary containing the model to return 
    472          
     472 
    473473        :return:  a model at this id or None if no FitArrange element was 
    474474            created with this id 
     
    478478        else: 
    479479            return None 
    480      
     480 
    481481    def remove_fit_problem(self, id): 
    482482        """remove   fitarrange in id""" 
    483483        if id in self.fit_arrange_dict: 
    484484            del self.fit_arrange_dict[id] 
    485              
     485 
    486486    def select_problem_for_fit(self, id, value): 
    487487        """ 
    488488        select a couple of model and data at the id position in dictionary 
    489489        and set in self.selected value to value 
    490          
     490 
    491491        :param value: the value to allow fitting. 
    492492                can only have the value one or zero 
     
    494494        if id in self.fit_arrange_dict: 
    495495            self.fit_arrange_dict[id].set_to_fit(value) 
    496               
     496 
    497497    def get_problem_to_fit(self, id): 
    498498        """ 
    499499        return the self.selected value of the fit problem of id 
    500          
     500 
    501501        :param id: the id of the problem 
    502502        """ 
    503503        if id in self.fit_arrange_dict: 
    504504            self.fit_arrange_dict[id].get_to_fit() 
    505      
    506      
     505 
     506 
    507507class FitArrange: 
    508508    def __init__(self): 
     
    511511        to perform the Fit.FitArrange must contain exactly one model 
    512512        and at least one data for the fit to be performed. 
    513          
     513 
    514514        model: the model selected by the user 
    515515        Ldata: a list of data what the user wants to fit 
    516              
     516 
    517517        """ 
    518518        self.model = None 
     
    525525        """ 
    526526        set_model save a copy of the model 
    527          
     527 
    528528        :param model: the model being set 
    529529        """ 
    530530        self.model = model 
    531          
     531 
    532532    def add_data(self, data): 
    533533        """ 
    534534        add_data fill a self.data_list with data to fit 
    535          
     535 
    536536        :param data: Data to add in the list 
    537537        """ 
    538538        if not data in self.data_list: 
    539539            self.data_list.append(data) 
    540              
     540 
    541541    def get_model(self): 
    542542        """ 
     
    544544        """ 
    545545        return self.model 
    546       
     546 
    547547    def get_data(self): 
    548548        """ 
     
    550550        """ 
    551551        return self.data_list[0] 
    552        
     552 
    553553    def remove_data(self, data): 
    554554        """ 
    555555        Remove one element from the list 
    556          
     556 
    557557        :param data: Data to remove from data_list 
    558558        """ 
    559559        if data in self.data_list: 
    560560            self.data_list.remove(data) 
    561              
     561 
    562562    def set_to_fit(self, value=0): 
    563563        """ 
    564564        set self.selected to 0 or 1  for other values raise an exception 
    565          
     565 
    566566        :param value: integer between 0 or 1 
    567567        """ 
    568568        self.selected = value 
    569          
     569 
    570570    def get_to_fit(self): 
    571571        """ 
     
    599599        if self.model is not None and self.data is not None: 
    600600            self.inputs = [(self.model, self.data)] 
    601       
     601 
    602602    def set_model(self, model): 
    603603        """ 
    604604        """ 
    605605        self.model = model 
    606          
     606 
    607607    def set_fitness(self, fitness): 
    608608        """ 
    609609        """ 
    610610        self.fitness = fitness 
    611          
     611 
    612612    def __str__(self): 
    613613        """ 
     
    624624        msg = [msg1, msg3] + msg2 
    625625        return "\n".join(msg) 
    626      
     626 
    627627    def print_summary(self): 
    628628        """ 
  • src/sas/sascalc/fit/BumpsFitting.py

    r9a5097c r1386b2f  
    1515    def get_fitter(): 
    1616        return FIT_CONFIG.selected_fitter, FIT_CONFIG.selected_values 
    17 except: 
     17except ImportError: 
    1818    # CRUFT: Bumps changed its handling of fit options around 0.7.5.6 
    1919    # Default bumps to use the Levenberg-Marquardt optimizer 
     
    5656        header = "=== Steps: %s  chisq: %s  ETA: %s\n"%(step, chisq, time) 
    5757        parameters = ["%15s: %-10.3g%s"%(k,v,("\n" if i%3==2 else " | ")) 
    58                       for i,(k,v) in enumerate(zip(pars,history.point[0]))] 
     58                      for i, (k, v) in enumerate(zip(pars, history.point[0]))] 
    5959        self.msg = "".join([header]+parameters) 
    6060 
     
    7777        self.handler.set_result(Progress(history, self.max_step, self.pars, self.dof)) 
    7878        self.handler.progress(history.step[0], self.max_step) 
    79         if len(history.step)>1 and history.step[1] > history.step[0]: 
     79        if len(history.step) > 1 and history.step[1] > history.step[0]: 
    8080            self.handler.improvement() 
    8181        self.handler.update_fit() 
     
    9797        try: 
    9898            p = history.population_values[0] 
    99             n,p = len(p), np.sort(p) 
    100             QI,Qmid, = int(0.2*n),int(0.5*n) 
    101             self.convergence.append((best, p[0],p[QI],p[Qmid],p[-1-QI],p[-1])) 
    102         except: 
    103             self.convergence.append((best, best,best,best,best,best)) 
     99            n, p = len(p), np.sort(p) 
     100            QI, Qmid = int(0.2*n), int(0.5*n) 
     101            self.convergence.append((best, p[0], p[QI], p[Qmid], p[-1-QI], p[-1])) 
     102        except Exception: 
     103            self.convergence.append((best, best, best, best, best, best)) 
    104104 
    105105 
     
    131131 
    132132    def _reset_pars(self, names, values): 
    133         for k,v in zip(names, values): 
     133        for k, v in zip(names, values): 
    134134            self._pars[k].value = v 
    135135 
     
    137137        self._pars = {} 
    138138        for k in self.model.getParamList(): 
    139             name = ".".join((self.name,k)) 
     139            name = ".".join((self.name, k)) 
    140140            value = self.model.getParam(k) 
    141             bounds = self.model.details.get(k,["",None,None])[1:3] 
     141            bounds = self.model.details.get(k, ["", None, None])[1:3] 
    142142            self._pars[k] = parameter.Parameter(value=value, bounds=bounds, 
    143143                                                fixed=True, name=name) 
     
    145145 
    146146    def _init_pars(self, kw): 
    147         for k,v in kw.items(): 
     147        for k, v in kw.items(): 
    148148            # dispersion parameters initialized with _field instead of .field 
    149             if k.endswith('_width'): k = k[:-6]+'.width' 
    150             elif k.endswith('_npts'): k = k[:-5]+'.npts' 
    151             elif k.endswith('_nsigmas'): k = k[:-7]+'.nsigmas' 
    152             elif k.endswith('_type'): k = k[:-5]+'.type' 
     149            if k.endswith('_width'): 
     150                k = k[:-6]+'.width' 
     151            elif k.endswith('_npts'): 
     152                k = k[:-5]+'.npts' 
     153            elif k.endswith('_nsigmas'): 
     154                k = k[:-7]+'.nsigmas' 
     155            elif k.endswith('_type'): 
     156                k = k[:-5]+'.type' 
    153157            if k not in self._pars: 
    154158                formatted_pars = ", ".join(sorted(self._pars.keys())) 
     
    159163            elif isinstance(v, parameter.BaseParameter): 
    160164                self._pars[k] = v 
    161             elif isinstance(v, (tuple,list)): 
     165            elif isinstance(v, (tuple, list)): 
    162166                low, high = v 
    163167                self._pars[k].value = (low+high)/2 
    164                 self._pars[k].range(low,high) 
     168                self._pars[k].range(low, high) 
    165169            else: 
    166170                self._pars[k].value = v 
     
    170174        Flag a set of parameters as fitted parameters. 
    171175        """ 
    172         for k,p in self._pars.items(): 
     176        for k, p in self._pars.items(): 
    173177            p.fixed = (k not in param_list or k in self.constraints) 
    174178        self.fitted_par_names = [k for k in param_list if k not in self.constraints] 
     
    182186 
    183187    def update(self): 
    184         for k,v in self._pars.items(): 
     188        for k, v in self._pars.items(): 
    185189            #print "updating",k,v,v.value 
    186             self.model.setParam(k,v.value) 
     190            self.model.setParam(k, v.value) 
    187191        self._dirty = True 
    188192 
     
    223227            symtab = dict((".".join((M.name, k)), p) 
    224228                          for M in self.models 
    225                           for k,p in M.parameters().items()) 
     229                          for k, p in M.parameters().items()) 
    226230            self.update = compile_constraints(symtab, exprs) 
    227231        else: 
     
    300304                                          np.NaN*np.ones(len(fitness.computed_pars)))) 
    301305                R.pvec = np.hstack((result['value'][fitted_index], 
    302                                       [p.value for p in fitness.computed_pars])) 
     306                                    [p.value for p in fitness.computed_pars])) 
    303307                R.fitness = np.sum(R.residuals**2)/(fitness.numpoints() - len(fitted_index)) 
    304308            else: 
    305309                R.stderr = np.NaN*np.ones(len(param_list)) 
    306                 R.pvec = np.asarray( [p.value for p in fitness.fitted_pars+fitness.computed_pars]) 
     310                R.pvec = np.asarray([p.value for p in fitness.fitted_pars+fitness.computed_pars]) 
    307311                R.fitness = np.NaN 
    308312            R.convergence = result['convergence'] 
     
    331335    steps = options.get('steps', 0) 
    332336    if steps == 0: 
    333         pop = options.get('pop',0)*len(problem._parameters) 
     337        pop = options.get('pop', 0)*len(problem._parameters) 
    334338        samples = options.get('samples', 0) 
    335339        steps = (samples+pop-1)/pop if pop != 0 else samples 
     
    343347    fitdriver = fitters.FitDriver(fitclass, problem=problem, 
    344348                                  abort_test=abort_test, **options) 
    345     omp_threads = int(os.environ.get('OMP_NUM_THREADS','0')) 
     349    omp_threads = int(os.environ.get('OMP_NUM_THREADS', '0')) 
    346350    mapper = MPMapper if omp_threads == 1 else SerialMapper 
    347351    fitdriver.mapper = mapper.start_mapper(problem, None) 
     
    359363    convergence_list = options['monitors'][-1].convergence 
    360364    convergence = (2*np.asarray(convergence_list)/problem.dof 
    361                    if convergence_list else np.empty((0,1),'d')) 
     365                   if convergence_list else np.empty((0, 1), 'd')) 
    362366 
    363367    success = best is not None 
     
    376380        'errors': '\n'.join(errors), 
    377381        } 
    378  
  • src/sas/sascalc/fit/pagestate.py

    r1fa4f736 r0315b63  
    11""" 
    2     Class that holds a fit page state 
     2Class that holds a fit page state 
    33""" 
    44# TODO: Refactor code so we don't need to use getattr/setattr 
     
    1515import os 
    1616import sys 
    17 import wx 
    1817import copy 
    1918import logging 
     
    2322import xml.dom.minidom 
    2423from xml.dom.minidom import parseString 
     24from xml.dom.minidom import getDOMImplementation 
    2525from lxml import etree 
    2626 
    2727from sasmodels import convert 
    2828import sasmodels.weights 
     29 
     30from sas.sasview import __version__ as SASVIEW_VERSION 
    2931 
    3032import sas.sascalc.dataloader 
     
    3840# Information to read/write state as xml 
    3941FITTING_NODE_NAME = 'fitting_plug_in' 
    40 CANSAS_NS = "cansas1d/1.0" 
     42CANSAS_NS = {"ns": "cansas1d/1.0"} 
    4143 
    4244CUSTOM_MODEL = 'Plugin Models' 
     
    7274                            ["cb1", "cb1", "bool"], 
    7375                            ["tcChi", "tcChi", "float"], 
    74                             ["smearer", "smearer", "float"], 
    75                             ["smear_type", "smear_type", "string"], 
    7676                            ["dq_l", "dq_l", "float"], 
    7777                            ["dq_r", "dq_r", "float"], 
     
    8383                            ["weights", "weights"]] 
    8484 
    85 DISPERSION_LIST = [["disp_obj_dict", "_disp_obj_dict", "string"]] 
     85DISPERSION_LIST = [["disp_obj_dict", "disp_obj_dict", "string"]] 
    8686 
    8787LIST_OF_STATE_PARAMETERS = [["parameters", "parameters"], 
     
    142142    Contains information to reconstruct a page of the fitpanel. 
    143143    """ 
    144     def __init__(self, parent=None, model=None, data=None): 
     144    def __init__(self, model=None, data=None): 
    145145        """ 
    146146        Initialize the current state 
     
    154154        self.timestamp = time.time() 
    155155        # Data member to store the dispersion object created 
    156         self._disp_obj_dict = {} 
     156        self.disp_obj_dict = {} 
    157157        # ------------------------ 
    158158        # Data used for fitting 
     
    190190        # fit page manager 
    191191        self.manager = None 
    192         # Store the parent of this panel parent 
    193         # For this application fitpanel is the parent 
    194         self.parent = parent 
    195192        # Event_owner is the owner of model event 
    196193        self.event_owner = None 
     
    211208        # orientation parameters for gaussian dispersity 
    212209        self.orientation_params_disp = [] 
    213         # smearer info 
    214         self.smearer = None 
    215         self.smear_type = None 
    216210        self.dq_l = None 
    217211        self.dq_r = None 
     
    231225        # contains link between a model and selected parameters to fit 
    232226        self.param_toFit = [] 
    233         # dictionary of model type and model class 
    234         self.model_list_box = None 
    235227        # save the state of the context menu 
    236228        self.saved_states = {} 
     
    277269        # store value of chisqr 
    278270        self.tcChi = None 
    279         self.version = (1,0,0) 
     271        self.version = (1, 0, 0) 
    280272 
    281273    def clone(self): 
     
    287279            model = self.model.clone() 
    288280            model.name = self.model.name 
    289         obj = PageState(self.parent, model=model) 
     281        obj = PageState(model=model) 
    290282        obj.file = copy.deepcopy(self.file) 
    291283        obj.data = copy.deepcopy(self.data) 
     
    294286        obj.data_name = self.data_name 
    295287        obj.is_data = self.is_data 
    296         obj.model_list_box = copy.deepcopy(self.model_list_box) 
    297288 
    298289        obj.categorycombobox = self.categorycombobox 
     
    321312        obj.tcChi = self.tcChi 
    322313 
    323         if len(self._disp_obj_dict) > 0: 
    324             for k, v in self._disp_obj_dict.iteritems(): 
    325                 obj._disp_obj_dict[k] = v 
     314        if len(self.disp_obj_dict) > 0: 
     315            for k, v in self.disp_obj_dict.iteritems(): 
     316                obj.disp_obj_dict[k] = v 
    326317        if len(self.disp_cb_dict) > 0: 
    327318            for k, v in self.disp_cb_dict.iteritems(): 
     
    337328        obj.pinhole_smearer = copy.deepcopy(self.pinhole_smearer) 
    338329        obj.slit_smearer = copy.deepcopy(self.slit_smearer) 
    339         obj.smear_type = copy.deepcopy(self.smear_type) 
    340330        obj.dI_noweight = copy.deepcopy(self.dI_noweight) 
    341331        obj.dI_didata = copy.deepcopy(self.dI_didata) 
     
    355345        obj.npts = copy.deepcopy(self.npts) 
    356346        obj.cb1 = copy.deepcopy(self.cb1) 
    357         obj.smearer = copy.deepcopy(self.smearer) 
    358347        obj.version = copy.deepcopy(self.version) 
    359348 
     
    519508        rep = "\nState name: %s\n" % self.file 
    520509        t = time.localtime(self.timestamp) 
    521         time_str = time.strftime("%b %d %Y %H;%M;%S ", t) 
     510        time_str = time.strftime("%b %d %Y %H:%M:%S ", t) 
    522511 
    523512        rep += "State created: %s\n" % time_str 
     
    559548        rep += "All parameters checkbox selected: %s\n" % self.cb1 
    560549        rep += "Value of Chisqr : %s\n" % str(self.tcChi) 
    561         rep += "Smear object : %s\n" % self.smearer 
    562         rep += "Smear type : %s\n" % self.smear_type 
    563550        rep += "dq_l  : %s\n" % self.dq_l 
    564551        rep += "dq_r  : %s\n" % self.dq_r 
     
    596583        return rep 
    597584 
    598     def set_report_string(self): 
     585    def _get_report_string(self): 
    599586        """ 
    600587        Get the values (strings) from __str__ for report 
     
    611598        q_range = "" 
    612599        strings = self.__repr__() 
     600        fixed_parameter = False 
    613601        lines = strings.split('\n') 
    614  
    615602        # get all string values from __str__() 
    616603        for line in lines: 
    617             value = "" 
    618             content = line.split(":") 
    619             if line == '' or len(content) == 1: 
     604            # Skip lines which are not key: value pairs, which includes 
     605            # blank lines and freeform notes in SASNotes fields. 
     606            if not ':' in line: 
     607                #msg = "Report string expected 'name: value' but got %r" % line 
     608                #logger.error(msg) 
    620609                continue 
    621             name = content[0] 
    622             try: 
    623                 value = content[1] 
    624             except Exception: 
    625                 msg = "Report string expected 'name: value' but got %r" % line 
    626                 logger.error(msg) 
    627             if name.count("State created"): 
    628                 repo_time = "" + value 
    629             if name.count("parameter name"): 
     610 
     611            name, value = [s.strip() for s in line.split(":", 1)] 
     612            if name == "State created": 
     613                repo_time = value 
     614            elif name == "parameter name": 
    630615                val_name = value.split(".") 
    631616                if len(val_name) > 1: 
     
    636621                else: 
    637622                    param_string += value + ',' 
    638             if name == "value": 
     623            elif name == "value": 
    639624                param_string += value + ',' 
    640             fixed_parameter = False 
    641             if name == "selected": 
    642                 if value == u' False': 
    643                     fixed_parameter = True 
    644             if name == "error value": 
     625            elif name == "selected": 
     626                # remember if it is fixed when reporting error value 
     627                fixed_parameter = (value == u'False') 
     628            elif name == "error value": 
    645629                if fixed_parameter: 
    646630                    param_string += '(fixed),' 
    647631                else: 
    648632                    param_string += value + ',' 
    649             if name == "parameter unit": 
     633            elif name == "parameter unit": 
    650634                param_string += value + ':' 
    651             if name == "Value of Chisqr ": 
     635            elif name == "Value of Chisqr": 
    652636                chi2 = ("Chi2/Npts = " + value) 
    653637                chi2_string = CENTRE % chi2 
    654             if name == "Title": 
     638            elif name == "Title": 
    655639                if len(value.strip()) == 0: 
    656640                    continue 
    657641                title = value + " [" + repo_time + "]" 
    658642                title_name = HEADER % title 
    659             if name == "data ": 
     643            elif name == "data": 
    660644                try: 
    661                     file_value = ("File name:" + content[2]) 
     645                    # parsing "data : File:     filename [mmm dd hh:mm]" 
     646                    name = value.split(':', 1)[1].strip() 
     647                    file_value = "File name:" + name 
    662648                    file_name = CENTRE % file_value 
    663649                    if len(title) == 0: 
    664                         title = content[2] + " [" + repo_time + "]" 
     650                        title = name + " [" + repo_time + "]" 
    665651                        title_name = HEADER % title 
    666652                except Exception: 
    667653                    msg = "While parsing 'data: ...'\n" 
    668654                    logger.error(msg + traceback.format_exc()) 
    669             if name == "model name ": 
     655            elif name == "model name": 
    670656                try: 
    671                     modelname = "Model name:" + content[1] 
    672                 except: 
     657                    modelname = "Model name:" + value 
     658                except Exception: 
    673659                    modelname = "Model name:" + " NAN" 
    674660                model_name = CENTRE % modelname 
    675661 
    676             if name == "Plotting Range": 
     662            elif name == "Plotting Range": 
    677663                try: 
    678                     q_range = content[1] + " = " + content[2] \ 
    679                             + " = " + content[3].split(",")[0] 
     664                    parts = value.split(':') 
     665                    q_range = parts[0] + " = " + parts[1] \ 
     666                            + " = " + parts[2].split(",")[0] 
    680667                    q_name = ("Q Range:    " + q_range) 
    681668                    q_range = CENTRE % q_name 
     
    683670                    msg = "While parsing 'Plotting Range: ...'\n" 
    684671                    logger.error(msg + traceback.format_exc()) 
     672 
    685673        paramval = "" 
    686674        for lines in param_string.split(":"): 
     
    711699                                   "\n" + paramval_string + \ 
    712700                                   "\n" + ELINE + \ 
    713                                    "\n" + FEET_1 % title + \ 
    714                                    "\n" + FEET_2 
     701                                   "\n" + FEET_1 % title 
    715702 
    716703        return html_string, text_string, title 
     
    725712        return name 
    726713 
    727     def report(self, figs=None, canvases=None): 
     714    def report(self, fig_urls): 
    728715        """ 
    729716        Invoke report dialog panel 
     
    731718        : param figs: list of pylab figures [list] 
    732719        """ 
    733         from sas.sasgui.perspectives.fitting.report_dialog import ReportDialog 
    734720        # get the strings for report 
    735         html_str, text_str, title = self.set_report_string() 
     721        html_str, text_str, title = self._get_report_string() 
    736722        # Allow 2 figures to append 
    737         if len(figs) == 1: 
    738             add_str = FEET_3 
    739         elif len(figs) == 2: 
    740             add_str = ELINE 
    741             add_str += FEET_2 % ("%s") 
    742             add_str += ELINE 
    743             add_str += FEET_3 
    744         elif len(figs) > 2: 
    745             add_str = ELINE 
    746             add_str += FEET_2 % ("%s") 
    747             add_str += ELINE 
    748             add_str += FEET_2 % ("%s") 
    749             add_str += ELINE 
    750             add_str += FEET_3 
    751         else: 
    752             add_str = "" 
     723        image_links = [FEET_2%fig for fig in fig_urls] 
    753724 
    754725        # final report html strings 
    755         report_str = html_str % ("%s") + add_str 
    756  
    757         # make plot image 
    758         images = self.set_plot_state(figs, canvases) 
    759         report_list = [report_str, text_str, images] 
    760         dialog = ReportDialog(report_list, None, wx.ID_ANY, "") 
    761         dialog.Show() 
     726        report_str = html_str + ELINE.join(image_links) 
     727 
     728        return report_str, text_str 
    762729 
    763730    def _to_xml_helper(self, thelist, element, newdoc): 
     
    794761        :param batch_fit_state: simultaneous fit state 
    795762        """ 
    796         from xml.dom.minidom import getDOMImplementation 
    797  
    798763        # Check whether we have to write a standalone XML file 
    799764        if doc is None: 
     
    807772            try: 
    808773                top_element = newdoc.createElement(FITTING_NODE_NAME) 
    809             except: 
     774            except Exception: 
    810775                string = etree.tostring(doc, pretty_print=True) 
    811776                newdoc = parseString(string) 
     
    816781                try: 
    817782                    entry_node.appendChild(top_element) 
    818                 except: 
     783                except Exception: 
    819784                    node_name = entry_node.tag 
    820785                    node_list = newdoc.getElementsByTagName(node_name) 
     
    823788 
    824789        attr = newdoc.createAttribute("version") 
    825         from sas import sasview 
    826         attr.nodeValue = sasview.__version__ 
     790        attr.nodeValue = SASVIEW_VERSION 
    827791        # attr.nodeValue = '1.0' 
    828792        top_element.setAttributeNode(attr) 
     
    880844            inputs.appendChild(element) 
    881845 
    882         # Create doc for the dictionary of self._disp_obj_dic 
     846        # Create doc for the dictionary of self.disp_obj_dic 
    883847        for tagname, varname, tagtype in DISPERSION_LIST: 
    884848            element = newdoc.createElement(tagname) 
     
    961925        """ 
    962926        for item in node: 
    963             try: 
    964                 name = item.get('name') 
    965             except: 
    966                 name = None 
    967             try: 
    968                 value = item.get('value') 
    969             except: 
    970                 value = None 
    971             try: 
    972                 selected_to_fit = (item.get('selected_to_fit') == "True") 
    973             except: 
    974                 selected_to_fit = None 
    975             try: 
    976                 error_displayed = (item.get('error_displayed') == "True") 
    977             except: 
    978                 error_displayed = None 
    979             try: 
    980                 error_value = item.get('error_value') 
    981             except: 
    982                 error_value = None 
    983             try: 
    984                 minimum_displayed = (item.get('minimum_displayed') == "True") 
    985             except: 
    986                 minimum_displayed = None 
    987             try: 
    988                 minimum_value = item.get('minimum_value') 
    989             except: 
    990                 minimum_value = None 
    991             try: 
    992                 maximum_displayed = (item.get('maximum_displayed') == "True") 
    993             except: 
    994                 maximum_displayed = None 
    995             try: 
    996                 maximum_value = item.get('maximum_value') 
    997             except: 
    998                 maximum_value = None 
    999             try: 
    1000                 unit = item.get('unit') 
    1001             except: 
    1002                 unit = None 
     927            name = item.get('name') 
     928            value = item.get('value') 
     929            selected_to_fit = (item.get('selected_to_fit') == "True") 
     930            error_displayed = (item.get('error_displayed') == "True") 
     931            error_value = item.get('error_value') 
     932            minimum_displayed = (item.get('minimum_displayed') == "True") 
     933            minimum_value = item.get('minimum_value') 
     934            maximum_displayed = (item.get('maximum_displayed') == "True") 
     935            maximum_value = item.get('maximum_value') 
     936            unit = item.get('unit') 
    1003937            list.append([selected_to_fit, name, value, "+/-", 
    1004938                         [error_displayed, error_value], 
     
    1030964            # Get file name 
    1031965            entry = get_content('ns:filename', node) 
    1032             if entry is not None: 
     966            if entry is not None and entry.text: 
    1033967                self.file = entry.text.strip() 
     968            else: 
     969                self.file = '' 
    1034970 
    1035971            # Get time stamp 
     
    1038974                try: 
    1039975                    self.timestamp = float(entry.get('epoch')) 
    1040                 except: 
     976                except Exception: 
    1041977                    msg = "PageState.fromXML: Could not" 
    1042978                    msg += " read timestamp\n %s" % sys.exc_value 
     
    10661002                                          list=getattr(self, item[1])) 
    10671003 
    1068                 # Recover _disp_obj_dict from xml file 
    1069                 self._disp_obj_dict = {} 
     1004                # Recover disp_obj_dict from xml file 
     1005                self.disp_obj_dict = {} 
    10701006                for tagname, varname, tagtype in DISPERSION_LIST: 
    10711007                    node = get_content("ns:%s" % tagname, entry) 
     
    10811017                            except Exception: 
    10821018                                base = "unable to load distribution %r for %s" 
    1083                                 logger.error(base % (value, parameter)) 
     1019                                logger.error(base, value, parameter) 
    10841020                                continue 
    1085                         _disp_obj_dict = getattr(self, varname) 
    1086                         _disp_obj_dict[parameter] = value 
     1021                        disp_obj_dict = getattr(self, varname) 
     1022                        disp_obj_dict[parameter] = value 
    10871023 
    10881024                # get self.values and self.weights dic. if exists 
     
    11071043                    setattr(self, varname, dic) 
    11081044 
    1109     def set_plot_state(self, figs, canvases): 
    1110         """ 
    1111         Build image state that wx.html understand 
    1112         by plotting, putting it into wx.FileSystem image object 
    1113  
    1114         """ 
    1115         images = [] 
    1116  
    1117         # Reset memory 
    1118         self.imgRAM = None 
    1119         wx.MemoryFSHandler() 
    1120  
    1121         # For no figures in the list, prepare empty plot 
    1122         if figs is None or len(figs) == 0: 
    1123             figs = [None] 
    1124  
    1125         # Loop over the list of figures 
    1126         # use wx.MemoryFSHandler 
    1127         self.imgRAM = wx.MemoryFSHandler() 
    1128         for fig in figs: 
    1129             if fig is not None: 
    1130                 ind = figs.index(fig) 
    1131                 canvas = canvases[ind] 
    1132  
    1133             # store the image in wx.FileSystem Object 
    1134             wx.FileSystem.AddHandler(wx.MemoryFSHandler()) 
    1135  
    1136             # index of the fig 
    1137             ind = figs.index(fig) 
    1138  
    1139             # AddFile, image can be retrieved with 'memory:filename' 
    1140             self.imgRAM.AddFile('img_fit%s.png' % ind, 
    1141                                 canvas.bitmap, wx.BITMAP_TYPE_PNG) 
    1142  
    1143             # append figs 
    1144             images.append(fig) 
    1145  
    1146         return images 
    1147  
     1045class SimFitPageState(object): 
     1046    """ 
     1047    State of the simultaneous fit page for saving purposes 
     1048    """ 
     1049 
     1050    def __init__(self): 
     1051        # Sim Fit Page Number 
     1052        self.fit_page_no = None 
     1053        # Select all data 
     1054        self.select_all = False 
     1055        # Data sets sent to fit page 
     1056        self.model_list = [] 
     1057        # Data sets to be fit 
     1058        self.model_to_fit = [] 
     1059        # Number of constraints 
     1060        self.no_constraint = 0 
     1061        # Dictionary of constraints 
     1062        self.constraint_dict = {} 
     1063        # List of constraints 
     1064        self.constraints_list = [] 
     1065 
     1066    def __repr__(self): 
     1067        # TODO: should use __str__, not __repr__ (similarly for PageState) 
     1068        # TODO: could use a nicer representation 
     1069        repr = """\ 
     1070fit page number : %(fit_page_no)s 
     1071select all : %(select_all)s 
     1072model_list : %(model_list)s 
     1073model to fit : %(model_to_fit)s 
     1074number of construsts : %(no_constraint)s 
     1075constraint dict : %(constraint_dict)s 
     1076constraints list : %(constraints_list)s 
     1077"""%self.__dict__ 
     1078        return repr 
    11481079 
    11491080class Reader(CansasReader): 
     
    12041135        try: 
    12051136            nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 
    1206                                 namespaces={'ns': CANSAS_NS}) 
     1137                                namespaces=CANSAS_NS) 
    12071138            if nodes: 
    12081139                # Create an empty state 
     
    12101141                state.from_xml(node=nodes[0]) 
    12111142 
    1212         except: 
     1143        except Exception: 
    12131144            logger.info("XML document does not contain fitting information.\n" 
    1214                          + traceback.format_exc()) 
     1145                        + traceback.format_exc()) 
    12151146 
    12161147        return state 
     
    12231154        """ 
    12241155        nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 
    1225                             namespaces={'ns': CANSAS_NS}) 
     1156                            namespaces=CANSAS_NS) 
    12261157        if nodes: 
    12271158            simfitstate = nodes[0].xpath('ns:simultaneous_fit', 
    1228                                          namespaces={'ns': CANSAS_NS}) 
     1159                                         namespaces=CANSAS_NS) 
    12291160            if simfitstate: 
    1230                 from simfitpage import SimFitPageState 
    12311161                sim_fit_state = SimFitPageState() 
    12321162                simfitstate_0 = simfitstate[0] 
    12331163                all = simfitstate_0.xpath('ns:select_all', 
    1234                                           namespaces={'ns': CANSAS_NS}) 
     1164                                          namespaces=CANSAS_NS) 
    12351165                atts = all[0].attrib 
    12361166                checked = atts.get('checked') 
    12371167                sim_fit_state.select_all = bool(checked) 
    12381168                model_list = simfitstate_0.xpath('ns:model_list', 
    1239                                                  namespaces={'ns': CANSAS_NS}) 
     1169                                                 namespaces=CANSAS_NS) 
    12401170                model_list_items = model_list[0].xpath('ns:model_list_item', 
    1241                                                        namespaces={'ns': 
    1242                                                                     CANSAS_NS}) 
     1171                                                       namespaces=CANSAS_NS) 
    12431172                for model in model_list_items: 
    12441173                    attrs = model.attrib 
     
    12461175 
    12471176                constraints = simfitstate_0.xpath('ns:constraints', 
    1248                                                 namespaces={'ns': CANSAS_NS}) 
     1177                                                  namespaces=CANSAS_NS) 
    12491178                constraint_list = constraints[0].xpath('ns:constraint', 
    1250                                                namespaces={'ns': CANSAS_NS}) 
     1179                                                       namespaces=CANSAS_NS) 
    12511180                for constraint in constraint_list: 
    12521181                    attrs = constraint.attrib 
     
    12661195 
    12671196        """ 
    1268         node = dom.xpath('ns:data_class', namespaces={'ns': CANSAS_NS}) 
     1197        node = dom.xpath('ns:data_class', namespaces=CANSAS_NS) 
    12691198        return_value, _ = self._parse_entry(dom) 
    12701199        return return_value, _ 
     
    12951224                    root = tree.getroot() 
    12961225                    entry_list = root.xpath('ns:SASentry', 
    1297                                             namespaces={'ns': CANSAS_NS}) 
     1226                                            namespaces=CANSAS_NS) 
    12981227                    for entry in entry_list: 
    12991228                        fitstate = self._parse_state(entry) 
     
    13191248                return None 
    13201249            else: 
    1321                 for ind in range(len(output)): 
     1250                for data in output: 
    13221251                    # Call back to post the new state 
    1323                     state = output[ind].meta_data['fitstate'] 
     1252                    state = data.meta_data['fitstate'] 
    13241253                    t = time.localtime(state.timestamp) 
    13251254                    time_str = time.strftime("%b %d %H:%M", t) 
     
    13321261 
    13331262                    if state is not None and state.is_data is not None: 
    1334                         output[ind].is_data = state.is_data 
    1335  
    1336                     output[ind].filename = state.file 
    1337                     state.data = output[ind] 
    1338                     state.data.name = output[ind].filename  # state.data_name 
     1263                        data.is_data = state.is_data 
     1264 
     1265                    data.filename = state.file 
     1266                    state.data = data 
     1267                    state.data.name = data.filename  # state.data_name 
    13391268                    state.data.id = state.data_id 
    13401269                    if state.is_data is not None: 
    13411270                        state.data.is_data = state.is_data 
    1342                     if output[ind].run_name is not None\ 
    1343                          and len(output[ind].run_name) != 0: 
    1344                         if isinstance(output[ind].run_name, dict): 
    1345                             name = output[ind].run_name.keys()[0] 
     1271                    if data.run_name is not None and len(data.run_name) != 0: 
     1272                        if isinstance(data.run_name, dict): 
     1273                            # Note: key order in dict is not guaranteed, so sort 
     1274                            name = data.run_name.keys()[0] 
    13461275                        else: 
    1347                             name = output[ind].run_name 
     1276                            name = data.run_name 
    13481277                    else: 
    13491278                        name = original_fname 
     
    13511280                    state.version = fitstate.version 
    13521281                    # store state in fitting 
    1353                     self.call_back(state=state, 
    1354                                    datainfo=output[ind], format=ext) 
     1282                    self.call_back(state=state, datainfo=data, format=ext) 
    13551283                    self.state = state 
    13561284                simfitstate = self._parse_simfit_state(entry) 
     
    14121340        return doc 
    14131341 
    1414 # Simple html report templet 
     1342# Simple html report template 
    14151343HEADER = "<html>\n" 
    14161344HEADER += "<head>\n" 
     
    14401368""" 
    14411369FEET_2 = \ 
    1442 """ 
    1443 <img src="%s" > 
    1444 </img> 
     1370"""<img src="%s" ></img> 
    14451371""" 
    14461372FEET_3 = \ 
    1447 """ 
    1448 </center> 
     1373"""</center> 
    14491374</div> 
    14501375</body> 
    14511376</html> 
    14521377""" 
    1453 ELINE = "<p class=MsoNormal>&nbsp;</p>" 
     1378ELINE = """<p class=MsoNormal>&nbsp;</p> 
     1379""" 
  • src/sas/sascalc/fit/qsmearing.py

    r8938502 r50fcb09  
    55#This software was developed by the University of Tennessee as part of the 
    66#Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    7 #project funded by the US National Science Foundation.  
     7#project funded by the US National Science Foundation. 
    88#See the license text in license.txt 
    99#copyright 2008, University of Tennessee 
     
    1919from sasmodels.sesans import SesansTransform 
    2020from sasmodels.resolution2d import Pinhole2D 
    21 from .nxsunit import Converter 
     21 
     22from sas.sascalc.data_util.nxsunit import Converter 
    2223 
    2324def smear_selection(data, model = None): 
  • src/sas/sascalc/pr/fit/AbstractFitEngine.py

    ra1b8fee r50fcb09  
    137137               that will smear the theory data (slit smearing or resolution 
    138138               smearing) when set. 
    139              
     139 
    140140            The proper way to set the smearing object would be to 
    141141            do the following: :: 
    142              
    143                 from sas.sascalc.data_util.qsmearing import smear_selection 
     142 
     143                from sas.sascalc.fit.qsmearing import smear_selection 
    144144                smearer = smear_selection(some_data) 
    145145                fitdata1d = FitData1D( x= [1,3,..,], 
     
    147147                                        dx=None, 
    148148                                        dy=[1,2...], smearer= smearer) 
    149             
     149 
    150150            :Note: that some_data _HAS_ to be of 
    151151                class DataLoader.data_info.Data1D 
    152152                Setting it back to None will turn smearing off. 
    153                  
     153 
    154154        """ 
    155155        Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy) 
     
    176176        ## Max Q-value 
    177177        self.qmax = max(self.x) 
    178          
     178 
    179179        # Range used for input to smearing 
    180180        self._qmin_unsmeared = self.qmin 
     
    184184        self.idx_unsmeared = (self.x >= self._qmin_unsmeared) \ 
    185185                            & (self.x <= self._qmax_unsmeared) 
    186    
     186 
    187187    def set_fit_range(self, qmin=None, qmax=None): 
    188188        """ to set the fit range""" 
     
    199199        self._qmin_unsmeared = self.qmin 
    200200        self._qmax_unsmeared = self.qmax 
    201          
     201 
    202202        self._first_unsmeared_bin = 0 
    203203        self._last_unsmeared_bin = len(self.x) - 1 
    204          
     204 
    205205        if self.smearer is not None: 
    206206            self._first_unsmeared_bin, self._last_unsmeared_bin = \ 
     
    208208            self._qmin_unsmeared = self.x[self._first_unsmeared_bin] 
    209209            self._qmax_unsmeared = self.x[self._last_unsmeared_bin] 
    210              
     210 
    211211        # Identify the bin range for the unsmeared and smeared spaces 
    212212        self.idx = (self.x >= self.qmin) & (self.x <= self.qmax) 
     
    231231        """ 
    232232            Compute residuals. 
    233              
     233 
    234234            If self.smearer has been set, use if to smear 
    235235            the data before computing chi squared. 
    236              
     236 
    237237            :param fn: function that return model value 
    238              
     238 
    239239            :return: residuals 
    240240        """ 
     
    242242        fx = np.zeros(len(self.x)) 
    243243        fx[self.idx_unsmeared] = fn(self.x[self.idx_unsmeared]) 
    244         
     244 
    245245        ## Smear theory data 
    246246        if self.smearer is not None: 
     
    253253            raise RuntimeError, msg 
    254254        return (self.y[self.idx] - fx[self.idx]) / self.dy[self.idx], fx[self.idx] 
    255              
     255 
    256256    def residuals_deriv(self, model, pars=[]): 
    257257        """ 
    258258            :return: residuals derivatives . 
    259              
    260             :note: in this case just return empty array  
     259 
     260            :note: in this case just return empty array 
    261261        """ 
    262262        return [] 
     
    293293        x_max = max(math.fabs(sas_data2d.xmin), math.fabs(sas_data2d.xmax)) 
    294294        y_max = max(math.fabs(sas_data2d.ymin), math.fabs(sas_data2d.ymax)) 
    295          
     295 
    296296        ## fitting range 
    297297        if qmin is None: 
     
    305305            self.res_err_data = copy.deepcopy(self.err_data) 
    306306        #self.res_err_data[self.res_err_data==0]=1 
    307          
     307 
    308308        self.radius = np.sqrt(self.qx_data**2 + self.qy_data**2) 
    309          
     309 
    310310        # Note: mask = True: for MASK while mask = False for NOT to mask 
    311311        self.idx = ((self.qmin <= self.radius) &\ 
     
    371371 
    372372        return res, gn 
    373          
     373 
    374374    def residuals_deriv(self, model, pars=[]): 
    375375        """ 
    376376        :return: residuals derivatives . 
    377          
     377 
    378378        :note: in this case just return empty array 
    379          
     379 
    380380        """ 
    381381        return [] 
    382      
    383      
     382 
     383 
    384384class FitAbort(Exception): 
    385385    """ 
     
    399399        self.fit_arrange_dict = {} 
    400400        self.fitter_id = None 
    401          
     401 
    402402    def set_model(self, model, id, pars=[], constraints=[], data=None): 
    403403        """ 
    404404        set a model on a given  in the fit engine. 
    405          
    406         :param model: sas.models type  
     405 
     406        :param model: sas.models type 
    407407        :param id: is the key of the fitArrange dictionary where model is saved as a value 
    408         :param pars: the list of parameters to fit  
    409         :param constraints: list of  
     408        :param pars: the list of parameters to fit 
     409        :param constraints: list of 
    410410            tuple (name of parameter, value of parameters) 
    411411            the value of parameter must be a string to constraint 2 different 
    412412            parameters. 
    413             Example:   
     413            Example: 
    414414            we want to fit 2 model M1 and M2 both have parameters A and B. 
    415415            constraints can be ``constraints = [(M1.A, M2.B+2), (M1.B= M2.A *5),...,]`` 
    416              
    417               
     416 
     417 
    418418        :note: pars must contains only name of existing model's parameters 
    419          
     419 
    420420        """ 
    421421        if not pars: 
     
    448448        in a FitArrange object and adds that object in a dictionary 
    449449        with key id. 
    450          
     450 
    451451        :param data: data added 
    452452        :param id: unique key corresponding to a fitArrange object with data 
     
    459459                                 dx=data.dx, dy=data.dy, smearer=smearer) 
    460460        fitdata.sas_data = data 
    461         
     461 
    462462        fitdata.set_fit_range(qmin=qmin, qmax=qmax) 
    463463        #A fitArrange is already created but contains model only at id 
     
    469469            fitproblem.add_data(fitdata) 
    470470            self.fit_arrange_dict[id] = fitproblem 
    471     
     471 
    472472    def get_model(self, id): 
    473473        """ 
    474474        :param id: id is key in the dictionary containing the model to return 
    475          
     475 
    476476        :return:  a model at this id or None if no FitArrange element was 
    477477            created with this id 
     
    481481        else: 
    482482            return None 
    483      
     483 
    484484    def remove_fit_problem(self, id): 
    485485        """remove   fitarrange in id""" 
    486486        if id in self.fit_arrange_dict: 
    487487            del self.fit_arrange_dict[id] 
    488              
     488 
    489489    def select_problem_for_fit(self, id, value): 
    490490        """ 
    491491        select a couple of model and data at the id position in dictionary 
    492492        and set in self.selected value to value 
    493          
     493 
    494494        :param value: the value to allow fitting. 
    495495                can only have the value one or zero 
     
    497497        if id in self.fit_arrange_dict: 
    498498            self.fit_arrange_dict[id].set_to_fit(value) 
    499               
     499 
    500500    def get_problem_to_fit(self, id): 
    501501        """ 
    502502        return the self.selected value of the fit problem of id 
    503          
     503 
    504504        :param id: the id of the problem 
    505505        """ 
    506506        if id in self.fit_arrange_dict: 
    507507            self.fit_arrange_dict[id].get_to_fit() 
    508      
    509      
     508 
     509 
    510510class FitArrange: 
    511511    def __init__(self): 
     
    514514        to perform the Fit.FitArrange must contain exactly one model 
    515515        and at least one data for the fit to be performed. 
    516          
     516 
    517517        model: the model selected by the user 
    518518        Ldata: a list of data what the user wants to fit 
    519              
     519 
    520520        """ 
    521521        self.model = None 
     
    528528        """ 
    529529        set_model save a copy of the model 
    530          
     530 
    531531        :param model: the model being set 
    532532        """ 
    533533        self.model = model 
    534          
     534 
    535535    def add_data(self, data): 
    536536        """ 
    537537        add_data fill a self.data_list with data to fit 
    538          
     538 
    539539        :param data: Data to add in the list 
    540540        """ 
    541541        if not data in self.data_list: 
    542542            self.data_list.append(data) 
    543              
     543 
    544544    def get_model(self): 
    545545        """ 
     
    547547        """ 
    548548        return self.model 
    549       
     549 
    550550    def get_data(self): 
    551551        """ 
     
    553553        """ 
    554554        return self.data_list[0] 
    555        
     555 
    556556    def remove_data(self, data): 
    557557        """ 
    558558        Remove one element from the list 
    559          
     559 
    560560        :param data: Data to remove from data_list 
    561561        """ 
    562562        if data in self.data_list: 
    563563            self.data_list.remove(data) 
    564              
     564 
    565565    def set_to_fit(self, value=0): 
    566566        """ 
    567567        set self.selected to 0 or 1  for other values raise an exception 
    568          
     568 
    569569        :param value: integer between 0 or 1 
    570570        """ 
    571571        self.selected = value 
    572          
     572 
    573573    def get_to_fit(self): 
    574574        """ 
     
    602602        if self.model is not None and self.data is not None: 
    603603            self.inputs = [(self.model, self.data)] 
    604       
     604 
    605605    def set_model(self, model): 
    606606        """ 
    607607        """ 
    608608        self.model = model 
    609          
     609 
    610610    def set_fitness(self, fitness): 
    611611        """ 
    612612        """ 
    613613        self.fitness = fitness 
    614          
     614 
    615615    def __str__(self): 
    616616        """ 
     
    627627        msg = [msg1, msg3] + msg2 
    628628        return "\n".join(msg) 
    629      
     629 
    630630    def print_summary(self): 
    631631        """ 
  • src/sas/sascalc/realspace/VolumeCanvas.py

    r235f514 r98e3f24  
    44    Simulation canvas for real-space simulation of SAS scattering intensity. 
    55    The user can create an arrangement of basic shapes and estimate I(q) and 
    6     I(q_x, q_y). Error estimates on the simulation are also available.  
    7      
     6    I(q_x, q_y). Error estimates on the simulation are also available. 
     7 
    88    Example: 
    9      
     9 
    1010    import sas.sascalc.realspace.VolumeCanvas as VolumeCanvas 
    1111    canvas = VolumeCanvas.VolumeCanvas() 
    1212    canvas.setParam('lores_density', 0.01) 
    13      
     13 
    1414    sphere = SphereDescriptor() 
    1515    handle = canvas.addObject(sphere) 
     
    1717    output, error = canvas.getIqError(q=0.1) 
    1818    output, error = canvas.getIq2DError(0.1, 0.1) 
    19      
     19 
    2020    or alternatively: 
    2121    iq = canvas.run(0.1) 
    2222    i2_2D = canvas.run([0.1, 1.57]) 
    23      
     23 
    2424""" 
    2525 
    26 from sas.models.BaseComponent import BaseComponent 
     26from sas.sascalc.calculator.BaseComponent import BaseComponent 
    2727from sas.sascalc.simulation.pointsmodelpy import pointsmodelpy 
    2828from sas.sascalc.simulation.geoshapespy import geoshapespy 
     
    3131import os.path, math 
    3232 
    33 class ShapeDescriptor: 
     33class ShapeDescriptor(object): 
    3434    """ 
    3535        Class to hold the information about a shape 
    3636        The descriptor holds a dictionary of parameters. 
    37          
     37 
    3838        Note: if shape parameters are accessed directly 
    3939        from outside VolumeCanvas. The getPr method 
    4040        should be called before evaluating I(q). 
    41                  
     41 
    4242    """ 
    4343    def __init__(self): 
     
    5555        self.params['is_lores'] = True 
    5656        self.params['order'] = 0 
    57              
     57 
    5858    def create(self): 
    5959        """ 
     
    6565        z0 = self.params["center"][2] 
    6666        geoshapespy.set_center(self.shapeObject, x0, y0, z0) 
    67          
     67 
    6868        # Set orientation 
    6969        x0 = self.params["orientation"][0] 
     
    7171        z0 = self.params["orientation"][2] 
    7272        geoshapespy.set_orientation(self.shapeObject, x0, y0, z0) 
    73                 
     73 
    7474class SphereDescriptor(ShapeDescriptor): 
    7575    """ 
    7676        Descriptor for a sphere 
    77          
     77 
    7878        The parameters are: 
    7979            - radius [Angstroem] [default = 20 A] 
    8080            - Contrast [A-2] [default = 1 A-2] 
    81              
     81 
    8282    """ 
    8383    def __init__(self): 
    8484        """ 
    8585            Initialization 
    86         """  
     86        """ 
    8787        ShapeDescriptor.__init__(self) 
    8888        # Default parameters 
    89         self.params["type"]   = "sphere" 
     89        self.params["type"] = "sphere" 
    9090        # Radius of the sphere 
    9191        self.params["radius"] = 20.0 
     
    100100        self.shapeObject = geoshapespy.new_sphere(\ 
    101101            self.params["radius"]) 
    102          
    103         ShapeDescriptor.create(self)    
     102 
     103        ShapeDescriptor.create(self) 
    104104        return self.shapeObject 
    105      
     105 
    106106class CylinderDescriptor(ShapeDescriptor): 
    107107    """ 
    108108        Descriptor for a cylinder 
    109109        Orientation: Default cylinder is along Y 
    110          
     110 
    111111        Parameters: 
    112112            - Length [default = 40 A] 
     
    117117        """ 
    118118            Initialization 
    119         """  
     119        """ 
    120120        ShapeDescriptor.__init__(self) 
    121121        # Default parameters 
    122         self.params["type"]   = "cylinder" 
     122        self.params["type"] = "cylinder" 
    123123        # Length of the cylinder 
    124124        self.params["length"] = 40.0 
     
    127127        # Constrast parameter 
    128128        self.params["contrast"] = 1.0 
    129          
     129 
    130130    def create(self): 
    131131        """ 
     
    138138        ShapeDescriptor.create(self) 
    139139        return self.shapeObject 
    140          
     140 
    141141 
    142142class EllipsoidDescriptor(ShapeDescriptor): 
    143143    """ 
    144144        Descriptor for an ellipsoid 
    145          
     145 
    146146        Parameters: 
    147147            - Radius_x along the x-axis [default = 30 A] 
     
    153153        """ 
    154154            Initialization 
    155         """  
     155        """ 
    156156        ShapeDescriptor.__init__(self) 
    157157        # Default parameters 
    158         self.params["type"]   = "ellipsoid" 
     158        self.params["type"] = "ellipsoid" 
    159159        self.params["radius_x"] = 30.0 
    160160        self.params["radius_y"] = 20.0 
    161161        self.params["radius_z"] = 10.0 
    162162        self.params["contrast"] = 1.0 
    163          
     163 
    164164    def create(self): 
    165165        """ 
     
    168168        """ 
    169169        self.shapeObject = geoshapespy.new_ellipsoid(\ 
    170             self.params["radius_x"], self.params["radius_y"],  
     170            self.params["radius_x"], self.params["radius_y"], 
    171171            self.params["radius_z"]) 
    172          
    173         ShapeDescriptor.create(self)    
     172 
     173        ShapeDescriptor.create(self) 
    174174        return self.shapeObject 
    175          
     175 
    176176class HelixDescriptor(ShapeDescriptor): 
    177177    """ 
    178178        Descriptor for an helix 
    179          
     179 
    180180        Parameters: 
    181181            -radius_helix: the radius of the helix [default = 10 A] 
     
    188188        """ 
    189189            Initialization 
    190         """  
     190        """ 
    191191        ShapeDescriptor.__init__(self) 
    192192        # Default parameters 
    193         self.params["type"]   = "singlehelix" 
     193        self.params["type"] = "singlehelix" 
    194194        self.params["radius_helix"] = 10.0 
    195195        self.params["radius_tube"] = 3.0 
     
    204204        """ 
    205205        self.shapeObject = geoshapespy.new_singlehelix(\ 
    206             self.params["radius_helix"], self.params["radius_tube"],  
     206            self.params["radius_helix"], self.params["radius_tube"], 
    207207            self.params["pitch"], self.params["turns"]) 
    208          
    209         ShapeDescriptor.create(self)    
     208 
     209        ShapeDescriptor.create(self) 
    210210        return self.shapeObject 
    211          
     211 
    212212class PDBDescriptor(ShapeDescriptor): 
    213213    """ 
    214214        Descriptor for a PDB set of points 
    215          
     215 
    216216        Parameter: 
    217217            - file = name of the PDB file 
     
    221221            Initialization 
    222222            @param filename: name of the PDB file to load 
    223         """  
     223        """ 
    224224        ShapeDescriptor.__init__(self) 
    225225        # Default parameters 
    226         self.params["type"]   = "pdb" 
     226        self.params["type"] = "pdb" 
    227227        self.params["file"] = filename 
    228228        self.params['is_lores'] = False 
     
    234234        """ 
    235235        self.shapeObject = pointsmodelpy.new_pdbmodel() 
    236         pointsmodelpy.pdbmodel_add(self.shapeObject, self.params['file'])        
    237          
    238         #ShapeDescriptor.create(self)    
     236        pointsmodelpy.pdbmodel_add(self.shapeObject, self.params['file']) 
     237 
     238        #ShapeDescriptor.create(self) 
    239239        return self.shapeObject 
    240          
     240 
    241241# Define a dictionary for the shape until we find 
    242242# a better way to create them 
     
    245245              'ellipsoid':EllipsoidDescriptor, 
    246246              'singlehelix':HelixDescriptor} 
    247          
     247 
    248248class VolumeCanvas(BaseComponent): 
    249249    """ 
    250         Class representing an empty space volume to add  
     250        Class representing an empty space volume to add 
    251251        geometrical object to. 
    252          
     252 
    253253        For 1D I(q) simulation, getPr() is called internally for the 
    254254        first call to getIq(). 
    255          
    256     """ 
    257      
     255 
     256    """ 
     257 
    258258    def __init__(self): 
    259259        """ 
     
    261261        """ 
    262262        BaseComponent.__init__(self) 
    263          
     263 
    264264        ## Maximum value of q reachable 
    265265        self.params['q_max'] = 0.1 
     
    267267        self.params['scale'] = 1.0 
    268268        self.params['background'] = 0.0 
    269          
     269 
    270270        self.lores_model = pointsmodelpy.new_loresmodel(self.params['lores_density']) 
    271271        self.complex_model = pointsmodelpy.new_complexmodel() 
    272272        self.shapes = {} 
    273         self.shapecount = 0         
     273        self.shapecount = 0 
    274274        self.points = None 
    275275        self.npts = 0 
    276         self.hasPr = False         
    277          
     276        self.hasPr = False 
     277 
    278278    def _model_changed(self): 
    279279        """ 
    280             Reset internal data members to reflect the fact that the  
     280            Reset internal data members to reflect the fact that the 
    281281            real-space model has changed 
    282282        """ 
    283         self.hasPr  = False 
     283        self.hasPr = False 
    284284        self.points = None 
    285          
    286     def addObject(self, shapeDesc, id = None): 
     285 
     286    def addObject(self, shapeDesc, id=None): 
    287287        """ 
    288288            Adds a real-space object to the canvas. 
    289          
     289 
    290290            @param shapeDesc: object to add to the canvas [ShapeDescriptor] 
    291291            @param id: string handle for the object [string] [optional] 
     
    295295        if id is None: 
    296296            id = shapeDesc.params["type"]+str(self.shapecount) 
    297           
     297 
    298298        # Self the order number 
    299299        shapeDesc.params['order'] = self.shapecount 
     
    307307 
    308308        return id 
    309              
    310      
    311     def add(self, shape, id = None): 
     309 
     310 
     311    def add(self, shape, id=None): 
    312312        """ 
    313313            The intend of this method is to eventually be able to use it 
     
    315315            analytical solutions. For instance, if one adds a cylinder and 
    316316            it is the only shape on the canvas, the analytical solution 
    317             could be called. If multiple shapes are involved, then  
     317            could be called. If multiple shapes are involved, then 
    318318            simulation has to be performed. 
    319              
     319 
    320320            This function is deprecated, use addObject(). 
    321          
     321 
    322322            @param shape: name of the object to add to the canvas [string] 
    323323            @param id: string handle for the object [string] [optional] 
     
    327327        if id is None: 
    328328            id = "shape"+str(self.shapecount) 
    329   
     329 
    330330        # shapeDesc = ShapeDescriptor(shape.lower()) 
    331331        if shape.lower() in shape_dict: 
     
    336336        else: 
    337337            raise ValueError("VolumeCanvas.add: Unknown shape %s" % shape) 
    338          
     338 
    339339        return self.addObject(shapeDesc, id) 
    340340 
     
    354354 
    355355 
    356     def setParam(self, name, value):     
    357         """ 
    358             Function to set the value of a parameter.  
     356    def setParam(self, name, value): 
     357        """ 
     358            Function to set the value of a parameter. 
    359359            Both VolumeCanvas parameters and shape parameters 
    360             are accessible.  
    361              
     360            are accessible. 
     361 
    362362            Note: if shape parameters are accessed directly 
    363363            from outside VolumeCanvas. The getPr method 
    364364            should be called before evaluating I(q). 
    365          
     365 
    366366            TODO: implemented a check method to protect 
    367367            against that. 
    368          
     368 
    369369            @param name: name of the parameter to change 
    370370            @param value: value to give the parameter 
    371371        """ 
    372          
     372 
    373373        # Lowercase for case insensitivity 
    374374        name = name.lower() 
    375          
     375 
    376376        # Look for shape access 
    377377        toks = name.split('.') 
    378          
     378 
    379379        # If a shape identifier was given, look the shape up 
    380380        # in the dictionary 
     
    390390            else: 
    391391                raise ValueError("Could not find shape %s" % toks[0]) 
    392          
     392 
    393393        else: 
    394             # If we are not accessing the parameters of a  
     394            # If we are not accessing the parameters of a 
    395395            # shape, see if the parameter is part of this object 
    396396            BaseComponent.setParam(self, name, value) 
    397397            self._model_changed() 
    398398 
    399     def getParam(self, name):     
     399    def getParam(self, name): 
    400400        """ 
    401401            @param name: name of the parameter to change 
    402402        """ 
    403403        #TODO: clean this up 
    404          
     404 
    405405        # Lowercase for case insensitivity 
    406406        name = name.lower() 
    407          
     407 
    408408        # Look for sub-model access 
    409409        toks = name.split('.') 
     
    435435        else: 
    436436            raise ValueError("VolumeCanvas.getParam: Could not find %s" % name) 
    437              
     437 
    438438    def getParamList(self, shapeid=None): 
    439439        """ 
    440                return a full list of all available parameters from  
     440               return a full list of all available parameters from 
    441441           self.params.keys(). If a key in self.params is a instance 
    442            of ShapeDescriptor, extend the return list to:  
     442           of ShapeDescriptor, extend the return list to: 
    443443           [param1,param2,shapeid.param1,shapeid.param2.......] 
    444444 
     
    456456                header = key2 + '.' 
    457457                for key3 in value2.params: 
    458                     fullname = header + key3                  
     458                    fullname = header + key3 
    459459                    param_list.append(fullname) 
    460       
     460 
    461461        else: 
    462462            if not shapeid in self.shapes: 
     
    470470    def getShapeList(self): 
    471471        """ 
    472             Return a list of the shapes  
     472            Return a list of the shapes 
    473473        """ 
    474474        return self.shapes.keys() 
     
    481481        # Create the object model 
    482482        shapeDesc.create() 
    483                      
     483 
    484484        if shapeDesc.params['is_lores']: 
    485485            # Add the shape to the lores_model 
    486             pointsmodelpy.lores_add(self.lores_model,  
    487                 shapeDesc.shapeObject, shapeDesc.params['contrast'])   
     486            pointsmodelpy.lores_add(self.lores_model, 
     487                                    shapeDesc.shapeObject, 
     488                                    shapeDesc.params['contrast']) 
    488489 
    489490    def _createVolumeFromList(self): 
     
    492493            Whenever we change a parameter of a shape, we have to re-create 
    493494            the whole thing. 
    494              
     495 
    495496            Items with higher 'order' number take precedence for regions 
    496             of space that are shared with other objects. Points in the  
     497            of space that are shared with other objects. Points in the 
    497498            overlapping region belonging to objects with lower 'order' 
    498499            will be ignored. 
    499              
     500 
    500501            Items are added in decreasing 'order' number. 
    501502            The item with the highest 'order' will be added *first*. 
    502503            [That conventions is prescribed by the realSpaceModeling module] 
    503504        """ 
    504          
     505 
    505506        # Create empty model 
    506507        self.lores_model = \ 
     
    509510        # Create empty complex model 
    510511        self.complex_model = pointsmodelpy.new_complexmodel() 
    511         
     512 
    512513        # Order the object first 
    513514        obj_list = [] 
    514      
     515 
    515516        for shape in self.shapes: 
    516517            order = self.shapes[shape].params['order'] 
    517518            # find where to place it in the list 
    518519            stored = False 
    519              
     520 
    520521            for i in range(len(obj_list)): 
    521522                if obj_list[i][0] > order: 
     
    523524                    stored = True 
    524525                    break 
    525              
     526 
    526527            if not stored: 
    527528                obj_list.append([order, shape]) 
    528                  
     529 
    529530        # Add each shape 
    530531        len_list = len(obj_list) 
     
    533534            self._addSingleShape(shapedesc) 
    534535 
    535         return 0      
    536      
     536        return 0 
     537 
    537538    def getPr(self): 
    538539        """ 
     
    540541            This method should always be called after the shapes 
    541542            on the VolumeCanvas have changed. 
    542              
    543             @return: calculation output flag  
     543 
     544            @return: calculation output flag 
    544545        """ 
    545546        # To find a complete example of the correct call order: 
    546547        # In LORES2, in actionclass.py, method CalculateAction._get_iq() 
    547          
     548 
    548549        # If there are not shapes, do nothing 
    549550        if len(self.shapes) == 0: 
    550551            self._model_changed() 
    551552            return 0 
    552          
     553 
    553554        # generate space filling points from shape list 
    554555        self._createVolumeFromList() 
     
    556557        self.points = pointsmodelpy.new_point3dvec() 
    557558 
    558         pointsmodelpy.complexmodel_add(self.complex_model,  
    559                                         self.lores_model, "LORES") 
     559        pointsmodelpy.complexmodel_add(self.complex_model, 
     560                                       self.lores_model, "LORES") 
    560561        for shape in self.shapes: 
    561             if self.shapes[shape].params['is_lores'] == False: 
    562                 pointsmodelpy.complexmodel_add(self.complex_model,  
     562            if not self.shapes[shape].params['is_lores']: 
     563                pointsmodelpy.complexmodel_add(self.complex_model, 
    563564                    self.shapes[shape].shapeObject, "PDB") 
    564          
     565 
    565566        #pointsmodelpy.get_lorespoints(self.lores_model, self.points) 
    566567        self.npts = pointsmodelpy.get_complexpoints(self.complex_model, self.points) 
    567          
     568 
    568569        # expecting the rmax is a positive float or 0. The maximum distance. 
    569         #rmax = pointsmodelpy.get_lores_pr(self.lores_model, self.points)    
    570           
    571         rmax = pointsmodelpy.get_complex_pr(self.complex_model, self.points)  
    572         self.hasPr = True    
     570        #rmax = pointsmodelpy.get_lores_pr(self.lores_model, self.points) 
     571 
     572        rmax = pointsmodelpy.get_complex_pr(self.complex_model, self.points) 
     573        self.hasPr = True 
    573574 
    574575        return rmax 
    575          
    576     def run(self, q = 0): 
     576 
     577    def run(self, q=0): 
    577578        """ 
    578579            Returns the value of I(q) for a given q-value 
     
    595596        else: 
    596597            raise ValueError("run(q): bad type for q") 
    597      
    598     def runXY(self, q = 0): 
     598 
     599    def runXY(self, q=0): 
    599600        """ 
    600601            Standard run command for the canvas. 
    601             Redirects to the correct method  
     602            Redirects to the correct method 
    602603            according to the input type. 
    603604            @param q: q-value [float] or [list] [A-1] 
     
    615616        else: 
    616617            raise ValueError("runXY(q): bad type for q") 
    617      
     618 
    618619    def _create_modelObject(self): 
    619620        """ 
    620621            Create the simulation model obejct from the list 
    621622            of shapes. 
    622              
     623 
    623624            This method needs to be called each time a parameter 
    624625            changes because of the way the underlying library 
    625             was (badly) written. It is impossible to change a  
    626             parameter, or remove a shape without having to  
     626            was (badly) written. It is impossible to change a 
     627            parameter, or remove a shape without having to 
    627628            refill the space points. 
    628              
     629 
    629630            TODO: improve that. 
    630631        """ 
    631632        # To find a complete example of the correct call order: 
    632633        # In LORES2, in actionclass.py, method CalculateAction._get_iq() 
    633          
     634 
    634635        # If there are not shapes, do nothing 
    635636        if len(self.shapes) == 0: 
    636637            self._model_changed() 
    637638            return 0 
    638          
     639 
    639640        # generate space filling points from shape list 
    640641        self._createVolumeFromList() 
     
    642643        self.points = pointsmodelpy.new_point3dvec() 
    643644 
    644         pointsmodelpy.complexmodel_add(self.complex_model,  
    645                                         self.lores_model, "LORES") 
     645        pointsmodelpy.complexmodel_add(self.complex_model, 
     646                                       self.lores_model, "LORES") 
    646647        for shape in self.shapes: 
    647             if self.shapes[shape].params['is_lores'] == False: 
    648                 pointsmodelpy.complexmodel_add(self.complex_model,  
     648            if not self.shapes[shape].params['is_lores']: 
     649                pointsmodelpy.complexmodel_add(self.complex_model, 
    649650                    self.shapes[shape].shapeObject, "PDB") 
    650          
     651 
    651652        #pointsmodelpy.get_lorespoints(self.lores_model, self.points) 
    652653        self.npts = pointsmodelpy.get_complexpoints(self.complex_model, self.points) 
    653          
    654          
     654 
     655 
    655656    def getIq2D(self, qx, qy): 
    656657        """ 
     
    660661            @return: I(q) [cm-1] 
    661662        """ 
    662          
     663 
    663664        # If this is the first simulation call, we need to generate the 
    664665        # space points 
    665666        if self.points is None: 
    666667            self._create_modelObject() 
    667              
     668 
    668669            # Protect against empty model 
    669670            if self.points is None: 
    670671                return 0 
    671                 
    672         # Evalute I(q)  
    673         norm =  1.0e8/self.params['lores_density']*self.params['scale'] 
     672 
     673        # Evalute I(q) 
     674        norm = 1.0e8/self.params['lores_density']*self.params['scale'] 
    674675        return norm*pointsmodelpy.get_complex_iq_2D(self.complex_model, self.points, qx, qy)\ 
    675676            + self.params['background'] 
    676                  
     677 
    677678    def write_pr(self, filename): 
    678679        """ 
    679680            Write P(r) to an output file 
    680681            @param filename: file name for P(r) output 
    681         """    
    682         if self.hasPr == False: 
     682        """ 
     683        if not self.hasPr: 
    683684            self.getPr() 
    684       
     685 
    685686        pointsmodelpy.outputPR(self.complex_model, filename) 
    686       
     687 
    687688    def getPrData(self): 
    688689        """ 
    689690            Write P(r) to an output file 
    690691            @param filename: file name for P(r) output 
    691         """    
    692         if self.hasPr == False: 
     692        """ 
     693        if not self.hasPr: 
    693694            self.getPr() 
    694       
     695 
    695696        return pointsmodelpy.get_pr(self.complex_model) 
    696       
     697 
    697698    def getIq(self, q): 
    698699        """ 
    699700            Returns the value of I(q) for a given q-value 
    700              
     701 
    701702            This method should remain internal to the class 
    702703            and the run() method should be used instead. 
    703              
     704 
    704705            @param q: q-value [float] 
    705706            @return: I(q) [float] 
    706707        """ 
    707          
    708         if self.hasPr == False: 
     708 
     709        if not self.hasPr: 
    709710            self.getPr() 
    710711 
    711         # By dividing by the density instead of the actuall V/N,  
    712         # we have an uncertainty of +-1 on N because the number  
     712        # By dividing by the density instead of the actuall V/N, 
     713        # we have an uncertainty of +-1 on N because the number 
    713714        # of points chosen for the simulation is int(density*volume). 
    714715        # Propagation of error gives: 
     
    716717        # where N is stored in self.npts 
    717718 
    718         norm =  1.0e8/self.params['lores_density']*self.params['scale'] 
     719        norm = 1.0e8/self.params['lores_density']*self.params['scale'] 
    719720        #return norm*pointsmodelpy.get_lores_i(self.lores_model, q) 
    720721        return norm*pointsmodelpy.get_complex_i(self.complex_model, q)\ 
    721722            + self.params['background'] 
    722      
     723 
    723724    def getError(self, q): 
    724725        """ 
     
    727728            @return: I(q) [float] 
    728729        """ 
    729          
    730         if self.hasPr == False: 
     730 
     731        if not self.hasPr: 
    731732            self.getPr() 
    732733 
    733         # By dividing by the density instead of the actual V/N,  
    734         # we have an uncertainty of +-1 on N because the number  
     734        # By dividing by the density instead of the actual V/N, 
     735        # we have an uncertainty of +-1 on N because the number 
    735736        # of points chosen for the simulation is int(density*volume). 
    736737        # Propagation of error gives: 
     
    738739        # where N is stored in self.npts 
    739740 
    740         norm =  1.0e8/self.params['lores_density']*self.params['scale'] 
     741        norm = 1.0e8/self.params['lores_density']*self.params['scale'] 
    741742        #return norm*pointsmodelpy.get_lores_i(self.lores_model, q) 
    742743        return norm*pointsmodelpy.get_complex_i_error(self.complex_model, q)\ 
    743744            + self.params['background'] 
    744      
     745 
    745746    def getIqError(self, q): 
    746747        """ 
    747748            Return the simulated value along with its estimated 
    748749            error for a given q-value 
    749              
     750 
    750751            Propagation of errors is used to evaluate the 
    751752            uncertainty. 
    752              
     753 
    753754            @param q: q-value [float] 
    754755            @return: mean, error [float, float] 
     
    765766            Return the simulated value along with its estimated 
    766767            error for a given q-value 
    767              
     768 
    768769            Propagation of errors is used to evaluate the 
    769770            uncertainty. 
    770              
     771 
    771772            @param qx: qx-value [float] 
    772773            @param qy: qy-value [float] 
     
    774775        """ 
    775776        self._create_modelObject() 
    776                  
    777         norm =  1.0e8/self.params['lores_density']*self.params['scale'] 
     777 
     778        norm = 1.0e8/self.params['lores_density']*self.params['scale'] 
    778779        val = norm*pointsmodelpy.get_complex_iq_2D(self.complex_model, self.points, qx, qy)\ 
    779780            + self.params['background'] 
    780          
     781 
    781782        # Simulation error (statistical) 
    782         norm =  1.0e8/self.params['lores_density']*self.params['scale'] \ 
    783                 * math.pow(self.npts/self.params['lores_density'], 1.0/3.0)/self.npts 
     783        norm = 1.0e8/self.params['lores_density']*self.params['scale'] \ 
     784               * math.pow(self.npts/self.params['lores_density'], 1.0/3.0)/self.npts 
    784785        err = norm*pointsmodelpy.get_complex_iq_2D_err(self.complex_model, self.points, qx, qy) 
    785786        # Error on V/N 
    786787        simerr = 2*val/self.npts 
    787          
     788 
    788789        # The error used for the position is over-simplified. 
    789790        # The actual error was empirically found to be about 
    790791        # an order of magnitude larger. 
    791792        return val, 10.0*err+simerr 
    792          
  • 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                                                          sel