source: sasview/src/sas/qtgui/Perspectives/Fitting/FittingLogic.py @ 2add354

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 2add354 was 2add354, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Code review fixes for SASVIEW-273

  • Property mode set to 100755
File size: 6.9 KB
Line 
1import numpy as np
2
3from sas.sasgui.guiframe.dataFitting import Data1D
4from sas.sasgui.guiframe.dataFitting import Data2D
5from sas.sascalc.dataloader.data_info import Detector
6from sas.sascalc.dataloader.data_info import Source
7
8
9class FittingLogic(object):
10    """
11    All the data-related logic. This class deals exclusively with Data1D/2D
12    No QStandardModelIndex here.
13    """
14    def __init__(self, data=None):
15        self._data = data
16        self.data_is_loaded = False
17        if data is not None:
18            self.data_is_loaded = True
19
20    @property
21    def data(self):
22        return self._data
23
24    @data.setter
25    def data(self, value):
26        """ data setter """
27        self._data = value
28        self.data_is_loaded = True
29
30    def isLoadedData(self):
31        """ accessor """
32        return self.data_is_loaded
33
34    def createDefault1dData(self, interval, tab_id=0):
35        """
36        Create default data for fitting perspective
37        Only when the page is on theory mode.
38        """
39        self._data = Data1D(x=interval)
40        self._data.xaxis('\\rm{Q}', "A^{-1}")
41        self._data.yaxis('\\rm{Intensity}', "cm^{-1}")
42        self._data.is_data = False
43        self._data.id = str(tab_id) + " data"
44        self._data.group_id = str(tab_id) + " Model1D"
45
46    def createDefault2dData(self, qmax, qstep, tab_id=0):
47        """
48        Create 2D data by default
49        Only when the page is on theory mode.
50        """
51        self._data = Data2D()
52        self._data.xaxis('\\rm{Q_{x}}', 'A^{-1}')
53        self._data.yaxis('\\rm{Q_{y}}', 'A^{-1}')
54        self._data.is_data = False
55        self._data.id = str(tab_id) + " data"
56        self._data.group_id = str(tab_id) + " Model2D"
57
58        # Default detector
59        self._data.detector.append(Detector())
60        index = len(self._data.detector) - 1
61        self._data.detector[index].distance = 8000   # mm
62        self._data.source.wavelength = 6             # A
63        self._data.detector[index].pixel_size.x = 5  # mm
64        self._data.detector[index].pixel_size.y = 5  # mm
65        self._data.detector[index].beam_center.x = qmax
66        self._data.detector[index].beam_center.y = qmax
67        # theory default: assume the beam
68        #center is located at the center of sqr detector
69        xmax = qmax
70        xmin = -qmax
71        ymax = qmax
72        ymin = -qmax
73
74        x = np.linspace(start=xmin, stop=xmax, num=qstep, endpoint=True)
75        y = np.linspace(start=ymin, stop=ymax, num=qstep, endpoint=True)
76        # Use data info instead
77        new_x = np.tile(x, (len(y), 1))
78        new_y = np.tile(y, (len(x), 1))
79        new_y = new_y.swapaxes(0, 1)
80
81        # all data required in 1d array
82        qx_data = new_x.flatten()
83        qy_data = new_y.flatten()
84        q_data = np.sqrt(qx_data * qx_data + qy_data * qy_data)
85
86        # set all True (standing for unmasked) as default
87        mask = np.ones(len(qx_data), dtype=bool)
88        # calculate the range of qx and qy: this way,
89        # it is a little more independent
90        # store x and y bin centers in q space
91        x_bins = x
92        y_bins = y
93
94        self._data.source = Source()
95        self._data.data = np.ones(len(mask))
96        self._data.err_data = np.ones(len(mask))
97        self._data.qx_data = qx_data
98        self._data.qy_data = qy_data
99        self._data.q_data = q_data
100        self._data.mask = mask
101        self._data.x_bins = x_bins
102        self._data.y_bins = y_bins
103        # max and min taking account of the bin sizes
104        self._data.xmin = xmin
105        self._data.xmax = xmax
106        self._data.ymin = ymin
107        self._data.ymax = ymax
108
109    def new1DPlot(self, return_data, tab_id):
110        """
111        Create a new 1D data instance based on fitting results
112        """
113        # Unpack return data from Calc1D
114        x, y, page_id, state, weight,\
115        fid, toggle_mode_on, \
116        elapsed, index, model,\
117        data, update_chisqr, source = return_data
118
119        # Create the new plot
120        new_plot = Data1D(x=x, y=y)
121        new_plot.is_data = False
122        new_plot.dy = np.zeros(len(y))
123        _yaxis, _yunit = data.get_yaxis()
124        _xaxis, _xunit = data.get_xaxis()
125
126        new_plot.group_id = data.group_id
127        new_plot.id = str(tab_id) + " " + data.name
128        new_plot.name = model.name + " [" + data.name + "]"
129        new_plot.title = new_plot.name
130        new_plot.xaxis(_xaxis, _xunit)
131        new_plot.yaxis(_yaxis, _yunit)
132
133        return new_plot
134
135    def new2DPlot(self, return_data):
136        """
137        Create a new 2D data instance based on fitting results
138        """
139        image, data, page_id, model, state, toggle_mode_on,\
140        elapsed, index, fid, qmin, qmax, weight, \
141        update_chisqr, source = return_data
142
143        np.nan_to_num(image)
144        new_plot = Data2D(image=image, err_image=data.err_data)
145        new_plot.name = model.name + '2d'
146        new_plot.title = "Analytical model 2D "
147        new_plot.id = str(page_id) + " " + data.name
148        new_plot.group_id = str(page_id) + " Model2D"
149        new_plot.detector = data.detector
150        new_plot.source = data.source
151        new_plot.is_data = False
152        new_plot.qx_data = data.qx_data
153        new_plot.qy_data = data.qy_data
154        new_plot.q_data = data.q_data
155        new_plot.mask = data.mask
156        ## plot boundaries
157        new_plot.ymin = data.ymin
158        new_plot.ymax = data.ymax
159        new_plot.xmin = data.xmin
160        new_plot.xmax = data.xmax
161
162        title = data.title
163
164        new_plot.is_data = False
165        if data.is_data:
166            data_name = str(data.name)
167        else:
168            data_name = str(model.__class__.__name__) + '2d'
169
170        if len(title) > 1:
171            new_plot.title = "Model2D for %s " % model.name + data_name
172        new_plot.name = model.name + " [" + \
173                                    data_name + "]"
174
175        return new_plot
176
177    def computeDataRange(self):
178        """
179        Compute the minimum and the maximum range of the data
180        return the npts contains in data
181        """
182        qmin, qmax, npts = None, None, None
183        if isinstance(self.data, Data1D):
184            try:
185                qmin = min(self.data.x)
186                qmax = max(self.data.x)
187                npts = len(self.data.x)
188            except (ValueError, TypeError):
189                msg = "Unable to find min/max/length of \n data named %s" % \
190                            self.data.filename
191                raise ValueError, msg
192
193        else:
194            qmin = 0
195            try:
196                x = max(np.fabs(self.data.xmin), np.fabs(self.data.xmax))
197                y = max(np.fabs(self.data.ymin), np.fabs(self.data.ymax))
198            except (ValueError, TypeError):
199                msg = "Unable to find min/max of \n data named %s" % \
200                            self.data.filename
201                raise ValueError, msg
202            qmax = np.sqrt(x * x + y * y)
203            npts = len(self.data.data)
204        return qmin, qmax, npts
Note: See TracBrowser for help on using the repository browser.