def test_reso(self): # Let the data module find out what smearing the # data needs smear = smear_selection(self.data_res) #self.assertEqual(smear.__class__.__name__, 'QSmearer') #self.assertEqual(smear.__class__.__name__, 'PySmearer') # Fit fitter = Fit() # Data: right now this is the only way to set the smearer object # We should improve that and have a way to get access to the # data for a given fit. fitter.set_data(self.data_res,1) fitter.fit_arrange_dict[1].data_list[0].smearer = smear # Model: maybe there's a better way to do this. # Ideally we should have to create a new model from our sas model. fitter.set_model(Model(self.sphere),1, ['radius','scale', 'background']) # Why do we have to do this...? fitter.select_problem_for_fit(id=1,value=1) # Perform the fit (might take a while) result1, = fitter.fit() #print "v",result1.pvec #print "dv",result1.stderr #print "chisq(v)",result1.fitness self.assertTrue( math.fabs(result1.pvec[0]-5000) < 20 ) self.assertTrue( math.fabs(result1.pvec[1]-0.48) < 0.02 ) self.assertTrue( math.fabs(result1.pvec[2]-0.060) < 0.002 )
def test_slit(self): smear = smear_selection(self.data_slit) #self.assertEqual(smear.__class__.__name__, 'SlitSmearer') #self.assertEqual(smear.__class__.__name__, 'PySmearer') fitter = Fit() # Data: right now this is the only way to set the smearer object # We should improve that and have a way to get access to the # data for a given fit. fitter.set_data(self.data_slit,1) fitter.fit_arrange_dict[1].data_list[0].smearer = smear fitter.fit_arrange_dict[1].data_list[0].qmax = 0.003 # Model fitter.set_model(Model(self.sphere),1, ['radius','scale']) fitter.select_problem_for_fit(id=1,value=1) result1, = fitter.fit() #print "v",result1.pvec #print "dv",result1.stderr #print "chisq(v)",result1.fitness numpy.testing.assert_allclose(result1.pvec, [2323.466,0.22137], rtol=0.001)
def _reset_helper(self, path=None, npts=NPTS): """ Set value to fitter and prepare inputs for map function """ for i in range(npts): data = Loader().load(path) fitter = Fit() #create model model = CylinderModel() model.setParam('scale', 1.0) model.setParam('radius', 20.0) model.setParam('length', 400.0) model.setParam('sldCyl', 4e-006) model.setParam('sldSolv', 1e-006) model.setParam('background', 0.0) for param in model.dispersion.keys(): model.set_dispersion(param, self.polydisp['gaussian']()) model.setParam('cyl_phi.width', 10) model.setParam('cyl_phi.npts', 3) model.setParam('cyl_theta.nsigmas', 10) # for 2 data cyl_theta = 60.0 [deg] cyl_phi= 60.0 [deg] fitter.set_model(model, i, self.param_to_fit, self.list_of_constraints) #smear data current_smearer = smear_selection(data, model) import cPickle p = cPickle.dumps(current_smearer) sm = cPickle.loads(p) fitter.set_data(data=data, id=i, smearer=current_smearer, qmin=self.qmin, qmax=self.qmax) fitter.select_problem_for_fit(id=i, value=1) self.list_of_fitter.append(copy.deepcopy(fitter)) self.list_of_function.append('fit') self.list_of_mapper.append(classMapper)
def test_slit(self): smear = smear_selection(self.data_slit) self.assertEqual(smear.__class__.__name__, 'SlitSmearer') fitter = Fit('bumps') # Data: right now this is the only way to set the smearer object # We should improve that and have a way to get access to the # data for a given fit. fitter.set_data(self.data_slit, 1) fitter._engine.fit_arrange_dict[1].data_list[0].smearer = smear fitter._engine.fit_arrange_dict[1].data_list[0].qmax = 0.003 # Model fitter.set_model(Model(self.sphere), 1, ['radius', 'scale']) fitter.select_problem_for_fit(id=1, value=1) result1, = fitter.fit() #print "v",result1.pvec #print "dv",result1.stderr #print "chisq(v)",result1.fitness self.assertTrue(math.fabs(result1.pvec[0] - 2340) < 20) self.assertTrue(math.fabs(result1.pvec[1] - 0.010) < 0.002)
def set_model(self, model): """ associates each model with its new created name :param model: model selected :param name: name created for model """ self.model = model self.smearer_computer_value = smear_selection(self.fit_data, self.model) self.smearer_computed = True
def get_smearer(self): """ return smear object """ if not self.smearer_enable: return None if not self.smearer_computed: #smeari_selection should be call only once per fitproblem self.smearer_computer_value = smear_selection( self.fit_data, self.model) self.smearer_computed = True return self.smearer_computer_value
def get_smearer(self): """ return smear object """ if not self.smearer_enable: return None if not self.smearer_computed: #smeari_selection should be call only once per fitproblem self.smearer_computer_value = smear_selection(self.fit_data, self.model) self.smearer_computed = True return self.smearer_computer_value
def set_fit_data(self, data): """ Store data associated with this class :param data: list of data selected """ self.original_data = None self.fit_data = None # original data: should not be modified self.original_data = data # fit data: used for fit and can be modified for convenience self.fit_data = copy.deepcopy(data) self.smearer_computer_value = smear_selection(self.fit_data, self.model) self.smearer_computed = True self.result = None
def eval_sasview(model_info, data): # type: (Modelinfo, Data) -> Calculator """ Return a model calculator using the pre-4.0 SasView models. """ # importing sas here so that the error message will be that sas failed to # import rather than the more obscure smear_selection not imported error import sas import sas.models from sas.models.qsmearing import smear_selection from sas.models.MultiplicationModel import MultiplicationModel from sas.models.dispersion_models import models as dispersers def get_model_class(name): # type: (str) -> "sas.models.BaseComponent" #print("new",sorted(_pars.items())) __import__('sas.models.' + name) ModelClass = getattr(getattr(sas.models, name, None), name, None) if ModelClass is None: raise ValueError("could not find model %r in sas.models" % name) return ModelClass # WARNING: ugly hack when handling model! # Sasview models with multiplicity need to be created with the target # multiplicity, so we cannot create the target model ahead of time for # for multiplicity models. Instead we store the model in a list and # update the first element of that list with the new multiplicity model # every time we evaluate. # grab the sasview model, or create it if it is a product model if model_info.composition: composition_type, parts = model_info.composition if composition_type == 'product': P, S = [get_model_class(revert_name(p))() for p in parts] model = [MultiplicationModel(P, S)] else: raise ValueError("sasview mixture models not supported by compare") else: old_name = revert_name(model_info) if old_name is None: raise ValueError("model %r does not exist in old sasview" % model_info.id) ModelClass = get_model_class(old_name) model = [ModelClass()] model[0].disperser_handles = {} # build a smearer with which to call the model, if necessary smearer = smear_selection(data, model=model) if hasattr(data, 'qx_data'): q = np.sqrt(data.qx_data**2 + data.qy_data**2) index = ((~data.mask) & (~np.isnan(data.data)) & (q >= data.qmin) & (q <= data.qmax)) if smearer is not None: smearer.model = model # because smear_selection has a bug smearer.accuracy = data.accuracy smearer.set_index(index) def _call_smearer(): smearer.model = model[0] return smearer.get_value() theory = _call_smearer else: theory = lambda: model[0].evalDistribution( [data.qx_data[index], data.qy_data[index]]) elif smearer is not None: theory = lambda: smearer(model[0].evalDistribution(data.x)) else: theory = lambda: model[0].evalDistribution(data.x) def calculator(**pars): # type: (float, ...) -> np.ndarray """ Sasview calculator for model. """ oldpars = revert_pars(model_info, pars) # For multiplicity models, create a model with the correct multiplicity control = oldpars.pop("CONTROL", None) if control is not None: # sphericalSLD has one fewer multiplicity. This update should # happen in revert_pars, but it hasn't been called yet. model[0] = ModelClass(control) # paying for parameter conversion each time to keep life simple, if not fast for k, v in oldpars.items(): if k.endswith('.type'): par = k[:-5] if v == 'gaussian': continue cls = dispersers[v if v != 'rectangle' else 'rectangula'] handle = cls() model[0].disperser_handles[par] = handle try: model[0].set_dispersion(par, handle) except Exception: exception.annotate_exception("while setting %s to %r" % (par, v)) raise #print("sasview pars",oldpars) for k, v in oldpars.items(): name_attr = k.split('.') # polydispersity components if len(name_attr) == 2: par, disp_par = name_attr model[0].dispersion[par][disp_par] = v else: model[0].setParam(k, v) return theory() calculator.engine = "sasview" return calculator
def eval_sasview(model_info, data): """ Return a model calculator using the pre-4.0 SasView models. """ # importing sas here so that the error message will be that sas failed to # import rather than the more obscure smear_selection not imported error import sas from sas.models.qsmearing import smear_selection def get_model(name): #print("new",sorted(_pars.items())) sas = __import__('sas.models.' + name) ModelClass = getattr(getattr(sas.models, name, None), name, None) if ModelClass is None: raise ValueError("could not find model %r in sas.models" % name) return ModelClass() # grab the sasview model, or create it if it is a product model if model_info['composition']: composition_type, parts = model_info['composition'] if composition_type == 'product': from sas.models.MultiplicationModel import MultiplicationModel P, S = [get_model(revert_name(p)) for p in parts] model = MultiplicationModel(P, S) else: raise ValueError("sasview mixture models not supported by compare") else: model = get_model(revert_name(model_info)) # build a smearer with which to call the model, if necessary smearer = smear_selection(data, model=model) if hasattr(data, 'qx_data'): q = np.sqrt(data.qx_data**2 + data.qy_data**2) index = ((~data.mask) & (~np.isnan(data.data)) & (q >= data.qmin) & (q <= data.qmax)) if smearer is not None: smearer.model = model # because smear_selection has a bug smearer.accuracy = data.accuracy smearer.set_index(index) theory = lambda: smearer.get_value() else: theory = lambda: model.evalDistribution( [data.qx_data[index], data.qy_data[index]]) elif smearer is not None: theory = lambda: smearer(model.evalDistribution(data.x)) else: theory = lambda: model.evalDistribution(data.x) def calculator(**pars): """ Sasview calculator for model. """ # paying for parameter conversion each time to keep life simple, if not fast pars = revert_pars(model_info, pars) for k, v in pars.items(): parts = k.split('.') # polydispersity components if len(parts) == 2: model.dispersion[parts[0]][parts[1]] = v else: model.setParam(k, v) return theory() calculator.engine = "sasview" return calculator
def eval_sasview(model_info, data): # type: (Modelinfo, Data) -> Calculator """ Return a model calculator using the pre-4.0 SasView models. """ # importing sas here so that the error message will be that sas failed to # import rather than the more obscure smear_selection not imported error import sas import sas.models from sas.models.qsmearing import smear_selection from sas.models.MultiplicationModel import MultiplicationModel def get_model_class(name): # type: (str) -> "sas.models.BaseComponent" #print("new",sorted(_pars.items())) __import__('sas.models.' + name) ModelClass = getattr(getattr(sas.models, name, None), name, None) if ModelClass is None: raise ValueError("could not find model %r in sas.models"%name) return ModelClass # WARNING: ugly hack when handling model! # Sasview models with multiplicity need to be created with the target # multiplicity, so we cannot create the target model ahead of time for # for multiplicity models. Instead we store the model in a list and # update the first element of that list with the new multiplicity model # every time we evaluate. # grab the sasview model, or create it if it is a product model if model_info.composition: composition_type, parts = model_info.composition if composition_type == 'product': P, S = [get_model_class(revert_name(p))() for p in parts] model = [MultiplicationModel(P, S)] else: raise ValueError("sasview mixture models not supported by compare") else: old_name = revert_name(model_info) if old_name is None: raise ValueError("model %r does not exist in old sasview" % model_info.id) ModelClass = get_model_class(old_name) model = [ModelClass()] # build a smearer with which to call the model, if necessary smearer = smear_selection(data, model=model) if hasattr(data, 'qx_data'): q = np.sqrt(data.qx_data**2 + data.qy_data**2) index = ((~data.mask) & (~np.isnan(data.data)) & (q >= data.qmin) & (q <= data.qmax)) if smearer is not None: smearer.model = model # because smear_selection has a bug smearer.accuracy = data.accuracy smearer.set_index(index) def _call_smearer(): smearer.model = model[0] return smearer.get_value() theory = lambda: _call_smearer() else: theory = lambda: model[0].evalDistribution([data.qx_data[index], data.qy_data[index]]) elif smearer is not None: theory = lambda: smearer(model[0].evalDistribution(data.x)) else: theory = lambda: model[0].evalDistribution(data.x) def calculator(**pars): # type: (float, ...) -> np.ndarray """ Sasview calculator for model. """ # For multiplicity models, recreate the model the first time the if model_info.control: model[0] = ModelClass(int(pars[model_info.control])) # paying for parameter conversion each time to keep life simple, if not fast oldpars = revert_pars(model_info, pars) for k, v in oldpars.items(): name_attr = k.split('.') # polydispersity components if len(name_attr) == 2: model[0].dispersion[name_attr[0]][name_attr[1]] = v else: model[0].setParam(k, v) return theory() calculator.engine = "sasview" return calculator