Changeset aa47ea5 in sasview


Ignore:
Timestamp:
Mar 28, 2019 8:54:29 AM (8 weeks ago)
Author:
ibressler
Branches:
ESS_GUI_bumps_abstraction
Children:
04a269f
Parents:
e900a47
git-author:
Ingo Breßler <dev@…> (03/27/19 12:26:03)
git-committer:
Ingo Breßler <dev@…> (03/28/19 08:54:29)
Message:

some new classes to handle fitting methods in a generic way

File:
1 edited

Legend:

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

    r33c0561 raa47ea5  
    1919 
    2020# Set the default optimizer 
    21 fitters.FIT_DEFAULT_ID = 'lm' 
    22  
     21 
     22class FittingMethodParameter: 
     23    _shortName = None 
     24    _longName = None 
     25    _type = None 
     26    _defaultValue = None 
     27    value = None 
     28 
     29    def __init__(self, shortName, longName, dtype, defaultValue): 
     30        self._shortName = shortName 
     31        self._longName = longName 
     32        self._type = dtype 
     33        self._defaultValue = defaultValue 
     34        self.value = defaultValue 
     35 
     36    @property 
     37    def shortName(self): 
     38        return self._shortName 
     39 
     40    @property 
     41    def longName(self): 
     42        return self._longName 
     43 
     44    @property 
     45    def type(self): 
     46        return self._type 
     47 
     48    @property 
     49    def defaultValue(self): 
     50        return self._defaultValue 
     51 
     52    def __str__(self): 
     53        return "'{}' ({}): {} ({})".format( 
     54                self.longName, self.sortName, self.defaultValue, self.type) 
     55 
     56class FittingMethod: 
     57    """ 
     58    Represents a generic fitting method. 
     59    """ 
     60    _shortName = None 
     61    _longName = None 
     62    _params = None    # dict of <param short names>: <FittingMethodParam> 
     63 
     64    def __init__(self, shortName, longName, params): 
     65        self._shortName = shortName 
     66        self._longName = longName 
     67        self._params = dict(zip([p.shortName for p in params], params)) 
     68 
     69    @property 
     70    def shortName(self): 
     71        return self._shortName 
     72 
     73    @property 
     74    def longName(self): 
     75        return self._longName 
     76 
     77    @property 
     78    def params(self): 
     79        return self._params 
     80 
     81    def __str__(self): 
     82        return "\n".join(["{} ({})".format(self.longName, self.shortName)] 
     83                + [str(p) for p in self.params]) 
     84 
     85class FittingMethods: 
     86    """ 
     87    A container for the available fitting methods. 
     88    Allows SasView to employ other methods than those provided by the bumps package. 
     89    """ 
     90    _methods = None # a dict containing FitMethod objects 
     91    _default = None 
     92 
     93    def __init__(self): 
     94        """Receives a list of FittingMethod instances to be initialized with.""" 
     95        self._methods = dict() 
     96 
     97    def add(self, fittingMethod): 
     98        if not isinstance(fittingMethod, FittingMethod): 
     99            return 
     100        self._methods[fittingMethod.longName] = fittingMethod 
     101 
     102    def importFromBumps(self, ids): 
     103        """ 
     104        Import fitting methods indicated by the provided list of ids from the bumps package. 
     105        """ 
     106        for f in fitters.FITTERS: 
     107            if f.id not in ids: 
     108                continue 
     109            params = [] 
     110            for shortName, defValue in f.settings: 
     111                longName, dtype = bumps.options.FIT_FIELDS[shortName] 
     112                param = FittingMethodParameter(shortName, longName, dtype, defValue) 
     113                params.append(param) 
     114            self.add(FittingMethod(f.id, f.name, params)) 
     115 
     116    @property 
     117    def longNames(self): 
     118        return list(self._methods.keys()) 
     119 
     120    @property 
     121    def ids(self): 
     122        return [fm.shortName for fm in self._methods.values()] 
     123 
     124    def __getitem__(self, name): 
     125        return self._methods[name] 
     126 
     127    @property 
     128    def default(self): 
     129        return self._default 
     130 
     131    def setDefault(self, methodName): 
     132        assert methodName in self._methods # silently fail instead? 
     133        self._default = self._methods[methodName] 
     134 
     135    def __str__(self): 
     136        return "\n".join(["{}: {}".format(key, fm) for key, fm in self._methods.items()]) 
    23137 
    24138class FittingOptions(QtWidgets.QDialog, Ui_FittingOptions): 
     
    37151    """ 
    38152    fit_option_changed = QtCore.pyqtSignal(str) 
     153    # storing of fitting methods here for now, dependencies might indicate a better place later 
     154    fittingMethods = None 
    39155 
    40156    def __init__(self, parent=None, config=None): 
     
    52168 
    53169        # Fill up the algorithm combo, based on what BUMPS says is available 
    54         self.cbAlgorithm.addItems([n.name for n in fitters.FITTERS if n.id in fitters.FIT_ACTIVE_IDS]) 
     170        self.fittingMethods = FittingMethods() 
     171        # option 1: hardcode the list of bumps fitting methods according to forms 
     172        # option 2: create forms dynamically based on selected fitting methods 
     173        self.fittingMethods.importFromBumps(fitters.FIT_ACTIVE_IDS) 
     174        self.fittingMethods.add(FittingMethod('mcsas', 'McSAS', [])) 
     175        self.fittingMethods.setDefault('Levenberg-Marquardt') 
     176        # build up the comboBox finally 
     177        self.cbAlgorithm.addItems(self.fittingMethods.longNames) 
    55178 
    56179        # Handle the Apply button click 
     
    63186 
    64187        # Set the default index 
    65         default_name = [n.name for n in fitters.FITTERS if n.id == fitters.FIT_DEFAULT_ID][0] 
    66         default_index = self.cbAlgorithm.findText(default_name) 
     188        default_index = self.cbAlgorithm.findText(self.fittingMethods.default.longName) 
    67189        self.cbAlgorithm.setCurrentIndex(default_index) 
    68190        # previous algorithm choice 
     
    73195 
    74196        # Set defaults 
    75         self.current_fitter_id = fitters.FIT_DEFAULT_ID 
     197        self.current_fitter_id = self.fittingMethods.default.shortName 
    76198 
    77199        # OK has to be initialized to True, after initial validator setup 
     
    93215            else: 
    94216                continue 
    95             for fitter_id in fitters.FIT_ACTIVE_IDS: 
     217            for fitter_id in self.fittingMethods.ids: 
    96218                line_edit = self.widgetFromOption(str(option), current_fitter=str(fitter_id)) 
    97219                if hasattr(line_edit, 'setValidator') and validator is not None: 
     
    118240        """ 
    119241        # Find the algorithm ID from name 
    120         self.current_fitter_id = \ 
    121             [n.id for n in fitters.FITTERS if n.name == str(self.cbAlgorithm.currentText())][0] 
     242        selectedName = str(self.cbAlgorithm.currentText()) 
     243        if selectedName in self.fittingMethods.longNames: 
     244            self.current_fitter_id = self.fittingMethods[selectedName].shortName 
    122245 
    123246        # find the right stacked widget 
Note: See TracChangeset for help on using the changeset viewer.