source: sasview/src/sas/sasgui/guiframe/dataFitting.py @ 65e61c1

Last change on this file since 65e61c1 was 9a5097c, checked in by andyfaff, 8 years ago

MAINT: import numpy as np

  • Property mode set to 100644
File size: 19.0 KB
RevLine 
[12aa9b5]1"""
[d955bf19]2Adapters for fitting module
[12aa9b5]3"""
[8e87ece]4import copy
[9a5097c]5import numpy as np
[901142f]6import math
[b699768]7from sas.sascalc.data_util.uncertainty import Uncertainty
[d7bb526]8from sas.sasgui.plottools.plottables import Data1D as PlotData1D
9from sas.sasgui.plottools.plottables import Data2D as PlotData2D
10from sas.sasgui.plottools.plottables import Theory1D as PlotTheory1D
[81812d9]11
[b699768]12from sas.sascalc.dataloader.data_info import Data1D as LoadData1D
13from sas.sascalc.dataloader.data_info import Data2D as LoadData2D
[81812d9]14
[f444b20]15
[3562fbc]16class Data1D(PlotData1D, LoadData1D):
[d955bf19]17    """
18    """
[a9f579c]19
20    def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=False):
[d955bf19]21        """
22        """
[32c0841]23        if x is None:
24            x = []
25        if y is None:
26            y = []
[a9f579c]27        self.isSesans = isSesans
28        PlotData1D.__init__(self, x, y, dx, dy, lam, dlam)
29        LoadData1D.__init__(self, x, y, dx, dy, lam, dlam, isSesans)
30
[901142f]31        self.id = None
[e88ebfd]32        self.list_group_id = []
33        self.group_id = None
[ff3f900b]34        self.is_data = True
[f444b20]35        self.path = None
[8a7d922]36        self.xtransform = None
[68adf86]37        if self.isSesans:
38            self.xtransform = "x"
[8a7d922]39        self.ytransform = None
[68adf86]40        if self.isSesans:
41            self.ytransform = "y"
[f444b20]42        self.title = ""
[5c4b674]43        self.scale = None
44       
[ff3f900b]45    def copy_from_datainfo(self, data1d):
46        """
[d955bf19]47        copy values of Data1D of type DataLaoder.Data_info
[ff3f900b]48        """
49        self.= copy.deepcopy(data1d.x)
50        self.= copy.deepcopy(data1d.y)
51        self.dy = copy.deepcopy(data1d.dy)
[8e87ece]52       
53        if hasattr(data1d, "dx"):
54            self.dx = copy.deepcopy(data1d.dx)   
55        if hasattr(data1d, "dxl"):
56            self.dxl = copy.deepcopy(data1d.dxl)
57        if hasattr(data1d, "dxw"):
58            self.dxw = copy.deepcopy(data1d.dxw)
[ff3f900b]59   
[901142f]60        self.xaxis(data1d._xaxis, data1d._xunit)
61        self.yaxis(data1d._yaxis, data1d._yunit)
[f444b20]62        self.title = data1d.title
[3562fbc]63       
64    def __str__(self):
65        """
[d955bf19]66        print data
[3562fbc]67        """
68        _str = "%s\n" % LoadData1D.__str__(self)
69     
70        return _str
[901142f]71   
72    def _perform_operation(self, other, operation):
73        """
74        """
75        # First, check the data compatibility
76        dy, dy_other = self._validity_check(other)
[a9f579c]77        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None)
[a48842a2]78        result.clone_without_data(length=len(self.x), clone=self)
[901142f]79        result.copy_from_datainfo(data1d=self)
[a48842a2]80        if self.dxw == None:
81            result.dxw = None
82        else:
[9a5097c]83            result.dxw = np.zeros(len(self.x))
[a48842a2]84        if self.dxl == None:
85            result.dxl = None
86        else:
[9a5097c]87            result.dxl = np.zeros(len(self.x))
[a48842a2]88
[901142f]89        for i in range(len(self.x)):
90            result.x[i] = self.x[i]
91            if self.dx is not None and len(self.x) == len(self.dx):
92                result.dx[i] = self.dx[i]
[a48842a2]93            if self.dxw is not None and len(self.x) == len(self.dxw):
94                result.dxw[i] = self.dxw[i]
95            if self.dxl is not None and len(self.x) == len(self.dxl):
96                result.dxl[i] = self.dxl[i]
[901142f]97           
98            a = Uncertainty(self.y[i], dy[i]**2)
99            if isinstance(other, Data1D):
100                b = Uncertainty(other.y[i], dy_other[i]**2)
[a48842a2]101                if other.dx is not None:
102                    result.dx[i] *= self.dx[i]
103                    result.dx[i] += (other.dx[i]**2)
104                    result.dx[i] /= 2
105                    result.dx[i] = math.sqrt(result.dx[i])
106                if result.dxl is not None and other.dxl is not None:
107                    result.dxl[i] *= self.dxl[i]
108                    result.dxl[i] += (other.dxl[i]**2)
109                    result.dxl[i] /= 2
110                    result.dxl[i] = math.sqrt(result.dxl[i])
[901142f]111            else:
112                b = other
113           
114            output = operation(a, b)
115            result.y[i] = output.x
116            result.dy[i] = math.sqrt(math.fabs(output.variance))
117        return result
118   
[a48842a2]119    def _perform_union(self, other):
120        """
121        """
122        # First, check the data compatibility
123        self._validity_check_union(other)
[a9f579c]124        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None)
[a48842a2]125        tot_length = len(self.x) + len(other.x)
126        result = self.clone_without_data(length=tot_length, clone=result)
[a9f579c]127        if self.dlam == None or other.dlam is None:
128            result.dlam = None
129        else:
[9a5097c]130            result.dlam = np.zeros(tot_length)
[a48842a2]131        if self.dy == None or other.dy is None:
132            result.dy = None
133        else:
[9a5097c]134            result.dy = np.zeros(tot_length)
[a48842a2]135        if self.dx == None or other.dx is None:
136            result.dx = None
137        else:
[9a5097c]138            result.dx = np.zeros(tot_length)
[a48842a2]139        if self.dxw == None or other.dxw is None:
140            result.dxw = None
141        else:
[9a5097c]142            result.dxw = np.zeros(tot_length)
[a48842a2]143        if self.dxl == None or other.dxl is None:
144            result.dxl = None
145        else:
[9a5097c]146            result.dxl = np.zeros(tot_length)
[a48842a2]147
[9a5097c]148        result.x = np.append(self.x, other.x)
[a48842a2]149        #argsorting
[9a5097c]150        ind = np.argsort(result.x)
[a48842a2]151        result.x = result.x[ind]
[9a5097c]152        result.y = np.append(self.y, other.y)
[a48842a2]153        result.y = result.y[ind]
[9a5097c]154        result.lam = np.append(self.lam, other.lam)
[a9f579c]155        result.lam = result.lam[ind]
156        if result.dlam != None:
[9a5097c]157            result.dlam = np.append(self.dlam, other.dlam)
[a9f579c]158            result.dlam = result.dlam[ind]
[a48842a2]159        if result.dy != None:
[9a5097c]160            result.dy = np.append(self.dy, other.dy)
[a48842a2]161            result.dy = result.dy[ind]
162        if result.dx is not None:
[9a5097c]163            result.dx = np.append(self.dx, other.dx)
[a48842a2]164            result.dx = result.dx[ind]
165        if result.dxw is not None:
[9a5097c]166            result.dxw = np.append(self.dxw, other.dxw)
[a48842a2]167            result.dxw = result.dxw[ind]
168        if result.dxl is not None:
[9a5097c]169            result.dxl = np.append(self.dxl, other.dxl)
[a48842a2]170            result.dxl = result.dxl[ind]
171        return result
172   
[f444b20]173 
174   
[32c0841]175class Theory1D(PlotTheory1D, LoadData1D):
[d955bf19]176    """
177    """
[32c0841]178    def __init__(self, x=None, y=None, dy=None):
[d955bf19]179        """
180        """
[32c0841]181        if x is None:
182            x = []
183        if y is None:
184            y = []
[e5664f2]185        PlotTheory1D.__init__(self, x, y, dy)
186        LoadData1D.__init__(self, x, y, dy)
[901142f]187        self.id = None
[e88ebfd]188        self.list_group_id = []
189        self.group_id = None
[e5664f2]190        self.is_data = True
[f444b20]191        self.path = None
[8a7d922]192        self.xtransform = None
193        self.ytransform = None
[f444b20]194        self.title = ""
[5c4b674]195        self.scale = None
[e5664f2]196   
197    def copy_from_datainfo(self, data1d):
198        """
[d955bf19]199        copy values of Data1D of type DataLaoder.Data_info
[e5664f2]200        """
201        self.= copy.deepcopy(data1d.x)
202        self.= copy.deepcopy(data1d.y)
203        self.dy = copy.deepcopy(data1d.dy)
[8e87ece]204        if hasattr(data1d, "dx"):
205            self.dx = copy.deepcopy(data1d.dx) 
206        if hasattr(data1d, "dxl"):
207            self.dxl = copy.deepcopy(data1d.dxl)
208        if hasattr(data1d, "dxw"):
209            self.dxw = copy.deepcopy(data1d.dxw)   
[901142f]210        self.xaxis(data1d._xaxis, data1d._xunit)
211        self.yaxis(data1d._yaxis, data1d._yunit)
[f444b20]212        self.title = data1d.title
[8e87ece]213       
[3562fbc]214    def __str__(self):
215        """
[d955bf19]216        print data
[3562fbc]217        """
218        _str = "%s\n" % LoadData1D.__str__(self)
219     
220        return _str
[901142f]221   
222    def _perform_operation(self, other, operation):
223        """
224        """
225        # First, check the data compatibility
226        dy, dy_other = self._validity_check(other)
[a48842a2]227        result = self.clone_without_data(len(self.x))
[901142f]228        result.copy_from_datainfo(data1d=self)
[a48842a2]229        if self.dxw == None:
230            result.dxw = None
231        else:
[9a5097c]232            result.dxw = np.zeros(len(self.x))
[a48842a2]233        if self.dxl == None:
234            result.dxl = None
235        else:
[9a5097c]236            result.dxl = np.zeros(len(self.x))
[a48842a2]237
[9a5097c]238        for i in range(np.size(self.x)):
[901142f]239            result.x[i] = self.x[i]
[a48842a2]240            if self.dx is not None and len(self.x) == len(self.dx):
241                result.dx[i] = self.dx[i]
242            if self.dxw is not None and len(self.x) == len(self.dxw):
243                result.dxw[i] = self.dxw[i]
244            if self.dxl is not None and len(self.x) == len(self.dxl):
245                result.dxl[i] = self.dxl[i]
246           
[901142f]247            a = Uncertainty(self.y[i], dy[i]**2)
248            if isinstance(other, Data1D):
249                b = Uncertainty(other.y[i], dy_other[i]**2)
[a48842a2]250                if other.dx is not None:
251                    result.dx[i] *= self.dx[i]
252                    result.dx[i] += (other.dx[i]**2)
253                    result.dx[i] /= 2
254                    result.dx[i] = math.sqrt(result.dx[i])
255                if result.dxl is not None and other.dxl is not None:
256                    result.dxl[i] *= self.dxl[i]
257                    other.dxl[i] += (other.dxl[i]**2)
258                    result.dxl[i] /= 2
259                    result.dxl[i] = math.sqrt(result.dxl[i])
260                if result.dxw is not None and self.dxw is not None:
261                    result.dxw[i] *= self.dxw[i]
262                    other.dxw[i] += (other.dxw[i]**2)
263                    result.dxw[i] /= 2
264                    result.dxw[i] = math.sqrt(result.dxw[i])
[901142f]265            else:
266                b = other
[a48842a2]267           
[901142f]268            output = operation(a, b)
269            result.y[i] = output.x
270            result.dy[i] = math.sqrt(math.fabs(output.variance))
271        return result
272   
[a48842a2]273    def _perform_union(self, other):
274        """
275        """
276        # First, check the data compatibility
277        self._validity_check_union(other)
[a9f579c]278        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=[])
[a48842a2]279        tot_length = len(self.x)+len(other.x)
280        result.clone_without_data(length=tot_length, clone=self)
[a9f579c]281        if self.dlam == None or other.dlam is None:
282            result.dlam = None
283        else:
[9a5097c]284            result.dlam = np.zeros(tot_length)
[a48842a2]285        if self.dy == None or other.dy is None:
286            result.dy = None
287        else:
[9a5097c]288            result.dy = np.zeros(tot_length)
[a48842a2]289        if self.dx == None or other.dx is None:
290            result.dx = None
291        else:
[9a5097c]292            result.dx = np.zeros(tot_length)
[a48842a2]293        if self.dxw == None or other.dxw is None:
294            result.dxw = None
295        else:
[9a5097c]296            result.dxw = np.zeros(tot_length)
[a48842a2]297        if self.dxl == None or other.dxl is None:
298            result.dxl = None
299        else:
[9a5097c]300            result.dxl = np.zeros(tot_length)
301        result.x = np.append(self.x, other.x)
[a48842a2]302        #argsorting
[9a5097c]303        ind = np.argsort(result.x)
[a48842a2]304        result.x = result.x[ind]
[9a5097c]305        result.y = np.append(self.y, other.y)
[a48842a2]306        result.y = result.y[ind]
[9a5097c]307        result.lam = np.append(self.lam, other.lam)
[a9f579c]308        result.lam = result.lam[ind]
[a48842a2]309        if result.dy != None:
[9a5097c]310            result.dy = np.append(self.dy, other.dy)
[a48842a2]311            result.dy = result.dy[ind]
312        if result.dx is not None:
[9a5097c]313            result.dx = np.append(self.dx, other.dx)
[a48842a2]314            result.dx = result.dx[ind]
315        if result.dxw is not None:
[9a5097c]316            result.dxw = np.append(self.dxw, other.dxw)
[a48842a2]317            result.dxw = result.dxw[ind]
318        if result.dxl is not None:
[9a5097c]319            result.dxl = np.append(self.dxl, other.dxl)
[a48842a2]320            result.dxl = result.dxl[ind]
321        return result
322 
[ff3f900b]323     
[32c0841]324class Data2D(PlotData2D, LoadData2D):
[d955bf19]325    """
326    """
[901142f]327    def __init__(self, image=None, err_image=None,
[0008f54]328                 qx_data=None, qy_data=None, q_data=None, 
329                 mask=None, dqx_data=None, dqy_data=None, 
[901142f]330                 xmin=None, xmax=None, ymin=None, ymax=None,
[0008f54]331                 zmin=None, zmax=None):
[d955bf19]332        """
333        """
[901142f]334        PlotData2D.__init__(self, image=image, err_image=err_image,
335                            xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
336                            zmin=zmin, zmax=zmax, qx_data=qx_data, 
337                            qy_data=qy_data)
[ff3f900b]338       
[901142f]339        LoadData2D.__init__(self, data=image, err_data=err_image,
340                            qx_data=qx_data, qy_data=qy_data,
341                            dqx_data=dqx_data, dqy_data=dqy_data,
342                            q_data=q_data, mask=mask)
[f444b20]343        self.id = None
[e88ebfd]344        self.list_group_id = []
345        self.group_id = None
[5c4b674]346        self.is_data = True
[f444b20]347        self.path = None
[5c4b674]348        self.xtransform = None
349        self.ytransform = None
[f444b20]350        self.title = ""
[8a7d922]351        self.scale = None
[ff3f900b]352       
353    def copy_from_datainfo(self, data2d):
354        """
[d955bf19]355        copy value of Data2D of type DataLoader.data_info
[ff3f900b]356        """
[32c0841]357        self.data = copy.deepcopy(data2d.data)
358        self.qx_data = copy.deepcopy(data2d.qx_data)
359        self.qy_data = copy.deepcopy(data2d.qy_data)
360        self.q_data = copy.deepcopy(data2d.q_data)
361        self.mask = copy.deepcopy(data2d.mask)
362        self.err_data = copy.deepcopy(data2d.err_data)
363        self.x_bins = copy.deepcopy(data2d.x_bins)
364        self.y_bins = copy.deepcopy(data2d.y_bins)
365        if data2d.dqx_data is not None:
366            self.dqx_data = copy.deepcopy(data2d.dqx_data)
367        if data2d.dqy_data is not None:
368            self.dqy_data = copy.deepcopy(data2d.dqy_data)
369        self.xmin = data2d.xmin
370        self.xmax = data2d.xmax
371        self.ymin = data2d.ymin
372        self.ymax = data2d.ymax
[f7a5c7e]373        if hasattr(data2d, "zmin"):
[32c0841]374            self.zmin = data2d.zmin
[f7a5c7e]375        if hasattr(data2d, "zmax"):
[32c0841]376            self.zmax = data2d.zmax
[901142f]377        self.xaxis(data2d._xaxis, data2d._xunit)
378        self.yaxis(data2d._yaxis, data2d._yunit)
[f444b20]379        self.title = data2d.title
[ff3f900b]380       
[3562fbc]381    def __str__(self):
382        """
[d955bf19]383        print data
[3562fbc]384        """
385        _str = "%s\n" % LoadData2D.__str__(self)
386        return _str
[fdef956]387
[901142f]388    def _perform_operation(self, other, operation):
389        """
[d955bf19]390        Perform 2D operations between data sets
391       
392        :param other: other data set
393        :param operation: function defining the operation
394       
[901142f]395        """
396        # First, check the data compatibility
397        dy, dy_other = self._validity_check(other)
398        result = Data2D(image=None, qx_data=None, qy_data=None,
[a48842a2]399                         q_data=None, err_image=None, xmin=None, xmax=None,
[901142f]400                         ymin=None, ymax=None, zmin=None, zmax=None)
[9053779]401        result.clone_without_data(len(self.data))
[901142f]402        result.copy_from_datainfo(data2d=self)
[a48842a2]403        result.xmin = self.xmin
404        result.xmax = self.xmax
405        result.ymin = self.ymin
406        result.ymax = self.ymax
407        if self.dqx_data == None or self.dqy_data == None:
408            result.dqx_data = None
409            result.dqy_data = None
410        else:
[9a5097c]411            result.dqx_data = np.zeros(len(self.data))
412            result.dqy_data = np.zeros(len(self.data))
413        for i in range(np.size(self.data)):
[dcf73a4]414            result.data[i] = self.data[i]
415            if self.err_data is not None and \
[9a5097c]416                            np.size(self.data) == np.size(self.err_data):
[dcf73a4]417                result.err_data[i] = self.err_data[i]   
418            if self.dqx_data is not None:
419                result.dqx_data[i] = self.dqx_data[i]
420            if self.dqy_data is not None:
421                result.dqy_data[i] = self.dqy_data[i]
422            result.qx_data[i] = self.qx_data[i]
423            result.qy_data[i] = self.qy_data[i]
424            result.q_data[i] = self.q_data[i]
425            result.mask[i] = self.mask[i]
426           
[a48842a2]427            a = Uncertainty(self.data[i], dy[i]**2)
428            if isinstance(other, Data2D):
429                b = Uncertainty(other.data[i], dy_other[i]**2)
430                if other.dqx_data is not None and \
431                        result.dqx_data is not None:
432                    result.dqx_data[i] *= self.dqx_data[i]
433                    result.dqx_data[i] += (other.dqx_data[i]**2)
434                    result.dqx_data[i] /= 2
435                    result.dqx_data[i] = math.sqrt(result.dqx_data[i])     
436                if other.dqy_data is not None and \
437                        result.dqy_data is not None:
438                    result.dqy_data[i] *= self.dqy_data[i]
439                    result.dqy_data[i] += (other.dqy_data[i]**2)
440                    result.dqy_data[i] /= 2
441                    result.dqy_data[i] = math.sqrt(result.dqy_data[i])
442            else:
443                b = other
444           
445            output = operation(a, b)
446            result.data[i] = output.x
447            result.err_data[i] = math.sqrt(math.fabs(output.variance))
448        return result
449   
450    def _perform_union(self, other):
451        """
452        Perform 2D operations between data sets
[901142f]453       
[a48842a2]454        :param other: other data set
455        :param operation: function defining the operation
456       
457        """
458        # First, check the data compatibility
459        self._validity_check_union(other)
460        result = Data2D(image=None, qx_data=None, qy_data=None,
461                         q_data=None, err_image=None, xmin=None, xmax=None,
462                         ymin=None, ymax=None, zmin=None, zmax=None)
463        length = len(self.data)
464        tot_length = length + len(other.data)
[9053779]465        result.clone_without_data(tot_length)
[a48842a2]466        result.xmin = self.xmin
467        result.xmax = self.xmax
468        result.ymin = self.ymin
469        result.ymax = self.ymax
470        if self.dqx_data == None or self.dqy_data == None or \
471                other.dqx_data == None or other.dqy_data == None :
472            result.dqx_data = None
473            result.dqy_data = None
474        else:
[9a5097c]475            result.dqx_data = np.zeros(len(self.data) + \
476                                       np.size(other.data))
477            result.dqy_data = np.zeros(len(self.data) + \
478                                       np.size(other.data))
[a48842a2]479       
[9a5097c]480        result.data = np.append(self.data, other.data)
481        result.qx_data = np.append(self.qx_data, other.qx_data)
482        result.qy_data = np.append(self.qy_data, other.qy_data)
483        result.q_data = np.append(self.q_data, other.q_data)
484        result.mask = np.append(self.mask, other.mask)
[a48842a2]485        if result.err_data is not None:
[9a5097c]486            result.err_data = np.append(self.err_data, other.err_data)
[a48842a2]487        if self.dqx_data is not None:
[9a5097c]488            result.dqx_data = np.append(self.dqx_data, other.dqx_data)
[a48842a2]489        if self.dqy_data is not None:
[9a5097c]490            result.dqy_data = np.append(self.dqy_data, other.dqy_data)
[a48842a2]491
[901142f]492        return result
[1913820]493       
494def check_data_validity(data):
[b21d32b]495    """
496    Return True is data is valid enough to compute chisqr, else False
497    """
498    flag = True
499    if data is not None:
500        if issubclass(data.__class__, Data2D):
501            if (data.data is None) or (len(data.data) == 0)\
502            or (len(data.err_data) == 0):
503                flag = False
504        else:
505            if (data.y is None) or (len(data.y) == 0): 
506                flag = False
507        if not data.is_data:
508            flag = False
509    else:
510        flag = False
511    return flag
Note: See TracBrowser for help on using the repository browser.