source: sasview/src/sas/sasgui/guiframe/dataFitting.py @ 68adf86

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 68adf86 was 68adf86, checked in by krzywon, 3 years ago

Apply a linear transform for SESANS data as default.

  • Property mode set to 100644
File size: 19.1 KB
Line 
1"""
2Adapters for fitting module
3"""
4import copy
5import numpy
6import math
7from sas.sascalc.data_util.uncertainty import Uncertainty
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
11
12from sas.sascalc.dataloader.data_info import Data1D as LoadData1D
13from sas.sascalc.dataloader.data_info import Data2D as LoadData2D
14
15
16class Data1D(PlotData1D, LoadData1D):
17    """
18    """
19
20    def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=False):
21        """
22        """
23        if x is None:
24            x = []
25        if y is None:
26            y = []
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
31        self.id = None
32        self.list_group_id = []
33        self.group_id = None
34        self.is_data = True
35        self.path = None
36        self.xtransform = None
37        if self.isSesans:
38            self.xtransform = "x"
39        self.ytransform = None
40        if self.isSesans:
41            self.ytransform = "y"
42        self.title = ""
43        self.scale = None
44       
45    def copy_from_datainfo(self, data1d):
46        """
47        copy values of Data1D of type DataLaoder.Data_info
48        """
49        self.= copy.deepcopy(data1d.x)
50        self.= copy.deepcopy(data1d.y)
51        self.dy = copy.deepcopy(data1d.dy)
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)
59   
60        self.xaxis(data1d._xaxis, data1d._xunit)
61        self.yaxis(data1d._yaxis, data1d._yunit)
62        self.title = data1d.title
63       
64    def __str__(self):
65        """
66        print data
67        """
68        _str = "%s\n" % LoadData1D.__str__(self)
69     
70        return _str
71   
72    def _perform_operation(self, other, operation):
73        """
74        """
75        # First, check the data compatibility
76        dy, dy_other = self._validity_check(other)
77        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None)
78        result.clone_without_data(length=len(self.x), clone=self)
79        result.copy_from_datainfo(data1d=self)
80        if self.dxw == None:
81            result.dxw = None
82        else:
83            result.dxw = numpy.zeros(len(self.x))
84        if self.dxl == None:
85            result.dxl = None
86        else:
87            result.dxl = numpy.zeros(len(self.x))
88
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]
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]
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)
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])
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   
119    def _perform_union(self, other):
120        """
121        """
122        # First, check the data compatibility
123        self._validity_check_union(other)
124        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None)
125        tot_length = len(self.x) + len(other.x)
126        result = self.clone_without_data(length=tot_length, clone=result)
127        if self.dlam == None or other.dlam is None:
128            result.dlam = None
129        else:
130            result.dlam = numpy.zeros(tot_length)
131        if self.dy == None or other.dy is None:
132            result.dy = None
133        else:
134            result.dy = numpy.zeros(tot_length)
135        if self.dx == None or other.dx is None:
136            result.dx = None
137        else:
138            result.dx = numpy.zeros(tot_length)
139        if self.dxw == None or other.dxw is None:
140            result.dxw = None
141        else:
142            result.dxw = numpy.zeros(tot_length)
143        if self.dxl == None or other.dxl is None:
144            result.dxl = None
145        else:
146            result.dxl = numpy.zeros(tot_length)
147
148        result.x = numpy.append(self.x, other.x)
149        #argsorting
150        ind = numpy.argsort(result.x)
151        result.x = result.x[ind]
152        result.y = numpy.append(self.y, other.y)
153        result.y = result.y[ind]
154        result.lam = numpy.append(self.lam, other.lam)
155        result.lam = result.lam[ind]
156        if result.dlam != None:
157            result.dlam = numpy.append(self.dlam, other.dlam)
158            result.dlam = result.dlam[ind]
159        if result.dy != None:
160            result.dy = numpy.append(self.dy, other.dy)
161            result.dy = result.dy[ind]
162        if result.dx is not None:
163            result.dx = numpy.append(self.dx, other.dx)
164            result.dx = result.dx[ind]
165        if result.dxw is not None:
166            result.dxw = numpy.append(self.dxw, other.dxw)
167            result.dxw = result.dxw[ind]
168        if result.dxl is not None:
169            result.dxl = numpy.append(self.dxl, other.dxl)
170            result.dxl = result.dxl[ind]
171        return result
172   
173 
174   
175class Theory1D(PlotTheory1D, LoadData1D):
176    """
177    """
178    def __init__(self, x=None, y=None, dy=None):
179        """
180        """
181        if x is None:
182            x = []
183        if y is None:
184            y = []
185        PlotTheory1D.__init__(self, x, y, dy)
186        LoadData1D.__init__(self, x, y, dy)
187        self.id = None
188        self.list_group_id = []
189        self.group_id = None
190        self.is_data = True
191        self.path = None
192        self.xtransform = None
193        self.ytransform = None
194        self.title = ""
195        self.scale = None
196   
197    def copy_from_datainfo(self, data1d):
198        """
199        copy values of Data1D of type DataLaoder.Data_info
200        """
201        self.= copy.deepcopy(data1d.x)
202        self.= copy.deepcopy(data1d.y)
203        self.dy = copy.deepcopy(data1d.dy)
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)   
210        self.xaxis(data1d._xaxis, data1d._xunit)
211        self.yaxis(data1d._yaxis, data1d._yunit)
212        self.title = data1d.title
213       
214    def __str__(self):
215        """
216        print data
217        """
218        _str = "%s\n" % LoadData1D.__str__(self)
219     
220        return _str
221   
222    def _perform_operation(self, other, operation):
223        """
224        """
225        # First, check the data compatibility
226        dy, dy_other = self._validity_check(other)
227        result = self.clone_without_data(len(self.x))
228        result.copy_from_datainfo(data1d=self)
229        if self.dxw == None:
230            result.dxw = None
231        else:
232            result.dxw = numpy.zeros(len(self.x))
233        if self.dxl == None:
234            result.dxl = None
235        else:
236            result.dxl = numpy.zeros(len(self.x))
237
238        for i in range(numpy.size(self.x)):
239            result.x[i] = self.x[i]
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           
247            a = Uncertainty(self.y[i], dy[i]**2)
248            if isinstance(other, Data1D):
249                b = Uncertainty(other.y[i], dy_other[i]**2)
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])
265            else:
266                b = other
267           
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   
273    def _perform_union(self, other):
274        """
275        """
276        # First, check the data compatibility
277        self._validity_check_union(other)
278        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=[])
279        tot_length = len(self.x)+len(other.x)
280        result.clone_without_data(length=tot_length, clone=self)
281        if self.dlam == None or other.dlam is None:
282            result.dlam = None
283        else:
284            result.dlam = numpy.zeros(tot_length)
285        if self.dy == None or other.dy is None:
286            result.dy = None
287        else:
288            result.dy = numpy.zeros(tot_length)
289        if self.dx == None or other.dx is None:
290            result.dx = None
291        else:
292            result.dx = numpy.zeros(tot_length)
293        if self.dxw == None or other.dxw is None:
294            result.dxw = None
295        else:
296            result.dxw = numpy.zeros(tot_length)
297        if self.dxl == None or other.dxl is None:
298            result.dxl = None
299        else:
300            result.dxl = numpy.zeros(tot_length)
301        result.x = numpy.append(self.x, other.x)
302        #argsorting
303        ind = numpy.argsort(result.x)
304        result.x = result.x[ind]
305        result.y = numpy.append(self.y, other.y)
306        result.y = result.y[ind]
307        result.lam = numpy.append(self.lam, other.lam)
308        result.lam = result.lam[ind]
309        if result.dy != None:
310            result.dy = numpy.append(self.dy, other.dy)
311            result.dy = result.dy[ind]
312        if result.dx is not None:
313            result.dx = numpy.append(self.dx, other.dx)
314            result.dx = result.dx[ind]
315        if result.dxw is not None:
316            result.dxw = numpy.append(self.dxw, other.dxw)
317            result.dxw = result.dxw[ind]
318        if result.dxl is not None:
319            result.dxl = numpy.append(self.dxl, other.dxl)
320            result.dxl = result.dxl[ind]
321        return result
322 
323     
324class Data2D(PlotData2D, LoadData2D):
325    """
326    """
327    def __init__(self, image=None, err_image=None,
328                 qx_data=None, qy_data=None, q_data=None, 
329                 mask=None, dqx_data=None, dqy_data=None, 
330                 xmin=None, xmax=None, ymin=None, ymax=None,
331                 zmin=None, zmax=None):
332        """
333        """
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)
338       
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)
343        self.id = None
344        self.list_group_id = []
345        self.group_id = None
346        self.is_data = True
347        self.path = None
348        self.xtransform = None
349        self.ytransform = None
350        self.title = ""
351        self.scale = None
352       
353    def copy_from_datainfo(self, data2d):
354        """
355        copy value of Data2D of type DataLoader.data_info
356        """
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
373        if hasattr(data2d, "zmin"):
374            self.zmin = data2d.zmin
375        if hasattr(data2d, "zmax"):
376            self.zmax = data2d.zmax
377        self.xaxis(data2d._xaxis, data2d._xunit)
378        self.yaxis(data2d._yaxis, data2d._yunit)
379        self.title = data2d.title
380       
381    def __str__(self):
382        """
383        print data
384        """
385        _str = "%s\n" % LoadData2D.__str__(self)
386        return _str
387
388    def _perform_operation(self, other, operation):
389        """
390        Perform 2D operations between data sets
391       
392        :param other: other data set
393        :param operation: function defining the operation
394       
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,
399                         q_data=None, err_image=None, xmin=None, xmax=None,
400                         ymin=None, ymax=None, zmin=None, zmax=None)
401        result.clone_without_data(len(self.data))
402        result.copy_from_datainfo(data2d=self)
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:
411            result.dqx_data = numpy.zeros(len(self.data))
412            result.dqy_data = numpy.zeros(len(self.data))
413        for i in range(numpy.size(self.data)):
414            result.data[i] = self.data[i]
415            if self.err_data is not None and \
416                numpy.size(self.data) == numpy.size(self.err_data):
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           
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
453       
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)
465        result.clone_without_data(tot_length)
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:
475            result.dqx_data = numpy.zeros(len(self.data) + \
476                                         numpy.size(other.data))
477            result.dqy_data = numpy.zeros(len(self.data) + \
478                                         numpy.size(other.data))
479       
480        result.data = numpy.append(self.data, other.data)
481        result.qx_data = numpy.append(self.qx_data, other.qx_data)
482        result.qy_data = numpy.append(self.qy_data, other.qy_data)
483        result.q_data = numpy.append(self.q_data, other.q_data)
484        result.mask = numpy.append(self.mask, other.mask)
485        if result.err_data is not None:
486            result.err_data = numpy.append(self.err_data, other.err_data) 
487        if self.dqx_data is not None:
488            result.dqx_data = numpy.append(self.dqx_data, other.dqx_data)
489        if self.dqy_data is not None:
490            result.dqy_data = numpy.append(self.dqy_data, other.dqy_data)
491
492        return result
493       
494def check_data_validity(data):
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.