Exemple #1
0
    def plot_theory(self, data=None, name=None):
        """
        Receive a data set and post a NewPlotEvent to parent.

        :param data: extrapolated data to be plotted
        :param name: Data's name to use for the legend
        """
        # import copy
        if data is None:
            id = str(self.__data.id) + name
            group_id = self.__data.group_id
            wx.PostEvent(
                self.parent,
                NewPlotEvent(id=id, group_id=group_id, action='Remove'))
            return

        new_plot = Data1D(x=[], y=[], dy=None)
        new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        scale = self.invariant_panel.get_scale()
        background = self.invariant_panel.get_background()

        if scale != 0:
            # Put back the sacle and bkg for plotting
            data.y = (data.y + background) / scale
            new_plot = Data1D(x=data.x, y=data.y, dy=None)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        else:
            msg = "Scale can not be zero."
            raise ValueError(msg)
        if len(new_plot.x) == 0:
            return

        new_plot.name = name
        new_plot.xaxis(self.__data._xaxis, self.__data._xunit)
        new_plot.yaxis(self.__data._yaxis, self.__data._yunit)
        new_plot.group_id = self.__data.group_id
        new_plot.id = str(self.__data.id) + name
        new_plot.title = self.__data.title
        # Save theory_data in a state
        if data is not None:
            name_head = name.split('-')
            if name_head[0] == 'Low':
                self.invariant_panel.state.theory_lowQ = copy.deepcopy(
                    new_plot)
            elif name_head[0] == 'High':
                self.invariant_panel.state.theory_highQ = copy.deepcopy(
                    new_plot)

        self.parent.update_theory(data_id=self.__data.id, theory=new_plot)
        wx.PostEvent(self.parent,
                     NewPlotEvent(plot=new_plot, title=self.__data.title))
Exemple #2
0
    def show_shpere(self, x, radius=70.0, x_range=70.0):
        """
        """
        # Show P(r)
        y_true = np.zeros(len(x))

        sum_true = 0.0
        for i in range(len(x)):
            y_true[i] = self.pr_theory(x[i], radius)
            sum_true += y_true[i]

        y_true = y_true / sum_true * x_range / len(x)

        # Show the theory P(r)
        new_plot = Data1D(x, y_true)
        new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        new_plot.name = "P_{true}(r)"
        new_plot.xaxis("\\rm{r}", 'A')
        new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
        new_plot.id = "P_{true}(r)"
        new_plot.group_id = "P_{true}(r)"
        self.parent.update_theory(data_id=self.data_id, theory=new_plot)
        #Put this call in plottables/guitools
        wx.PostEvent(self.parent,
                     NewPlotEvent(plot=new_plot, title="Sphere P(r)"))
Exemple #3
0
    def _on_scale_unity(self, evt):
        """
        Scale the maximum P(r) value on each displayed plot to 1.

        :param evt: Menu event

        """
        self._scale_output_unity = True
        self._normalize_output = False

        self.show_pr(self._last_out, self._last_pr, self._last_cov)

        # Now scale the added plots too
        for plot in self._added_plots:
            _max = 0
            for y in self._added_plots[plot].y:
                if y > _max:
                    _max = y
            y = self._added_plots[plot].y / _max

            new_plot = Data1D(self._added_plots[plot].x, y)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
            new_plot.name = self._added_plots[plot].name
            new_plot.xaxis("\\rm{r}", 'A')
            new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
            self.parent.update_theory(data_id=self.data_id, theory=new_plot)
            wx.PostEvent(
                self.parent,
                NewPlotEvent(plot=new_plot,
                             update=True,
                             title=self._added_plots[plot].name))
