Changeset 4e9f227 in sasview


Ignore:
Timestamp:
May 15, 2014 5:07:43 PM (10 years ago)
Author:
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, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
786685e
Parents:
e3efa6b3
Message:

support simultaneous fitting in bumps

Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • src/sans/fit/BumpsFitting.py

    re3efa6b3 r4e9f227  
    22BumpsFitting module runs the bumps optimizer. 
    33""" 
    4 import time 
    5  
    64import numpy 
    75 
     
    119from bumps.fitproblem import FitProblem 
    1210 
    13 from sans.fit.AbstractFitEngine import FitEngine 
    14 from sans.fit.AbstractFitEngine import FResult 
     11from .AbstractFitEngine import FitEngine 
     12from .AbstractFitEngine import FResult 
     13from .expression import compile_constraints 
    1514 
    1615class BumpsMonitor(object): 
     
    5251 
    5352 
     53# Note: currently using bumps parameters for each parameter object so that 
     54# a SasFitness can be used directly in bumps with the usual semantics. 
     55# The disadvantage of this technique is that we need to copy every parameter 
     56# back into the model each time the function is evaluated.  We could instead 
     57# define reference parameters for each sans parameter, but then we would not 
     58# be able to express constraints using python expressions in the usual way 
     59# from bumps, and would instead need to use string expressions. 
    5460class SasFitness(object): 
    5561    """ 
    5662    Wrap SAS model as a bumps fitness object 
    5763    """ 
    58     def __init__(self, name, model, data, fitted=[], **kw): 
    59         self.name = name 
    60         self.model = model 
     64    def __init__(self, model, data, fitted=[], constraints={}, **kw): 
     65        self.name = model.name 
     66        self.model = model.model 
    6167        self.data = data 
    6268        self._define_pars() 
    6369        self._init_pars(kw) 
     70        self.constraints = dict(constraints) 
    6471        self.set_fitted(fitted) 
    6572        self._dirty = True 
     
    7380            self._pars[k] = parameter.Parameter(value=value, bounds=bounds, 
    7481                                                fixed=True, name=name) 
     82        #print parameter.summarize(self._pars.values()) 
    7583 
    7684    def _init_pars(self, kw): 
     
    102110        """ 
    103111        for k,p in self._pars.items(): 
    104             p.fixed = (k not in param_list) 
     112            p.fixed = (k not in param_list or k in self.constraints) 
    105113        self.fitted_pars = [self._pars[k] for k in param_list] 
    106114        self.fitted_par_names = param_list 
     
    112120    def update(self): 
    113121        for k,v in self._pars.items(): 
     122            #print "updating",k,v,v.value 
    114123            self.model.setParam(k,v.value) 
    115124        self._dirty = True 
     
    154163            ftol=1.49012e-8, reset_flag=False): 
    155164        # Build collection of bumps fitness calculators 
    156         models = [ SasFitness(name="M%d"%(i+1), 
    157                               model=M.get_model().model, 
     165        models = [ SasFitness(model=M.get_model(), 
    158166                              data=M.get_data(), 
     167                              constraints=M.constraints, 
    159168                              fitted=M.pars) 
    160169                   for i,M in enumerate(self.fit_arrange_dict.values()) 
    161170                   if M.get_to_fit() == 1 ] 
    162171        problem = FitProblem(models) 
     172 
     173 
     174        # Build constraint expressions 
     175        exprs = {} 
     176        for M in models: 
     177            exprs.update((".".join((M.name,k)),v) for k,v in M.constraints.items()) 
     178        if exprs: 
     179            symtab = dict((".".join((M.name,k)),p) 
     180                          for M in models 
     181                          for k,p in M.parameters().items()) 
     182            constraints = compile_constraints(symtab,exprs) 
     183        else: 
     184            constraints = lambda: 0 
     185 
     186        # Override model update so that parameter constraints are applied 
     187        problem._model_update = problem.model_update 
     188        def model_update(): 
     189            constraints() 
     190            problem._model_update() 
     191        problem.model_update = model_update 
    163192 
    164193        # Run the fit 
  • src/sans/perspectives/fitting/fitpage.py

    rd44648e r4e9f227  
    661661                          wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    662662         
    663         if self.engine_type == "park": 
     663        if self.engine_type in ("park","bumps"): 
    664664            self.text_disp_max.Show(True) 
    665665            self.text_disp_min.Show(True) 
     
    738738                                          wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
    739739 
    740                         if self.engine_type == "park": 
     740                        if self.engine_type in ("park","bumps"): 
    741741                            ctl3.Show(True) 
    742742                            ctl4.Show(True) 
     
    10051005            return 
    10061006 
    1007         if len(self._manager.fit_thread_list) > 0 and\ 
    1008                     self._manager._fit_engine != "park" and\ 
    1009                     self._manager.sim_page != None and \ 
    1010                     self._manager.sim_page.uid == self.uid: 
     1007        if (len(self._manager.fit_thread_list) > 0 
     1008                and self._manager._fit_engine not in ("park","bumps") 
     1009                and self._manager.sim_page != None 
     1010                and self._manager.sim_page.uid == self.uid): 
    10111011            msg = "The FitEnging will be set to 'ParkMC'\n" 
    10121012            msg += " to fit with more than one data set..." 
     
    21082108        if chisqr != None and numpy.isfinite(chisqr): 
    21092109            #format chi2 
    2110             if self.engine_type == "park": 
     2110            if self.engine_type in ("park","bumps"): 
    21112111                npt_fit = float(self.get_npts2fit()) 
    21122112            chi2 = format_number(chisqr, True) 
  • src/sans/perspectives/fitting/fitting.py

    rf121904 r4e9f227  
    999999            #simulatanous fit only one engine need to be created 
    10001000            ## if simultaneous fit change automatically the engine to park 
    1001             self._on_change_engine(engine='park') 
     1001            if self._fit_engine not in ("park","bumps"): 
     1002                self._on_change_engine(engine='park') 
    10021003            sim_fitter = Fit(self._fit_engine) 
    10031004            sim_fitter.fitter_id = self.sim_page.uid 
     
    10071008             
    10081009        self.fitproblem_count = fitproblem_count 
    1009         if self._fit_engine == "park": 
     1010        if self._fit_engine in ("park","bumps"): 
    10101011            engineType = "Simultaneous Fit" 
    10111012        else: 
  • src/sans/perspectives/fitting/simfitpage.py

    rfb7180c r4e9f227  
    152152        ## making sure all parameters content a constraint 
    153153        ## validity of the constraint expression is own by fit engine 
    154         if self.parent._manager._fit_engine != "park" and flag: 
     154        if self.parent._manager._fit_engine not in ("park","bumps") and flag: 
    155155            msg = "The FitEnging will be set to 'Park' fit engine\n" 
    156156            msg += " for the simultaneous fit..." 
  • test/park_integration/test/utest_fit_cylinder.py

    re3efa6b3 r4e9f227  
    1010from sans.dataloader.loader import Loader 
    1111 
     12#@unittest.skip("") 
    1213class TestSingleFit(unittest.TestCase): 
    1314    """ test single fitting """ 
     
    3334        fitter.set_model(self.model,1,self.pars1) 
    3435        fitter.select_problem_for_fit(id=1,value=1) 
    35         return  fitter.fit() 
    36         
     36        result1, = fitter.fit() 
    3737 
    38     def test_scipy(self): 
    39         """ Simple cylinder model fit (scipy)  """ 
    40          
    41         result1, = self._fit("scipy") 
    42          
    4338        self.assert_(result1) 
    4439        self.assertTrue(len(result1.pvec)>0 or len(result1.pvec)==0 ) 
    4540        self.assertTrue(len(result1.stderr)> 0 or len(result1.stderr)==0) 
    46          
     41 
    4742        self.assertTrue( math.fabs(result1.pvec[0]-400.0)/3.0 < result1.stderr[0] ) 
    4843        self.assertTrue( math.fabs(result1.pvec[1]-20.0)/3.0  < result1.stderr[1] ) 
    4944        self.assertTrue( math.fabs(result1.pvec[2]-1.0)/3.0   < result1.stderr[2] ) 
    5045        self.assertTrue( result1.fitness < 1.0 ) 
    51          
    52          
     46 
     47 
     48    def test_scipy(self): 
     49        """ Simple cylinder model fit (scipy)  """ 
     50        self._fit("scipy") 
     51 
     52 
    5353    def test_park(self): 
    5454        """ Simple cylinder model fit (park)  """ 
    55         #raise NotImplementedError() 
    56         result1, = self._fit("park") 
    57          
    58         self.assert_(result1) 
    59         self.assertTrue(len(result1.pvec)>0 or len(result1.pvec)==0 ) 
    60         self.assertTrue(len(result1.stderr)> 0 or len(result1.stderr)==0) 
    61         
    62         self.assertTrue( math.fabs(result1.pvec[0]-400.0)/3.0 < result1.stderr[0] ) 
    63         self.assertTrue( math.fabs(result1.pvec[1]-20.0)/3.0  < result1.stderr[1] ) 
    64         self.assertTrue( math.fabs(result1.pvec[2]-1.0)/3.0   < result1.stderr[2] ) 
    65         self.assertTrue( result1.fitness < 1.0 ) 
    66          
    67          
     55        self._fit("park") 
     56 
     57    def test_bumps(self): 
     58        """ Simple cylinder model fit (park)  """ 
     59        self._fit("bumps") 
     60 
     61 
    6862         
    6963class TestSimultaneousFit(unittest.TestCase): 
     
    8276        self.model1.set(scale= 1.0) 
    8377        self.model1.set(radius=18) 
    84         self.model1.set(length=396) 
     78        self.model1.set(length=200) 
    8579        self.model1.set(sldCyl=3e-006, sldSolv=0.0) 
    8680        self.model1.set(background=0.0) 
    87          
     81 
    8882        cyl2  = CylinderModel() 
    8983        cyl2.name = "C2" 
     
    9185        self.model2.set(scale= 1.0) 
    9286        self.model2.set(radius=37) 
    93         self.model2.set(length='C1.length') 
     87        self.model2.set(length=300) 
    9488        self.model2.set(sldCyl=3e-006, sldSolv=0.0) 
    9589        self.model2.set(background=0.0) 
    96         
    9790 
    98     def test_park2(self): 
     91 
     92    def test_constrained_bumps(self): 
     93        """ Simultaneous cylinder model fit (park)  """ 
     94        self._run_fit(Fit('bumps')) 
     95 
     96    #@unittest.skip("") 
     97    def test_constrained_park(self): 
    9998        """ Simultaneous cylinder model fit (park)  """ 
    10099        self._run_fit(Fit('park')) 
     
    107106 
    108107        for n, v, dv in zip(result1.param_list, result1.pvec, result1.stderr): 
    109             print "M1.%s = %s +/- %s"%(n,v,dv) 
     108            print "%s M1.%s = %s +/- %s"%(fitter._engine.__class__.__name__,n,v,dv) 
    110109            if n == "length": 
    111110                self.assertTrue( math.fabs(v-400.0)/3.0 < dv ) 
     
    115114                self.assertTrue( math.fabs(v-1.0)/3.0 < dv ) 
    116115        for n, v, dv in zip(result2.param_list, result2.pvec, result2.stderr): 
    117             print "M2.%s = %s +/- %s"%(n,v,dv) 
     116            print "%s M2.%s = %s +/- %s"%(fitter._engine.__class__.__name__,n,v,dv) 
    118117            if n=='radius': 
    119118                self.assertTrue( math.fabs(v-40.0)/3.0 < dv ) 
     
    127126 
    128127        fitter.set_data(self.data2,2) 
    129         fitter.set_model(self.model2, 2, ['radius','scale']) 
     128        fitter.set_model(self.model2, 2, ['radius','scale'], 
     129                         constraints=[("length","C1.length")]) 
    130130        fitter.select_problem_for_fit(id=1,value=1) 
    131131        fitter.select_problem_for_fit(id=2,value=1) 
Note: See TracChangeset for help on using the changeset viewer.