source: sasview/src/sas/qtgui/Perspectives/Inversion/InversionLogic.py @ 57ad773

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 57ad773 was 57ad773, checked in by krzywon, 7 years ago

Plots generated and linked to data set.

  • Property mode set to 100644
File size: 5.7 KB
Line 
1import math
2import pylab
3import numpy as np
4
5from sas.qtgui.Plotting.PlotterData import Data1D
6
7PR_FIT_LABEL = r"$P_{fit}(r)$"
8PR_LOADED_LABEL = r"$P_{loaded}(r)$"
9IQ_DATA_LABEL = r"$I_{obs}(q)$"
10IQ_FIT_LABEL = r"$I_{fit}(q)$"
11IQ_SMEARED_LABEL = r"$I_{smeared}(q)$"
12GROUP_ID_IQ_DATA = r"$I_{obs}(q)$"
13GROUP_ID_PR_FIT = r"$P_{fit}(r)$"
14
15
16class InversionLogic(object):
17    """
18    All the data-related logic. This class deals exclusively with Data1D/2D
19    No QStandardModelIndex here.
20    """
21
22    # TODO: Add way to change this value
23    _pr_n_pts = 51
24
25    def __init__(self, data=None):
26        self._data = data
27        self.data_is_loaded = False
28        if data is not None:
29            self.data_is_loaded = True
30
31    @property
32    def data(self):
33        return self._data
34
35    @data.setter
36    def data(self, value):
37        """ data setter """
38        self._data = value
39        self.data_is_loaded = True
40
41    def isLoadedData(self):
42        """ accessor """
43        return self.data_is_loaded
44
45    def new1DPlot(self, out, pr, q=None):
46        """
47        Create a new 1D data instance based on fitting results
48        """
49
50        qtemp = pr.x
51        if q is not None:
52            qtemp = q
53
54        # Make a plot
55        maxq = max(qtemp)
56
57        minq = min(qtemp)
58
59        # Check for user min/max
60        if pr.q_min is not None and maxq >= pr.q_min >= minq:
61            minq = pr.q_min
62        if pr.q_max is not None and maxq >= pr.q_max >= minq:
63            maxq = pr.q_max
64
65        x = pylab.arange(minq, maxq, maxq / 301.0)
66        y = np.zeros(len(x))
67        err = np.zeros(len(x))
68        for i in range(len(x)):
69            value = pr.iq(out, x[i])
70            y[i] = value
71            try:
72                err[i] = math.sqrt(math.fabs(value))
73            except:
74                err[i] = 1.0
75                print("Error getting error", value, x[i])
76
77        new_plot = Data1D(x, y)
78        new_plot.name = IQ_FIT_LABEL
79        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
80        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
81        title = "I(q)"
82        new_plot.title = title
83
84        # If we have a group ID, use it
85        if 'plot_group_id' in pr.info:
86            new_plot.group_id = pr.info["plot_group_id"]
87        new_plot.id = IQ_FIT_LABEL
88
89        # If we have used slit smearing, plot the smeared I(q) too
90        if pr.slit_width > 0 or pr.slit_height > 0:
91            x = pylab.arange(minq, maxq, maxq / 301.0)
92            y = np.zeros(len(x))
93            err = np.zeros(len(x))
94            for i in range(len(x)):
95                value = pr.iq_smeared(pr.out, x[i])
96                y[i] = value
97                try:
98                    err[i] = math.sqrt(math.fabs(value))
99                except:
100                    err[i] = 1.0
101                    print("Error getting error", value, x[i])
102
103            new_plot = Data1D(x, y)
104            new_plot.name = IQ_SMEARED_LABEL
105            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
106            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
107            # If we have a group ID, use it
108            if 'plot_group_id' in pr.info:
109                new_plot.group_id = pr.info["plot_group_id"]
110            new_plot.id = IQ_SMEARED_LABEL
111            new_plot.title = title
112
113        return new_plot
114
115    def newPRPlot(self, out, pr, cov=None):
116        """
117        """
118        # Show P(r)
119        x = pylab.arange(0.0, pr.d_max, pr.d_max / self._pr_n_pts)
120
121        y = np.zeros(len(x))
122        dy = np.zeros(len(x))
123        y_true = np.zeros(len(x))
124
125        total = 0.0
126        pmax = 0.0
127        cov2 = np.ascontiguousarray(cov)
128
129        for i in range(len(x)):
130            if cov2 is None:
131                value = pr.pr(out, x[i])
132            else:
133                (value, dy[i]) = pr.pr_err(out, cov2, x[i])
134            total += value * pr.d_max / len(x)
135
136            # keep track of the maximum P(r) value
137            if value > pmax:
138                pmax = value
139
140            y[i] = value
141
142        # if self._normalize_output == True:
143        #     y = y / total
144        #     dy = dy / total
145        # elif self._scale_output_unity == True:
146        #     y = y / pmax
147        #     dy = dy / pmax
148
149        if cov2 is None:
150            new_plot = Data1D(x, y)
151        else:
152            new_plot = Data1D(x, y, dy=dy)
153        new_plot.name = PR_FIT_LABEL
154        new_plot.xaxis("\\rm{r}", 'A')
155        new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
156        new_plot.title = "P(r) fit"
157        new_plot.id = PR_FIT_LABEL
158        # Make sure that the plot is linear
159        new_plot.xtransform = "x"
160        new_plot.ytransform = "y"
161        new_plot.group_id = GROUP_ID_PR_FIT
162
163        return new_plot
164
165    def computeDataRange(self):
166        """
167        Wrapper for calculating the data range based on local dataset
168        """
169        return self.computeRangeFromData(self.data)
170
171    def computeRangeFromData(self, data):
172        """
173        Compute the minimum and the maximum range of the data
174        return the npts contains in data
175        """
176        qmin, qmax = None, None
177        if isinstance(data, Data1D):
178            try:
179                qmin = min(data.x)
180                qmax = max(data.x)
181            except (ValueError, TypeError):
182                msg = "Unable to find min/max/length of \n data named %s" % \
183                            self.data.filename
184                raise ValueError, msg
185
186        else:
187            qmin = 0
188            try:
189                x = max(np.fabs(data.xmin), np.fabs(data.xmax))
190                y = max(np.fabs(data.ymin), np.fabs(data.ymax))
191            except (ValueError, TypeError):
192                msg = "Unable to find min/max of \n data named %s" % \
193                            self.data.filename
194                raise ValueError, msg
195            qmax = np.sqrt(x * x + y * y)
196        return qmin, qmax
Note: See TracBrowser for help on using the repository browser.