Exemple #4
0
 def set_data(self, data_list=None):
     """
     receive a list of data to compute pr
     """
     if data_list is None:
         data_list = []
     if len(data_list) >= 1:
         if len(data_list) == 1:
             data = data_list[0]
         else:
             data_1d_list = []
             data_2d_list = []
             error_msg = ""
             # separate data into data1d and data2d list
             for data in data_list:
                 if data is not None:
                     if issubclass(data.__class__, Data1D):
                         data_1d_list.append(data)
                     else:
                         error_msg += " %s type %s \n" % (str(data.name),
                                                          str(data.__class__.__name__))
                         data_2d_list.append(data)
             if len(data_2d_list) > 0:
                 msg = "PrView does not support the following data types:\n"
                 msg += error_msg
             if len(data_1d_list) == 0:
                 wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
                 return
             msg = "Prview does not allow multiple data!\n"
             msg += "Please select one.\n"
             if len(data_list) > 1:
                 from pr_widgets import DataDialog
                 dlg = DataDialog(data_list=data_1d_list, text=msg)
                 if dlg.ShowModal() == wx.ID_OK:
                     data = dlg.get_data()
                 else:
                     data = None
                 dlg.Destroy()
         if data is None:
             msg += "PrView receives no data. \n"
             wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
             return
         if issubclass(data.__class__, Data1D):
             try:
                 wx.PostEvent(self.parent,
                              NewPlotEvent(action='remove',
                                           group_id=GROUP_ID_IQ_DATA,
                                           id=self.data_id))
                 self.data_id = data.id
                 self.control_panel._change_file(evt=None, data=data)
             except:
                 msg = "Prview Set_data: " + str(sys.exc_value)
                 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
         else:
             msg = "Pr cannot be computed for data of "
             msg += "type %s" % (data_list[0].__class__.__name__)
             wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
     else:
         msg = "Pr contain no data"
         wx.PostEvent(self.parent, StatusEvent(status=msg, info='warning'))
Exemple #5
0
    def _on_normalize(self, evt):
        """
        Normalize the area under the P(r) curve to 1.
        This operation is done for all displayed plots.

        :param evt: Menu event

        """
        self._normalize_output = True
        self._scale_output_unity = False

        self.show_pr(self._last_out, self._last_pr, self._last_cov)

        # Now scale the added plots too
        for plot in self._added_plots:
            total = np.sum(self._added_plots[plot].y)
            npts = len(self._added_plots[plot].x)
            total *= self._added_plots[plot].x[npts - 1] / npts
            y = self._added_plots[plot].y / total

            new_plot = Data1D(self._added_plots[plot].x, y)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
            new_plot.group_id = self._added_plots[plot].group_id
            new_plot.id = self._added_plots[plot].id
            new_plot.title = self._added_plots[plot].title
            new_plot.name = self._added_plots[plot].name
            new_plot.xaxis("\\rm{r}", 'A')
            new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
            self.parent.update_theory(data_id=self.data_id, theory=new_plot)
            wx.PostEvent(
                self.parent,
                NewPlotEvent(plot=new_plot,
                             update=True,
                             title=self._added_plots[plot].name))
Exemple #6
0
    def onCircular(self, event, ismask=False):
        """
        perform circular averaging on Data2D

        :param event: wx.menu event

        """
        # Find the best number of bins
        npt = math.sqrt(len(self.data2D.data[np.isfinite(self.data2D.data)]))
        npt = math.floor(npt)
        from sas.sascalc.dataloader.manipulations import CircularAverage
        # compute the maximum radius of data2D
        self.qmax = max(math.fabs(self.data2D.xmax),
                        math.fabs(self.data2D.xmin))
        self.ymax = max(math.fabs(self.data2D.ymax),
                        math.fabs(self.data2D.ymin))
        self.radius = math.sqrt(
            math.pow(self.qmax, 2) + math.pow(self.ymax, 2))
        # Compute beam width
        bin_width = (self.qmax + self.qmax) / npt
        # Create data1D circular average of data2D
        Circle = CircularAverage(r_min=0,
                                 r_max=self.radius,
                                 bin_width=bin_width)
        circ = Circle(self.data2D, ismask=ismask)
        from sas.sasgui.guiframe.dataFitting import Data1D
        if hasattr(circ, "dxl"):
            dxl = circ.dxl
        else:
            dxl = None
        if hasattr(circ, "dxw"):
            dxw = circ.dxw
        else:
            dxw = None

        new_plot = Data1D(x=circ.x, y=circ.y, dy=circ.dy, dx=circ.dx)
        new_plot.dxl = dxl
        new_plot.dxw = dxw
        new_plot.name = "Circ avg " + self.data2D.name
        new_plot.source = self.data2D.source
        # new_plot.info = self.data2D.info
        new_plot.interactive = True
        new_plot.detector = self.data2D.detector

        # If the data file does not tell us what the axes are, just assume...
        new_plot.xaxis("\\rm{Q}", "A^{-1}")
        if hasattr(self.data2D, "scale") and \
                    self.data2D.scale == 'linear':
            new_plot.ytransform = 'y'
            new_plot.yaxis("\\rm{Residuals} ", "normalized")
        else:
            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")

        new_plot.group_id = "2daverage" + self.data2D.name
        new_plot.id = "Circ avg " + self.data2D.name
        new_plot.is_data = True
        self.parent.update_theory(data_id=self.data2D.id, theory=new_plot)
        wx.PostEvent(self.parent,
                     NewPlotEvent(plot=new_plot, title=new_plot.name))
