source: sasview/src/sas/sasgui/perspectives/corfunc/corfunc.py @ afb311e

Last change on this file since afb311e was 9b90bf8, checked in by lewis, 7 years ago

Use DCT to calculate IDF

  • Property mode set to 100644
File size: 8.8 KB
Line 
1"""
2    Corfunc perspective
3"""
4import wx
5import sys
6import logging
7import copy
8from sas.sasgui.guiframe.plugin_base import PluginBase
9from sas.sasgui.guiframe.gui_manager import MDIFrame
10from sas.sasgui.guiframe.events import StatusEvent
11from sas.sasgui.guiframe.events import NewPlotEvent
12from sas.sasgui.guiframe.events import PlotLimitEvent
13from sas.sasgui.guiframe.gui_style import GUIFRAME_ID
14from sas.sasgui.perspectives.corfunc.corfunc_panel import CorfuncPanel
15from sas.sasgui.guiframe.dataFitting import Data1D
16from sas.sasgui.perspectives.pr.pr_widgets import DataDialog
17from sas.sasgui.perspectives.corfunc.corfunc_state import Reader
18from sas.sascalc.dataloader.loader import Loader
19import sas.sascalc.dataloader
20from plot_labels import *
21
22logger = logging.getLogger(__name__)
23
24class Plugin(PluginBase):
25    """
26    This class defines the interface for a plugin class for a correlation
27    function perspective
28    """
29
30    def __init__(self):
31        PluginBase.__init__(self, name="Correlation Function")
32        logger.info("Correlation function plug-in started")
33        self._always_active = True
34        self.state_reader = Reader(self.set_state)
35        self._extensions = '.crf'
36
37    def get_panels(self, parent):
38        """
39        Define the GUI panels
40        """
41        self.parent = parent
42        self.frame = MDIFrame(self.parent, None, 'None', (100,200))
43        self.data_id = IQ_DATA_LABEL
44        self.corfunc_panel = CorfuncPanel(parent=self.frame)
45        self.frame.set_panel(self.corfunc_panel)
46        self.corfunc_panel.set_manager(self)
47        self._frame_set_helper()
48        self.perspective.append(self.corfunc_panel.window_name)
49
50        l = Loader()
51        l.associate_file_reader('.crf', self.state_reader)
52
53        return [self.corfunc_panel]
54
55    def get_context_menu(self, plotpanel=None):
56        """
57        Get the context menu items available for Corfunc.
58
59        :param plotpanel: A Plotter1D panel
60
61        :return: a list of menu items with call-back function
62
63        :note: if Data1D was generated from Theory1D
64                the fitting option is not allowed
65        """
66        graph = plotpanel.graph
67        if graph.selected_plottable not in plotpanel.plots:
68            return []
69        data = plotpanel.plots[graph.selected_plottable]
70        if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL1 or data.id == TRANSFORM_LABEL3:
71            return []
72        item = plotpanel.plots[graph.selected_plottable]
73        if item.__class__.__name__ is "Data2D":
74            return []
75        elif item.__class__.__name__ is "Data1D":
76            return [["Select data in corfunc",
77                "Send this data to the correlation function perspective",
78                self._on_select_data]]
79
80
81
82    def set_state(self, state=None, datainfo=None):
83        """
84        Callback for CorfuncState reader. Called when a .crf file is loaded
85        """
86        if isinstance(datainfo, list):
87            data = datainfo[0]
88        else:
89            data = datainfo
90        self.corfunc_panel.set_state(state=state, data=data)
91        self.on_perspective(event=None)
92        data = self.parent.create_gui_data(data, None)
93        self.parent.add_data({ data.id: data })
94
95    def set_data(self, data_list=None):
96        """
97        Load the data that's been selected
98
99        :param data_list: The data to load in
100        """
101        if data_list is None:
102            data_list = []
103        if len(data_list) >= 1:
104            msg = ""
105            if len(data_list) == 1:
106                data = data_list[0]
107            else:
108                data_1d_list = []
109                data_2d_list = []
110                err_msg = ""
111
112                for data in data_list:
113                    if data is not None:
114                        if issubclass(data.__class__, Data1D):
115                            data_1d_list.append(data)
116                        else:
117                            err_msg += "{} type {} \n".format(str(data.name),
118                                str(data.__class__))
119                            data_2d_list.append(data)
120                if len(data_2d_list) > 0:
121                    msg = "Corfunc doesn't support the following data types:\n"
122                    msg += err_msg
123                if len(data_1d_list) == 0:
124                    msg += "No data recieved"
125                    wx.PostEvent(self.parent, StatusEvent(status=msg,
126                                                info='error'))
127                    return
128                elif len(data_list) > 1:
129                    msg = "Corfunc does not allow multiple data\n"
130                    msg += "Please select one.\n"
131                    dlg = DataDialog(data_list=data_1d_list, text=msg)
132                    if dlg.ShowModal() == wx.ID_OK:
133                        data = dlg.get_data()
134                    else:
135                        data = None
136                    dlg.Destroy()
137
138            if data is None:
139                msg += "Corfunc recieved no data\n"
140                wx.PostEvent(self.parent, StatusEvent(status=msg,
141                                            info='error'))
142                return
143            if issubclass(data.__class__, Data1D):
144                try:
145                    wx.PostEvent(self.parent, NewPlotEvent(action='remove',
146                                                group_id=GROUP_ID_IQ_DATA,
147                                                id=self.data_id))
148                    self.data_id = data.id
149                    self.corfunc_panel.set_data(data)
150                except:
151                    msg = "Corfunc set_data: " + str(sys.exc_value)
152                    wx.PostEvent(self.parent, StatusEvent(status=msg,
153                        info='error'))
154
155    def delete_data(self, data):
156        """
157        Delete the data from the perspective
158        """
159        self.clear_data()
160        self.corfunc_panel.set_data(None)
161
162    def show_data(self, data, label, reset=False, active_ctrl=None):
163        """
164        Show data read from a file
165
166        :param data: The data to plot (Data1D)
167        :param label: What to label the plot. Also used as the plot ID
168        :param reset: If True, all other plottables will be cleared
169        """
170        new_plot = Data1D(data.x, copy.deepcopy(data.y), dy=data.dy)
171        group_id = ""
172        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
173            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
174            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
175            new_plot.y -= self.corfunc_panel.background
176            # Show data on a log(Q)/I scale
177            new_plot.ytransform = 'y'
178            group_id = GROUP_ID_IQ_DATA
179            if label == IQ_EXTRAPOLATED_DATA_LABEL:
180                # Show the extrapolation as a curve instead of points
181                new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
182        elif label == TRANSFORM_LABEL1 or label == TRANSFORM_LABEL3:
183            new_plot.xaxis("{x}", 'A')
184            new_plot.yaxis("{\\Gamma}", '')
185            # Show transform on a linear scale
186            new_plot.xtransform = 'x'
187            new_plot.ytransform = 'y'
188            group_id = GROUP_ID_TRANSFORM
189            # Show the transformation as a curve instead of points
190            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
191        elif label == IDF_LABEL:
192            new_plot.xaxis("{x}", 'A')
193            new_plot.yaxis("{g_1}", '')
194            # Linear scale
195            new_plot.xtransform = 'x'
196            new_plot.ytransform = 'y'
197            group_id = GROUP_ID_IDF
198            # Show IDF as a curve instead of points
199            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
200        new_plot.id = label
201        new_plot.name = label
202        new_plot.group_id = group_id
203        new_plot.interactive = True
204        new_plot.title = group_id.replace('$', '').replace('\\', '')
205        wx.PostEvent(self.parent,
206                     NewPlotEvent(plot=new_plot, title=new_plot.title,
207                        reset=reset))
208        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
209            wx.CallAfter(self.corfunc_panel.plot_qrange, active=active_ctrl,
210                leftdown=True)
211        if label == IQ_EXTRAPOLATED_DATA_LABEL:
212            # Zoom in to the region we're interested in
213            xlim = (min(self.corfunc_panel._extrapolated_data.x), self.corfunc_panel.qmax[1]*1.2)
214            wx.CallAfter(wx.PostEvent, self.parent, PlotLimitEvent(id=IQ_DATA_LABEL, group_id=GROUP_ID_IQ_DATA, xlim=xlim))
215
216    def clear_data(self):
217        wx.PostEvent(self.parent,
218            NewPlotEvent(action='delete', group_id=GROUP_ID_TRANSFORM))
219        wx.PostEvent(self.parent,
220            NewPlotEvent(action='clear', group_id=GROUP_ID_IQ_DATA))
221
222    def _on_select_data(self, event):
223        panel = event.GetEventObject()
224        if not panel.graph.selected_plottable in panel.plots:
225            return
226        data = panel.plots[panel.graph.selected_plottable]
227        self.set_data([data])
Note: See TracBrowser for help on using the repository browser.