from sans.models.BaseComponent import BaseComponent from sans.models.SphereSLDModel import SphereSLDModel from copy import deepcopy from math import floor #from scipy.special import erf func_list = {'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, \ 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4} max_nshells = 10 class SphericalSLDModel(BaseComponent): """ This multi-model is based on Parratt formalism and provides the capability of changing the number of layers between 0 and 10. """ def __init__(self, multfactor=1): BaseComponent.__init__(self) """ :param multfactor: number of layers in the model, assumes 0<= n_shells <=10. """ ## Setting model name model description self.description="" model = SphereSLDModel() self.model = model self.name = "SphericalSLDModel" self.description=model.description self.n_shells = multfactor ## Define parameters self.params = {} ## Parameter details [units, min, max] self.details = {} # non-fittable parameters self.non_fittable = model.non_fittable # list of function in order of the function number self.fun_list = self._get_func_list() ## dispersion self._set_dispersion() ## Define parameters self._set_params() ## Parameter details [units, min, max] self._set_details() #list of parameter that can be fitted self._set_fixed_params() self.model.params['n_shells'] = self.n_shells ## functional multiplicity info of the model # [int(maximum no. of functionality),"str(Titl), # [str(name of function0),...], [str(x-asix name of sld),...]] self.multiplicity_info = [max_nshells,"No. of Shells:",[],['Radius']] def _clone(self, obj): """ Internal utility function to copy the internal data members to a fresh copy. """ obj.params = deepcopy(self.params) obj.non_fittable = deepcopy(self.non_fittable) obj.description = deepcopy(self.description) obj.details = deepcopy(self.details) obj.dispersion = deepcopy(self.dispersion) obj.model = self.model.clone() return obj def _set_dispersion(self): """ model dispersions """ ##set dispersion from model for name , value in self.model.dispersion.iteritems(): nshell = -1 if name.split('_')[0] == 'thick': while nshell<1: nshell += 1 if name.split('_')[1] == 'inter%s' % str(nshell): self.dispersion[name]= value else: continue else: self.dispersion[name]= value def _set_params(self): """ Concatenate the parameters of the model to create this model parameters """ # rearrange the parameters for the given # of shells for name , value in self.model.params.iteritems(): n = 0 pos = len(name.split('_'))-1 first_name = name.split('_')[0] last_name = name.split('_')[pos] if first_name == 'npts': self.params[name]=value continue elif first_name == 'func': n= -1 while n