Exemple #7
0
    def _post_data(self, nbins=None):
        """
        compute sector averaging of data2D into data1D

        :param nbins: the number of point to plot for the average 1D data
        """
        ## get the data2D to average
        data = self.base.data2D
        # If we have no data, just return
        if data == None:
            return
        ## Averaging
        from sas.sascalc.dataloader.manipulations import SectorQ
        radius = self.qmax
        phimin = -self.left_line.phi + self.main_line.theta
        phimax = self.left_line.phi + self.main_line.theta
        if nbins == None:
            nbins = 20
        sect = SectorQ(r_min=0.0,
                       r_max=radius,
                       phi_min=phimin + math.pi,
                       phi_max=phimax + math.pi,
                       nbins=nbins)

        sector = sect(self.base.data2D)
        ##Create 1D data resulting from average

        if hasattr(sector, "dxl"):
            dxl = sector.dxl
        else:
            dxl = None
        if hasattr(sector, "dxw"):
            dxw = sector.dxw
        else:
            dxw = None
        new_plot = Data1D(x=sector.x, y=sector.y, dy=sector.dy, dx=sector.dx)
        new_plot.dxl = dxl
        new_plot.dxw = dxw
        new_plot.name = "SectorQ" + "(" + self.base.data2D.name + ")"
        new_plot.source = self.base.data2D.source
        #new_plot.info=self.base.data2D.info
        new_plot.interactive = True
        new_plot.detector = self.base.data2D.detector
        ## If the data file does not tell us what the axes are, just assume...
        new_plot.xaxis("\\rm{Q}", "A^{-1}")
        new_plot.yaxis("\\rm{Intensity}", "cm^{-1}")
        if hasattr(data, "scale") and data.scale == 'linear' and \
                self.base.data2D.name.count("Residuals") > 0:
            new_plot.ytransform = 'y'
            new_plot.yaxis("\\rm{Residuals} ", "/")

        new_plot.group_id = "2daverage" + self.base.data2D.name
        new_plot.id = "SectorQ" + self.base.data2D.name
        new_plot.is_data = True
        self.base.parent.update_theory(data_id=data.id, theory=new_plot)
        wx.PostEvent(
            self.base.parent,
            NewPlotEvent(plot=new_plot,
                         title="SectorQ" + self.base.data2D.name))
Exemple #8
0
    def set_data(self, data_list=None):
        """
        Load the data that's been selected

        :param data_list: The data to load in
        """
        if data_list is None:
            data_list = []
        if len(data_list) >= 1:
            msg = ""
            if len(data_list) == 1:
                data = data_list[0]
            else:
                data_1d_list = []
                data_2d_list = []
                err_msg = ""

                for data in data_list:
                    if data is not None:
                        if issubclass(data.__class__, Data1D):
                            data_1d_list.append(data)
                        else:
                            err_msg += "{} type {} \n".format(str(data.name),
                                str(data.__class__))
                            data_2d_list.append(data)
                if len(data_2d_list) > 0:
                    msg = "Corfunc doesn't support the following data types:\n"
                    msg += err_msg
                if len(data_1d_list) == 0:
                    msg += "No data recieved"
                    wx.PostEvent(self.parent, StatusEvent(status=msg,
                                                info='error'))
                    return
                elif len(data_list) > 1:
                    msg = "Corfunc does not allow multiple data\n"
                    msg += "Please select one.\n"
                    dlg = DataDialog(data_list=data_1d_list, text=msg)
                    if dlg.ShowModal() == wx.ID_OK:
                        data = dlg.get_data()
                    else:
                        data = None
                    dlg.Destroy()

            if data is None:
                msg += "Corfunc recieved no data\n"
                wx.PostEvent(self.parent, StatusEvent(status=msg,
                                            info='error'))
                return
            if issubclass(data.__class__, Data1D):
                try:
                    wx.PostEvent(self.parent, NewPlotEvent(action='remove',
                                                group_id=GROUP_ID_IQ_DATA,
                                                id=self.data_id))
                    self.data_id = data.id
                    self.corfunc_panel.set_data(data)
                except:
                    msg = "Corfunc set_data: " + str(sys.exc_value)
                    wx.PostEvent(self.parent, StatusEvent(status=msg,
                        info='error'))
