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

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 d6e38661 was d6e38661, checked in by Piotr Rozyczko <rozyczko@…>, 4 years ago

Fixed naming of datasets for both theory and file data

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