Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py

    r70f4458 r44deced  
    88from sas.qtgui.Plotting.PlotterData import Data1D 
    99from sas.qtgui.Plotting.PlotterData import Data2D 
     10 
     11from sas.qtgui.Perspectives.Fitting.AssociatedComboBox import AssociatedComboBox 
    1012 
    1113model_header_captions = ['Parameter', 'Value', 'Min', 'Max', 'Units'] 
     
    2123 
    2224poly_header_tooltips = ['Select parameter for fitting', 
    23                         'Enter polydispersity ratio (STD/mean). ' 
     25                        'Enter polydispersity ratio (Std deviation/mean).\n'+ 
     26                        'For angles this can be either std deviation or full width (for uniform distributions) in degrees', 
    2427                        'STD: standard deviation from the mean value', 
    2528                        'Enter minimum value for parameter', 
     
    6164    return (param_name, param_length) 
    6265 
    63 def addParametersToModel(parameters, kernel_module, is2D): 
    64     """ 
    65     Update local ModelModel with sasmodel parameters 
     66def createFixedChoiceComboBox(param, item_row): 
     67    """ 
     68    Determines whether param is a fixed-choice parameter, modifies items in item_row appropriately and returns a combo 
     69    box containing the fixed choices. Returns None if param is not fixed-choice. 
     70     
     71    item_row is a list of QStandardItem objects for insertion into the parameter table.  
     72    """ 
     73 
     74    # Determine whether this is a fixed-choice parameter. There are lots of conditionals, simply because the 
     75    # implementation is not yet concrete; there are several possible indicators that the parameter is fixed-choice. 
     76    # TODO: (when the sasmodels implementation is concrete, clean this up) 
     77    choices = None 
     78    if isinstance(param.choices, (list, tuple)) and len(param.choices) > 0: 
     79        # The choices property is concrete in sasmodels, probably will use this 
     80        choices = param.choices 
     81    elif isinstance(param.units, (list, tuple)): 
     82        choices = [str(x) for x in param.units] 
     83 
     84    cbox = None 
     85    if choices is not None: 
     86        # Use combo box for input, if it is fixed-choice 
     87        cbox = AssociatedComboBox(item_row[1], idx_as_value=True) 
     88        cbox.addItems(choices) 
     89        item_row[2].setEditable(False) 
     90        item_row[3].setEditable(False) 
     91 
     92    return cbox 
     93 
     94def addParametersToModel(parameters, kernel_module, is2D, model=None, view=None): 
     95    """ 
     96    Update local ModelModel with sasmodel parameters. 
     97    Actually appends to model, if model and view params are not None. 
     98    Always returns list of lists of QStandardItems. 
    6699    """ 
    67100    multishell_parameters = getIterParams(parameters) 
     
    72105    else: 
    73106        params = parameters.iq_parameters 
    74     item = [] 
     107 
     108    rows = [] 
    75109    for param in params: 
    76110        # don't include shell parameters 
    77111        if param.name == multishell_param_name: 
    78112            continue 
     113 
    79114        # Modify parameter name from <param>[n] to <param>1 
    80115        item_name = param.name 
    81116        if param in multishell_parameters: 
    82117            continue 
    83         #    item_name = replaceShellName(param.name, 1) 
    84118 
    85119        item1 = QtGui.QStandardItem(item_name) 
    86120        item1.setCheckable(True) 
    87121        item1.setEditable(False) 
    88         # item_err = QtGui.QStandardItem() 
     122 
    89123        # check for polydisp params 
    90124        if param.polydisperse: 
     
    93127            item1_1 = QtGui.QStandardItem("Distribution") 
    94128            item1_1.setEditable(False) 
     129 
    95130            # Find param in volume_params 
    96             for p in parameters.form_volume_parameters: 
     131            poly_pars = copy.deepcopy(parameters.form_volume_parameters) 
     132            if is2D: 
     133                poly_pars += parameters.orientation_parameters 
     134            for p in poly_pars: 
    97135                if p.name != param.name: 
    98136                    continue 
    99137                width = kernel_module.getParam(p.name+'.width') 
    100138                ptype = kernel_module.getParam(p.name+'.type') 
    101  
    102139                item1_2 = QtGui.QStandardItem(str(width)) 
    103140                item1_2.setEditable(False) 
     
    110147                poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 
    111148                break 
     149 
    112150            # Add the polydisp item as a child 
    113151            item1.appendRow([poly_item]) 
     152 
    114153        # Param values 
    115154        item2 = QtGui.QStandardItem(str(param.default)) 
    116         # TODO: the error column. 
    117         # Either add a proxy model or a custom view delegate 
    118         #item_err = QtGui.QStandardItem() 
    119155        item3 = QtGui.QStandardItem(str(param.limits[0])) 
    120156        item4 = QtGui.QStandardItem(str(param.limits[1])) 
    121         item5 = QtGui.QStandardItem(param.units) 
     157        item5 = QtGui.QStandardItem(str(param.units)) 
    122158        item5.setEditable(False) 
    123         item.append([item1, item2, item3, item4, item5]) 
    124     return item 
    125  
    126 def addSimpleParametersToModel(parameters, is2D, parameters_original=None): 
    127     """ 
    128     Update local ModelModel with sasmodel parameters 
    129     parameters_original: list of parameters before any tagging on their IDs, e.g. for product model 
    130     (so that those are the display names; see below) 
     159 
     160        # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
     161        row = [item1, item2, item3, item4, item5] 
     162        cbox = createFixedChoiceComboBox(param, row) 
     163 
     164        # Append to the model and use the combobox, if required 
     165        if None not in (model, view): 
     166            model.appendRow(row) 
     167            if cbox: 
     168                view.setIndexWidget(item2.index(), cbox) 
     169        rows.append(row) 
     170 
     171    return rows 
     172 
     173def addSimpleParametersToModel(parameters, is2D, parameters_original=None, model=None, view=None, row_num=None): 
     174    """ 
     175    Update local ModelModel with sasmodel parameters (non-dispersed, non-magnetic) 
     176    Actually appends to model, if model and view params are not None. 
     177    Always returns list of lists of QStandardItems. 
     178 
     179    parameters_original: list of parameters before any tagging on their IDs, e.g. for product model (so that those are 
     180    the display names; see below) 
    131181    """ 
    132182    if is2D: 
     
    147197        params_orig = params 
    148198 
    149     item = [] 
     199    rows = [] 
    150200    for param, param_orig in zip(params, params_orig): 
    151201        # Create the top level, checkable item 
     
    155205        item1.setCheckable(True) 
    156206        item1.setEditable(False) 
     207 
    157208        # Param values 
    158209        # TODO: add delegate for validation of cells 
    159210        item2 = QtGui.QStandardItem(str(param.default)) 
    160         item4 = QtGui.QStandardItem(str(param.limits[0])) 
    161         item5 = QtGui.QStandardItem(str(param.limits[1])) 
    162         item6 = QtGui.QStandardItem(str(param.units)) 
    163         item6.setEditable(False) 
    164         item.append([item1, item2, item4, item5, item6]) 
    165     return item 
     211        item3 = QtGui.QStandardItem(str(param.limits[0])) 
     212        item4 = QtGui.QStandardItem(str(param.limits[1])) 
     213        item5 = QtGui.QStandardItem(str(param.units)) 
     214        item5.setEditable(False) 
     215 
     216        # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
     217        row = [item1, item2, item3, item4, item5] 
     218        cbox = createFixedChoiceComboBox(param, row) 
     219 
     220        # Append to the model and use the combobox, if required 
     221        if None not in (model, view): 
     222            if row_num is None: 
     223                model.appendRow(row) 
     224            else: 
     225                model.insertRow(row_num, row) 
     226                row_num += 1 
     227 
     228            if cbox: 
     229                view.setIndexWidget(item2.index(), cbox) 
     230 
     231        rows.append(row) 
     232 
     233    return rows 
    166234 
    167235def markParameterDisabled(model, row): 
     
    259327    model.header_tooltips = copy.copy(poly_header_error_tooltips) 
    260328 
    261 def addShellsToModel(parameters, model, index, row_num=None): 
     329def addShellsToModel(parameters, model, index, row_num=None, view=None): 
    262330    """ 
    263331    Find out multishell parameters and update the model with the requested number of them. 
    264332    Inserts them after the row at row_num, if not None; otherwise, appends to end. 
     333    If view param is not None, supports fixed-choice params. 
    265334    Returns a list of lists of QStandardItem objects. 
    266335    """ 
     
    285354                    item1_3 = QtGui.QStandardItem(str(p.limits[0])) 
    286355                    item1_4 = QtGui.QStandardItem(str(p.limits[1])) 
    287                     item1_5 = QtGui.QStandardItem(p.units) 
     356                    item1_5 = QtGui.QStandardItem(str(p.units)) 
    288357                    poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 
    289358                    break 
     
    293362            item3 = QtGui.QStandardItem(str(par.limits[0])) 
    294363            item4 = QtGui.QStandardItem(str(par.limits[1])) 
    295             item5 = QtGui.QStandardItem(par.units) 
     364            item5 = QtGui.QStandardItem(str(par.units)) 
     365            item5.setEditable(False) 
     366 
     367            # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
    296368            row = [item1, item2, item3, item4, item5] 
    297             rows.append(row) 
    298  
     369            cbox = createFixedChoiceComboBox(par, row) 
     370 
     371            # Always add to the model 
    299372            if row_num is None: 
    300373                model.appendRow(row) 
     
    302375                model.insertRow(row_num, row) 
    303376                row_num += 1 
     377 
     378            # Apply combobox if required 
     379            if None not in (view, cbox): 
     380                view.setIndexWidget(item2.index(), cbox) 
     381 
     382            rows.append(row) 
    304383 
    305384    return rows 
     
    474553 
    475554    theory_name = str(current_data.name.split()[0]) 
    476     residuals.name = "Residuals for " + str(theory_name) + "[" + \ 
    477                     str(reference_data.filename) + "]" 
     555    res_name = reference_data.filename if reference_data.filename else reference_data.name 
     556    residuals.name = "Residuals for " + str(theory_name) + "[" + res_name + "]" 
    478557    residuals.title = residuals.name 
    479558    residuals.ytransform = 'y' 
     
    492571    return residuals 
    493572 
     573def plotPolydispersities(model): 
     574    plots = [] 
     575    if model is None: 
     576        return plots 
     577    # test for model being a sasmodels.sasview_model.SasviewModel? 
     578    for name in model.dispersion.keys(): 
     579        xarr, yarr = model.get_weights(name) 
     580        if len(xarr) <= 1: # param name not found or no polydisp. 
     581            continue 
     582        # create Data1D as in residualsData1D() and fill x/y members 
     583        # similar to FittingLogic._create1DPlot() but different data/axes 
     584        data1d = Data1D(x=xarr, y=yarr) 
     585        xunit = model.details[name][0] 
     586        data1d.xaxis(r'\rm{{{}}}'.format(name.replace('_', '\_')), xunit) 
     587        data1d.yaxis(r'\rm{weight}', 'normalized') 
     588        data1d.scale = 'linear' 
     589        data1d.symbol = 'Line' 
     590        data1d.name = "{} polydispersity".format(name) 
     591        data1d.id = data1d.name # placeholder, has to be completed later 
     592        data1d.plot_role = Data1D.ROLE_RESIDUAL 
     593        plots.append(data1d) 
     594    return plots 
     595 
    494596def binary_encode(i, digits): 
    495597    return [i >> d & 1 for d in range(digits)] 
     
    501603    """ 
    502604    weight = None 
     605    if data is None: 
     606        return [] 
    503607    if is2d: 
     608        if not hasattr(data, 'err_data'): 
     609            return [] 
    504610        dy_data = data.err_data 
    505611        data = data.data 
    506612    else: 
     613        if not hasattr(data, 'dy'): 
     614            return [] 
    507615        dy_data = data.dy 
    508616        data = data.y 
     
    696804 
    697805    return output_string 
     806 
     807def isParamPolydisperse(param_name, kernel_params, is2D=False): 
     808    """ 
     809    Simple lookup for polydispersity for the given param name 
     810    """ 
     811    parameters = kernel_params.form_volume_parameters 
     812    if is2D: 
     813        parameters += kernel_params.orientation_parameters 
     814    has_poly = False 
     815    for param in parameters: 
     816        if param.name==param_name and param.polydisperse: 
     817            has_poly = True 
     818            break 
     819    return has_poly 
     820 
Note: See TracChangeset for help on using the changeset viewer.