Exemple #9
0
    def set_state(self, state=None, datainfo=None):
        """
        Call-back method for the inversion state reader.
        This method is called when a .prv file is loaded.

        :param state: InversionState object
        :param datainfo: Data1D object [optional]

        """
        try:
            if datainfo.__class__.__name__ == 'list':
                if len(datainfo) >= 1:
                    data = datainfo[0]
                else:
                    data = None
            else:
                data = datainfo
            if data is None:
                msg = "Pr.set_state: datainfo parameter cannot "
                msg += "be None in standalone mode"
                raise RuntimeError, msg

            # Ensuring that plots are coordinated correctly
            t = time.localtime(data.meta_data['prstate'].timestamp)
            time_str = time.strftime("%b %d %H:%M", t)

            # Check that no time stamp is already appended
            max_char = data.meta_data['prstate'].file.find("[")
            if max_char < 0:
                max_char = len(data.meta_data['prstate'].file)

            datainfo.meta_data['prstate'].file = \
                data.meta_data['prstate'].file[0:max_char]\
                + ' [' + time_str + ']'

            data.filename = data.meta_data['prstate'].file
            # TODO:
            #remove this call when state save all information about the gui data
            # such as ID , Group_ID, etc...
            #make self.current_plottable = datainfo directly
            self.current_plottable = self.parent.create_gui_data(data, None)
            self.current_plottable.group_id = data.meta_data['prstate'].file

            # Make sure the user sees the P(r) panel after loading
            #self.parent.set_perspective(self.perspective)
            self.on_perspective(event=None)
            # Load the P(r) results
            #state = self.state_reader.get_state()
            data_dict = {self.current_plottable.id: self.current_plottable}
            self.parent.add_data(data_list=data_dict)
            wx.PostEvent(
                self.parent,
                NewPlotEvent(plot=self.current_plottable,
                             title=self.current_plottable.title))
            self.control_panel.set_state(state)
        except:
            logger.error("prview.set_state: %s" % sys.exc_value)
Exemple #10
0
    def show_data(self, data, label, reset=False, active_ctrl=None):
        """
        Show data read from a file

        :param data: The data to plot (Data1D)
        :param label: What to label the plot. Also used as the plot ID
        :param reset: If True, all other plottables will be cleared
        """
        new_plot = Data1D(data.x, copy.deepcopy(data.y), dy=data.dy)
        group_id = ""
        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
            new_plot.y -= self.corfunc_panel.background
            # Show data on a log(Q)/I scale
            new_plot.ytransform = 'y'
            group_id = GROUP_ID_IQ_DATA
            if label == IQ_EXTRAPOLATED_DATA_LABEL:
                # Show the extrapolation as a curve instead of points
                new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        elif label == TRANSFORM_LABEL1 or label == TRANSFORM_LABEL3:
            new_plot.xaxis("{x}", 'A')
            new_plot.yaxis("{\\Gamma}", '')
            # Show transform on a linear scale
            new_plot.xtransform = 'x'
            new_plot.ytransform = 'y'
            group_id = GROUP_ID_TRANSFORM
            # Show the transformation as a curve instead of points
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        elif label == IDF_LABEL:
            new_plot.xaxis("{x}", 'A')
            new_plot.yaxis("{g_1}", '')
            # Linear scale
            new_plot.xtransform = 'x'
            new_plot.ytransform = 'y'
            group_id = GROUP_ID_IDF
            # Show IDF as a curve instead of points
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        new_plot.id = label
        new_plot.name = label
        new_plot.group_id = group_id
        new_plot.interactive = True
        new_plot.title = group_id.replace('$', '').replace('\\', '')
        wx.PostEvent(self.parent,
                     NewPlotEvent(plot=new_plot, title=new_plot.title,
                        reset=reset))
        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
            wx.CallAfter(self.corfunc_panel.plot_qrange, active=active_ctrl,
                leftdown=True)
        if label == IQ_EXTRAPOLATED_DATA_LABEL:
            # Zoom in to the region we're interested in
            xlim = (min(self.corfunc_panel._extrapolated_data.x), self.corfunc_panel.qmax[1]*1.2)
            wx.CallAfter(wx.PostEvent, self.parent, PlotLimitEvent(id=IQ_DATA_LABEL, group_id=GROUP_ID_IQ_DATA, xlim=xlim))
