Changeset 9be22cd in sasview for src/sas/sascalc


Ignore:
Timestamp:
Sep 27, 2017 8:50:02 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
fca1f50
Parents:
69a6897 (diff), 83db1cc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'ticket-887-reorg' into ticket-853-fit-gui-to-calc

Location:
src/sas/sascalc
Files:
1 added
5 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/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          
Note: See TracChangeset for help on using the changeset viewer.