Exemple #11
0
    def post_data(self, new_sector):
        """ post data averaging in Q"""
        if self.inner_circle.get_radius() < self.outer_circle.get_radius():
            rmin = self.inner_circle.get_radius()
            rmax = self.outer_circle.get_radius()
        else:
            rmin = self.outer_circle.get_radius()
            rmax = self.inner_circle.get_radius()
        if self.right_edge.get_angle() < self.left_edge.get_angle():
            phimin = self.right_edge.get_angle()
            phimax = self.left_edge.get_angle()
        else:
            phimin = self.left_edge.get_angle()
            phimax = self.right_edge.get_angle()
        # print "phimin, phimax, rmin ,rmax",math.degrees(phimin),
        # math.degrees(phimax), rmin ,rmax
        # from sas.sascalc.dataloader.manipulations import SectorQ

        sect = new_sector(r_min=rmin,
                          r_max=rmax,
                          phi_min=phimin,
                          phi_max=phimax)
        sector = sect(self.base.data2D)

        from sas.sasgui.guiframe.dataFitting import Data1D
        if hasattr(sector, "dxl"):
            dxl = sector.dxl
        else:
            dxl = None
        if hasattr(sector, "dxw"):
            dxw = sector.dxw
        else:
            dxw = None
        new_plot = Data1D(x=sector.x,
                          y=sector.y,
                          dy=sector.dy,
                          dxl=dxl,
                          dxw=dxw)
        new_plot.name = str(new_sector.__name__) + \
                        "(" + self.base.data2D.name + ")"
        new_plot.source = self.base.data2D.source
        new_plot.interactive = True
        # print "loader output.detector",output.source
        new_plot.detector = self.base.data2D.detector
        # If the data file does not tell us what the axes are, just assume...
        new_plot.xaxis("\\rm{Q}", 'rad')
        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
        new_plot.group_id = str(new_sector.__name__) + self.base.data2D.name
        self.base.parent.update_theory(data_id=self.base.data2D.id, \
                                       theory=new_plot)
        wx.PostEvent(
            self.base.parent,
            NewPlotEvent(plot=new_plot, title=str(new_sector.__name__)))
Exemple #12
0
    def show_pr(self, out, pr, cov=None):
        """
        """
        # Show P(r)
        x = pylab.arange(0.0, pr.d_max, pr.d_max / self._pr_npts)

        y = np.zeros(len(x))
        dy = np.zeros(len(x))
        y_true = np.zeros(len(x))

        total = 0.0
        pmax = 0.0
        cov2 = np.ascontiguousarray(cov)

        for i in range(len(x)):
            if cov2 is None:
                value = pr.pr(out, x[i])
            else:
                (value, dy[i]) = pr.pr_err(out, cov2, x[i])
            total += value * pr.d_max / len(x)

            # keep track of the maximum P(r) value
            if value > pmax:
                pmax = value

            y[i] = value

        if self._normalize_output:
            y = y / total
            dy = dy / total
        elif self._scale_output_unity:
            y = y / pmax
            dy = dy / pmax

        if cov2 is None:
            new_plot = Data1D(x, y)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        else:
            new_plot = Data1D(x, y, dy=dy)
        new_plot.name = PR_FIT_LABEL
        new_plot.xaxis("\\rm{r}", 'A')
        new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
        new_plot.title = "P(r) fit"
        new_plot.id = PR_FIT_LABEL
        # Make sure that the plot is linear
        new_plot.xtransform = "x"
        new_plot.ytransform = "y"
        new_plot.group_id = GROUP_ID_PR_FIT
        self.parent.update_theory(data_id=self.data_id, theory=new_plot)
        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
                                               title="P(r) fit"))
        return x, pr.d_max
Exemple #13
0
    def _fit_pr(self, evt):
        """
        """
        # Generate P(r) for sphere
        radius = 60.0
        d_max = 2 * radius

        r = pylab.arange(0.01, d_max, d_max / 51.0)
        M = len(r)
        y = np.zeros(M)
        pr_err = np.zeros(M)

        total = 0.0
        for j in range(M):
            value = self.pr_theory(r[j], radius)
            total += value
            y[j] = value
            pr_err[j] = math.sqrt(y[j])

        y = y / total * d_max / len(r)

        # Perform fit
        pr = Invertor()
        pr.d_max = d_max
        pr.alpha = 0
        pr.x = r
        pr.y = y
        pr.err = pr_err
        out, cov = pr.pr_fit()
        for i in range(len(out)):
            print("%g +- %g" % (out[i], math.sqrt(cov[i][i])))

        # Show input P(r)
        title = "Pr"
        new_plot = Data1D(pr.x, pr.y, dy=pr.err)
        new_plot.name = "P_{obs}(r)"
        new_plot.xaxis("\\rm{r}", 'A')
        new_plot.yaxis("\\rm{P(r)} ", "cm^{-3}")
        new_plot.group_id = "P_{obs}(r)"
        new_plot.id = "P_{obs}(r)"
        new_plot.title = title
        self.parent.update_theory(data_id=self.data_id, theory=new_plot)
        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title))

        # Show P(r) fit
        self.show_pr(out, pr)

        # Show I(q) fit
        q = pylab.arange(0.001, 0.1, 0.01 / 51.0)
        self.show_iq(out, pr, q)
Exemple #14
0
    def plot_data(self, scale, background):
        """
        replot the current data if the user enters a new scale or background
        """
        new_plot = scale * self.__data - background
        new_plot.name = self.__data.name
        new_plot.group_id = self.__data.group_id
        new_plot.id = self.__data.id
        new_plot.title = self.__data.title

        # Save data in a state: but seems to never happen
        if new_plot != None:
            self.invariant_panel.state.data = copy.deepcopy(new_plot)
        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
                                               title=new_plot.title))
Exemple #15
0
    def _on_disable_scaling(self, evt):
        """
        Disable P(r) scaling

        :param evt: Menu event

        """
        self._normalize_output = False
        self._scale_output_unity = False
        self.show_pr(self._last_out, self._last_pr, self._last_cov)

        # Now replot the original added data
        for plot in self._added_plots:
            self._added_plots[plot].y = np.copy(self._default_Iq[plot])
            wx.PostEvent(self.parent,
                         NewPlotEvent(plot=self._added_plots[plot],
                                      title=self._added_plots[plot].name,
                                      update=True))
Exemple #16
0
    def set_state(self, state=None, datainfo=None):
        """
        Call-back method for the state reader.
        This method is called when a .inv/.svs file is loaded.

        :param state: State object
        """
        self.temp_state = None
        try:
            if datainfo.__class__.__name__ == 'list':
                data = datainfo[0]
            else:
                data = datainfo
            if data is None:
                msg = "invariant.set_state: datainfo parameter cannot"
                msg += " be None in standalone mode"
                raise RuntimeError(msg)
            # Make sure the user sees the invariant panel after loading
            # self.parent.set_perspective(self.perspective)
            self.on_perspective(event=None)
            name = data.meta_data['invstate'].file
            data.meta_data['invstate'].file = name
            data.name = name
            data.filename = name

            data = self.parent.create_gui_data(data, None)
            self.__data = data
            wx.PostEvent(
                self.parent,
                NewPlotEvent(plot=self.__data,
                             reset=True,
                             title=self.__data.title))
            data_dict = {self.__data.id: self.__data}
            self.parent.add_data(data_list=data_dict)
            # set state
            self.invariant_panel.is_state_data = True

            # Load the invariant states
            self.temp_state = state
            # Requires to have self.__data and self.temp_state  first.
            self.on_set_state_helper(None)

        except Exception as exc:
            logger.error("invariant.set_state: %s" % exc)
Exemple #17
0
    def show_data(self, path=None, data=None, reset=False):
        """
        Show data read from a file

        :param path: file path
        :param reset: if True all other plottables will be cleared

        """
        #if path is not None:
        if data is not None:
            try:
                pr = self._create_file_pr(data)
            except:
                status = "Problem reading data: %s" % sys.exc_value
                wx.PostEvent(self.parent, StatusEvent(status=status))
                raise RuntimeError, status

            # If the file contains nothing, just return
            if pr is None:
                raise RuntimeError, "Loaded data is invalid"

            self.pr = pr

        # Make a plot of I(q) data
        if self.pr.err is None:
            new_plot = Data1D(self.pr.x, self.pr.y)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        else:
            new_plot = Data1D(self.pr.x, self.pr.y, dy=self.pr.err)
        new_plot.name = IQ_DATA_LABEL
        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
        new_plot.interactive = True
        new_plot.group_id = GROUP_ID_IQ_DATA
        new_plot.id = self.data_id
        new_plot.title = "I(q)"
        wx.PostEvent(self.parent,
                     NewPlotEvent(plot=new_plot, title="I(q)", reset=reset))

        self.current_plottable = new_plot
        # Get Q range
        self.control_panel.q_min = min(self.pr.x)
        self.control_panel.q_max = max(self.pr.x)
Exemple #18
0
    def _post_data(self, nbins=None):
        """
        Uses annulus parameters to plot averaged data into 1D data.

        :param nbins: the number of points to plot

        """
        # Data to average
        data = self.base.data2D
        # If we have no data, just return
        if data == None:
            return

        from sas.sascalc.dataloader.manipulations import Ring
        rmin = min(math.fabs(self.inner_circle.get_radius()),
                   math.fabs(self.outer_circle.get_radius()))
        rmax = max(math.fabs(self.inner_circle.get_radius()),
                   math.fabs(self.outer_circle.get_radius()))
        # if the user does not specify the numbers of points to plot
        # the default number will be nbins= 36
        if nbins == None:
            self.nbins = 36
        else:
            self.nbins = nbins
        # # create the data1D Q average of data2D
        sect = Ring(r_min=rmin, r_max=rmax, nbins=self.nbins)
        sector = sect(self.base.data2D)

        if hasattr(sector, "dxl"):
            dxl = sector.dxl
        else:
            dxl = None
        if hasattr(sector, "dxw"):
            dxw = sector.dxw
        else:
            dxw = None
        new_plot = Data1D(x=(sector.x - math.pi) * 180 / math.pi,
                          y=sector.y,
                          dy=sector.dy)
        new_plot.dxl = dxl
        new_plot.dxw = dxw
        new_plot.name = "AnnulusPhi" + "(" + self.base.data2D.name + ")"

        new_plot.source = self.base.data2D.source
        # new_plot.info=self.base.data2D.info
        new_plot.interactive = True
        new_plot.detector = self.base.data2D.detector
        # If the data file does not tell us what the axes are, just assume...
        new_plot.xaxis("\\rm{\phi}", 'degrees')
        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
        if hasattr(data, "scale") and data.scale == 'linear' and \
                self.base.data2D.name.count("Residuals") > 0:
            new_plot.ytransform = 'y'
            new_plot.yaxis("\\rm{Residuals} ", "/")

        new_plot.group_id = "AnnulusPhi" + self.base.data2D.name
        new_plot.id = "AnnulusPhi" + self.base.data2D.name
        new_plot.is_data = True
        new_plot.xtransform = "x"
        new_plot.ytransform = "y"
        self.base.parent.update_theory(data_id=data.id, theory=new_plot)
        wx.PostEvent(self.base.parent,
                     NewPlotEvent(plot=new_plot, title="AnnulusPhi"))
Exemple #19
0
 def clear_data(self):
     wx.PostEvent(self.parent,
         NewPlotEvent(action='delete', group_id=GROUP_ID_TRANSFORM))
     wx.PostEvent(self.parent,
         NewPlotEvent(action='clear', group_id=GROUP_ID_IQ_DATA))
Exemple #20
0
    def post_data(self, new_slab=None, nbins=None, direction=None):
        """
        post data averaging in Qx or Qy given new_slab type

        :param new_slab: slicer that determine with direction to average
        :param nbins: the number of points plotted when averaging
        :param direction: the direction of averaging

        """
        if self.direction is None:
            self.direction = direction

        x_min = -1 * math.fabs(self.vertical_lines.x)
        x_max = math.fabs(self.vertical_lines.x)
        y_min = -1 * math.fabs(self.horizontal_lines.y)
        y_max = math.fabs(self.horizontal_lines.y)

        if nbins is not None:
            self.nbins = nbins
        if self.averager is None:
            if new_slab is None:
                msg = "post data:cannot average , averager is empty"
                raise ValueError(msg)
            self.averager = new_slab
        if self.direction == "X":
            if self.fold:
                x_low = 0
            else:
                x_low = math.fabs(x_min)
            bin_width = (x_max + x_low) / self.nbins
        elif self.direction == "Y":
            if self.fold:
                y_low = 0
            else:
                y_low = math.fabs(y_min)
            bin_width = (y_max + y_low) / self.nbins
        else:
            msg = "post data:no Box Average direction was supplied"
            raise ValueError(msg)
        # # Average data2D given Qx or Qy
        box = self.averager(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max,
                            bin_width=bin_width)
        box.fold = self.fold
        boxavg = box(self.base.data2D)
        # 3 Create Data1D to plot
        if hasattr(boxavg, "dxl"):
            dxl = boxavg.dxl
        else:
            dxl = None
        if hasattr(boxavg, "dxw"):
            dxw = boxavg.dxw
        else:
            dxw = None
        new_plot = Data1D(x=boxavg.x, y=boxavg.y, dy=boxavg.dy)
        new_plot.dxl = dxl
        new_plot.dxw = dxw
        new_plot.name = str(self.averager.__name__) + \
                        "(" + self.base.data2D.name + ")"
        new_plot.source = self.base.data2D.source
        new_plot.interactive = True
        new_plot.detector = self.base.data2D.detector
        # # If the data file does not tell us what the axes are, just assume...
        new_plot.xaxis("\\rm{Q}", "A^{-1}")
        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")

        data = self.base.data2D
        if hasattr(data, "scale") and data.scale == 'linear' and \
                self.base.data2D.name.count("Residuals") > 0:
            new_plot.ytransform = 'y'
            new_plot.yaxis("\\rm{Residuals} ", "/")

        new_plot.group_id = "2daverage" + self.base.data2D.name
        new_plot.id = (self.averager.__name__) + self.base.data2D.name
        new_plot.is_data = True
        self.base.parent.update_theory(data_id=self.base.data2D.id, \
                                       theory=new_plot)
        wx.PostEvent(self.base.parent,
                     NewPlotEvent(plot=new_plot, title=str(self.averager.__name__)))
Exemple #21
0
    def set_data(self, data_list=None):
        """
        receive a list of data and compute invariant
        """
        msg = ""
        data = None
        if data_list is None:
            data_list = []
        if len(data_list) >= 1:
            if len(data_list) == 1:
                data = data_list[0]
            else:
                data_1d_list = []
                data_2d_list = []
                error_msg = ""
                # separate data into data1d and data2d list
                for data in data_list:
                    if data is not None:
                        if issubclass(data.__class__, Data1D):
                            data_1d_list.append(data)
                        else:
                            error_msg += " %s  type %s \n" % (str(data.name),
                                                              str(data.__class__.__name__))
                            data_2d_list.append(data)
                if len(data_2d_list) > 0:
                    msg = "Invariant does not support the following data types:\n"
                    msg += error_msg
                if len(data_1d_list) == 0:
                    wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
                    return
                msg += "Invariant panel does not allow multiple data!\n"
                msg += "Please select one.\n"
                if len(data_list) > 1:
                    from invariant_widgets import DataDialog
                    dlg = DataDialog(data_list=data_1d_list, text=msg)
                    if dlg.ShowModal() == wx.ID_OK:
                        data = dlg.get_data()
                    else:
                        data = None
                    dlg.Destroy()

            if data is None:
                msg += "invariant receives no data. \n"
                wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
                return
            if not issubclass(data.__class__, Data1D):
                msg += "invariant cannot be computed for data of "
                msg += "type %s\n" % (data.__class__.__name__)
                wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
                return
            else:
                wx.PostEvent(self.parent, NewPlotEvent(plot=data, title=data.title))
                try:
                    self.compute_helper(data)
                except:
                    msg = "Invariant Set_data: " + str(sys.exc_value)
                    wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
        else:
            msg = "invariant cannot be computed for data of "
            msg += "type %s" % (data.__class__.__name__)
            wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
Exemple #22
0
    def show_iq(self, out, pr, q=None):
        """
            Display computed I(q)
        """
        qtemp = pr.x
        if q is not None:
            qtemp = q

        # Make a plot
        maxq = -1
        for q_i in qtemp:
            if q_i > maxq:
                maxq = q_i

        minq = 0.001

        # Check for user min/max
        if pr.q_min is not None:
            minq = pr.q_min
        if pr.q_max is not None:
            maxq = pr.q_max

        x = pylab.arange(minq, maxq, maxq / 301.0)
        y = np.zeros(len(x))
        err = np.zeros(len(x))
        for i in range(len(x)):
            value = pr.iq(out, x[i])
            y[i] = value
            try:
                err[i] = math.sqrt(math.fabs(value))
            except:
                err[i] = 1.0
                print("Error getting error", value, x[i])

        new_plot = Data1D(x, y)
        new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
        new_plot.name = IQ_FIT_LABEL
        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
        title = "I(q)"
        new_plot.title = title

        # If we have a group ID, use it
        if 'plot_group_id' in pr.info:
            new_plot.group_id = pr.info["plot_group_id"]
        new_plot.id = IQ_FIT_LABEL
        self.parent.update_theory(data_id=self.data_id, theory=new_plot)

        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title))

        # If we have used slit smearing, plot the smeared I(q) too
        if pr.slit_width > 0 or pr.slit_height > 0:
            x = pylab.arange(minq, maxq, maxq / 301.0)
            y = np.zeros(len(x))
            err = np.zeros(len(x))
            for i in range(len(x)):
                value = pr.iq_smeared(out, x[i])
                y[i] = value
                try:
                    err[i] = math.sqrt(math.fabs(value))
                except:
                    err[i] = 1.0
                    print("Error getting error", value, x[i])

            new_plot = Data1D(x, y)
            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
            new_plot.name = IQ_SMEARED_LABEL
            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
            # If we have a group ID, use it
            if 'plot_group_id' in pr.info:
                new_plot.group_id = pr.info["plot_group_id"]
            new_plot.id = IQ_SMEARED_LABEL
            new_plot.title = title
            self.parent.update_theory(data_id=self.data_id, theory=new_plot)
            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title))