Exemple #1
0
def get_canvas_and_axes():
    'It returns a matplotlib canvas and axes instance'
    fig = Figure()
    fig.clf()
    canvas = FigureCanvas(fig)
    axes = fig.add_subplot(111)
    return canvas, axes, fig
Exemple #2
0
class HistogramEquityWinLoss(FigureCanvas):
    def __init__(self, ui):
        self.ui = proxy(ui)
        self.fig = Figure(dpi=50)
        super(HistogramEquityWinLoss, self).__init__(self.fig)
        # self.drawfigure(template,game_stage,decision)
        self.ui.horizontalLayout_3.insertWidget(1, self)

    def drawfigure(self, p_name, game_stage, decision, l):
        data = l.get_histrogram_data('Template', p_name, game_stage, decision)
        wins = data[0]
        losses = data[1]
        bins = np.linspace(0, 1, 50)

        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(True)  # discards the old graph
        self.axes.set_title('Histogram')
        self.axes.set_xlabel('Equity')
        self.axes.set_ylabel('Number of hands')

        self.axes.hist(wins, bins, alpha=0.5, label='wins', color='g')
        self.axes.hist(losses, bins, alpha=0.5, label='losses', color='r')
        self.axes.legend(loc='upper right')
        self.draw()
class PlotOverview(qtgui.QWidget):
    def __init__(self, db):
        self.db = db
        self.fig = Figure()
        self.canvas = FigureCanvas(self.fig)
        super().__init__()

        lay_v = qtgui.QVBoxLayout()
        self.setLayout(lay_v)

        self.year = qtgui.QComboBox()
        self.year.currentIndexChanged.connect(self.plot)

        lay_h = qtgui.QHBoxLayout()
        lay_h.addWidget(self.year)
        lay_h.addStretch(1)
        lay_v.addLayout(lay_h)
        lay_v.addWidget(self.canvas)

        self.update()

    def update(self):
        constraints = self.db.get_constraints()
        current_year = self.year.currentText()
        self.year.clear()
        years = [y for y in range(min(constraints['start_date']).year, datetime.datetime.now().year + 1)]
        self.year.addItems([str(y) for y in years])
        try:
            self.year.setCurrentIndex(years.index(current_year))
        except ValueError:
            self.year.setCurrentIndex(len(years) - 1)

    def plot(self):
        self.fig.clf()
        ax = self.fig.add_subplot(111)

        worked = np.zeros((12, 34)) + np.nan

        year = int(self.year.currentText())
        for month in range(12):
            for day in range(calendar.monthrange(year, month + 1)[1]):
                date = datetime.date(year, month + 1, day + 1)
                if date < datetime.datetime.now().date():
                    t = self.db.get_worktime(date).total_seconds() / 60.0 - self.db.get_desiredtime(date)
                    worked[month, day] = t
                    ax.text(day, month, re.sub('0(?=[.])', '', ('{:.1f}'.format(t / 60))), ha='center', va='center')

        worked[:, 32:] = np.nansum(worked[:, :31], axis=1, keepdims=True)

        for month in range(12):
            ax.text(32.5, month, re.sub('0(?=[.])', '', ('{:.1f}'.format(worked[month, -1] / 60))), ha='center', va='center')

        ax.imshow(worked, vmin=-12*60, vmax=12*60, interpolation='none', cmap='coolwarm')
        ax.set_xticks(np.arange(31))
        ax.set_yticks(np.arange(12))
        ax.set_xticklabels(1 + np.arange(31))
        ax.set_yticklabels(calendar.month_name[1:])

        self.fig.tight_layout()
        self.canvas.draw()
Exemple #4
0
def plotwo(e,idata,fig=None,mode='pd',clean=True,ang=75):
    '''you can plot according to 'mode':
    pd: psi/delta
    pd-tc: tan(psi),cos(delta)
    eps: dielectric function
    nk: refractive indices
    '''
    from numpy import sqrt,iterable
    if fig==None:
        from matplotlib.figure import Figure
        fig=Figure()
    elif clean: fig.clf()
    from matplotlib.pyplot import subplot
    if iterable(idata[0]): data=idata[0]+1j*idata[1]
    else: data=idata
    if mode[:2]!='pd':data=from_ellips(data.real,data.imag,ang=ang,unit='deg')
    if mode=='nk':data=sqrt(data)
    if mode=='pd_ct':
        from numpy import tan,cos
        data=tan(data.real*pi/180)+1j*cos(data.imag*pi/180)
    for j in range(2):
        axa=subplot(2,1,j+1)
        if clean:
            axa.set_xlabel('energy [eV]')
            if mode=='nk':axa.set_ylabel(['n','k'][j])
            elif mode=='eps':axa.set_ylabel('$\epsilon$ '+['real','imag'][j])
            elif mode=='pd_ct': axa.set_ylabel(['tan $\Psi$','cos $\Delta$'][j])
            elif mode=='pd': axa.set_ylabel(['$\Psi$','$\Delta$'][j])
        if j==0:axa.plot(e,data.real)
        else:axa.plot(e,data.imag)
Exemple #5
0
class MatplotlibCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):

        self.figure = Figure(figsize=(width, height), dpi=dpi)
        super(MatplotlibCanvas, self).__init__(self.figure)

        self.reset()
        self.setParent(parent)
        super(MatplotlibCanvas, self).setSizePolicy(
            QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding
            )
        super(MatplotlibCanvas, self).updateGeometry()

    def reset(self):

        self.figure.clf()
        self.change_layout('1x1')
        self.figure.canvas.draw()

    def change_layout(self, new_layout_string, active_index=1):

        self.figure.clf()
        self.figure_layout = [int(x) for x in new_layout_string.split('x')]
        self.layoutSize = self.figure_layout[0] * self.figure_layout[1]
        self.axes = self.figure.add_subplot(
            self.figure_layout[0], self.figure_layout[1], active_index
            )
        self.figure.canvas.draw()

    def select_subfigure(self, index):

        self.axes = self.figure.add_subplot(
            self.figure_layout[0], self.figure_layout[1], index
            )
Exemple #6
0
class MatplotlibWidget(FigureCanvas):

	def __init__(self, parent=None, width=5, height=4, dpi=100):

		super(MatplotlibWidget, self).__init__(Figure())

#		self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
		self.setParent(parent)
		self.figure = Figure(figsize=(width, height), dpi=dpi) 
		self.canvas = FigureCanvas(self.figure)

#		FigureCanvas.setSizePolicy(self,
#				QtGui.QSizePolicy.Expanding,
#				QtGui.QSizePolicy.Expanding)

		FigureCanvas.updateGeometry(self)
		self.axes = self.figure.add_subplot(111)
		self.setMinimumSize(self.size()*0.3)

		print("---------------------- done")




	def subplot(self,label='111'):
		self.axes=self.figure.add_subplot(label)

	def plot(self,*args,**args2):
		self.axes.plot(*args,**args2)
		self.draw()

	def clf(self):
		self.figure.clf()
class PlotCanvas(wx.Panel, Observable):
    def __init__(self, parent, subplots):
        wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)
        Observable.__init__(self)

        self.fig = Figure()
        self.canvas = FigCanvas(self, -1, self.fig)
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()

        self.initialize_subplots(subplots)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.toolbar, 1, wx.GROW | wx.CENTER)
        self.sizer.Add(self.canvas, 30, wx.GROW)

        self.SetSizer(self.sizer)

    def initialize_subplots(self, subplots):
        self.sub_data_plots = subplots

        for plot in self.sub_data_plots:
            plot.initialize_figure(self.fig)

    def draw(self):
        for plot in self.sub_data_plots:
            plot.prepare_plot_for_draw()
        self.canvas.draw()

    def update_subplots(self, subplots):
        self.fig.clf()
        self.initialize_subplots(subplots)
        self.canvas.draw()
Exemple #8
0
class PlotCanvas(FigureCanvas):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    def __init__(self):
        self.fig = Figure()
        super(PlotCanvas, self).__init__(self.fig)
        self.axes1 = None
        self.axes1b = None
        self.axes2 = None
        self.axes2b = None
        self.init_axes()
        self.placeholder()

    def placeholder(self):
        t__ = np.arange(0.0, 3.0, 0.01)
        s__ = np.sin(2*np.pi*t__)
        self.axes1.plot(t__, s__, 'b-')
        self.axes2.plot(t__, s__, 'r-')
        self.axes1.grid(True, which="both", color="0.65", ls='-')
        self.axes2.grid(True, which="both", color="0.65", ls='-')
        self.axes1.set_xscale('log')
        self.axes1.set_xlim(right=3)
        self.axes2.set_title("Scimpy Speaker Designer!")

    def init_axes(self):
        self.axes1 = self.fig.add_subplot(211)
        self.axes2 = self.fig.add_subplot(212)
        self.axes1b = matplotlib.axes.Axes.twinx(self.axes1)
        self.axes2b = matplotlib.axes.Axes.twinx(self.axes2)

    def clear_axes(self):
        if self.parentWidget().holdplotaction.isChecked() == False:
            self.fig.clf()
            self.init_axes()
def plot():
    fig = Figure()
    i = 0
    while True:
        print i,report_memory(i)
        fig.clf()
        ax = fig.add_axes([0.1,0.1,0.7,0.7])
        ax.plot([1,2,3])
        i += 1
class plotwidget(FigureCanvas):
    def __init__(self, parent, width=12, height=6, dpi=72, projection3d=False):

        #plotdata can be 2d array for image plot or list of 2 1d arrays for x-y plot or 2d array for image plot or list of lists of 2 1D arrays
        self.projection3d=projection3d
        self.fig=Figure(figsize=(width, height), dpi=dpi)
        if projection3d:
            self.axes=self.fig.add_subplot(111, navigate=True, projection='3d')
        else:
            self.axes=self.fig.add_subplot(111, navigate=True)

        self.axes.hold(True)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        #self.parent=parent
        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        #NavigationToolbar(self, parent)
        NavigationToolbar(self, self)

        self.mpl_connect('button_press_event', self.myclick)
        self.clicklist=[]
        self.cbax=None
    
    def redoaxes(self, projection3d=False, onlyifprojectionchanges=True, cbaxkwargs={}):
        if onlyifprojectionchanges and (projection3d==self.projection3d):
            return
        self.fig.clf()
        if projection3d:
            self.axes=self.fig.add_subplot(111, navigate=True, projection='3d')
            self.axes.set_axis_off()
        else:
            self.axes=self.fig.add_subplot(111, navigate=True)
        if not self.cbax is None or len(cbaxkwargs)>0:
            self.createcbax(**cbaxkwargs)

        self.axes.hold(True)
    
    def createcbax(self, axrect=[0.88, 0.1, 0.04, 0.8], left=0, rshift=.01):

        self.fig.subplots_adjust(left=left, right=axrect[0]-rshift)
        self.cbax=self.fig.add_axes(axrect)

        
    def myclick(self, event):
        if not (event.xdata is None or event.ydata is None):
            arrayxy=[event.xdata, event.ydata]
            print 'clicked on image: array indeces ', arrayxy, ' using button', event.button
            self.clicklist+=[arrayxy]
            self.emit(SIGNAL("genericclickonplot"), [event.xdata, event.ydata, event.button, event.inaxes])
Exemple #11
0
class Plotter(FigureCanvas):

    def __init__(self, parent=None):
        dpi = 100
        self.plot_options = {"linewidth":3,"color":"k"}
        self.plot_options_axes = {"linewidth":2, "color":'0.7'} #,'alpha':0.7}
        self.fig = Figure(figsize=(16,9), dpi=dpi)
        
        # x=np.arange(-10,10,0.1)
        # y=np.sin(x)
        # self.make_graph(x,y)

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
    
    def save(self):
        self.fig.savefig('plot.png')    

    def make_graph(self, x, y,*args):
        """
        This just makes a very simple plot.
        """
        # try:
        #     a = args[0]
        # except IndexError:
        #     a = 1.0
        # y = a*y
        self.fig.clf()
        ax1 = self.fig.add_subplot(111)
        # ax1.hold(False)
        x_space = np.absolute(x[0] - x[1])
        y_max, y_min = np.amax(y), np.amin(y)
        y_space = np.absolute(y_max - y_min)
        ax1.set_xlim((x[0]-5.0*x_space,x[-1]+5.0*x_space))
        ax1.set_ylim([y_min-0.25*y_space, y_max+0.25*y_space])
        ax1.grid()
        ax1.set_xlabel(r"$x$")
        ax1.set_ylabel(r"$f(x)$")
        # ax1.set_title(r"Graph of $f(x)$")
        x_axis = np.linspace(x[0]-5.0*x_space,x[-1]+5.0*x_space,x.size)
        ax1.plot(x_axis, np.zeros(x.size), **self.plot_options_axes)
        ax1.plot(np.zeros(x.size), np.linspace(y_min-0.25*y_space, y_max+0.25*y_space,x.size),**self.plot_options_axes)
        ax1.plot(x, y, **self.plot_options)
Exemple #12
0
class PiePlotter(FigureCanvas):
    def __init__(self, ui, winnerCardTypeList):
        self.ui = proxy(ui)
        self.fig = Figure(dpi=50)
        super(PiePlotter, self).__init__(self.fig)
        # self.drawfigure(winnerCardTypeList)
        self.ui.vLayout4.insertWidget(1, self)

    def drawfigure(self, winnerCardTypeList):
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(False)
        self.axes.pie([float(v) for v in winnerCardTypeList.values()],
                      labels=[k for k in winnerCardTypeList.keys()], autopct=None)
        self.axes.set_title('Winning probabilities')
        self.draw()
Exemple #13
0
def plot(request, image_format):
    plot_filepath = os.path.join(settings.CACHE_ROOT, "kicker", "kicker." + image_format)
    try:
        timestamps = [models.KickerNumber.objects.latest().timestamp]
    except models.KickerNumber.DoesNotExist:
        timestamps = []
    if is_update_necessary(plot_filepath, timestamps=timestamps):
        eligible_players = [entry[0] for entry in get_eligible_players()]
        hundred_days_ago = datetime.datetime.now() - datetime.timedelta(days=100)
        plot_data = []
        for player in eligible_players:
            x_values, y_values = [], []
            latest_day = None
            kicker_numbers = list(models.KickerNumber.objects.filter(player=player, timestamp__gt=hundred_days_ago))
            for i, kicker_number in enumerate(kicker_numbers):
                if i == len(kicker_numbers) - 1 or \
                        kicker_numbers[i + 1].timestamp.toordinal() != kicker_number.timestamp.toordinal():
                    x_values.append(kicker_number.timestamp)
                    y_values.append(kicker_number.number)
            plot_data.append((x_values, y_values, player.kicker_user_details.nickname or player.username))
        if image_format == "png":
            figsize, position, legend_loc, legend_bbox, ncol = (8, 12), (0.1, 0.5, 0.8, 0.45), "upper center", [0.5, -0.1], 3
        else:
            figsize, position, legend_loc, legend_bbox, ncol = (10, 7), (0.1, 0.1, 0.6, 0.8), "best", [1, 1], 1
        figure = Figure(frameon=False, figsize=figsize)
        canvas = FigureCanvasAgg(figure)
        axes = figure.add_subplot(111)
        axes.set_position(position)
        for line in plot_data:
            if len(line[0]) == 1:
                line[0].append(line[0][0] - datetime.timedelta(days=1))
                line[1].append(line[1][0])
            axes.plot(line[0], line[1], label=line[2], linewidth=2)
        months_locator = matplotlib.dates.MonthLocator()
        axes.xaxis.set_major_locator(months_locator)
        months_formatter = matplotlib.dates.DateFormatter('%b')
        axes.xaxis.set_major_formatter(months_formatter)
        axes.grid(True)
        axes.legend(loc=legend_loc, bbox_to_anchor=legend_bbox, ncol=ncol, shadow=True)
        mkdirs(plot_filepath)
        canvas.print_figure(plot_filepath)
        figure.clf()
        storage_changed.send(models.KickerNumber)
    if not os.path.exists(plot_filepath):
        raise Http404("No kicker data available.")
    return static_file_response(plot_filepath, "kicker.pdf" if image_format == "pdf" else None)
class ExporterBackend(Backend):
    def __init__(self, model, file_format):
        super(ExporterBackend, self).__init__(model)
        self._figure = Figure()
        self._file_format = file_format

    def render(self, filename_base):
        FigureCanvasAgg(self._figure)
        for i, plot in enumerate(self._model.get_plots()):
            self._figure.clf()
            backend = InteractiveBackend(self._model, self._figure)
            title = plot.get_title()
            if title == '':
                title = 'unnamed_plot_' + str(i)
            filename = '{}_{}.{}'.format(
                filename_base, title, self._file_format)
            backend.render(filename, i)
            self._figure.savefig(filename)
Exemple #15
0
class ScatterPlot(FigureCanvas):
    def __init__(self, ui):
        self.ui = proxy(ui)
        self.fig = Figure()
        super(ScatterPlot, self).__init__(self.fig)
        self.ui.horizontalLayout_4.insertWidget(1, self)

    def drawfigure(self, p_name, game_stage, decision, l, smallBlind, bigBlind, maxValue, minEquityBet, max_X,
                   maxEquityBet,
                   power):
        wins, losses = l.get_scatterplot_data('Template', p_name, game_stage, decision)
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(True)
        self.axes.set_title('Wins and Losses')
        self.axes.set_xlabel('Equity')
        self.axes.set_ylabel('Minimum required call')

        try:
            self.axes.set_ylim(0, max(wins['minCall'].tolist() + losses['minCall'].tolist()) * 1.1)
        except:
            self.axes.set_ylim(0, 1)
        self.axes.set_xlim(0, 1)

        # self.axes.set_xlim(.5, .8)
        # self.axes.set_ylim(0, .2)

        area = np.pi * (50 * wins['FinalFundsChange'])  # 0 to 15 point radiuses
        green_dots = self.axes.scatter(x=wins['equity'].tolist(), y=wins['minCall'], s=area, c='green', alpha=0.5)

        area = np.pi * (50 * abs(losses['FinalFundsChange']))
        red_dots = self.axes.scatter(x=losses['equity'].tolist(), y=losses['minCall'], s=area, c='red', alpha=0.5)

        self.axes.legend((green_dots, red_dots),
                         ('Wins', 'Losses'), loc=2)

        x2 = np.linspace(0, 1, 100)
        d2 = Curvefitting(x2, 0, 0, maxValue, minEquityBet, maxEquityBet, max_X, power)
        self.line3, = self.axes.plot(np.arange(0, 1, 0.01), d2.y[-100:],
                                     'r-')  # Returns a tuple of line objects, thus the comma

        self.axes.grid()
        self.draw()
Exemple #16
0
class Canvas(FigureCanvas):
    """Matplotlib Figure widget to display CPU utilization"""
    def __init__(self, parent):
        self.parent = parent
        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)
        self.cnt = 0
        
        
    def newAxes(self, hstart, hend, vstart, vend):
        self.fig.clf()
        self.ax = self.fig.add_subplot(111)
        print hstart, hend, vstart, vend
        self.im = self.ax.imshow(self.data, extent=[hstart, hend, vstart, vend], origin='lower', interpolation='nearest')#, cmap=cm.hot)#gist_heat)
        self.setupSelector()


    def updateData(self, data, width, height):
        try:
            self.data = np.reshape(data, (height, width))
        except ValueError:
            pass # happens if update data is called before the new width and height are calculated upon changing the image size

        self.im.set_data(self.data)
        self.im.axes.figure.canvas.draw()
   
    def onselect(self, eclick, erelease):
        'eclick and erelease are matplotlib events at press and release'
        print ' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata)
        print ' endposition   : (%f, %f)' % (erelease.xdata, erelease.ydata)
          
        if (eclick.ydata > erelease.ydata):
            eclick.ydata, erelease.ydata= erelease.ydata, eclick.ydata
        if (eclick.xdata > erelease.xdata):
            eclick.xdata, erelease.xdata = erelease.xdata, eclick.xdata
        
        # data sent will always have the eclick point be the left point and the erelease point be the right point
        self.parent.parent.changeImageRegion(int(eclick.xdata), int(eclick.ydata), int(erelease.xdata), int(erelease.ydata))
    
    def setupSelector(self):
        self.rectSelect = RectangleSelector(self.ax, self.onselect, drawtype='box', rectprops = dict(facecolor='red', edgecolor = 'white',
                 alpha=0.5, fill=False))   
class PlotPunchcard(FigureCanvas):
    def __init__(self, db):
        self.db = db
        self.fig = Figure()
        super().__init__(self.fig)

    def plot(self):
        events = self.db.get_events()
        days = np.array([e[0].weekday() for e in events])
        times = np.array([e[0].time() for e in events])
        types = np.array([e[1] for e in events])

        here = np.zeros((7, 24 * 60))
        for a, b, c, d in zip(times[types=='check-in'], times[types=='check-out'], days[types=='check-in'], days[types=='check-out']):

            if c == d:
                a = a.hour * 60.0 + a.minute
                b = b.hour * 60.0 + b.minute

                here[c][a:b] += 1
            else:
                raise NotImplementedError("Punchcard: Checkout not on the same day is not supported")

        here = here.reshape(7, -1, 15).mean(-1)
        here /= np.max(here)

        self.fig.clf()
        ax = self.fig.add_subplot(111)

        for i, h in enumerate(here):
            ax.bar(np.arange(len(h)), h, width=1.0, bottom=i*2 - h*0.5)

        l = np.linspace(0, len(h), 7)
        ax.set_xticks(l)
        ax.set_xticklabels(['{:02d}:00'.format(int(i * 24 / len(h))) for i in l])
        ax.set_xlim(0, len(h))

        ax.set_yticks([0, 2, 4, 6, 8, 10, 12])
        ax.set_yticklabels(['Monday', 'Tuesday', 'Wednesday', 'Thirsday', 'Friday', 'Saturday', 'Sunday'])

        ax.set_ylim(-1, 13)
        ax.invert_yaxis()
Exemple #18
0
class Figure():
    """ WxAgg version of the Matplotlib figure.
        Pass it a wx.Panel as a parent, and then you can
        access axes, etc.
        I tried directly inheriting from MatplotlibFigure but
        I kept getting an error about the axes not being iterable...
    """
    def __init__( self, parent, **kwargs ):
        self.fig = MatplotlibFigure( facecolor=(0.94117,0.92156,0.88627), figsize=(4,4) )
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)
        
        if 'xlabel' in kwargs.keys():
            self.axes.set_xlabel( kwargs['xlabel'] )

        if 'ylabel' in kwargs.keys():
            self.axes.set_ylabel( kwargs['ylabel'] )

        self.canvas = MatplotlibFigureCanvas( parent=parent, id=wx.ID_ANY,
                        figure=self.fig )
Exemple #19
0
def marker_image(path, size, trans,
                 edgecolor='k', facecolor = 'b',
                 edgewidth= 1.0):


   
   fig = Figure(figsize=((size*2+1)/72., (size*2+1)/72.), dpi = 72)


   #fig.set_edgecolor([1,1,1,0])
   #fig.set_facecolor([1,1,1,0])
   fig.set_edgecolor([0,0,0,0])
   fig.set_facecolor([0,0,0,0])
   fig.patch.set_alpha(0.0)   
   fig.clf()
   fig.frameon = False
   ax = fig.add_subplot(111)
   ax.set_position((0,0,1,1))      
   ed=ax.transAxes.transform([(0,0), (1,1)])

   path = trans.transform_path(path)
   patch = patches.PathPatch(path, facecolor=facecolor, edgecolor=edgecolor,
                             lw=edgewidth)
   ax.patch.set_facecolor([0,0,0,0])
   ax.patch.set_edgecolor([0,0,0,0])
   ax.patch.set_alpha(0.0)
   ax.add_patch(patch)
   ax.set_xlim(-1,1)
   ax.set_ylim(-1,1)
   ax.tick_params(length=0)

   ax.set_axis_off()
   canvas = FigureCanvasAgg(fig)
   buff, size = canvas.print_to_buffer()
   
   im =  np.fromstring(buff, np.uint8).reshape(size[1], size[0], -1)
   #idx = np.where(im[:,:,-1] == 0)
   #im[:,:,0][idx] = 0
   #im[:,:,1][idx] = 0
   #im[:,:,2][idx] = 0   
   return im
Exemple #20
0
    def render_to_response(self, context):
        """Create a png image and write the control chart image to it"""

        fig = Figure(dpi=72, facecolor="white")
        dpi = fig.get_dpi()
        fig.set_size_inches(
            self.get_number_from_request("width", 700) / dpi,
            self.get_number_from_request("height", 480) / dpi,
        )
        canvas = FigureCanvas(fig)
        dates, data = [], []

        if context["data"] and context["data"].values():
            name, points = context["data"].items()[0]
            dates, data = zip(*[(ti["date"], ti["value"]) for ti in points])

        n_baseline_subgroups = self.get_number_from_request("n_baseline_subgroups", 2, dtype=int)
        n_baseline_subgroups = max(2, n_baseline_subgroups)

        subgroup_size = self.get_number_from_request("subgroup_size", 2, dtype=int)
        if not (1 < subgroup_size < 100):
            subgroup_size = 1

        include_fit = self.request.GET.get("fit_data", "") == "true"

        response = HttpResponse(mimetype="image/png")
        if n_baseline_subgroups < 1 or n_baseline_subgroups > len(data) / subgroup_size:
            fig.text(0.1, 0.9, "Not enough data for control chart", fontsize=20)
            canvas.print_png(response)
        else:
            try:
                control_chart.display(fig, numpy.array(data), subgroup_size, n_baseline_subgroups, fit=include_fit, dates=dates)
                fig.autofmt_xdate()
                canvas.print_png(response)
            except (RuntimeError, OverflowError) as e:  # pragma: nocover
                fig.clf()
                msg = "There was a problem generating your control chart:\n%s" % str(e)
                fig.text(0.1, 0.9, "\n".join(textwrap.wrap(msg, 40)), fontsize=12)
                canvas.print_png(response)

        return response
Exemple #21
0
class FundsChangePlot(FigureCanvas):
    def __init__(self, ui_analyser):
        self.ui_analyser = proxy(ui_analyser)
        self.fig = Figure(dpi=50)
        super(FundsChangePlot, self).__init__(self.fig)
        self.drawfigure()
        self.ui_analyser.vLayout_fundschange.insertWidget(1, self)

    def drawfigure(self):
        LogFilename = 'log'
        L = GameLogger(LogFilename)
        p_name = str(self.ui_analyser.combobox_strategy.currentText())
        data = L.get_fundschange_chart(p_name)
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(False)  # discards the old graph
        self.axes.set_title('My Funds')
        self.axes.set_xlabel('Time')
        self.axes.set_ylabel('$')
        self.axes.plot(data, '-')  # plot data
        self.draw()
Exemple #22
0
class FundsPlotter(FigureCanvas):
    def __init__(self, ui, p):
        self.p = p
        self.ui = proxy(ui)
        self.fig = Figure(dpi=50)
        super(FundsPlotter, self).__init__(self.fig)
        # self.drawfigure()
        self.ui.vLayout.insertWidget(1, self)

    def drawfigure(self, L):
        Strategy = str(self.p.current_strategy)
        data = L.get_fundschange_chart(Strategy)
        data = np.cumsum(data)
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(False)  # discards the old graph
        self.axes.set_title('My Funds')
        self.axes.set_xlabel('Time')
        self.axes.set_ylabel('$')
        self.axes.plot(data, '-')  # plot data
        self.draw()
Exemple #23
0
class WavePanel:

    def __init__(self, controller, parent):
        self.parent = parent
        self.controller = controller
        self.container = Frame(self.parent, width = 800, height=300)
        w = Label(self.container, text="Select sample number")
        w.grid(row=0, column=0)
        self.sampVal = StringVar(self.container)
        self.sampSelect = OptionMenu(self.container, self.sampVal, *range(0, 16), command=self.loadSample)
        self.sampSelect.grid(row=0, column=1)

        self.sample = None
        self.figure = Figure(figsize=(5,1), dpi=120)

        self.canvas = FigureCanvasTkAgg(self.figure, master=self.container)
        self.canvas._tkcanvas.config(background="white")

        self.canvas.get_tk_widget().grid(row=2, column = 0, columnspan=2)

        self.container.pack()


    def loadSample(self, val):
        print int(self.sampVal.get())
        sample = self.controller.samples[int(self.sampVal.get())]
        sample = sample.getSample()
        if sample is None:
            print "No sample"
            return
        self.sample = sample
        self.figure.clf()
        #self.figure.tight_layout()
        self.plot = self.figure.add_subplot(111, frameon=False)
        self.plot.axis('off')
        t = sample.getSoundPoints()
        #print t
        self.plot.plot(t)
        self.canvas.show()
        self.canvas.draw()
Exemple #24
0
class CameraCanvas(FigureCanvas):
    """Matplotlib Figure widget to display CPU utilization"""
    def __init__(self, parent):
        self.parent = parent
        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)
      
        
    def newAxes(self, data, hstart, hend, vstart, vend):
        self.fig.clf()
        self.ax = self.fig.add_subplot(111)
        print hstart, hend, vstart, vend
        self.im = self.ax.imshow(data, extent=[hstart, hend, vstart, vend], origin='lower', interpolation='nearest')#, cmap=cm.hot)#gist_heat)


    def updateData(self, data, width, height):
        try:
            self.data = np.reshape(data, (height, width))
        except ValueError:
            pass # happens if update data is called before the new width and height are calculated upon changing the image size

        self.im.set_data(self.data)
        self.im.axes.figure.canvas.draw()
Exemple #25
0
class DepthChart(tk.Frame):
    def __init__(self, parent, controller, **kwargs):
        tk.Frame.__init__(self, parent, **kwargs)
        self.data = DepthData()
        self.fig = None
        self.canvas = None

    def update_blockchain_data(self, blockchain_data):
        self.data.update_blockchain_data(blockchain_data)
        pool_price = self.data.get_pool_price()
        prices = []
        prices.extend(
            [pr.price for pr in blockchain_data['market_orderbook']['asks']])
        self.pricewindow = [pool_price * (1 / 2), pool_price * (3 / 2)]
        self.draw()

    def draw(self):

        pool_sell_curve = self.data.get_pool_sells(*self.pricewindow)
        pool_buy_curve = self.data.get_pool_buys(*self.pricewindow)
        book_sell_curve = self.data.get_book_sells(*self.pricewindow)
        book_buy_curve = self.data.get_book_buys(*self.pricewindow)

        if self.fig is None:
            self.fig = Figure(figsize=(7, 4.5))
        self.fig.clf()
        self.fig.patch.set_facecolor("burlywood")
        a = self.fig.gca()
        a.set_facecolor("ghostwhite")

        attr = {
            "book": {
                "buy": {
                    "line": {
                        "color": "darkgreen",
                    },
                    "area": {
                        "color": "darkgreen",
                        "alpha": 0.25,
                    },
                },
                "sell": {
                    "line": {
                        "color": "darkred",
                    },
                    "area": {
                        "color": "darkred",
                        "alpha": 0.25,
                    },
                },
            },
            "pool": {
                "buy": {
                    "line": {
                        "color": "green",
                    },
                    "area": {
                        "color": "green",
                        "alpha": 0.25,
                    },
                },
                "sell": {
                    "line": {
                        "color": "red",
                    },
                    "area": {
                        "color": "red",
                        "alpha": 0.25,
                    },
                },
            },
        }

        a.plot(pool_sell_curve['x'], pool_sell_curve['y'],
               **attr['pool']['sell']['line'])
        a.plot(pool_buy_curve['x'], pool_buy_curve['y'],
               **attr['pool']['buy']['line'])
        a.fill_between(pool_sell_curve['x'], pool_sell_curve['y'],
                       **attr['pool']['sell']['area'])
        a.fill_between(pool_buy_curve['x'], pool_buy_curve['y'],
                       **attr['pool']['buy']['area'])

        a.plot(book_sell_curve['x'], book_sell_curve['y'],
               **attr['book']['sell']['line'])
        a.plot(book_buy_curve['x'], book_buy_curve['y'],
               **attr['book']['buy']['line'])
        a.fill_between(book_sell_curve['x'], book_sell_curve['y'],
                       **attr['book']['sell']['area'])
        a.fill_between(book_buy_curve['x'], book_buy_curve['y'],
                       **attr['book']['buy']['area'])

        a.set_xlim(self.pricewindow)
        a.set_ylim(bottom=0)
        a.ticklabel_format(style='plain')

        a.set_title(self.data.pool.market().get_string(separator=":"),
                    loc="left")
        a.set_ylabel("Depth (%s)" % (self.data.pool.asset_y()['symbol']))
        a.set_xlabel("Price (%s/%s)" % (self.data.pool.asset_x()['symbol'],
                                        self.data.pool.asset_y()['symbol']))

        if self.canvas is None:
            self.canvas = FigureCanvasTkAgg(self.fig, self)
            self.canvas.get_tk_widget().pack(side=tk.BOTTOM,
                                             fill=tk.BOTH,
                                             expand=True)
        self.canvas.draw()
Exemple #26
0
class TRACE_ALLCHAN_WINDOW(Tk.Frame):
  """
  This window displays a live ADC redout
  """
  
  def __init__(self, master=None, packedHighSpeed=False):
    self.maxtraces = 5
    self.selChan = 0

    Tk.Frame.__init__(self,master) # hack to make work in python2

    self.pack()
    self.figure = Figure(figsize=(15,7), dpi=100, facecolor='white')
       
    self.canvas = FigureCanvas(self.figure, master=self)
    self.canvas.show()
    self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
    self.toolbar = NaviationToolbar(self.canvas,self)
    self.toolbar.update()
    self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

    self.pauseButton = Tk.Button(self,text="Pause",command=self.pause)
    self.pauseButton.pack(side=Tk.LEFT)

    self.playButton = Tk.Button(self,text="Play",command=self.play,state=Tk.DISABLED)
    self.playButton.pack(side=Tk.LEFT)

    self.prevButton = Tk.Button(self,text="Previous Trace",command=self.prevTrace,state=Tk.DISABLED)
    self.prevButton.pack(side=Tk.LEFT)

    self.nextButton = Tk.Button(self,text="Next Trace",command=self.nextTrace,state=Tk.DISABLED)
    self.nextButton.pack(side=Tk.LEFT)

    self.packedHighSpeed = packedHighSpeed
    self.femb = None
    self.iTrace = -1
    self.traces = []
    self.timestamps = []

    self.reset()

  def reset(self,iTrace=None):
    self.femb = FEMB_UDP()
    self.femb_eh = FPGA_UDP()
    self.figure.clf()
    self.subgs = [None]*16
    self.ax = [None]*16
    self.plot = [None]*16

    # 4x4 grid, one cell per channel
    self.gs  = gridspec.GridSpec(4,4)
    self.gs.update(wspace=0.2,hspace=0.2)
    # 1 plots per channel
    for row in range(4):
      for col in range(4):        
        self.subgs[col+4*row] = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=self.gs[col+4*row],hspace=0.0)
        self.ax[col+4*row] = self.figure.add_subplot(self.subgs[col+4*row][0])
        self.ax[col+4*row].tick_params(axis='x', colors='black',labelsize='medium')
        self.ax[col+4*row].tick_params(axis='y', colors='black',labelsize='smaller')

    if iTrace is None:
        self.ani = animation.FuncAnimation(self.figure, self.plotData, interval=1000, blit=True)
    else:
        self.plotData(0,iTrace)
    self.canvas.draw()

  def pause(self):
    self.ani.event_source.stop()
    self.reset(self.iTrace)
    self.pauseButton['state'] = Tk.DISABLED
    self.playButton['state'] = Tk.NORMAL
    self.prevButton['state'] = Tk.NORMAL
    self.nextButton['state'] = Tk.DISABLED

  def play(self):
    self.ani.event_source.start()
    self.pauseButton['state'] = Tk.NORMAL
    self.playButton['state'] = Tk.DISABLED
    self.prevButton['state'] = Tk.DISABLED
    self.nextButton['state'] = Tk.DISABLED

  def prevTrace(self):
    self.iTrace -= 1
    self.reset(self.iTrace)
    if self.iTrace < 1:
        self.prevButton['state'] = Tk.DISABLED
    else:
        self.prevButton['state'] = Tk.NORMAL
    if self.iTrace >= len(self.traces) - 1:
        self.nextButton['state'] = Tk.DISABLED
    else:
        self.nextButton['state'] = Tk.NORMAL

  def nextTrace(self):
    self.iTrace += 1
    self.reset(self.iTrace)
    if self.iTrace < 1:
        self.prevButton['state'] = Tk.DISABLED
    else:
        self.prevButton['state'] = Tk.NORMAL
    if self.iTrace >= len(self.traces) - 1:
        self.nextButton['state'] = Tk.DISABLED
    else:
        self.nextButton['state'] = Tk.NORMAL

  def plotData(self,iFrame,iTrace=None):
    for a in self.ax:
        a.cla()
        a.locator_params(tight=True, nbins=3)

    # In case no data, return an empty plot
    self.plot[0] = self.ax[0].plot()

    for r in range(4):
        for c in range(4):
            t, adc, thistimestamp = self.getTraceAndFFT(iTrace=iTrace,chan=c+4*r)
            if not (t is None) and not (adc is None):
                self.plot[c+4*r] = self.ax[c+4*r].plot(t,adc)
                if c+4*r < 12: self.ax[c+4*r].set_xticklabels([])
    self.figure.text(0.5,0.02,'Time [us]',ha='center',color='black',fontsize='25.0',weight='bold')
    self.figure.text(0.08,0.5,'ADC',ha='center',rotation=90,color='black',fontsize='25.0',weight='bold') 

    if not (thistimestamp is None):
        self.figure.suptitle(thistimestamp.replace(microsecond=0).isoformat(" "))
    self.canvas.draw()
    return self.plot[0]

  def getTraceAndFFT(self,iTrace=None,chan=0):
    """
    Gets trace from FEMB and returns 4 1D arrays:
        times, ADC counts
    """
    data = None
    timestamp = None
    if iTrace is None:
        #data = self.femb.get_data(100)
        data = self.femb_eh.get_data_packets(data_type = "int", num = 1, header = False)
        timestamp = datetime.datetime.now()
        self.traces.append(data)
        self.timestamps.append(timestamp)
        if len(self.traces) > self.maxtraces:
            self.traces.pop(0)
            self.timestamps.pop(0)
        self.iTrace = len(self.traces) - 1
    else:
        data = self.traces[iTrace]
        timestamp = self.timestamps[iTrace]
    if data == None:
        return None, None, None, None, None
    if len(data ) == 0:
        return None, None, None, None, None

    # something wrong is happening within WRITE_ROOT_TREE...
    #chSamples = None
    chSamples = []
    """
    if self.packedHighSpeed:
      chSamples = WRITE_ROOT_TREE.convertHighSpeedPacked(None, data)
    else:
      chSamples = WRITE_ROOT_TREE.convertHighSpeedSimple(None, data)
    """

    chSamples = WRITE_ROOT_TREE.convertHighSpeedPacked(None, data)

    xpoint = []
    ypoint = []
    num = 0
    for samp in chSamples[chan]:
      xpoint.append(num*0.5)
      ypoint.append(samp)
      num = num + 1
      
    xarr = np.array(xpoint)
    yarr = np.array(ypoint)
    
    return xarr, yarr, timestamp
def main():
    scanfile = sys.argv[1]
    plotem = "False"
    #plotem can have values missing=False, AllBx, TenBx, VersusBX, or combinations like AllVersusBx
    try:
        z = sys.argv[2]
        plotem = z
    except:
        plotem = "False"
    output = open("linearityOverPCC.csv", "a")
    fillreport = pd.read_csv(
        '/nfshome0/stickzh/VdMFramework/Run2FillReport.csv',
        index_col='fill',
        sep='\t')
    fields = scanfile.split('/')
    filename = fields[len(fields) - 1]
    fill = filename[0:4]
    print "fill ", fill
    detectors = ["PLT", "HFET", "HFOC", "BCM1F"]
    scanpoints, pccBunches, pcclumi, pcclumiErr = getRates(
        "PCC", fill, scanfile)
    scanpoints, pltBunches, pltlumi, pltlumiErr = getRates(
        "PLT", fill, scanfile)
    scanpoints, hfetBunches, hfetlumi, hfetlumiErr = getRates(
        "HFET", fill, scanfile)
    scanpoints, hfocBunches, hfoclumi, hfoclumiErr = getRates(
        "HFOC", fill, scanfile)
    scanpoints, pcvdBunches, pcvdlumi, pcvdlumiErr = getRates(
        "BCM1F", fill, scanfile)
    #plotem=False
    leadgap = 1
    pltresults = ""
    hfetresults = ""
    hfocresults = ""
    pcvdresults = ""

    figdir = "/scratch/stickzh/linearity/" + filename
    if not os.path.exists(figdir):
        os.makedirs(figdir)

    print "pccBunches", pccBunches
    for det in detectors:
        pp = PdfPages(figdir + '/' + det + '_overPCC.pdf')
        leading = []
        train = []
        trainwgt = []
        leadingwgt = []
        leadingicept = []
        trainicept = []
        lastbx = 0
        grads = []
        graderr = []
        bxx = []
        gap = []
        nbxDone = 0

        for i, bx in enumerate(pccBunches):
            #if bx<570 or bx>625:
            #	continue
            #py.figure(figsize=(8,5))
            ratio = []
            ratioErr = []
            x = []

            for j in range(0, len(pcclumi[i])):
                try:
                    #print pcclumi[i][j]
                    if pcclumi[i][j] > 1.0:
                        b = pcclumiErr[i][j] / pcclumi[i][j]
                        if det == "HFET":
                            r = hfetlumi[i][j] / pcclumi[i][j]
                            a = hfetlumiErr[i][j] / hfetlumi[i][j]
                        elif det == "HFOC":
                            r = hfoclumi[i][j] / pcclumi[i][j]
                            a = hfoclumiErr[i][j] / hfoclumi[i][j]
                        elif det == "PLT":
                            if (fill == '7358') and (j == 0):
                                continue
                            r = pltlumi[i][j] / pcclumi[i][j]
                            a = pltlumiErr[i][j] / pltlumi[i][j]
                            if abs(pltlumiErr[i][j]) < 0.0001 or abs(
                                    pltlumi[i][j]) < 0.001:
                                continue
                        elif det == "BCM1F":
                            r = pcvdlumi[i][j] / pcclumi[i][j]
                            a = pcvdlumiErr[i][j] / pcvdlumi[i][j]
                            if abs(pcvdlumiErr[i][j]) < 0.0001 or abs(
                                    pcvdlumi[i][j]) < 0.001:
                                continue
                        rerr = math.sqrt(r * r * (a * a + b * b))
                        ratio.append(r)
                        ratioErr.append(rerr)
                        x.append(pcclumi[i][j])

                except Exception as e:
                    print(e)
                #print 'failed for BX ',bx
            #print bx,len(hfoclumi[i]),len(ratio)
            if len(x) == len(ratio) and len(x) > 5:
                gradient, intercept, r_value, p_value, std_err = stats.linregress(
                    x, ratio)
                if ("Ten" in plotem and nbxDone < 10) or ("All" in plotem):
                    nbxDone = nbxDone + 1
                    fig = Figure()
                    canvas = FigureCanvas(fig)
                    ax = fig.add_subplot(111)
                    ax.errorbar(x, ratio, yerr=ratioErr, marker='s', fmt='o')
                    xmin, xmax = ax.get_xlim()
                    ymin, ymax = ax.get_ylim()
                    ax.grid()
                    ax.plot([xmin, xmax], [
                        intercept + gradient * xmin,
                        intercept + gradient * xmax
                    ],
                            color='r',
                            linestyle='-',
                            linewidth=3)
                    ax.text(xmin + (xmax - xmin) * .75,
                            ymin + (ymax - ymin) * .2,
                            "slope = " + str(round(gradient * 100, 2)) + "%" +
                            "\n    +- " + str(round(std_err * 100, 2)),
                            color="r",
                            bbox=dict(facecolor='white', alpha=1.0))
                    ax.set_ylabel(det + ' SBIL/PCC SBIL')
                    ax.set_title('SBIL ' + det + '/PCC fill ' + str(fill) +
                                 '  BX ' + str(bx))
                    ax.set_xlabel('PCC SBIL')
                    pp.savefig(fig)
                    fig.clf()
                    py.close(fig)
                    #print det,bx,len(x),round(gradient*100,3),round(std_err*100,3),xmin,xmax
                gap.append(bx - lastbx)
                if (bx - lastbx) == 1:
                    train.append(gradient)
                    trainwgt.append(1 / (std_err * std_err))
                    trainicept.append(intercept)
                    #print "Train\t",det,"\t",bx,"\t",bx-lastbx,"\t",gradient,"\t",std_err

                elif (bx - lastbx) > leadgap:
                    leading.append(gradient)
                    #print "Leading\t",det,"\t",bx,"\t",bx-lastbx,"\t",gradient,"\t",std_err
                    leadingwgt.append(1 / (std_err * std_err))
                    leadingicept.append(intercept)
                grads.append(gradient)
                graderr.append(std_err)
                bxx.append(bx)
                lastbx = bx

        nbx = len(bxx)
        nlead = len(leading)
        ntrain = len(train)
        #print "Means ",np.mean(leading), np.average(leading), np.average(leading,weights=leadingwgt)
        if det == "PLT":
            pltresults=pltresults\
            +str(round(np.average(leading,weights=leadingwgt),5))+","\
            +str(round(np.std(leading),5))+","\
            +str(round(np.mean(leadingicept),3))+","
            if ntrain > 0:
                pltresults=pltresults\
                +str(round(np.average(train,weights=trainwgt),5))+","\
                +str(round(np.std(train),5))+","\
                +str(round(np.mean(trainicept),3))+","
            else:
                pltresults = pltresults + ",,,"
        elif det == "HFET":
            hfetresults=hfetresults\
            +str(round(np.average(leading,weights=leadingwgt),5))+","\
            +str(round(np.std(leading),5))+","\
            +str(round(np.mean(leadingicept),3))+","
            if ntrain > 0:
                hfetresults=hfetresults\
                +str(round(np.average(train,weights=trainwgt),5))+","\
                +str(round(np.std(train),5))+","\
                +str(round(np.mean(trainicept),3))+","
            else:
                hfetresults = hfetresults + ",,,"
        elif det == "BCM1F":
            pcvdresults=pcvdresults\
            +str(round(np.average(leading,weights=leadingwgt),5))+","\
            +str(round(np.std(leading),5))+","\
            +str(round(np.mean(leadingicept),3))+","
            if ntrain > 0:
                pcvdresults=pcvdresults\
                +str(round(np.average(train,weights=trainwgt),5))+","\
                +str(round(np.std(train),5))+","\
                +str(round(np.mean(trainicept),3))+","
            else:
                hfetresults = hfetresults + ",,,"
        elif det == "HFOC":
            hfocresults=hfocresults\
            +str(round(np.average(leading,weights=leadingwgt),5))+","\
            +str(round(np.std(leading),5))+","\
            +str(round(np.mean(leadingicept),3))+","
            if ntrain > 0:
                hfocresults=hfocresults\
                +str(round(np.average(train,weights=trainwgt),5))+","\
                +str(round(np.std(train),5))+","\
                +str(round(np.mean(trainicept),3))+","
            else:
                hfocresults = hfocresultst + ",,,"

        if nlead > 1:
            print det + " Average Leading Slope =", round(
                np.average(leading, weights=leadingwgt),
                5), "   +- ", round(np.std(leading), 5)
        if ntrain > 1:
            print det + " Average Train Slope =", round(
                np.average(train, weights=trainwgt),
                5), "   +- ", round(np.std(train), 5)

        if "Versus" in plotem:
            fig, ax = py.subplots()
            ax.errorbar(bxx, grads, yerr=graderr, marker='s', fmt='o')
            ax.set_ylabel(det + ' Gradient wrt PCC')
            ax.grid()
            if fill == '7358':
                ax.set_xlim(1640, 1660)
            ax.set_title('Gradient ' + det + ' wrt PCC fill ' + str(fill))
            ax.set_xlabel('BX')
            #py.show()
            #fig.savefig(figdir+'/'+det+'allBX'".png")
            pp.savefig(fig)
            py.close(fig)
            if fill == '7358':
                fig, ax = py.subplots()
                ax.errorbar(bxx, grads, yerr=graderr, marker='s', fmt='o')
                ax.set_ylabel(det + ' Gradient wrt PCC')
                ax.grid()
                if fill == '7358':
                    ax.set_xlim(745, 765)
                ax.set_title('Gradient ' + det + ' wrt PCC fill ' + str(fill))
                ax.set_xlabel('BX')
                pp.savefig(fig)
                py.close(fig)

            fig, ax = py.subplots()
            ax.errorbar(gap, grads, yerr=graderr, marker='s', fmt='o')
            ax.set_ylabel(det + ' Gradient wrt PCC')
            ax.set_title('Gradient ' + det + ' wrt PCC fill ' + str(fill))

            ax.set_xlabel('Gap before this BX')
            #py.show()
            #fig.savefig(figdir+'/'+det+'gapBX'".png")
            pp.savefig(fig)

        if plotem != "False":
            pp.close()
            py.close(fig)


    header=scanfile+","+str(fill)+","\
    +str(fillreport.loc[int(fill),'ilumi'])+","\
    +str(fillreport.loc[int(fill),'run1'])+","\
    +str(nbx)+","+str(nlead)+","+str(ntrain)+","+str(scanpoints)+","
    output.write(header + pltresults + hfetresults + pcvdresults +
                 hfocresults + "\n")

    if plotem != "False":
        print "plots sent to ", figdir
Exemple #28
0
class FittingPlotView(QtWidgets.QWidget, Ui_plot):
    def __init__(self, parent=None):
        super(FittingPlotView, self).__init__(parent)
        self.setupUi(self)

        self.figure = None
        self.toolbar = None
        self.fitprop_toolbar = None
        self.fit_browser = None
        self.plot_dock = None
        self.dock_window = None
        self.initial_chart_width = None
        self.initial_chart_height = None
        self.has_first_undock_occurred = 0

        self.setup_figure()
        self.setup_toolbar()

    def setup_figure(self):
        self.figure = Figure()
        self.figure.canvas = FigureCanvas(self.figure)
        self.figure.canvas.mpl_connect('button_press_event', self.mouse_click)
        self.figure.add_subplot(111, projection="mantid")
        self.toolbar = FittingPlotToolbar(self.figure.canvas, self, False)
        self.toolbar.setMovable(False)

        self.dock_window = QMainWindow(self.group_plot)
        self.dock_window.setWindowFlags(Qt.Widget)
        self.dock_window.setDockOptions(QMainWindow.AnimatedDocks)
        self.dock_window.setCentralWidget(self.toolbar)
        self.plot_dock = QDockWidget()
        self.plot_dock.setWidget(self.figure.canvas)
        self.plot_dock.setFeatures(QDockWidget.DockWidgetFloatable
                                   | QDockWidget.DockWidgetMovable)
        self.plot_dock.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.plot_dock.setWindowTitle("Fit Plot")
        self.plot_dock.topLevelChanged.connect(self.make_undocked_plot_larger)
        self.initial_chart_width, self.initial_chart_height = self.plot_dock.width(
        ), self.plot_dock.height()
        self.plot_dock.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.dock_window.addDockWidget(Qt.BottomDockWidgetArea, self.plot_dock)
        self.vLayout_plot.addWidget(self.dock_window)

        self.fit_browser = EngDiffFitPropertyBrowser(
            self.figure.canvas, ToolbarStateManager(self.toolbar))
        # remove SequentialFit from fit menu (implemented a different way)
        qmenu = self.fit_browser.getFitMenu()
        qmenu.removeAction([
            qact for qact in qmenu.actions() if qact.text() == "Sequential Fit"
        ][0])
        # hide unnecessary properties of browser
        hide_props = [
            'Minimizer', 'Cost function', 'Max Iterations', 'Output',
            'Ignore invalid data', 'Peak Radius', 'Plot Composite Members',
            'Convolve Composite Members', 'Show Parameter Errors',
            'Evaluate Function As'
        ]
        self.fit_browser.removePropertiesFromSettingsBrowser(hide_props)
        self.fit_browser.toggleWsListVisible()
        self.fit_browser.closing.connect(self.toolbar.handle_fit_browser_close)
        self.vLayout_fitprop.addWidget(self.fit_browser)
        self.fit_browser.hide()

    def mouse_click(self, event):
        if event.button == event.canvas.buttond.get(Qt.RightButton):
            menu = QMenu()
            self.fit_browser.add_to_menu(menu)
            menu.exec_(QCursor.pos())

    def resizeEvent(self, QResizeEvent):
        self.update_axes_position()

    def make_undocked_plot_larger(self):
        # only make undocked plot larger the first time it is undocked as the undocked size gets remembered
        if self.plot_dock.isFloating() and self.has_first_undock_occurred == 0:
            factor = 1.0
            aspect_ratio = self.initial_chart_width / self.initial_chart_height
            new_height = self.initial_chart_height * factor
            docked_height = self.dock_window.height()
            if docked_height > new_height:
                new_height = docked_height
            new_width = new_height * aspect_ratio
            self.plot_dock.resize(new_width, new_height)
            self.has_first_undock_occurred = 1

        self.update_axes_position()

    def ensure_fit_dock_closed(self):
        if self.plot_dock.isFloating():
            self.plot_dock.close()

    def setup_toolbar(self):
        self.toolbar.sig_home_clicked.connect(self.display_all)
        self.toolbar.sig_toggle_fit_triggered.connect(self.fit_toggle)

    # =================
    # Component Setters
    # =================

    def fit_toggle(self):
        """Toggle fit browser and tool on/off"""
        if self.fit_browser.isVisible():
            self.fit_browser.hide()
        else:
            self.fit_browser.show()

    def clear_figure(self):
        self.figure.clf()
        self.figure.add_subplot(111, projection="mantid")
        self.figure.canvas.draw()

    def update_figure(self):
        self.toolbar.update()
        self.update_legend(self.get_axes()[0])
        self.update_axes_position()
        self.figure.canvas.draw()
        self.update_fitbrowser()

    def update_axes_position(self):
        """
        Set axes position so that labels are always visible - it deliberately ignores height of ylabel (and less
        importantly the length of xlabel). This is because the plot window typically has a very small height when docked
        in the UI.
        """
        ax = self.get_axes()[0]
        y0_lab = ax.xaxis.get_tightbbox(
            renderer=self.figure.canvas.get_renderer()
        ).transformed(
            self.figure.transFigure.inverted()
        ).y0  # vertical coord of bottom left corner of xlabel in fig ref. frame
        x0_lab = ax.yaxis.get_tightbbox(
            renderer=self.figure.canvas.get_renderer()
        ).transformed(
            self.figure.transFigure.inverted()
        ).x0  # horizontal coord of bottom left corner ylabel in fig ref. frame
        pos = ax.get_position()
        x0_ax = pos.x0 + 0.05 - x0_lab  # move so that ylabel left bottom corner at horizontal coord 0.05
        y0_ax = pos.y0 + 0.05 - y0_lab  # move so that xlabel left bottom corner at vertical coord 0.05
        ax.set_position([x0_ax, y0_ax, 0.95 - x0_ax, 0.95 - y0_ax])

    def update_fitbrowser(self):
        is_visible = self.fit_browser.isVisible()
        self.toolbar.set_fit_checkstate(False)
        self.fit_browser.hide()
        if self.fit_browser.getWorkspaceNames() and is_visible:
            self.toolbar.set_fit_checkstate(True)
            self.fit_browser.show()

    def remove_ws_from_fitbrowser(self, ws):
        # only one spectra per workspace
        try:
            self.fit_browser.removeWorkspaceAndSpectra(ws.name())
        except:
            pass  # name may not be available if ws has just been deleted

    def update_legend(self, ax):
        if ax.get_lines():
            ax.make_legend()
            ax.get_legend().set_title("")
        else:
            if ax.get_legend():
                ax.get_legend().remove()

    def display_all(self):
        for ax in self.get_axes():
            if ax.lines:
                ax.relim()
            ax.autoscale()
        self.update_figure()

    def read_fitprop_from_browser(self):
        return self.fit_browser.read_current_fitprop()

    def update_browser(self, status, func_str, setup_name):
        self.fit_browser.fitResultsChanged.emit(status)
        self.fit_browser.changeWindowTitle.emit(status)
        # update browser with output function and save setup if successful
        if "success" in status.lower():
            self.fit_browser.loadFunction(func_str)
            self.fit_browser.save_current_setup(setup_name)

    # =================
    # Component Getters
    # =================

    def get_axes(self):
        return self.figure.axes

    def get_figure(self):
        return self.figure
class App:
    def __init__(self, master, image_path):
        self.point = [0, 0, 0]
        master.title("3d Point")
        self.image1 = Image.open(image_path)
        self.tkpi = ImageTk.PhotoImage(self.image1)
        self.frame = Frame(master,
                           height=self.image1.size[1],
                           width=self.image1.size[0])
        self.frame.grid_propagate(0)
        self.frame.pack()
        self.frame.grid(row=0, column=0, sticky=NW)

        # place a graph somewhere here
        self.f = Figure(figsize=(6.4, 7.2), dpi=100)
        self.a = self.f.add_subplot(311)
        self.a.set_xlabel("t")
        self.a.set_ylabel("Info")
        self.a.plot([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])

        self.canvas = FigureCanvasTkAgg(self.f, self.frame)
        self.canvas.show()
        self.canvas.mpl_connect('button_press_event', self.get_t)
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)

        self.frame1 = Frame(master,
                            height=self.image1.size[1],
                            width=2 * self.image1.size[0],
                            bg='red')
        self.frame1.pack()
        self.frame1.grid_propagate(0)
        self.frame1.grid(row=0, column=1, sticky=NW)
        self.label_image = Label(self.frame1, image=self.tkpi)
        self.label_image.pack(side=LEFT)
        self.label_image.bind("<Button-1>", self.runprobe)
        master.mainloop()

    def get_t(self, event):
        self.t = event.xdata
        self.ty = event.ydata
        # clear the figure
        print self.t
        self.point[0], self.point[1], self.point[2] = get_3d_from_depth(
            pcam, self.posx, self.posy, self.t)
        print "3-d point  ", self.point[0], self.point[1], self.point[2]
        # self.point[0] = 0.03285;#0.0694333;#0.0908;
        # self.point[1] = 0.08402;#0.0636396;#-0.0068;
        # self.point[2] = 0.181359;#0.150683; #0.13447;
        self.get_intensities()

    def runprobe(self, event):
        self.posx = event.x
        self.posy = event.y
        array2d = list()
        xs = list()
        ys = list()
        zs = list()
        len_array_1d, alpha_array_1d, vis_array_1d, tabs_array_1d, phongs_array_1d, nelems = scene.get_info_along_ray(
            cam, self.posx, self.posy, "boxm2_mog3_grey")
        print "NELEMS ", nelems
        surface_p = list()
        air_p = list()
        air_p1 = list()
        num_observations = list()
        for i in range(0, len(len_array_1d)):
            surface_p.append(phongs_array_1d[i * nelems + 5])
            air_p.append(phongs_array_1d[i * nelems + 6])
            num_observations.append(phongs_array_1d[i * nelems + 7])

        self.f.clf()
        self.a = self.f.add_subplot(311)
        self.a.set_xlabel("zs")
        self.a.set_ylabel("Cubic p")
        self.a.plot(tabs_array_1d, surface_p)
        self.a.plot(tabs_array_1d, vis_array_1d)

        self.b = self.f.add_subplot(312)
        self.b.set_xlabel("zs")
        self.b.set_ylabel("Air p")
        self.b.plot(tabs_array_1d, air_p)
        self.b.plot(tabs_array_1d, vis_array_1d)

        self.b = self.f.add_subplot(313)
        self.b.set_xlabel("zs")
        self.b.set_ylabel("Nobs")
        self.b.plot(tabs_array_1d, num_observations)
        self.canvas.show()

    def get_intensities(self):
        thetas = list()
        phis = list()
        cam_exp = 0
        img_ids = range(0, 255, 10)
        scene.query_cell_brdf(self.point, "cubic_model")

        #create stream cache using image/type lists:
        image_id_fname = "./image_list.txt"
        fd = open(image_id_fname, "w")
        print >> fd, len(img_ids)
        for i in img_ids:
            print >> fd, "img_%05d" % i
        fd.close()

        type_id_fname = "./type_names_list.txt"
        fd2 = open(type_id_fname, "w")
        print >> fd2, 4
        print >> fd2, "aux0"
        print >> fd2, "aux1"
        print >> fd2, "aux2"
        print >> fd2, "aux3"
        fd2.close()

        # open the stream cache, this is a read-only cache
        boxm2_batch.init_process("boxm2CreateStreamCacheProcess")
        boxm2_batch.set_input_from_db(0, scene.scene)
        boxm2_batch.set_input_string(1, type_id_fname)
        boxm2_batch.set_input_string(2, image_id_fname)
        boxm2_batch.set_input_float(3, 3)
        boxm2_batch.run_process()
        (cache_id, cache_type) = boxm2_batch.commit_output(0)
        strcache = dbvalue(cache_id, cache_type)

        #get intensities/visibilities
        intensities, visibilities = probe_intensities(scene.scene,
                                                      scene.cpu_cache,
                                                      strcache, self.point)

        boxm2_batch.init_process("boxm2StreamCacheCloseFilesProcess")
        boxm2_batch.set_input_from_db(0, strcache)
        boxm2_batch.run_process()
        image_id_fname = "./image_list.txt"
        # write image identifiers to file
        fd = open(image_id_fname, "w")
        print >> fd, len(img_ids)
        for i in img_ids:
            print >> fd, "viewdir_%05d" % i
        fd.close()

        # open the stream cache, this is a read-only cache
        boxm2_batch.init_process("boxm2CreateStreamCacheProcess")
        boxm2_batch.set_input_from_db(0, scene.scene)
        boxm2_batch.set_input_string(1, type_id_fname)
        boxm2_batch.set_input_string(2, image_id_fname)
        boxm2_batch.set_input_float(3, 3)
        boxm2_batch.run_process()
        (cache_id, cache_type) = boxm2_batch.commit_output(0)
        strcache = dbvalue(cache_id, cache_type)

        boxm2_batch.init_process("boxm2CppBatchProbeIntensitiesProcess")
        boxm2_batch.set_input_from_db(0, scene.scene)
        boxm2_batch.set_input_from_db(1, scene.cpu_cache)
        boxm2_batch.set_input_from_db(2, strcache)
        boxm2_batch.set_input_float(3, self.point[0])
        boxm2_batch.set_input_float(4, self.point[1])
        boxm2_batch.set_input_float(5, self.point[2])
        boxm2_batch.run_process()
        (id, type) = boxm2_batch.commit_output(0)
        xdir = boxm2_batch.get_bbas_1d_array_float(id)
        (id, type) = boxm2_batch.commit_output(1)
        ydir = boxm2_batch.get_bbas_1d_array_float(id)
        (id, type) = boxm2_batch.commit_output(2)
        zdir = boxm2_batch.get_bbas_1d_array_float(id)
        phis = []
        for i in range(0, len(xdir)):
            phis.append(arctan2(ydir[i], xdir[i]))
            thetas.append(arccos(zdir[i]))

        boxm2_batch.init_process("boxm2StreamCacheCloseFilesProcess")
        boxm2_batch.set_input_from_db(0, strcache)
        boxm2_batch.run_process()

        boxm2_batch.init_process("bradEstimateSynopticFunction1dProcess")
        boxm2_batch.set_input_float_array(0, intensities)
        boxm2_batch.set_input_float_array(1, visibilities)
        boxm2_batch.set_input_float_array(2, thetas)
        boxm2_batch.set_input_float_array(3, phis)
        boxm2_batch.set_input_bool(4, 1)
        boxm2_batch.run_process()
        (id, type) = boxm2_batch.commit_output(0)
        fitted_intensities = boxm2_batch.get_bbas_1d_array_float(id)
        (id, type) = boxm2_batch.commit_output(1)
        surf_prob_density = boxm2_batch.get_output_float(id)

        boxm2_batch.init_process("bradEstimateEmptyProcess")
        boxm2_batch.set_input_float_array(0, intensities)
        boxm2_batch.set_input_float_array(1, visibilities)
        boxm2_batch.run_process()
        (id, type) = boxm2_batch.commit_output(0)
        air_prob_density = boxm2_batch.get_output_float(id)
        print "surf_prob_density ", surf_prob_density, "air_prob_density ", air_prob_density

        #fig = plt.figure(2)
        #fig.clf();
        #ax = fig.gca(projection='3d')

        select_intensities = list()
        select_intensities_img = list()
        select_fitted_intensities = list()
        select_visibilities = list()
        select_indices = list()
        print len(thetas), len(intensities)
        for pindex in range(0, len(intensities)):
            r = intensities[pindex]
            theta = thetas[pindex]
            phi = phis[pindex]
            r1 = fitted_intensities[pindex]
            if (intensities[pindex] < 0.0):
                visibilities[pindex] = 0.0
            if (visibilities[pindex] > 0.0):
                vispl = visibilities[pindex]
                #ax.plot([0,r*sin(theta)*cos(phi)],[0,r*sin(theta)*sin(phi)],[0,r*cos(theta)], color='b');
                #ax.scatter([r1*sin(theta)*cos(phi)],[r1*sin(theta)*sin(phi)],[r1*cos(theta)], color='g');
                #ax.scatter([vispl*sin(theta)*cos(phi)],[vispl*sin(theta)*sin(phi)],[vispl*cos(theta)], color='r');
                print intensities[pindex], phis[pindex], visibilities[pindex]
                select_intensities.append(r)
                select_visibilities.append(vispl)
                select_indices.append(pindex)
                select_fitted_intensities.append(r1)
                #select_intensities_img.append(intensities_img[pindex]);
            #ax.plot([0,sin(suntheta)*cos(sunphi)],[0,sin(suntheta)*sin(sunphi)],[0,cos(suntheta)], color='r');
            #ax.plot([0,0],[0,0],[0,1], color='k');
            #ax.set_xlim3d(-1,1);ax.set_ylim3d(-1,1);ax.set_zlim3d(0,1);

    #plt.show();
        fig_hist = plt.figure(3)
        plt.xlabel("ViewPoints")
        plt.ylabel("Intensities")
        plt.plot(select_indices, select_intensities, 'r*-')
        plt.plot(select_indices, select_fitted_intensities, 'g.-')
        plt.ylim((0, 1))
        plt.plot(select_indices, select_visibilities, 'bo-')
        #plt.plot(select_indices,select_intensities_img,'ko-');
        #plt.legend( ('Intensities Observed', 'Phong\'s Model','Visibilities'), loc='lower left');
        plt.show()
class App(tk.Frame):
    def __init__(self, parent, file_path):
        tk.Frame.__init__(self, parent)
        parent.deiconify()
        self.events_flag = False
        self.baseline_flag = False
        self.file_path = file_path

        ##### Trace plotting widgets #####
        self.trace_frame = tk.LabelFrame(parent, text='Current Trace')
        self.trace_fig = Figure(figsize=(7, 5), dpi=100)
        self.trace_canvas = FigureCanvasTkAgg(self.trace_fig,
                                              master=self.trace_frame)
        self.trace_toolbar_frame = tk.Frame(self.trace_frame)
        self.trace_toolbar = NavigationToolbar2TkAgg(self.trace_canvas,
                                                     self.trace_toolbar_frame)
        self.trace_toolbar.update()

        self.trace_frame.grid(row=0,
                              column=0,
                              columnspan=6,
                              sticky=tk.N + tk.S)
        self.trace_toolbar_frame.grid(row=1, column=0, columnspan=6)
        self.trace_canvas.get_tk_widget().grid(row=0, column=0, columnspan=6)

        ##### PSD plotting widgets #####
        self.psd_frame = tk.LabelFrame(parent, text='Power Spectrum')
        self.psd_fig = Figure(figsize=(7, 5), dpi=100)
        self.psd_canvas = FigureCanvasTkAgg(self.psd_fig,
                                            master=self.psd_frame)
        self.psd_toolbar_frame = tk.Frame(self.psd_frame)
        self.psd_toolbar = NavigationToolbar2TkAgg(self.psd_canvas,
                                                   self.psd_toolbar_frame)
        self.psd_toolbar.update()

        self.psd_frame.grid(row=0, column=6, columnspan=6, sticky=tk.N + tk.S)
        self.psd_toolbar_frame.grid(row=1, column=6, columnspan=6)
        self.psd_canvas.get_tk_widget().grid(row=0, column=6, columnspan=6)

        ##### Control widgets #####
        self.control_frame = tk.LabelFrame(parent, text='Controls')
        self.control_frame.grid(row=2,
                                column=0,
                                columnspan=6,
                                sticky=tk.N + tk.S + tk.E + tk.W)

        self.start_entry = tk.Entry(self.control_frame)
        self.start_entry.insert(0, '0')
        self.start_label = tk.Label(self.control_frame, text='Start Time (s)')
        self.start_label.grid(row=0, column=0, sticky=tk.E + tk.W)
        self.start_entry.grid(row=0, column=1, sticky=tk.E + tk.W)

        self.end_entry = tk.Entry(self.control_frame)
        self.end_entry.insert(0, '10')
        self.end_label = tk.Label(self.control_frame, text='End Time (s)')
        self.end_label.grid(row=0, column=2, sticky=tk.E + tk.W)
        self.end_entry.grid(row=0, column=3, sticky=tk.E + tk.W)

        self.cutoff_entry = tk.Entry(self.control_frame)
        self.cutoff_entry.insert(0, '')
        self.cutoff_label = tk.Label(self.control_frame, text='Cutoff (Hz)')
        self.cutoff_label.grid(row=1, column=0, sticky=tk.E + tk.W)
        self.cutoff_entry.grid(row=1, column=1, sticky=tk.E + tk.W)

        self.order_entry = tk.Entry(self.control_frame)
        self.order_entry.insert(0, '')
        self.order_label = tk.Label(self.control_frame, text='Filter Order')
        self.order_label.grid(row=1, column=2, sticky=tk.E + tk.W)
        self.order_entry.grid(row=1, column=3, sticky=tk.E + tk.W)

        self.samplerate_entry = tk.Entry(self.control_frame)
        self.samplerate_entry.insert(0, '250000')
        self.samplerate_label = tk.Label(self.control_frame,
                                         text='Sampling Frequency (Hz)')
        self.samplerate_label.grid(row=1, column=4, sticky=tk.E + tk.W)
        self.samplerate_entry.grid(row=1, column=5, sticky=tk.E + tk.W)

        self.savegain_entry = tk.Entry(self.control_frame)
        self.savegain_entry.insert(0, '1')
        self.savegain_label = tk.Label(self.control_frame,
                                       text='Sampling Frequency (Hz)')
        self.savegain_label.grid(row=0, column=4, sticky=tk.E + tk.W)
        self.savegain_entry.grid(row=0, column=5, sticky=tk.E + tk.W)

        self.plot_trace = tk.Button(self.control_frame,
                                    text='Update Trace',
                                    command=self.update_trace)
        self.plot_trace.grid(row=2, column=0, columnspan=2, sticky=tk.E + tk.W)

        self.normalize = tk.IntVar()
        self.normalize.set(0)
        self.normalize_check = tk.Checkbutton(self.control_frame,
                                              text='Normalize',
                                              variable=self.normalize)
        self.normalize_check.grid(row=2, column=2, sticky=tk.E + tk.W)

        self.plot_psd = tk.Button(self.control_frame,
                                  text='Update PSD',
                                  command=self.update_psd)
        self.plot_psd.grid(row=2, column=3, sticky=tk.E + tk.W)

        ##### Feedback Widgets #####
        self.feedback_frame = tk.LabelFrame(parent, text='Status')
        self.feedback_frame.grid(row=2,
                                 column=6,
                                 columnspan=6,
                                 sticky=tk.N + tk.S + tk.E + tk.W)

        self.export_psd = tk.Button(self.feedback_frame,
                                    text='Export PSD',
                                    command=self.export_psd)
        self.export_psd.grid(row=1, column=0, columnspan=6, sticky=tk.E + tk.W)
        self.export_trace = tk.Button(self.feedback_frame,
                                      text='Export Trace',
                                      command=self.export_trace)
        self.export_trace.grid(row=2,
                               column=0,
                               columnspan=6,
                               sticky=tk.E + tk.W)

        self.load_memmap()
        self.initialize_samplerate()

    def export_psd(self):
        try:
            data_path = tkinter.filedialog.asksaveasfilename(
                defaultextension='.csv', initialdir='G:\PSDs for Sam')
            np.savetxt(data_path,
                       np.c_[self.f, self.Pxx, self.rms],
                       delimiter=',')
        except AttributeError:
            self.wildcard.set('Plot the PSD first')

    def export_trace(self):
        try:
            data_path = tkinter.filedialog.asksaveasfilename(
                defaultextension='.csv',
                initialdir='G:\Analysis\Pores\NPN\PSDs')
            np.savetxt(data_path, self.plot_data, delimiter=',')
        except AttributeError:
            self.wildcard.set('Plot the trace first')

    def load_mapped_data(self):
        self.total_samples = len(self.map)
        self.samplerate = int(self.samplerate_entry.get())
        if self.start_entry.get() != '':
            self.start_time = float(self.start_entry.get())
            start_index = int(
                (float(self.start_entry.get()) * self.samplerate))
        else:
            self.start_time = 0
            start_index = 0

        if self.end_entry.get() != '':
            self.end_time = float(self.end_entry.get())
            end_index = int((float(self.end_entry.get()) * self.samplerate))
            if end_index > self.total_samples:
                end_index = self.total_samples

        self.data = self.map[start_index:end_index]
        self.data = float(self.savegain_entry.get()) * self.data

    def load_memmap(self):
        columntypes = np.dtype([('current', '>i2'), ('voltage', '>i2')])
        self.map = np.memmap(self.file_path, dtype=columntypes,
                             mode='r')['current']

    def integrate_noise(self, f, Pxx):
        df = f[1] - f[0]
        return np.sqrt(np.cumsum(Pxx * df))

    def filter_data(self):
        cutoff = float(self.cutoff_entry.get())
        order = int(self.order_entry.get())
        Wn = 2.0 * cutoff / float(self.samplerate)
        b, a = bessel(order, Wn, 'low')
        padding = 1000
        padded = np.pad(self.data, pad_width=padding, mode='median')
        self.filtered_data = filtfilt(b, a, padded,
                                      padtype=None)[padding:-padding]

    def initialize_samplerate(self):
        self.samplerate = float(self.samplerate_entry.get())

    ##### Plot Updating functions #####
    def update_trace(self):
        self.initialize_samplerate()
        self.load_mapped_data()
        self.filtered_data = self.data
        self.plot_data = self.filtered_data
        plot_samplerate = self.samplerate

        if self.cutoff_entry.get() != '' and self.order_entry != '':
            self.filter_data()
            self.plot_data = self.filtered_data

        self.trace_fig.clf()
        a = self.trace_fig.add_subplot(111)

        time = np.linspace(1.0 / self.samplerate,
                           len(self.plot_data) / float(self.samplerate),
                           len(self.plot_data)) + self.start_time

        a.set_xlabel(r'Time ($\mu s$)')
        a.set_ylabel('Current (pA)')
        self.trace_fig.subplots_adjust(bottom=0.14, left=0.21)
        a.plot(time * 1e6, self.plot_data, '.', markersize=1)

        self.trace_canvas.show()

    def update_psd(self):
        self.initialize_samplerate()
        self.load_mapped_data()
        self.filtered_data = self.data
        self.plot_data = self.filtered_data
        plot_samplerate = self.samplerate

        if self.cutoff_entry.get() != '' and self.order_entry != '':
            self.filter_data()
            self.plot_data = self.filtered_data
            maxf = 2 * float(self.cutoff_entry.get())
        else:
            maxf = 2 * float(self.samplerate_entry.get())

        length = np.minimum(2**18, len(self.filtered_data))
        end_index = int(np.floor(len(self.filtered_data) / length) * length)

        current = np.average(self.filtered_data[:end_index])

        f, Pxx = welch(self.filtered_data, plot_samplerate, nperseg=length)
        self.rms = self.integrate_noise(f, Pxx)

        if self.normalize.get():
            Pxx /= current**2
            Pxx *= maxf / 2.0
            self.rms /= np.absolute(current)

        self.f = f
        self.Pxx = Pxx

        minf = 1
        BW_index = np.searchsorted(f, maxf / 2)
        logPxx = np.log10(Pxx[1:BW_index])
        minP = 10**np.floor(np.amin(logPxx))
        maxP = 10**np.ceil(np.amax(logPxx))

        self.psd_fig.clf()
        a = self.psd_fig.add_subplot(111)
        a.set_xlabel('Frequency (Hz)')
        a.set_ylabel(r'Spectral Power ($\mathrm{pA}^2/\mathrm{Hz}$)')
        a.set_xlim(minf, maxf)
        a.set_ylim(minP, maxP)
        self.psd_fig.subplots_adjust(bottom=0.14, left=0.21)
        a.loglog(f[1:], Pxx[1:], 'b-')
        for tick in a.get_yticklabels():
            tick.set_color('b')

        a2 = a.twinx()
        a2.semilogx(f, self.rms, 'r-')
        a2.set_ylabel('RMS Noise (pA)')
        a2.set_xlim(minf, maxf)
        for tick in a2.get_yticklabels():
            tick.set_color('r')
        a2.format_coord = make_format(a2, a)

        self.psd_canvas.show()
Exemple #31
0
def _make_pretty_from_fits(fname=None,
                           title=None,
                           figsize=(10, 10 / 1.325),
                           dpi=150,
                           alpha=0.2,
                           number_ticks=7,
                           clip_percent=99.9,
                           **kwargs):

    with open_fits(fname) as hdu:
        header = hdu[0].header
        data = hdu[0].data
        data = focus_utils.mask_saturated(data)
        wcs = WCS(header)

    if not title:
        field = header.get('FIELD', 'Unknown field')
        exptime = header.get('EXPTIME', 'Unknown exptime')
        filter_type = header.get('FILTER', 'Unknown filter')

        try:
            date_time = header['DATE-OBS']
        except KeyError:
            # If we don't have DATE-OBS, check filename for date
            try:
                basename = os.path.splitext(os.path.basename(fname))[0]
                date_time = date_parser.parse(basename).isoformat()
            except Exception:
                # Otherwise use now
                date_time = current_time(pretty=True)

        date_time = date_time.replace('T', ' ', 1)

        title = '{} ({}s {}) {}'.format(field, exptime, filter_type, date_time)

    norm = ImageNormalize(interval=PercentileInterval(clip_percent), stretch=LogStretch())

    fig = Figure()
    FigureCanvas(fig)
    fig.set_size_inches(*figsize)
    fig.dpi = dpi

    if wcs.is_celestial:
        ax = fig.add_subplot(1, 1, 1, projection=wcs)
        ax.coords.grid(True, color='white', ls='-', alpha=alpha)

        ra_axis = ax.coords['ra']
        ra_axis.set_axislabel('Right Ascension')
        ra_axis.set_major_formatter('hh:mm')
        ra_axis.set_ticks(
            number=number_ticks,
            color='white',
            exclude_overlapping=True
        )

        dec_axis = ax.coords['dec']
        dec_axis.set_axislabel('Declination')
        dec_axis.set_major_formatter('dd:mm')
        dec_axis.set_ticks(
            number=number_ticks,
            color='white',
            exclude_overlapping=True
        )
    else:
        ax = fig.add_subplot(111)
        ax.grid(True, color='white', ls='-', alpha=alpha)

        ax.set_xlabel('X / pixels')
        ax.set_ylabel('Y / pixels')

    im = ax.imshow(data, norm=norm, cmap=palette, origin='lower')
    fig.colorbar(im)
    fig.suptitle(title)

    new_filename = fname.replace('.fits', '.jpg')
    fig.savefig(new_filename, bbox_inches='tight')

    # explicitly close and delete figure
    fig.clf()
    del fig

    return new_filename
Exemple #32
0
class BarPlotter2(FigureCanvas):
    def __init__(self, ui_analyser, l):
        self.ui_analyser = proxy(ui_analyser)
        self.fig = Figure(dpi=70)
        super(BarPlotter2, self).__init__(self.fig)
        self.drawfigure(l, self.ui_analyser.combobox_strategy.currentText())
        self.ui_analyser.vLayout_bar.insertWidget(1, self)

    def drawfigure(self, l, strategy):
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)  # create an axis
        self.axes.hold(True)  # discards the old graph

        p_name = str(strategy)
        data = l.get_stacked_bar_data('Template', p_name, 'stackedBar')

        N = 11
        Bluff = data[0]
        BP = data[1]
        BHP = data[2]
        Bet = data[3]
        Call = data[4]
        Check = data[5]
        Fold = data[6]
        ind = np.arange(N)  # the x locations for the groups
        width = 1  # the width of the bars: can also be len(x) sequence

        self.p0 = self.axes.bar(ind, Bluff, width, color='y')
        self.p1 = self.axes.bar(ind, BP, width, color='k', bottom=Bluff)
        self.p2 = self.axes.bar(ind, BHP, width, color='b', bottom=[sum(x) for x in zip(Bluff, BP)])
        self.p3 = self.axes.bar(ind, Bet, width, color='c', bottom=[sum(x) for x in zip(Bluff, BP, BHP)])
        self.p4 = self.axes.bar(ind, Call, width, color='g', bottom=[sum(x) for x in zip(Bluff, BP, BHP, Bet)])
        self.p5 = self.axes.bar(ind, Check, width, color='w', bottom=[sum(x) for x in zip(Bluff, BP, BHP, Bet, Call)])
        self.p6 = self.axes.bar(ind, Fold, width, color='r',
                                bottom=[sum(x) for x in zip(Bluff, BP, BHP, Bet, Call, Check)])

        self.axes.set_ylabel('Profitability')
        self.axes.set_title('FinalFundsChange ABS')
        self.axes.set_xlabel(['PF Win', 'Loss', '', 'F Win', 'Loss', '', 'T Win', 'Loss', '', 'R Win', 'Loss'])
        # plt.yticks(np.arange(0,10,0.5))
        # self.c.tight_layout()
        self.axes.legend((self.p0[0], self.p1[0], self.p2[0], self.p3[0], self.p4[0], self.p5[0], self.p6[0]),
                         ('Bluff', 'BetPot', 'BetHfPot', 'Bet/Bet+', 'Call', 'Check', 'Fold'), labelspacing=0.03,
                         prop={'size': 12})
        i = 0
        maxh = 0.02
        for rect0, rect1, rect2, rect3, rect4, rect5, rect6 in zip(self.p0.patches, self.p1.patches,
                                                                   self.p2.patches,
                                                                   self.p3.patches, self.p4.patches,
                                                                   self.p5.patches, self.p6.patches):
            g = list(zip(data[0], data[1], data[2], data[3], data[4], data[5], data[6]))
            height = g[i]
            i += 1
            rect0.set_height(height[0])
            rect1.set_y(height[0])
            rect1.set_height(height[1])
            rect2.set_y(height[0] + height[1])
            rect2.set_height(height[2])
            rect3.set_y(height[0] + height[1] + height[2])
            rect3.set_height(height[3])
            rect4.set_y(height[0] + height[1] + height[2] + height[3])
            rect4.set_height(height[4])
            rect5.set_y(height[0] + height[1] + height[2] + height[3] + height[4])
            rect5.set_height(height[5])
            rect6.set_y(height[0] + height[1] + height[2] + height[3] + height[4] + height[5])
            rect6.set_height(height[6])
            maxh = max(height[0] + height[1] + height[2] + height[3] + height[4] + height[5] + height[6], maxh)

        # self.axes.set_ylim((0, maxh))

        self.draw()
Exemple #33
0
class StatsPanel(wx.Panel): 
    """class for the first page of the notebook """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

# default variables
        self.fontSize = 'x-small'

#split the notebook page in two and create panels
        panelsizer = wx.BoxSizer(wx.HORIZONTAL) # sizer
        splitter = wx.SplitterWindow(self, -1) 
        self.left_panel = wx.Panel(splitter, -1, style=wx.BORDER_SUNKEN)
        self.right_panel = wx.Panel(splitter, -1, style=wx.BORDER_SUNKEN)
        splitter.SetMinimumPaneSize(180) # cannot shrink panel to less than this

#initialize the figure and canvas
        self.dataFigure = Figure(figsize=(4,4),facecolor='white')
        self.dataCanvas = FigureCanvas(self.right_panel, -1, self.dataFigure)
        self.toolbar = VMToolbar(self.dataCanvas)

#layout of widgets, left panel
        self.control1 = wx.TextCtrl(self.left_panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
        self.copyBtn = wx.Button(self.left_panel, -1, _('Copy'), size=(60, 30))
        self.saveBtn = wx.Button(self.left_panel, -1, _('Save as'), size=(60, 30))

        hboxbt = wx.BoxSizer(wx.HORIZONTAL)
        hboxbt.Add(self.saveBtn,0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,3)
        hboxbt.Add(self.copyBtn,0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,3)

        self.Bind(wx.EVT_BUTTON, self.saveStats, self.saveBtn)
        self.Bind(wx.EVT_BUTTON, self.copyStats, self.copyBtn)

        box3 = wx.BoxSizer(wx.VERTICAL)
        box3.Add(self.control1, 1, wx.EXPAND)
        box3.Add(hboxbt,0,wx.ALIGN_CENTER)
        self.left_panel.SetSizer(box3)

#layout of canvas, right panel
# create draw/clear buttons 
        self.clearPlot_Button = wx.Button(self.right_panel, -1, _('Clear'), size=(55, 30))
        self.plotFlinn_Button = wx.Button(self.right_panel, -1, _('2-axis'), size=(55, 30))
        self.plotVollmer_Button = wx.Button(self.right_panel, -1, _('Triang.'), size=(55, 30))

        hboxTB = wx.BoxSizer(wx.HORIZONTAL)
        hboxTB.Add(self.plotFlinn_Button,0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,3)
        hboxTB.Add(self.plotVollmer_Button,0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,3)
        hboxTB.Add(self.clearPlot_Button,0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,3)
        hboxTB.Add(self.toolbar, 1, wx.EXPAND|wx.ALL, 1)

        self.Bind(wx.EVT_BUTTON, self.ClearPlot, self.clearPlot_Button)
        self.Bind(wx.EVT_BUTTON, self.PlotFlinn, self.plotFlinn_Button)
        self.Bind(wx.EVT_BUTTON, self.PlotVollmer, self.plotVollmer_Button)

#layout of canvas
        vbox2 = wx.BoxSizer(wx.VERTICAL)
        vbox2.Add(self.dataCanvas, 1, wx.EXPAND)
        vbox2.Add(hboxTB,0, wx.EXPAND|wx.ALL, 1)
#        vbox2.Add(self.toolbar, 0, wx.EXPAND|wx.ALL, 1)
        self.right_panel.SetSizer(vbox2)

#splitter
        splitter.SplitVertically(self.left_panel,self.right_panel,190) 
        panelsizer.Add(splitter,1, wx.EXPAND|wx.ALL, 2) # the panels are inside this sizer with 2px border

        self.SetSizer(panelsizer)
#        panelsizer.Fit(self)

# subscriptions to pubsub  
        pub.subscribe(self.__onReceivePlanarData, 'object.Plan_added_DDD') # from MainForm
        pub.subscribe(self.__onReceivePlanarData, 'object.Plan_added_RH') # from MainForm
        pub.subscribe(self.__onReceiveLinearData, 'object.Lin_added') # from MainForm
        pub.subscribe(self.__onReceiveFontSize, 'object.FontSize') # from MainForm

        pub.subscribe(self.__onReceiveChecked, 'object.checked') # from TreePanel (namesList)

        pub.subscribe(self.__onReceiveNameSel, 'object.selected_vals') # from TreePanel
        pub.subscribe(self.__onReceiveSelection, 'object.selected') # from TreePanel

        pub.subscribe(self.__onReceivePropsPlan, 'object.PropsPlanReceiv') # from TreePanel, OnPopup_childPlanar, OnDClick_childPlanar
        pub.subscribe(self.__onReceivePropsLin, 'object.PropsLinReceiv')# from TreePanel, OnPopup_childLinear, OnDClick_childLinear



# planar data file(s) opened
    def __onReceivePlanarData(self, message): 

        try:
            len(self.Pname) # dummy action just to see if self.Pname exists
        except:
            self.Ptype=[]
            self.Pname=[]
            self.Pndata=[]
            self.Pazim=[]
            self.Pdip=[]
            self.PeigenList=[]
            self.PidxList=[]
            self.PProps=[]

        for i in range(len(message.data)):
            self.Ptype.append(message.data[i][0])       # filetype
#            self.Pname.append(message.data[i][1])       # filename
            self.Pndata.append(message.data[i][2])      # n_data
            self.Pazim.append(message.data[i][3])       # azim
            self.Pdip.append(message.data[i][4])        # dip
            self.PeigenList.append(message.data[i][6])  # eigenDict
            self.PidxList.append(message.data[i][7])    # DDD_idx
            self.PProps.append(message.data[i][8])      # pplist

            if message.data[i][7].startswith('D'): # dip-dir data
                self.Pname.append('[P(dd)] %s' % message.data[i][1])
            else: # right-hand data
                self.Pname.append('[P(rh)] %s' % message.data[i][1])


# linear data file(s) opened
    def __onReceiveLinearData(self, message): 

        try:
            len(self.Lname) # dummy action just to see if self.Lname exists
        except:
            self.Ltype=[]
            self.Lname=[]
            self.Lndata=[]
            self.Lazim=[]
            self.Ldip=[]
            self.LeigenList=[]
            self.LidxList=[]
            self.LProps=[]

        for i in range(len(message.data)):
            self.Ltype.append(message.data[i][0])       # filetype
            self.Lname.append('[L] %s' % message.data[i][1])       # filename
            self.Lndata.append(message.data[i][2])      # n_data
            self.Lazim.append(message.data[i][3])       # azim
            self.Ldip.append(message.data[i][4])        # dip
            self.LeigenList.append(message.data[i][6])  # eigenDict
            self.LidxList.append(message.data[i][7])    # Lin_idx
            self.LProps.append(message.data[i][8])      # lplist

# graphic properties of planar data - same as in StereoPanel, but doesn't send data to TreePanel
    def __onReceivePropsPlan(self, message): # object.PropsPlanRec
        PropsPlan = message.data
        idx = self.PidxList.index(PropsPlan["pdata"])
        self.PProps[idx] = PropsPlan # replace default props by user-defined ones


# graphic properties of linear data - same as in StereoPanel, but doesn't send data to TreePanel
    def __onReceivePropsLin(self, message): 
        PropsLin = message.data
        idx = self.LidxList.index(PropsLin["pdata"])
        self.LProps[idx] = PropsLin # replace default props by user-defined ones


# which files are checked to plot
    def __onReceiveChecked(self, message): 
        checkedList = message.data
        self.idxPlan = []
        self.idxLin = []

        for checked in checkedList:
            if checked[1] == 1 and checked[0] in self.PidxList: # checked[1] = 1: planar data
                self.idxPlan.append(self.PidxList.index(checked[0]))
            elif checked[1] == 2 and checked[0] in self.LidxList: # checked[1] = 2: linear data
                self.idxLin.append(self.LidxList.index(checked[0]))

# which file is selected
    def __onReceiveSelection(self, message): 
        self.file_i = message.data

# font size
    def __onReceiveFontSize(self, message):
        self.fontSize = message.data


# which kind of file is selected
    def __onReceiveNameSel(self, message):
        self.name = message.data["itemName"]
        self.nametype = message.data["dtype"]

        if message.data["dtype"] == 1 or message.data["dtype"] == 2:        # 1 == Planar, 2 == Linear

            if message.data["dtype"] == 1:
                nametype = str(message.data["itemName"])#[3:len(message.data["itemName"])]) + ' (planar)'
            else:
                nametype = str(message.data["itemName"])#[3:len(message.data["itemName"])]) + ' (linear)'


            if message.data["ndata"] <= 3: # must have at least three values for eigen analysis
                args = (nametype, message.data["ndata"])
#os.linesep 
                showdata =''' file: %s

 n = %d

 There are too
 few points in file.

 Must have at least 
 three points for
 statistical analysis.

''' % args

            else: # there are more than three values in file

                # uniformity test(from QuickPlot)
                # original comments from QuickPlot source code:
                # van Everdingen et al., 1992, Computers and Geosciences v18 n2/3, p183-287.
                # ------------------------------------
                # rv95 contains critical values for the Rayleigh test of uniformity at the
                # 0.05 level. Values range from N = 5 to 100+ and model a Chi squared
                # distribution 0 degres of freedom) at N > 100. Based on Table Appendix 3.5
                # Mardia, 1972 - in Griffis et al.; 1985; Computers and Geosciences v4 n4, p369-408.

                rv95 =[0.7, 0.642, 0.597, 0.56, 0.529, 0.503, 0.48, 0.46, 0.442, 0.427, 0.413, 0.4, 0.388, 0.377, 0.367, \
                        0.358, 0.35, 0.342, 0.334, 0.328, 0.321, 0.29, 0.27, 0.26, 0.24, 0.23, 0.16, 7.185]

                ndata = message.data["ndata"]
                vector = message.data["Vect"]
                RB = vector / ndata
                if ndata < 5:
                    IV = 0
                elif ndata >= 5 and ndata <= 25:
                    IV = ndata - 5
                elif ndata > 25 and ndata <= 50:
                    IV = ((ndata-25) / 5) + 20
                elif ndata > 50 and ndata <= 100:
                    IV = 26
                elif ndata > 100:
                    IV = 27
                ISIG = 2

                if IV == 0:
                    uniformtxt = ''' There are too
 few points to test 
 significance '''

                if IV != 0:
                    ISIG = 0
                    if RB > rv95[IV]:
                        ISIG = 1

                if ISIG == 0:
                    uniformtxt = ''' Data do not differ
 significantly from
 uniform at the 0.95 level '''

                if ISIG ==1:
                    uniformtxt = ''' Data differ
 significantly from 
 uniform at the 0.95 level '''

                # check if distribution is cluster or girdle (from QuickPlot)
                if message.data["K"] >= 1.1:
                    dist = 'Cluster'
                    if message.data["az_v1"] + 180.0 <= 360: 
                        dipdir = message.data["az_v1"] + 180.0
                    else:
                        dipdir = message.data["az_v1"] + 180.0 - 360.0
                    meanclstr = (dipdir,90-message.data["dp_v1"],message.data["az_v1"],message.data["dp_v1"])
                    disttxt =''' Mean Plane:
 dipdir/dip = %3.1f/%2.1f

 Axis:
 azim/plunge = %3.1f/%2.1f''' % meanclstr

                elif message.data["K"] >= 0.9 and message.data["K"] < 1.1:
                    dist = 'Cluster or Glirdle'
                    disttxt =''
                else:
                    dist = 'Girdle'
                    if message.data["az_v3"] + 180.0 <= 360:  
                        dipdir = message.data["az_v3"] + 180.0
                    else:
                        dipdir = message.data["az_v3"] + 180.0 - 360.0
                    girdl = (message.data["az_v3"],message.data["dp_v3"],dipdir,90-message.data["dp_v3"]) 
                    disttxt =''' Fold Axis:
 azim/plunge = %3.1f/%2.1f

 Best-fit Girdle:
 dipdir/dip = %3.1f/%2.1f''' % girdl

                # check the force of the preferential orientation (from QuickPlot)
                if message.data["C"] >= 6.0:
                    force = 'Strong'
                elif message.data["C"] >= 4.0 and message.data["C"] < 6.0:
                    force = 'Moderate'
                elif message.data["C"] >= 2.0 and message.data["C"] < 4.0:
                    force = 'Weak'
                else:
                    force = 'None'

                args = (nametype, message.data["ndata"], uniformtxt, dist, force, disttxt, \
                        message.data["confCone"], message.data["confK"], \
                        message.data["az_v1"], message.data["dp_v1"], \
                        message.data["az_v2"], message.data["dp_v2"], \
                        message.data["az_v3"], message.data["dp_v3"], \
                        message.data["K"], message.data["C"], \
                        message.data["S1"], message.data["S2"], message.data["S3"],\
                        message.data["P"], message.data["G"], message.data["R"])

                showdata =''' file: %s

 n = %d 

%s

 Expected Distribution:
 %s

 Preferential Orientation:
 %s

%s

 Radius of confidence
 at 5%%:
 %3.2f degrees
 K = %3.2f
 
 Eigenvectors: 
 1: %3.1f / %2.1f
 2: %3.1f / %2.1f
 3: %3.1f / %2.1f

 Shape parameter
 K = %3.2f

 Strength parameter
 C = %3.2f

 Normalized Eigenvalues:
 S1: %3.3f
 S2: %3.3f
 S3: %3.3f

 Fabric (triangular diag.): 
 Point  = %3.3f
 Girdle = %3.3f
 Random = %3.3f
''' % args

        else:
            
            
        
            if message.data["dtype"] == 3:
                showdata = '''
 Sorry, no stats
 for Small Circles.

'''
            else:
                showdata = '''
 Sorry, no stats
 for Faults/Slickensides.
 
 If you need stats, you
 can open only the Planar
 or Linear (slickensides)
 data from faults.
 (menu File -> Fault Data)


'''
        self.control1.SetValue(showdata) # show the stats

#save stats to txt file
    def saveStats(self, event):
        dlg = wx.FileDialog ( None, message='Save stats as', \
        wildcard='Text files (*.txt)|*.txt', style = wx.SAVE | wx.OVERWRITE_PROMPT )
        if self.nametype == 1: # planar data
            savename = 'stats_%s_%s' % (self.name[:7],self.name[8:len(self.name)])
        elif self.nametype == 2: # linear data
            savename = 'stats_%s_%s' % (self.name[:3],self.name[4:len(self.name)])

        dlg.SetFilename(savename)
        if dlg.ShowModal() == wx.ID_OK:
            statstxt = self.control1.GetValue()
            self.filename=dlg.GetFilename()
            self.dirname=dlg.GetDirectory()
            filehandle=open(os.path.join(self.dirname, self.filename),'wt')
            filehandle.write(statstxt)
            filehandle.close()
        else:
           pass

        dlg.Destroy()

# copy stats to clipboard
    def copyStats(self, event):
        self.control1.SelectAll()
        self.control1.Copy()
        self.control1.SetSelection(0,0) #clear selection


# plot two-axis diagram (modfied Flinn by Woodcock) - from QuickPlot
    def PlotFlinn(self, event): 

        #initialize the plot areas
        self.dataFigure.clf()
        axes = Subplot(self.dataFigure, 111, clip_on='True',xlim=(-0.2,7.2), ylim=(-0.2,7.2),autoscale_on='True',xlabel='ln(S2/S3)',ylabel='ln(S1/S2)',label='flinn',aspect='equal', adjustable='box',anchor='W')
        self.dataFigure.add_subplot(axes)
        axes.axis["right"].set_visible(False)
        axes.axis["top"].set_visible(False)

        try:
            # plot lines of K
            for i in [0.2, 0.5, 1.0, 2.0, 5.0]:
                if i <= 1.0:
                    diag = Line2D((0,7.0),(0,(i*7.0)),c='grey',lw=0.5)
                    axes.add_line(diag)
                else:
                    diag = Line2D((0,(7.0/i)),(0,7.0),c='grey',lw=0.5)
                    axes.add_line(diag)

            # plot lines of C
            for j in [2,4,6]:
                diag2 = Line2D((0,j),(j,0),c='grey',lw=0.5)
                axes.add_line(diag2)

            # texts
            axes.text(6.25,0.05,'K = 0',family='sans-serif',size=self.fontSize,horizontalalignment='left',color='grey')
            axes.text(0.15,6.1,'K = inf.',family='sans-serif',size=self.fontSize,horizontalalignment='left',color='grey',rotation='vertical')
            axes.text(6.45,6.4,'K = 1',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='45')
            axes.text(3.2,6.4,'K = 2',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='63.5')
            axes.text(1.2,6.4,'K = 5',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='78.7')
            axes.text(6.4,3.1,'K = 0.5',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='26.6')
            axes.text(6.5,1.3,'K = 0.2',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='11.3')
            axes.text(2.6,3.35,'C = 6',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='-45')
            axes.text(1.75,2.2,'C = 4',family='sans-serif',size=self.fontSize,horizontalalignment='center',color='grey',rotation='-45')

            axes.text(3.5,3.75,'Girdle/Cluster Transition',family='sans-serif',size=self.fontSize,horizontalalignment='left',verticalalignment='bottom',color='grey',rotation='45')
            axes.text(6.5,7.2,'CLUSTERS',family='sans-serif',size=self.fontSize,horizontalalignment='right',verticalalignment='bottom',color='grey')
            axes.text(7.2,6.5,'GIRDLES',family='sans-serif',size=self.fontSize,horizontalalignment='left',verticalalignment='top',color='grey',rotation='-90')


            # plot the selected (checked) files
            # propsPList = [pdata, itemName, PolColor, symbPoles, polespin,...
            # propsLList = [pdata, itemName, LinColor, LineSymb, linespin,...

            if len(self.idxPlan) == 0 and len(self.idxLin) == 0: # in case we have only one one opened file but it is not checked
                raise AttributeError
            else:
                for i in range(len(self.idxPlan)):
                    axes.plot(self.PeigenList[i]["K_x"],self.PeigenList[i]["K_y"], self.PProps[i]["PoleSymb"], c=self.PProps[i]["PolColor"], ms=self.PProps[i]["polespin"], label='%s n=%d' % (self.Pname[i],self.Pndata[i]))

                for j in range(len(self.idxLin)):
                    axes.plot(self.LeigenList[j]["K_x"],self.LeigenList[j]["K_y"], self.LProps[j]["LineSymb"], c=self.LProps[j]["LinColor"], ms=self.LProps[j]["linespin"], label='%s n=%d' % (self.Lname[j],self.Lndata[j]))

            axes.legend(bbox_to_anchor=(1.1, 1), loc=2, prop=FontProperties(size='small'),numpoints=1)

            #set the axes limits and draws the stuff
            axes.set_xlim(0.0,7.2)
            axes.set_ylim(0.0,7.2)
            self.dataCanvas.draw()

        except AttributeError:
            self.dataFigure.clf()
            dlg = wx.MessageDialog(None, 'No file(s) selected (checked).\n\n', 'Oooops!', wx.OK|wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            pass


# plot triangular fabric diagram (Vollmer) - from QuickPlot
    def PlotVollmer(self, event): 

        #initialize the plot areas
        self.dataFigure.clf()
        axes = Subplot(self.dataFigure, 111, clip_on='True',xlim=(-0.1,1.05), ylim=(-0.1,1.05),autoscale_on='True',label='vollmer',aspect='equal', adjustable='box',anchor='SW')
        self.dataFigure.add_subplot(axes)
        axes.axis["right"].set_visible(False)
        axes.axis["top"].set_visible(False)
        axes.axis["bottom"].set_visible(False)
        axes.axis["left"].set_visible(False)



        try:
            sqrt3_2 = 0.866025  #m_sqrt(3)/2

            tr1 = Line2D((0,1),(0,0),c='black')
            axes.add_line(tr1)
            tr2 = Line2D((0,0.5),(0,sqrt3_2),c='black')
            axes.add_line(tr2)
            tr3 = Line2D((1,0.5),(0,sqrt3_2),c='black')
            axes.add_line(tr3)



            for i in [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]:
                diag = Line2D((i/2,1.0-i/2),(sqrt3_2*i,sqrt3_2*i),c='grey',lw=0.5)
                axes.add_line(diag)
                diag2 = Line2D((i/2,i),(sqrt3_2*i,0),c='grey',lw=0.5)
                axes.add_line(diag2)
                diag3 = Line2D((i,i+(1-i)/2),(0,sqrt3_2-sqrt3_2*i),c='grey',lw=0.5)
                axes.add_line(diag3)


            axes.text(-0.08,-0.05,'Point',family='sans-serif',size=self.fontSize,horizontalalignment='left' )
            axes.text(0.97,-0.05,'Girdle',family='sans-serif',size=self.fontSize,horizontalalignment='left' )
            axes.text(0.5,0.88,'Random',family='sans-serif',size=self.fontSize,horizontalalignment='center' )

            # label axes values
            for i in [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]:
                axes.text((1-i)/2, sqrt3_2*(1-i)-0.01, '%d' % (i*100), family='sans-serif', size=self.fontSize, horizontalalignment='right', color='grey', rotation='60')
                axes.text(i, -0.02,'%d' % (i*100), family='sans-serif', size=self.fontSize, horizontalalignment='center', verticalalignment='top', color='grey')
                axes.text(1.0-i/2, sqrt3_2*i-0.01,'%d' % (i*100) , family='sans-serif', size=self.fontSize, horizontalalignment='left', color='grey', rotation='-60')


            # ternary plot (from wikipedia)
            # P = (0,0)
            # G = (1,0)
            # R = (1/2, sqrt(3)/2)
            # given (P,G,R):
            # x = G + R/2
            # y = (sqrt(3)/2) * R

            if len(self.idxPlan) == 0 and len(self.idxLin) == 0: # in case we have only one one opened file but it is not checked
                raise AttributeError
            else:
                for i in range(len(self.idxPlan)):
                    x = self.PeigenList[i]["G"] + (self.PeigenList[i]["R"] / 2)
                    y = self.PeigenList[i]["R"] * sqrt3_2
                    axes.plot(x,y, self.PProps[i]["PoleSymb"], c=self.PProps[i]["PolColor"], ms=self.PProps[i]["polespin"],label='%s n=%d' % (self.Pname[i],self.Pndata[i]))

                for j in range(len(self.idxLin)):
                    x = self.LeigenList[j]["G"] + (self.LeigenList[j]["R"] / 2)
                    y = self.LeigenList[j]["R"] * sqrt3_2
                    axes.plot(x,y, self.LProps[j]["LineSymb"], c=self.LProps[j]["LinColor"], ms=self.LProps[j]["linespin"],label='%s n=%d' % (self.Lname[j],self.Lndata[j]))


            axes.legend(bbox_to_anchor=(0.97, 0.8), loc=2, prop=FontProperties(size=self.fontSize),numpoints=1)

            axes.set_xlim(-0.1,1.05)
            axes.set_ylim(-0.1,1.05)
            self.dataCanvas.draw()

        except AttributeError:
            self.dataFigure.clf()
            dlg = wx.MessageDialog(None, _('No file(s) selected (checked).\n\n'), _('Oooops!'), wx.OK|wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            pass


# clear plot area
    def ClearPlot(self, event):
        self.dataFigure.clf()
        self.dataCanvas.draw()
Exemple #34
0
class CanvasPanel(wx.Panel):
    def __init__(self,parent,figsize=(6,6)):
        wx.Panel.__init__(self,parent)
        self.SharedVariables()
        self.figure = Figure(figsize=figsize)
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.SetColor(None)
        buttongrid = self.ButtonGrid()
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.add_toolbar(sizer)
        sizer.Add(self.canvas, 0)
        sizer.Add(buttongrid,0,wx.ALIGN_CENTER_HORIZONTAL)
        hbox.Add(sizer,0)
        self.SetSizer(sizer)
        self.Show(True)

    ###################
    # Shared Variables
    ###################

    def SharedVariables(self):
        '''Get variables defined by another panel, needed
           by this panel.'''
        self._definecurpanel
        
    ##############
    # Boxes/Grids
    ##############

    def ButtonGrid(self):
        grid = wx.FlexGridSizer(1,5,0,0)
        x = wx.ALIGN_CENTER_HORIZONTAL
        rawdatabutton = wx.Button(self,-1,'Raw Data')
        self.Bind(wx.EVT_BUTTON,self.OnPlotRawDataClick,rawdatabutton)
        timeplotbutton = wx.Button(self,-1,'Time Plot')
        self.Bind(wx.EVT_BUTTON,self.OnTimePlotClick,timeplotbutton)
        self.freqplotbutton = wx.Button(self,-1,'Bode Plot')
        self.Bind(wx.EVT_BUTTON,self.OnFreqPlotClick,self.freqplotbutton)
        self.optimizebutton = wx.Button(self,-1,'Optimize')
        self.Bind(wx.EVT_BUTTON,self.OnOptimizeClick,self.optimizebutton)
        clearfigbutton = wx.Button(self,-1,'Clear')
        self.Bind(wx.EVT_BUTTON, self.OnCLF, clearfigbutton)
        grid.Add(rawdatabutton,0,wx.ALIGN_CENTER_HORIZONTAL)
        grid.Add(timeplotbutton,0,wx.ALIGN_CENTER_HORIZONTAL)
        grid.Add(self.freqplotbutton,0,wx.ALIGN_CENTER_HORIZONTAL)
        grid.Add(self.optimizebutton,0,x)
        grid.Add(clearfigbutton,0)
        return grid

    def add_toolbar(self,sizer):
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        tw, th = self.toolbar.GetSizeTuple()
        fw, fh = self.canvas.GetSizeTuple()
        self.toolbar.SetSize(wx.Size(fw, th))
        sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        self.toolbar.update()

    ########
    # Misc.
    ########

    def _definecurpanel(self):
        self.curpanel = self.Parent.Parent#self.Parent.curpanel

    def RenewCurpanel(self):
        self._definecurpanel()

    def Plot(self,x,y,**kwargs):
        if type(x)==list:
            for cx, cy in zip(x,y):
                self.axes.plot(cx,cy)
        else:
            self.axes.plot(x,y)
        self.canvas.draw()

    def show(self):
        self.ReDraw()
        
    def ReDraw(self):
        self.canvas.draw()

    def clf(self):
        self.figure.clf()
        self.axes = self.figure.add_subplot(111)
        self.canvas.draw()

    def cla(self):
        self.axes.cla()
        self.canvas.draw()

    def SetColor(self, rgbtuple):
        """Set figure and canvas colours to be the same"""
        if not rgbtuple:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        col = [c/255.0 for c in rgbtuple]
        self.figure.set_facecolor(col)
        self.figure.set_edgecolor(col)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    #########################
    # Widget Bound Functions
    #########################

    def OnPlot(self,e):
        self.Plot()

    def OnCLA(self,e):
        self.cla()

    def OnCLF(self,e):
        self.clf()

    def OnPaint(self, event):
        self.canvas.draw()

    def OnFreqPlotClick(self,e):
        self.RenewCurpanel()
        self.curpanel.FreqPlot()

    def OnTimePlotClick(self,e):
        self.RenewCurpanel()
        self.curpanel.TimePlot()
        
    def OnPlotRawDataClick(self,e):
        self.RenewCurpanel()
        self.curpanel.RawDataPlot()
        
    def OnOptimizeClick(self,e):
        self.RenewCurpanel()
        self.curpanel.Optimize()
class TRACE_ALLCHAN_WINDOW(Tk.Frame):
    """
  This window displays a live ADC redout
  """
    def __init__(self, master=None):
        self.maxtraces = 5
        self.selChan = 0

        Tk.Frame.__init__(self, master)  # hack to make work in python2

        self.pack()
        self.figure = Figure(figsize=(20, 8), dpi=100, facecolor='white')

        self.canvas = FigureCanvas(self.figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        self.toolbar = NaviationToolbar(self.canvas, self)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

        self.pauseButton = Tk.Button(self, text="Pause", command=self.pause)
        self.pauseButton.pack(side=Tk.LEFT)

        self.playButton = Tk.Button(self,
                                    text="Play",
                                    command=self.play,
                                    state=Tk.DISABLED)
        self.playButton.pack(side=Tk.LEFT)

        self.prevButton = Tk.Button(self,
                                    text="Previous Trace",
                                    command=self.prevTrace,
                                    state=Tk.DISABLED)
        self.prevButton.pack(side=Tk.LEFT)

        self.nextButton = Tk.Button(self,
                                    text="Next Trace",
                                    command=self.nextTrace,
                                    state=Tk.DISABLED)
        self.nextButton.pack(side=Tk.LEFT)

        self.femb = None
        self.iTrace = -1
        self.traces = []
        self.timestamps = []

        self.reset()

    def reset(self, iTrace=None):
        self.femb = FEMB_UDP()
        self.femb_config = CONFIG()
        self.figure.clf()
        self.subgs = [None] * 16 * 4
        self.ax = [None] * 16 * 4
        self.plot = [None] * 16 * 4

        # 4x4x4 grid, one cell per channel
        self.gs = gridspec.GridSpec(4, 16)
        self.gs.update(wspace=0.2, hspace=0.2)
        # 1 plots per channel
        for row in range(4):
            for col in range(16):
                self.subgs[col + 16 * row] = gridspec.GridSpecFromSubplotSpec(
                    1, 1, subplot_spec=self.gs[col + 16 * row], hspace=0.0)
                self.ax[col + 16 * row] = self.figure.add_subplot(
                    self.subgs[col + 16 * row][0])
                self.ax[col + 16 * row].tick_params(axis='x',
                                                    colors='black',
                                                    labelsize='medium')
                self.ax[col + 16 * row].tick_params(axis='y',
                                                    colors='black',
                                                    labelsize='smaller')

        if iTrace is None:
            self.ani = animation.FuncAnimation(self.figure,
                                               self.plotData,
                                               interval=100,
                                               blit=True)
        else:
            self.plotData(0, iTrace)
        self.canvas.draw()

    def pause(self):
        self.ani.event_source.stop()
        self.reset(self.iTrace)
        self.pauseButton['state'] = Tk.DISABLED
        self.playButton['state'] = Tk.NORMAL
        self.prevButton['state'] = Tk.NORMAL
        self.nextButton['state'] = Tk.DISABLED

    def play(self):
        self.ani.event_source.start()
        self.pauseButton['state'] = Tk.NORMAL
        self.playButton['state'] = Tk.DISABLED
        self.prevButton['state'] = Tk.DISABLED
        self.nextButton['state'] = Tk.DISABLED

    def prevTrace(self):
        self.iTrace -= 1
        self.reset(self.iTrace)
        if self.iTrace < 1:
            self.prevButton['state'] = Tk.DISABLED
        else:
            self.prevButton['state'] = Tk.NORMAL
        if self.iTrace >= len(self.traces) - 1:
            self.nextButton['state'] = Tk.DISABLED
        else:
            self.nextButton['state'] = Tk.NORMAL

    def nextTrace(self):
        self.iTrace += 1
        self.reset(self.iTrace)
        if self.iTrace < 1:
            self.prevButton['state'] = Tk.DISABLED
        else:
            self.prevButton['state'] = Tk.NORMAL
        if self.iTrace >= len(self.traces) - 1:
            self.nextButton['state'] = Tk.DISABLED
        else:
            self.nextButton['state'] = Tk.NORMAL

    def plotData(self, iFrame, iTrace=None):
        for a in self.ax:
            a.cla()
            a.locator_params(tight=True, nbins=3)

        # In case no data, return an empty plot
        self.plot[0] = self.ax[0].plot()

        for a in range(4):
            #for a in [2]:
            #if a != 0:
            #    continue
            asicNum = a
            #asicNum = 2
            self.femb_config.setExtClockRegs(asicNum)
            self.femb_config.selectAsic(asicNum)
            #self.femb_config.doAdcAsicConfig(a)
            #self.femb_config.initAsic(a)
            chPlots, thistimestamp = self.getTraceAndFFT(iTrace=iTrace)
            if chPlots == None:
                continue
            if thistimestamp == None:
                continue
            if len(chPlots) != 16:
                continue
            for chan in range(0, 16, 1):
                t = chPlots[chan][0]
                adc = chPlots[chan][1]
                if not (t is None) and not (adc is None):
                    self.plot[chan + 16 * a] = self.ax[chan + 16 * a].plot(
                        t, adc)
                    #if c+4*r < 12: self.ax[c+4*r].set_xticklabels([])
        self.figure.text(0.5,
                         0.02,
                         'Time [us]',
                         ha='center',
                         color='black',
                         fontsize='25.0',
                         weight='bold')
        self.figure.text(0.08,
                         0.5,
                         'ADC',
                         ha='center',
                         rotation=90,
                         color='black',
                         fontsize='25.0',
                         weight='bold')

        if not (thistimestamp is None):
            self.figure.suptitle(
                thistimestamp.replace(microsecond=0).isoformat(" "))
        self.canvas.draw()
        return self.plot[0]

    def getTraceAndFFT(self, iTrace=None):
        """
    Gets trace from FEMB and returns 4 1D arrays:
        times, ADC counts
    """
        data = None
        timestamp = None
        if iTrace is None:
            data = self.femb.get_data(5)
            timestamp = datetime.datetime.now()
            self.traces.append(data)
            self.timestamps.append(timestamp)
            if len(self.traces) > self.maxtraces:
                self.traces.pop(0)
                self.timestamps.pop(0)
            self.iTrace = len(self.traces) - 1
        else:
            data = self.traces[iTrace]
            timestamp = self.timestamps[iTrace]
        if data == None:
            return None, None
        if len(data) == 0:
            return None, None

        chSamples = self.convertHighSpeedPacked(data)

        if len(chSamples) != 16:
            return None, None

        chPlots = []
        for chan in range(0, 16, 1):
            xpoint = []
            ypoint = []
            num = 0
            for samp in chSamples[chan]:
                xpoint.append(num * 0.5)
                ypoint.append(samp)
                num = num + 1

            xarr = np.array(xpoint)
            yarr = np.array(ypoint)
            chPlots.append([xarr, yarr])

        return chPlots, timestamp

    #taken from write_root_tree
    def convertHighSpeedPacked(self, data):
        packetNum = 0
        wordArray = []
        result = [[] for chan in range(16)]
        for word in data:
            if str(hex(word)) == "0xface":
                packetNum = 0
                wordArray = []
            if packetNum > 0 and packetNum < 13:
                wordArray.append(word)
            if packetNum == 12:
                result[0].append(((wordArray[5] & 0xFFF0) >> 4))
                result[1].append(((wordArray[4] & 0xFF00) >> 8)
                                 | ((wordArray[5] & 0x000F) << 8))
                result[2].append(((wordArray[4] & 0x00FF) << 4)
                                 | ((wordArray[3] & 0xF000) >> 12))
                result[3].append(((wordArray[3] & 0x0FFF) >> 0))
                result[4].append(((wordArray[2] & 0xFFF0) >> 4))
                result[5].append(((wordArray[2] & 0x000F) << 8)
                                 | ((wordArray[1] & 0xFF00) >> 8))
                result[6].append(((wordArray[1] & 0x00FF) << 4)
                                 | ((wordArray[0] & 0xF000) >> 12))
                result[7].append(((wordArray[0] & 0x0FFF) >> 0))
                result[8].append(((wordArray[11] & 0xFFF0) >> 4))
                result[9].append(((wordArray[11] & 0x000F) << 8)
                                 | ((wordArray[10] & 0xFF00) >> 8))
                result[10].append(((wordArray[10] & 0x00FF) << 4)
                                  | ((wordArray[9] & 0xF000) >> 12))
                result[11].append(((wordArray[9] & 0x0FFF)))
                result[12].append(((wordArray[8] & 0xFFF0) >> 4))
                result[13].append(((wordArray[8] & 0x000F) << 8)
                                  | ((wordArray[7] & 0xFF00) >> 8))
                result[14].append(((wordArray[7] & 0x00FF) << 4)
                                  | ((wordArray[6] & 0xF000) >> 12))
                result[15].append(((wordArray[6] & 0x0FFF)))
            packetNum = packetNum + 1
        return result
class graph_panel(wx.Panel):
	def __init__(self, *args, **kwargs):
		wx.Panel.__init__(self, *args, **kwargs)
		self.previous_patterns=[]
		self.history_size=100
		self.hi_contrast=False
		self.build()
		
	def build(self):
		self.fig = Figure(dpi=110)
		#self.fig.set_facecolor('#d4d0c8')
		self.fig.set_facecolor('#888888')
		self.canvas = FigCanvas(self, -1, self.fig)
		self.Bind(wx.EVT_SIZE, self.sizeHandler)
		self.SetMinSize((400,200))
		self.clear()
		self.draw()
		
	def sizeHandler(self, *args, **kwargs):
		''' makes sure that the canvas is properly resized '''
		self.canvas.SetSize(self.GetSize())
		
	########################
	
	def set_hi_contrast(self, event):
		''' set the contrast '''
		self.hi_contrast=event.IsChecked()

	def clear(self):
		''' called when the pattern changes '''
		self.need_data=True
		self.singles_curves=[]
		self.coincidence_curves=[]
		
	def add_counts(self, data):
		''' add a set of counts '''
		new_singles=filter(lambda x: len(x[1])==1, data)
		new_coincidences=filter(lambda x: len(x[1])>1, data)
		
		if self.need_data:
			self.singles_curves=[curve(q[0], self.history_size) for q in new_singles]
			self.coincidence_curves=[curve(q[0], self.history_size) for q in new_coincidences]
			self.need_data=False
			
		for i in range(len(self.singles_curves)):
			self.singles_curves[i].add_point(new_singles[i][2])
			
		for i in range(len(self.coincidence_curves)):
			self.coincidence_curves[i].add_point(new_coincidences[i][2])
		self.draw()
		
	def draw_curve_set(self, curves, subplot_index):
		ax=self.fig.add_subplot(subplot_index)
		ax.set_axis_bgcolor('#000000')
		for c in curves:
			c.draw(ax, self.hi_contrast)
		ax.set_xlim(0, self.history_size)
		yfm=ax.yaxis.get_major_formatter()
		yfm.set_powerlimits([0,1])
		
	def draw(self):
		''' draw all of the curves etc '''
		self.fig.clf()
		self.draw_curve_set(self.singles_curves, 211)
		self.draw_curve_set(self.coincidence_curves, 212)
		self.fig.subplots_adjust(left=.05, right=.98, top=.97, bottom=.05)
		self.canvas.draw()
Exemple #37
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16384

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(24 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # initialize cursor
    self.cursor = None
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pButton.clicked.connect(self.write_s2p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.addItems(['500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(0, self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    self.gainPlot.clicked.connect(self.plot_gain)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    if not self.reading:
      self.socket.readAll()
      return
    size = self.socket.bytesAvailable()
    self.progress.setValue((self.offset + size) / 24)
    limit = 24 * (self.sweep_size + 1)
    if self.offset + size < limit:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
      self.adc1 = self.data[0::3]
      self.adc2 = self.data[1::3]
      self.dac1 = self.data[2::3]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1]
      getattr(self, 'plot_%s' % self.mode)()
      self.reading = False
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def set_rate(self, value):
    if self.idle: return
    rate = [1, 5, 10, 50, 100, 500][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0))))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 6<<28))
    self.offset = 0
    self.reading = True
    self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1)
    self.progress.setModal(True)
    self.progress.setMinimumDuration(1000)
    self.progress.canceled.connect(self.cancel)

  def cancel(self):
    self.offset = 0
    self.reading = False
    self.socket.write(struct.pack('<I', 7<<28))
    self.sweepFrame.setEnabled(True)
    self.selectFrame.setEnabled(True)

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def gain(self):
    size = self.sweep_size
    return self.dut[0:size]/self.short[0:size]

  def impedance(self):
    size = self.sweep_size
    return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_gain(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    gain = self.gain()
    axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Gain, dB')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_magphase(self, data):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith_grid(self, axes, color):
    load = 50.0
    ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
    for tick in ticks * load:
      axis = np.logspace(-4, np.log10(1.0e3), 200) * load
      z = tick + 1.0j * axis
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      z = axis + 1.0j * tick
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      if tick == 0.0:
        axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0)
        axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
        continue
      lab = u'%d\u03A9' % tick
      x = (tick - load) / (tick + load)
      axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
      lab = u'j%d\u03A9' % tick
      z =  1.0j * tick
      gamma = (z - load)/(z + load) * 1.05
      x = gamma.real
      y = gamma.imag
      angle = np.angle(gamma) * 180.0 / np.pi - 90.0
      axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0)
      lab = u'-j%d\u03A9' % tick
      axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0)

  def plot_smith(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0)
    axes1 = self.figure.add_subplot(111)
    self.plot_smith_grid(axes1, 'blue')
    gamma = self.gamma()
    plot, = axes1.plot(gamma.real, gamma.imag, color = 'red')
    axes1.axis('equal')
    axes1.set_xlim(-1.12, 1.12)
    axes1.set_ylim(-1.12, 1.12)
    axes1.xaxis.set_visible(False)
    axes1.yaxis.set_visible(False)
    for loc, spine in axes1.spines.items():
      spine.set_visible(False)
    self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple')
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_rl(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(0, size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gain = self.gain()
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()
Exemple #38
0
class PlottingCanvasView(QtWidgets.QWidget, PlottingCanvasViewInterface):
    def __init__(self, quick_edit, settings, parent=None):
        super().__init__(parent)
        # later we will allow these to be changed in the settings
        self._settings = settings
        self._min_y_range = settings.min_y_range
        self._y_axis_margin = settings.y_axis_margin
        self._x_tick_labels = None
        self._y_tick_labels = None
        # create the figure
        self.fig = Figure()
        self.fig.canvas = FigureCanvas(self.fig)
        self.fig.canvas.setMinimumHeight(500)
        self.toolBar = PlotToolbar(self.fig.canvas, self)

        # Create a set of Mantid axis for the figure
        self.fig, axes = get_plot_fig(overplot=False,
                                      ax_properties=None,
                                      axes_num=1,
                                      fig=self.fig)
        self._number_of_axes = 1
        self._color_queue = [ColorQueue(DEFAULT_COLOR_CYCLE)]

        # Add a splitter for the plotting canvas and quick edit toolbar
        splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        splitter.addWidget(self.fig.canvas)
        self._quick_edit = quick_edit
        splitter.addWidget(self._quick_edit)
        splitter.setChildrenCollapsible(False)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.toolBar)
        layout.addWidget(splitter)
        self.setLayout(layout)

        self._plot_information_list = []  # type : List[PlotInformation}

    @property
    def autoscale_state(self):
        return self._quick_edit.autoscale_state

    @property
    def plotted_workspace_information(self):
        return self._plot_information_list

    @property
    def plotted_workspaces_and_indices(self):
        plotted_workspaces = []
        plotted_indices = []
        for plot_info in self._plot_information_list:
            plotted_workspaces.append(plot_info.workspace_name)
            plotted_indices.append(plot_info.index)

        return plotted_workspaces, plotted_indices

    @property
    def num_plotted_workspaces(self):
        return len(self._plot_information_list)

    @property
    def number_of_axes(self):
        return self._number_of_axes

    def set_x_ticks(self, x_ticks=None):
        self._x_tick_labels = x_ticks

    def set_y_ticks(self, y_ticks=None):
        self._y_tick_labels = y_ticks

    def create_new_plot_canvas(self, num_axes):
        """Creates a new blank plotting canvas"""
        self.toolBar.reset_gridline_flags()
        self._plot_information_list = []
        self._number_of_axes = num_axes
        self._color_queue = [
            ColorQueue(DEFAULT_COLOR_CYCLE) for _ in range(num_axes)
        ]
        self.fig.clf()
        self.fig, axes = get_plot_fig(overplot=False,
                                      ax_properties=None,
                                      axes_num=num_axes,
                                      fig=self.fig)
        if self._settings.is_condensed:
            self.fig.subplots_adjust(wspace=0, hspace=0)
        else:
            self.fig.tight_layout()
        self.fig.canvas.draw()

    def clear_all_workspaces_from_plot(self):
        """Clears all workspaces from the plot"""
        for ax in self.fig.axes:
            ax.cla()
            ax.tracked_workspaces.clear()
            ax.set_prop_cycle(None)

        for color_queue in self._color_queue:
            color_queue.reset()

        self._plot_information_list = []

    def _make_plot(self, workspace_plot_info: WorkspacePlotInformation):
        workspace_name = workspace_plot_info.workspace_name
        try:
            workspace = AnalysisDataService.Instance().retrieve(workspace_name)
        except (RuntimeError, KeyError):
            return -1
        self._plot_information_list.append(workspace_plot_info)
        errors = workspace_plot_info.errors
        ws_index = workspace_plot_info.index
        axis_number = workspace_plot_info.axis
        ax = self.fig.axes[axis_number]
        plot_kwargs = self._get_plot_kwargs(workspace_plot_info)
        plot_kwargs['color'] = self._color_queue[axis_number]()
        _do_single_plot(ax,
                        workspace,
                        ws_index,
                        errors=errors,
                        plot_kwargs=plot_kwargs)
        return axis_number

    def add_workspaces_to_plot(
            self, workspace_plot_info_list: List[WorkspacePlotInformation]):
        """Add a list of workspaces to the plot - The workspaces are contained in a list PlotInformation
        The PlotInformation contains the workspace name, workspace index and target axis."""
        nrows, ncols = get_num_row_and_col(self._number_of_axes)
        for workspace_plot_info in workspace_plot_info_list:
            axis_number = self._make_plot(workspace_plot_info)
            if axis_number < 0:
                continue
            self._set_text_tick_labels(axis_number)
            if self._settings.is_condensed:
                self.hide_axis(axis_number, nrows, ncols)
        #remove labels from empty plots
        if self._settings.is_condensed:
            for axis_number in range(int(self._number_of_axes),
                                     int(nrows * ncols)):
                self.hide_axis(axis_number, nrows, ncols)

    def _wrap_labels(self, labels: list) -> list:
        """Wraps a list of labels so that every line is at most self._settings.wrap_width characters long."""
        return [
            "\n".join(wrap(label, self._settings.wrap_width))
            for label in labels
        ]

    def _set_text_tick_labels(self, axis_number):
        ax = self.fig.axes[axis_number]
        if self._x_tick_labels:
            ax.set_xticks(range(len(self._x_tick_labels)))
            labels = self._wrap_labels(self._x_tick_labels)
            ax.set_xticklabels(labels,
                               fontsize=self._settings.font_size,
                               rotation=self._settings.rotation,
                               ha="right")
        if self._y_tick_labels:
            ax.set_yticks(range(len(self._y_tick_labels)))
            labels = self._wrap_labels(self._y_tick_labels)
            ax.set_yticklabels(labels, fontsize=self._settings.font_size)

    def hide_axis(self, axis_number, nrows, ncols):
        row, col = convert_index_to_row_and_col(axis_number, nrows, ncols)
        ax = self.fig.axes[axis_number]
        if row != nrows - 1:
            labels = ["" for item in ax.get_xticks().tolist()]
            ax.set_xticklabels(labels)
            ax.xaxis.label.set_visible(False)
        if col != 0 and col != ncols - 1:
            labels = ["" for item in ax.get_yticks().tolist()]
            ax.set_yticklabels(labels)
            ax.yaxis.label.set_visible(False)
        elif col == ncols - 1 and ncols > 1:
            ax.yaxis.set_label_position('right')
            ax.yaxis.tick_right()

    def remove_workspace_info_from_plot(
            self, workspace_plot_info_list: List[WorkspacePlotInformation]):
        # We reverse the workspace info list so that we can maintain a unique color queue
        # See _update_color_queue_on_workspace_removal for more
        workspace_plot_info_list.reverse()
        for workspace_plot_info in workspace_plot_info_list:
            workspace_name = workspace_plot_info.workspace_name
            if not AnalysisDataService.Instance().doesExist(workspace_name):
                continue

            workspace = AnalysisDataService.Instance().retrieve(workspace_name)
            for plotted_information in self._plot_information_list.copy():
                if workspace_plot_info.workspace_name == plotted_information.workspace_name and \
                        workspace_plot_info.axis == plotted_information.axis:
                    self._update_color_queue_on_workspace_removal(
                        workspace_plot_info.axis, workspace_name)
                    axis = self.fig.axes[workspace_plot_info.axis]
                    axis.remove_workspace_artists(workspace)
                    self._plot_information_list.remove(plotted_information)

        # If we have no plotted lines, reset the color cycle
        if self.num_plotted_workspaces == 0:
            self._reset_color_cycle()

    def remove_workspace_from_plot(self, workspace):
        """Remove all references to a workspaces from the plot """
        for workspace_plot_info in self._plot_information_list.copy():
            workspace_name = workspace_plot_info.workspace_name
            if workspace_name == workspace.name():
                self._update_color_queue_on_workspace_removal(
                    workspace_plot_info.axis, workspace_name)
                axis = self.fig.axes[workspace_plot_info.axis]
                axis.remove_workspace_artists(workspace)
                self._plot_information_list.remove(workspace_plot_info)

    def _update_color_queue_on_workspace_removal(self, axis_number,
                                                 workspace_name):
        try:
            artist_info = self.fig.axes[axis_number].tracked_workspaces[
                workspace_name]
        except KeyError:
            return
        for ws_artist in artist_info:
            for artist in ws_artist._artists:
                if isinstance(artist, ErrorbarContainer):
                    color = artist[0].get_color()
                else:
                    color = artist.get_color()
                # When we repeat colors we don't want to add colors to the queue if they are already plotted.
                # We know we are repeating colors if we have more lines than colors, then we check if the color
                # removed is already the color of an existing line. If it is we don't manually re-add the color
                # to the queue. This ensures we only plot lines of the same colour if we have more lines
                # plotted than colours
                lines = self.fig.axes[axis_number].get_lines()
                if len(lines) > NUMBER_OF_COLOURS:
                    current_colors = [line.get_c() for line in lines]
                    if color in current_colors:
                        return
                self._color_queue[axis_number] += color

    # Ads observer functions
    def replace_specified_workspace_in_plot(self, workspace):
        """Replace specified workspace in the plot with a new and presumably updated instance"""
        for workspace_plot_info in self._plot_information_list:
            plotted_workspace_name = workspace_plot_info.workspace_name
            workspace_name = workspace.name()
            if workspace_name == plotted_workspace_name:
                axis = self.fig.axes[workspace_plot_info.axis]
                axis.replace_workspace_artists(workspace)
        self.redraw_figure()

    def replot_workspace_with_error_state(self, workspace_name,
                                          with_errors: bool):
        for plot_info in self.plotted_workspace_information:
            if plot_info.workspace_name == workspace_name:
                axis = self.fig.axes[plot_info.axis]
                workspace_name = plot_info.workspace_name
                artist_info = axis.tracked_workspaces[workspace_name]
                for ws_artist in artist_info:
                    for artist in ws_artist._artists:
                        if isinstance(artist, ErrorbarContainer):
                            color = artist[0].get_color()
                        else:
                            color = artist.get_color()
                        plot_kwargs = self._get_plot_kwargs(plot_info)
                        plot_kwargs["color"] = color
                        axis.replot_artist(artist, with_errors, **plot_kwargs)
        self.redraw_figure()

    def set_axis_xlimits(self, axis_number, xlims):
        ax = self.fig.axes[axis_number]
        ax.set_xlim(xlims[0], xlims[1])

    def set_axis_ylimits(self, axis_number, ylims):
        ax = self.fig.axes[axis_number]
        ax.set_ylim(ylims[0], ylims[1])

    def set_axes_limits(self, xlim, ylim):
        plt.setp(self.fig.axes, xlim=xlim, ylim=ylim)

    def autoscale_y_axes(self):
        ymin = 1e9
        ymax = -1e9
        for axis in self.fig.axes:
            ymin_i, ymax_i = self._get_y_axis_autoscale_limits(axis)
            if ymin_i < ymin:
                ymin = ymin_i
            if ymax_i > ymax:
                ymax = ymax_i
        plt.setp(self.fig.axes, ylim=[ymin, ymax])

    @property
    def get_xlim_list(self):
        xlim_list = []
        for axis in self.fig.axes:
            min, max = axis.get_xlim()
            xlim_list.append([min, max])
        return xlim_list

    @property
    def get_ylim_list(self):
        ylim_list = []
        for axis in self.fig.axes:
            min, max = axis.get_ylim()
            ylim_list.append([min, max])
        return ylim_list

    def autoscale_selected_y_axis(self, axis_number):
        if axis_number >= len(self.fig.axes):
            return
        axis = self.fig.axes[axis_number]
        bottom, top, = self._get_y_axis_autoscale_limits(axis)
        axis.set_ylim(bottom, top)

    def set_title(self, axis_number, title):
        if axis_number >= self.number_of_axes or self._settings.is_condensed:
            return
        axis = self.fig.axes[axis_number]
        axis.set_title(title)

    def get_axis_limits(self, axis_number):
        xmin, xmax = self.fig.axes[axis_number].get_xlim()
        ymin, ymax = self.fig.axes[axis_number].get_ylim()

        return xmin, xmax, ymin, ymax

    def redraw_figure(self):
        self.fig.canvas.toolbar.update()
        self._redraw_legend()
        if not self._settings.is_condensed:
            self.fig.tight_layout()
        self.fig.canvas.draw()

    def _redraw_legend(self):
        for ax in self.fig.axes:
            if ax.get_legend_handles_labels()[0]:
                legend = ax.legend(prop=dict(size=5))
                legend_set_draggable(legend, True)

    def _get_plot_kwargs(self, workspace_info: WorkspacePlotInformation):
        label = workspace_info.label
        plot_kwargs = {
            'distribution': True,
            'autoscale_on_update': False,
            'label': label
        }
        plot_kwargs["marker"] = self._settings.get_marker(
            workspace_info.workspace_name)
        plot_kwargs["linestyle"] = self._settings.get_linestyle(
            workspace_info.workspace_name)
        return plot_kwargs

    def _get_y_axis_autoscale_limits(self, axis):
        x_min, x_max = sorted(axis.get_xlim())
        y_min, y_max = np.inf, -np.inf
        for line in axis.lines:
            y_min, y_max = get_y_min_max_between_x_range(
                line, x_min, x_max, y_min, y_max)
        if y_min == np.inf:
            y_min = -self._min_y_range
        if y_max == -np.inf:
            y_max = self._min_y_range
        if y_min == y_max:
            y_min -= self._min_y_range
            y_max += self._min_y_range
        y_margin = abs(y_max - y_min) * self._y_axis_margin

        return y_min - y_margin, y_max + y_margin

    def _reset_color_cycle(self):
        for i, ax in enumerate(self.fig.axes):
            ax.cla()
            ax.tracked_workspaces.clear()

    def resizeEvent(self, event):
        if self._settings.is_condensed:
            return
        self.fig.tight_layout()

    def add_uncheck_autoscale_subscriber(self, observer):
        self.toolBar.uncheck_autoscale_notifier.add_subscriber(observer)

    def add_enable_autoscale_subscriber(self, observer):
        self.toolBar.enable_autoscale_notifier.add_subscriber(observer)

    def add_disable_autoscale_subscriber(self, observer):
        self.toolBar.uncheck_autoscale_notifier.add_subscriber(observer)

    def add_range_changed_subscriber(self, observer):
        self.toolBar.range_changed_notifier.add_subscriber(observer)
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__( *args, **kwargs)

        self.setWindowTitle("Simulation Mode")

        main_layout = QVBoxLayout()
        header_layout = QHBoxLayout()
        simdisplay_layout = QVBoxLayout()
        slider_layout = QHBoxLayout()
        graph_layout = QVBoxLayout()
        input_layout = QVBoxLayout()

        self.windowbutton = QPushButton("Switch to Question Mode")
        self.windowbutton.pressed.connect(self.switch_mode)

        self.rangedisplay = QLabel("Final Range: ")
        self.timedisplay = QLabel("Final Time Taken: ")

        self.veloinp = QLineEdit(self)
        self.velolabel = QLabel("Enter your velocity:")
        self.anglespin = QDoubleSpinBox(cleanText = None, decimals = 2, maximum = 90, minimum = 0, prefix = None, singleStep = 1, stepType = None, suffix = None, value = 0)
        self.anglelabel = QLabel("Enter your angle:")
        self.elevinp = QLineEdit(self)
        self.elevlabel = QLabel("Enter your elevation:")

        self.elevslider = QSlider(Qt.Vertical)
        self.elevslider.setMinimum(0)
        self.elevslider.setMaximum(100)
        self.elevslider.setSingleStep(1)
        self.elevslider.sliderReleased.connect(self.get_elevation)
        
        self.sliderlabel = QGraphicsScene(self)
        self.sliderlabel.addText("Adjust elevation") 
        self.view = QGraphicsView(self.sliderlabel)
        self.view.rotate(270)
        self.view.show()

        self.figure = Figure(figsize=(5,10),dpi=100)
        self.canvas = FigureCanvas(self.figure)
        self.animbutton = QPushButton("Start")
        self.animbutton.pressed.connect(self.animate)
        self.animbutton.pressed.connect(self.display_range_time)

        simdisplay_layout.addWidget(self.rangedisplay)
        simdisplay_layout.addWidget(self.timedisplay)
        simdisplay_layout.setAlignment(Qt.AlignRight)

        header_layout.addWidget(self.windowbutton)
        header_layout.addLayout(simdisplay_layout)

        slider_layout.addWidget(self.view)
        slider_layout.addWidget(self.elevslider)
        slider_layout.addWidget(self.canvas)

        graph_layout.addLayout(slider_layout)
        graph_layout.addWidget(self.animbutton)

        input_layout.addWidget(self.velolabel)
        input_layout.addWidget(self.veloinp)
        input_layout.addWidget(self.anglelabel)
        input_layout.addWidget(self.anglespin)
        input_layout.addWidget(self.elevlabel)
        input_layout.addWidget(self.elevinp)

        main_layout.addLayout(header_layout)
        main_layout.addLayout(graph_layout)
        main_layout.addLayout(input_layout)

        self.veloinp.editingFinished.connect(self.input_velocity)
        self.anglespin.editingFinished.connect(self.input_angle)
        self.elevinp.editingFinished.connect(self.input_elevation)

        self.sim_widget = QWidget()
        self.sim_widget.setLayout(main_layout)

        select_layout = QHBoxLayout()
        input_layout = QVBoxLayout()
        ans_layout = QHBoxLayout()
        interface_layout = QVBoxLayout()
        whole_layout = QHBoxLayout()

        graph_layout = QVBoxLayout()

        self.selectgvalue = QPushButton("Select G Value")

        self.selectlabel = QLabel("Select A Target Value")
        self.selectlabel.setAlignment(Qt.AlignCenter)
        self.selectrange = QPushButton("Range")
        self.selectmaxheight = QPushButton("Max Height")
        self.selecttimetaken = QPushButton("Time Taken")
        self.selectinitvelo = QPushButton("Initial Velocity")
        self.selectang = QPushButton("Angle of Projection")
        self.selectgivenvelocity = QPushButton("Velocity at given time")
        self.selectxypos = QPushButton("X & Y Position")
        self.selectdirec = QPushButton("Angle of flight")

        self.veloinp = QLineEdit(self)
        self.velolabel = QLabel("Enter your velocity:")
        self.angleinp = QLineEdit(self)
        self.anglelabel = QLabel("Enter your angle:")
        self.elevinp = QLineEdit(self)
        self.elevlabel = QLabel("Enter your elevation:")
        self.timeinp = QLineEdit(self)
        self.timelabel = QLabel("Enter your time:")
        self.ansinp = QLineEdit(self)
        self.anslabel = QLabel("Enter your answer:")

        self.correctans = QLabel("Correct")
        self.falseans = QLabel("False")
        self.ansdisplay_widget = QStackedWidget()

        self.checkbuttR = QPushButton("Check Range")
        self.checkbuttH = QPushButton("Check Max Height")
        self.checkbuttT = QPushButton("Check Time Taken")
        self.checkbuttXY = QPushButton("Check XY Position")
        self.multicheck_widget = QStackedWidget()

        self.figure = Figure(figsize=(5,5),dpi=100)
        self.canvas = FigureCanvas(self.figure)
        self.animbutton = QPushButton("Start")
        self.animbutton.pressed.connect(self.animate)

        select_layout.addWidget(self.selectrange)
        select_layout.addWidget(self.selectmaxheight)
        select_layout.addWidget(self.selecttimetaken)
        select_layout.addWidget(self.selectxypos)

        input_layout.addWidget(self.velolabel)
        input_layout.addWidget(self.veloinp)
        input_layout.addWidget(self.anglelabel)
        input_layout.addWidget(self.angleinp)
        input_layout.addWidget(self.elevlabel)
        input_layout.addWidget(self.elevinp)
        input_layout.addWidget(self.timelabel)
        input_layout.addWidget(self.timeinp)

        ans_layout.addWidget(self.anslabel)
        ans_layout.addWidget(self.ansinp)
        
        self.selectgvalue.pressed.connect(self.showgvalue)

        self.ansdisplay_widget.addWidget(self.correctans)
        self.ansdisplay_widget.addWidget(self.falseans)
        ans_layout.addWidget(self.ansdisplay_widget)
        self.ansdisplay_widget.hide()

        self.multicheck_widget.addWidget(self.checkbuttR)
        self.multicheck_widget.addWidget(self.checkbuttH)
        self.multicheck_widget.addWidget(self.checkbuttT)
        self.multicheck_widget.addWidget(self.checkbuttXY)
        self.multicheck_widget.show()

        self.selectrange.pressed.connect(self.choose_range)
        self.selectmaxheight.pressed.connect(self.choose_maxheight)
        self.selecttimetaken.pressed.connect(self.choose_timetaken)
        self.selectxypos.pressed.connect(self.choose_xypos)

        self.veloinp.editingFinished.connect(self.input_velocity)
        self.angleinp.editingFinished.connect(self.input_angle)
        self.elevinp.editingFinished.connect(self.input_elevation)
        self.timeinp.editingFinished.connect(self.input_time)

        self.checkbuttR.pressed.connect(self.check_rangeans)
        self.checkbuttH.pressed.connect(self.check_maxheightans)
        self.checkbuttT.pressed.connect(self.check_timetakenans)
        self.checkbuttXY.pressed.connect(self.check_xypos)

        interface_layout.addWidget(self.selectgvalue)
        interface_layout.addWidget(self.selectlabel)
        interface_layout.addLayout(select_layout)
        interface_layout.addLayout(input_layout)
        interface_layout.addLayout(ans_layout)
        interface_layout.addWidget(self.multicheck_widget)

        whole_layout.addLayout(interface_layout)
        whole_layout.addWidget(self.canvas)

        self.que_widget = QWidget()
        self.que_widget.setLayout(whole_layout)

        self.main_widget = QStackedWidget()
        self.main_widget.addWidget(self.sim_widget)
        self.main_widget.addWidget(self.que_widget)

        self.setCentralWidget(self.main_widget)

    def animate(self):
        try:
            self.cl = self.figure.clf()
            self.ax = self.figure.add_subplot()
            self.circle = Circle((0,0), 0.3) 
            self.ax.add_artist(self.circle) 
            self.ax.set_xlim([0,30]) 
            self.ax.set_ylim([0,30])
            self.animation = animation.FuncAnimation(self.figure,self.animate_loop,frames=np.arange(0, CalcTimeTaken(float(self.veloinp.text()), float(self.anglespin.text()), float(self.elevinp.text())), 0.01),interval=10,repeat=False) 
            self.canvas.draw()
        except:
            print("Error")
    
    def animate_loop(self,t):
        self.circle.center=(float(self.veloinp.text()) * np.cos((np.pi/180)*float(self.anglespin.text())) * t, float(self.veloinp.text()) * np.sin((np.pi/180)*float(self.anglespin.text())) * t - (0.5) * g * (t)**2 + float(self.elevinp.text()))
        return self.circle
    
    def switch_mode(self):
        self.main_widget.setCurrentWidget(self.que_widget)
        self.setWindowTitle("Question Mode")

    def input_velocity(self):
        calclist[0] = float(self.veloinp.text())

    def input_angle(self):
        calclist[1] = float(self.anglespin.text())

    def input_elevation(self):
        calclist[2] = float(self.elevinp.text())
        rounded_elev = round(float(self.elevinp.text()), 0)
        self.elevslider.setValue(int(rounded_elev))

    def input_time(self):
        calclist[3] = float(self.timeinp.text())
    
    def get_elevation(self):
        elevation = str(self.elevslider.value())
        self.elevinp.setText(elevation)
    
    def display_range_time(self):
        self.rangedisplay.setText(f'Final Range: {str(CalcRange(calclist[0], calclist[1], calclist[2]))}')
        self.timedisplay.setText(f'Final Time Taken: {str(CalcTimeTaken(calclist[0], calclist[1], calclist[2]))}')
    
    def showgvalue(self):
        gdialog = QDialog()
        g_layout = QHBoxLayout()
        self.nineeightcheck = QCheckBox()
        self.nineeightlabel = QLabel("9.8")
        self.nineeightonecheck = QCheckBox()
        self.nineeightonelabel = QLabel("9.81")
        self.customginput = QLineEdit(self)
        self.customglabel = QLabel("Enter a g value:")

        g_layout.addWidget(self.nineeightlabel)
        g_layout.addWidget(self.nineeightcheck)
        g_layout.addWidget(self.nineeightonelabel)
        g_layout.addWidget(self.nineeightonecheck)
        g_layout.addWidget(self.customglabel)
        g_layout.addWidget(self.customginput)

        gdialog.setWindowTitle("Change g value")
        gdialog.setLayout(g_layout)
        gdialog.exec_()
    
    def setgvalue(self):
        if self.nineeightcheck.isChecked == True:
            g = 9.8
        if self.nineeightcheck.isChecked == True:
            g = 9.81
        if self.nineeightcheck.isChecked == True:
            g = self.customginput.text()
    
    def calculate_range(self):
        CalcRange(calclist[0], calclist[1], calclist[2])
    
    def check_rangeans(self):
        if float(self.ansinp.text()) == CalcRange(calclist[0], calclist[1], calclist[2]):
            self.ansdisplay_widget.setCurrentWidget(self.correctans)
            self.ansdisplay_widget.show()
            self.animate()
        else:
            self.ansdisplay_widget.setCurrentWidget(self.falseans)
            self.ansdisplay_widget.show()
    
    def calculate_maxheight(self):
        CalcMaxHeight(calclist[0], calclist[1], calclist[2])

    def check_maxheightans(self):
        if float(self.ansinp.text()) == CalcMaxHeight(calclist[0], calclist[1], calclist[2]):
            self.ansdisplay_widget.setCurrentWidget(self.correctans)
            self.ansdisplay_widget.show()
            self.animate()
        else:
            self.ansdisplay_widget.setCurrentWidget(self.falseans)
            self.ansdisplay_widget.show()

    def calculate_timetaken(self):
        CalcTimeTaken(calclist[0], calclist[1], calclist[2])

    def check_timetakenans(self):
        if float(self.ansinp.text()) == CalcTimeTaken(calclist[0], calclist[1], calclist[2]):
            self.ansdisplay_widget.setCurrentWidget(self.correctans)
            self.ansdisplay_widget.show()
            self.animate()
        else:
            self.ansdisplay_widget.setCurrentWidget(self.falseans)
            self.ansdisplay_widget.show()

    def calculate_xypos(self):
        CalcXYPosition(calclist[0], calclist[1], calclist[2], calclist[3])

    def check_xypos(self):
        if float(self.ansinp.text()) == CalcXYPosition(calclist[0], calclist[1], calclist[2], calclist[3]):
            self.ansdisplay_widget.setCurrentWidget(self.correctans)
            self.ansdisplay_widget.show()
            self.animate()
        else:
            self.ansdisplay_widget.setCurrentWidget(self.falseans)
            self.ansdisplay_widget.show()
    
    def choose_range(self):
        self.multicheck_widget.setCurrentWidget(self.checkbuttR)
        self.multicheck_widget.show()

    def choose_maxheight(self):
        self.multicheck_widget.setCurrentWidget(self.checkbuttH)
        self.multicheck_widget.show()

    def choose_timetaken(self):
        self.multicheck_widget.setCurrentWidget(self.checkbuttT)
        self.multicheck_widget.show()

    def choose_xypos(self):
        self.multicheck_widget.setCurrentWidget(self.checkbuttXY)
        self.multicheck_widget.show()
Exemple #40
0
class FigureTab:
    cursors = [15000, 35000]
    colors = ['orange', 'violet']

    def __init__(self, layout, vna):
        # create figure
        self.figure = Figure()
        if sys.platform != 'win32':
            self.figure.set_facecolor('none')
        self.canvas = FigureCanvas(self.figure)
        layout.addWidget(self.canvas)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, None, False)
        self.toolbar.layout().setSpacing(6)
        # remove subplots action
        actions = self.toolbar.actions()
        if int(matplotlib.__version__[0]) < 2:
            self.toolbar.removeAction(actions[7])
        else:
            self.toolbar.removeAction(actions[6])
        self.toolbar.addSeparator()
        self.cursorLabels = {}
        self.cursorValues = {}
        self.cursorMarkers = {}
        self.cursorPressed = {}
        for i in range(len(self.cursors)):
            self.cursorMarkers[i] = None
            self.cursorPressed[i] = False
            self.cursorLabels[i] = QLabel('Cursor %d, kHz' % (i + 1))
            self.cursorLabels[i].setStyleSheet('color: %s' % self.colors[i])
            self.cursorValues[i] = QSpinBox()
            self.cursorValues[i].setMinimumSize(90, 0)
            self.cursorValues[i].setSingleStep(10)
            self.cursorValues[i].setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                              | Qt.AlignVCenter)
            self.toolbar.addWidget(self.cursorLabels[i])
            self.toolbar.addWidget(self.cursorValues[i])
            self.cursorValues[i].valueChanged.connect(
                partial(self.set_cursor, i))
            self.canvas.mpl_connect('button_press_event',
                                    partial(self.press_marker, i))
            self.canvas.mpl_connect('motion_notify_event',
                                    partial(self.move_marker, i))
            self.canvas.mpl_connect('button_release_event',
                                    partial(self.release_marker, i))
        self.toolbar.addSeparator()
        self.plotButton = QPushButton('Rescale')
        self.toolbar.addWidget(self.plotButton)
        layout.addWidget(self.toolbar)
        self.plotButton.clicked.connect(self.plot)
        self.mode = None
        self.vna = vna

    def add_cursors(self, axes):
        if self.mode == 'gain_short' or self.mode == 'gain_open':
            columns = ['Freq., kHz', 'G, dB', r'$\angle$ G, deg']
        else:
            columns = [
                'Freq., kHz', 'Re(Z), \u03A9', 'Im(Z), \u03A9', '|Z|, \u03A9',
                r'$\angle$ Z, deg', 'SWR', r'|$\Gamma$|',
                r'$\angle$ $\Gamma$, deg', 'RL, dB'
            ]
        y = len(self.cursors) * 0.04 + 0.01
        for i in range(len(columns)):
            self.figure.text(0.19 + 0.1 * i,
                             y,
                             columns[i],
                             horizontalalignment='right')
        self.cursorRows = {}
        for i in range(len(self.cursors)):
            y = len(self.cursors) * 0.04 - 0.03 - 0.04 * i
            self.figure.text(0.01,
                             y,
                             'Cursor %d' % (i + 1),
                             color=self.colors[i])
            self.cursorRows[i] = {}
            for j in range(len(columns)):
                self.cursorRows[i][j] = self.figure.text(
                    0.19 + 0.1 * j, y, '', horizontalalignment='right')
            if self.mode == 'smith':
                self.cursorMarkers[i], = axes.plot(0.0,
                                                   0.0,
                                                   marker='o',
                                                   color=self.colors[i])
            else:
                self.cursorMarkers[i] = axes.axvline(0.0,
                                                     color=self.colors[i],
                                                     linewidth=2)
            self.set_cursor(i, self.cursorValues[i].value())

    def set_cursor(self, index, value):
        FigureTab.cursors[index] = value
        marker = self.cursorMarkers[index]
        if marker is None: return
        row = self.cursorRows[index]
        freq = value
        gamma = self.vna.gamma(freq)
        if self.mode == 'smith':
            marker.set_xdata(gamma.real)
            marker.set_ydata(gamma.imag)
        else:
            marker.set_xdata(freq)
        row[0].set_text('%d' % freq)
        if self.mode == 'gain_short':
            gain = self.vna.gain_short(freq)
            magnitude = 20.0 * np.log10(np.absolute(gain))
            angle = np.angle(gain, deg=True)
            row[1].set_text(unicode_minus('%.2f' % magnitude))
            row[2].set_text(unicode_minus('%.1f' % angle))
        elif self.mode == 'gain_open':
            gain = self.vna.gain_open(freq)
            magnitude = 20.0 * np.log10(np.absolute(gain))
            angle = np.angle(gain, deg=True)
            row[1].set_text(unicode_minus('%.2f' % magnitude))
            row[2].set_text(unicode_minus('%.1f' % angle))
        else:
            swr = self.vna.swr(freq)
            z = self.vna.impedance(freq)
            rl = 20.0 * np.log10(np.absolute(gamma))
            if rl > -0.01: rl = 0.0
            row[1].set_text(metric_prefix(z.real))
            row[2].set_text(metric_prefix(z.imag))
            row[3].set_text(metric_prefix(np.absolute(z)))
            angle = np.angle(z, deg=True)
            if np.abs(angle) < 0.1: angle = 0.0
            row[4].set_text(unicode_minus('%.1f' % angle))
            row[5].set_text(unicode_minus('%.2f' % swr))
            row[6].set_text(unicode_minus('%.2f' % np.absolute(gamma)))
            angle = np.angle(gamma, deg=True)
            if np.abs(angle) < 0.1: angle = 0.0
            row[7].set_text(unicode_minus('%.1f' % angle))
            row[8].set_text(unicode_minus('%.2f' % rl))
        self.canvas.draw()

    def press_marker(self, index, event):
        if not event.inaxes: return
        if self.mode == 'smith': return
        marker = self.cursorMarkers[index]
        if marker is None: return
        contains, misc = marker.contains(event)
        if not contains: return
        self.cursorPressed[index] = True

    def move_marker(self, index, event):
        if not event.inaxes: return
        if self.mode == 'smith': return
        if not self.cursorPressed[index]: return
        self.cursorValues[index].setValue(event.xdata)

    def release_marker(self, index, event):
        self.cursorPressed[index] = False

    def xlim(self, freq):
        start = freq[0]
        stop = freq[-1]
        min = np.minimum(start, stop)
        max = np.maximum(start, stop)
        margin = (max - min) / 50
        return (min - margin, max + margin)

    def plot(self):
        getattr(self, 'plot_%s' % self.mode)()

    def update(self, mode):
        start = self.vna.dut.freq[0]
        stop = self.vna.dut.freq[-1]
        min = np.minimum(start, stop)
        max = np.maximum(start, stop)
        for i in range(len(self.cursors)):
            value = self.cursors[i]
            self.cursorValues[i].setRange(min, max)
            self.cursorValues[i].setValue(value)
            value = self.cursorValues[i].value()
            self.set_cursor(i, value)
        getattr(self, 'update_%s' % mode)()

    def plot_curves(self, freq, data1, label1, limit1, data2, label2, limit2):
        matplotlib.rcdefaults()
        matplotlib.rcParams['axes.formatter.use_mathtext'] = True
        self.figure.clf()
        bottom = len(self.cursors) * 0.04 + 0.13
        self.figure.subplots_adjust(left=0.16,
                                    bottom=bottom,
                                    right=0.84,
                                    top=0.96)
        axes1 = self.figure.add_subplot(111)
        axes1.cla()
        axes1.xaxis.grid()
        axes1.set_xlabel('kHz')
        axes1.set_ylabel(label1)
        xlim = self.xlim(freq)
        axes1.set_xlim(xlim)
        if limit1 is not None: axes1.set_ylim(limit1)
        self.curve1, = axes1.plot(freq, data1, color='blue', label=label1)
        self.add_cursors(axes1)
        if data2 is None:
            self.canvas.draw()
            return
        axes1.tick_params('y', color='blue', labelcolor='blue')
        axes1.yaxis.label.set_color('blue')
        axes2 = axes1.twinx()
        axes2.spines['left'].set_color('blue')
        axes2.spines['right'].set_color('red')
        axes2.set_ylabel(label2)
        axes2.set_xlim(xlim)
        if limit2 is not None: axes2.set_ylim(limit2)
        axes2.tick_params('y', color='red', labelcolor='red')
        axes2.yaxis.label.set_color('red')
        self.curve2, = axes2.plot(freq, data2, color='red', label=label2)
        self.canvas.draw()

    def plot_gain(self, gain):
        freq = self.vna.dut.freq
        data1 = 20.0 * np.log10(np.absolute(gain))
        data2 = np.angle(gain, deg=True)
        self.plot_curves(freq, data1, 'G, dB', (-110, 110.0), data2,
                         r'$\angle$ G, deg', (-198, 198))

    def plot_gain_short(self):
        self.mode = 'gain_short'
        self.plot_gain(self.vna.gain_short(self.vna.dut.freq))

    def plot_gain_open(self):
        self.mode = 'gain_open'
        self.plot_gain(self.vna.gain_open(self.vna.dut.freq))

    def update_gain(self, gain, mode):
        if self.mode == mode:
            self.curve1.set_xdata(self.vna.dut.freq)
            self.curve1.set_ydata(20.0 * np.log10(np.absolute(gain)))
            self.curve2.set_xdata(self.vna.dut.freq)
            self.curve2.set_ydata(np.angle(gain, deg=True))
            self.canvas.draw()
        else:
            self.mode = mode
            self.plot_gain(gain)

    def update_gain_short(self):
        self.update_gain(self.vna.gain_short(self.vna.dut.freq), 'gain_short')

    def update_gain_open(self):
        self.update_gain(self.vna.gain_open(self.vna.dut.freq), 'gain_open')

    def plot_magphase(self, freq, data, label, mode):
        self.mode = mode
        data1 = np.absolute(data)
        data2 = np.angle(data, deg=True)
        max = np.fmax(0.01, data1.max())
        label1 = r'|%s|' % label
        label2 = r'$\angle$ %s, deg' % label
        self.plot_curves(freq, data1, label1, (-0.05 * max, 1.05 * max), data2,
                         label2, (-198, 198))

    def update_magphase(self, freq, data, label, mode):
        if self.mode == mode:
            self.curve1.set_xdata(freq)
            self.curve1.set_ydata(np.absolute(data))
            self.curve2.set_xdata(freq)
            self.curve2.set_ydata(np.angle(data, deg=True))
            self.canvas.draw()
        else:
            self.plot_magphase(freq, data, label, mode)

    def plot_open(self):
        self.plot_magphase(self.vna.open.freq, self.vna.open.data, 'open',
                           'open')

    def update_open(self):
        self.update_magphase(self.vna.open.freq, self.vna.open.data, 'open',
                             'open')

    def plot_short(self):
        self.plot_magphase(self.vna.short.freq, self.vna.short.data, 'short',
                           'short')

    def update_short(self):
        self.update_magphase(self.vna.short.freq, self.vna.short.data, 'short',
                             'short')

    def plot_load(self):
        self.plot_magphase(self.vna.load.freq, self.vna.load.data, 'load',
                           'load')

    def update_load(self):
        self.update_magphase(self.vna.load.freq, self.vna.load.data, 'load',
                             'load')

    def plot_dut(self):
        self.plot_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut', 'dut')

    def update_dut(self):
        self.update_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut',
                             'dut')

    def plot_smith_grid(self, axes, color):
        load = 50.0
        ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
        for tick in ticks * load:
            axis = np.logspace(-4, np.log10(1.0e3), 200) * load
            z = tick + 1.0j * axis
            gamma = (z - load) / (z + load)
            axes.plot(gamma.real,
                      gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            axes.plot(gamma.real,
                      -gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            z = axis + 1.0j * tick
            gamma = (z - load) / (z + load)
            axes.plot(gamma.real,
                      gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            axes.plot(gamma.real,
                      -gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            if tick == 0.0:
                axes.text(1.0,
                          0.0,
                          u'\u221E',
                          color=color,
                          ha='left',
                          va='center',
                          clip_on=True,
                          fontsize='x-large')
                axes.text(-1.0,
                          0.0,
                          u'0\u03A9',
                          color=color,
                          ha='left',
                          va='bottom',
                          clip_on=True)
                continue
            lab = u'%d\u03A9' % tick
            x = (tick - load) / (tick + load)
            axes.text(x,
                      0.0,
                      lab,
                      color=color,
                      ha='left',
                      va='bottom',
                      clip_on=True)
            lab = u'j%d\u03A9' % tick
            z = 1.0j * tick
            gamma = (z - load) / (z + load) * 1.05
            x = gamma.real
            y = gamma.imag
            angle = np.angle(gamma) * 180.0 / np.pi - 90.0
            axes.text(x,
                      y,
                      lab,
                      color=color,
                      ha='center',
                      va='center',
                      clip_on=True,
                      rotation=angle)
            lab = u'\u2212j%d\u03A9' % tick
            axes.text(x,
                      -y,
                      lab,
                      color=color,
                      ha='center',
                      va='center',
                      clip_on=True,
                      rotation=-angle)

    def plot_smith(self):
        self.mode = 'smith'
        matplotlib.rcdefaults()
        self.figure.clf()
        bottom = len(self.cursors) * 0.04 + 0.05
        self.figure.subplots_adjust(left=0.0,
                                    bottom=bottom,
                                    right=1.0,
                                    top=1.0)
        axes1 = self.figure.add_subplot(111)
        self.plot_smith_grid(axes1, 'blue')
        gamma = self.vna.gamma(self.vna.dut.freq)
        self.curve1, = axes1.plot(gamma.real, gamma.imag, color='red')
        axes1.axis('equal')
        axes1.set_xlim(-1.12, 1.12)
        axes1.set_ylim(-1.12, 1.12)
        axes1.xaxis.set_visible(False)
        axes1.yaxis.set_visible(False)
        for loc, spine in axes1.spines.items():
            spine.set_visible(False)
        self.add_cursors(axes1)
        self.canvas.draw()

    def update_smith(self):
        if self.mode == 'smith':
            gamma = self.vna.gamma(self.vna.dut.freq)
            self.curve1.set_xdata(gamma.real)
            self.curve1.set_ydata(gamma.imag)
            self.canvas.draw()
        else:
            self.plot_smith()

    def plot_imp(self):
        self.mode = 'imp'
        freq = self.vna.dut.freq
        z = self.vna.impedance(freq)
        data1 = np.fmin(9.99e4, np.absolute(z))
        data2 = np.angle(z, deg=True)
        max = np.fmax(0.01, data1.max())
        self.plot_curves(freq, data1, '|Z|, \u03A9', (-0.05 * max, 1.05 * max),
                         data2, r'$\angle$ Z, deg', (-198, 198))

    def update_imp(self):
        if self.mode == 'imp':
            freq = self.vna.dut.freq
            z = self.vna.impedance(freq)
            data1 = np.fmin(9.99e4, np.absolute(z))
            data2 = np.angle(z, deg=True)
            self.curve1.set_xdata(freq)
            self.curve1.set_ydata(data1)
            self.curve2.set_xdata(freq)
            self.curve2.set_ydata(data2)
            self.canvas.draw()
        else:
            self.plot_imp()

    def plot_swr(self):
        self.mode = 'swr'
        freq = self.vna.dut.freq
        data1 = self.vna.swr(freq)
        self.plot_curves(freq, data1, 'SWR', (0.9, 3.1), None, None, None)

    def update_swr(self):
        if self.mode == 'swr':
            self.curve1.set_xdata(self.vna.dut.freq)
            self.curve1.set_ydata(self.vna.swr(self.vna.dut.freq))
            self.canvas.draw()
        else:
            self.plot_swr()

    def plot_gamma(self):
        self.plot_magphase(self.vna.dut.freq,
                           self.vna.gamma(self.vna.dut.freq), r'$\Gamma$',
                           'gamma')

    def update_gamma(self):
        self.update_magphase(self.vna.dut.freq,
                             self.vna.gamma(self.vna.dut.freq), r'$\Gamma$',
                             'gamma')

    def plot_rl(self):
        self.mode = 'rl'
        freq = self.vna.dut.freq
        gamma = self.vna.gamma(freq)
        data1 = 20.0 * np.log10(np.absolute(gamma))
        self.plot_curves(freq, data1, 'RL, dB', (-105, 5.0), None, None, None)

    def update_rl(self):
        if self.mode == 'rl':
            freq = self.vna.dut.freq
            gamma = self.vna.gamma(freq)
            data1 = 20.0 * np.log10(np.absolute(gamma))
            self.curve1.set_xdata(freq)
            self.curve1.set_ydata(data1)
            self.canvas.draw()
        else:
            self.plot_rl()
Exemple #41
0
class PlotResponses(QtWidgets.QWidget):
    """
    the plot and list of stations
    """
    def __init__(self, data_fn=None, resp_fn=None):
        super(PlotResponses, self).__init__()

        self.file_watcher_dfn = QtCore.QFileSystemWatcher()
        self.file_watcher_dfn.fileChanged.connect(self.file_changed_dfn)

        self.modem_data = None
        self.modem_resp = None

        self.station = None

        self._modem_data_copy = None

        self._plot_z = False
        self.plot_settings = PlotSettings()

        self._ax = None
        self._ax2 = None
        self._key = 'z'
        self._ax_index = 0
        self.ax_list = None

        self.setup_ui()

        self._data_fn = data_fn
        self._resp_fn = resp_fn

    #------------------------------------------------
    # make the data_fn and resp_fn properties so that if they are reset
    # they will read in the data to a new modem.Data object
    # trying to use decorators for syntactical sugar
    @property
    def data_fn(self):
        return self._data_fn

    @data_fn.setter
    def data_fn(self, data_fn):
        self._data_fn = os.path.abspath(data_fn)
        self.file_watcher_dfn.addPath(self._data_fn)

        # create new modem data object
        self.modem_data = modem.Data()
        self.modem_data.read_data_file(self._data_fn)

        # make a back up copy that will be unchanged
        # that way we can revert back
        self._modem_data_copy = modem.Data()
        self._modem_data_copy.read_data_file(self._data_fn)

        self.dirpath = os.path.dirname(self._data_fn)

        # fill list of stations
        station_list = np.array(sorted(self.modem_data.mt_dict.keys()))
        self.list_widget.clear()
        for station in station_list:
            self.list_widget.addItem(station)

        if self.station is None:
            self.station = station_list[0]

        self.plot()

    @property
    def resp_fn(self):
        return self._resp_fn

    @resp_fn.setter
    def resp_fn(self, resp_fn):
        self._resp_fn = os.path.abspath(resp_fn)
        self.modem_resp = modem.Data()

        self.modem_resp.read_data_file(self._resp_fn)
        self.plot()

    @property
    def plot_z(self):
        return self._plot_z

    @plot_z.setter
    def plot_z(self, value):
        self._plot_z = value
        self.plot()

    #----------------------------
    def setup_ui(self):
        """
        setup the user interface with list of stations on the left and the 
        plot on the right.  There will be a button for save edits.
        """

        #make a widget that will be the station list
        self.list_widget = QtWidgets.QListWidget()
        self.list_widget.itemClicked.connect(self.get_station)
        self.list_widget.setMaximumWidth(150)

        self.save_edits_button = QtWidgets.QPushButton()
        self.save_edits_button.setText("Save Edits")
        self.save_edits_button.setStyleSheet("background-color: #42f489")
        self.save_edits_button.pressed.connect(self.save_edits)

        self.apply_edits_button = QtWidgets.QPushButton()
        self.apply_edits_button.setText('Apply Edits')
        self.apply_edits_button.setStyleSheet("background-color: #c6dcff")
        self.apply_edits_button.pressed.connect(self.apply_edits)

        #        self.undo_edit_button = QtWidgets.QPushButton()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.figure = Figure(dpi=150)
        self.mpl_widget = FigureCanvas(self.figure)
        self.mpl_widget.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.mpl_widget.setFocus()

        # be able to edit the data
        self.mpl_widget.mpl_connect('pick_event', self.on_pick)
        self.mpl_widget.mpl_connect('axes_enter_event', self.in_axes)

        #make sure the figure takes up the entire plottable space
        self.mpl_widget.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                      QtWidgets.QSizePolicy.Expanding)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.mpl_toolbar = NavigationToolbar(self.mpl_widget, self)

        # set the layout for the plot
        mpl_vbox = QtWidgets.QVBoxLayout()
        mpl_vbox.addWidget(self.mpl_toolbar)
        mpl_vbox.addWidget(self.mpl_widget)

        left_layout = QtWidgets.QVBoxLayout()
        left_layout.addWidget(self.list_widget)
        left_layout.addWidget(self.apply_edits_button)
        left_layout.addWidget(self.save_edits_button)

        # set the layout the main window
        layout = QtWidgets.QHBoxLayout()
        layout.addLayout(left_layout)
        layout.addLayout(mpl_vbox)

        self.setLayout(layout)

    def get_station(self, widget_item):
        """
        get the station name from the clicked station 
        """
        self.station = str(widget_item.text())
        self.plot()

    def file_changed_dfn(self):
        """
        data file changed outside the program reload it
        """

        print '{0} changed'.format(self.data_fn)
        self.data_fn = self._data_fn

    def save_edits(self):
        """
        save edits to another file
        """
        fn_dialog = QtWidgets.QFileDialog()
        save_fn = str(
            fn_dialog.getSaveFileName(caption='Choose File to save',
                                      filter='*.dat')[0])

        self.modem_data.write_data_file(save_path=os.path.dirname(save_fn),
                                        fn_basename=os.path.basename(save_fn),
                                        compute_error=False,
                                        fill=False,
                                        elevation=True)

    def apply_edits(self):
        self.plot()

    def plot(self):
        """
        plot the data
        """

        if self.station is None:
            return

        z_obj = self.modem_data.mt_dict[self.station].Z
        t_obj = self.modem_data.mt_dict[self.station].Tipper
        period = self.modem_data.period_list

        # need to make sure that resistivity and phase is computed
        z_obj.compute_resistivity_phase()

        plt.rcParams['font.size'] = self.plot_settings.fs
        fontdict = {'size': self.plot_settings.fs + 2, 'weight': 'bold'}

        #--> make key word dictionaries for plotting
        kw_xx = {
            'color': self.plot_settings.cted,
            'marker': self.plot_settings.mted,
            'ms': self.plot_settings.ms,
            'ls': ':',
            'lw': self.plot_settings.lw,
            'e_capsize': self.plot_settings.e_capsize,
            'e_capthick': self.plot_settings.e_capthick,
            'picker': 3
        }

        kw_yy = {
            'color': self.plot_settings.ctmd,
            'marker': self.plot_settings.mtmd,
            'ms': self.plot_settings.ms,
            'ls': ':',
            'lw': self.plot_settings.lw,
            'e_capsize': self.plot_settings.e_capsize,
            'e_capthick': self.plot_settings.e_capthick,
            'picker': 3
        }

        #convert to apparent resistivity and phase
        if self.plot_z == True:
            scaling = np.zeros_like(z_obj.z)
            for ii in range(2):
                for jj in range(2):
                    scaling[:, ii, jj] = 1. / np.sqrt(z_obj.freq)
            plot_res = abs(z_obj.z.real * scaling)
            plot_res_err = abs(z_obj.z_err * scaling)
            plot_phase = abs(z_obj.z.imag * scaling)
            plot_phase_err = abs(z_obj.z_err * scaling)
            h_ratio = [1, 1, .5]

        elif self.plot_z == False:
            plot_res = z_obj.resistivity
            plot_res_err = z_obj.resistivity_err
            plot_phase = z_obj.phase
            plot_phase_err = z_obj.phase_err
            h_ratio = [1.5, 1, .5]

        #find locations where points have been masked
        nzxx = np.nonzero(z_obj.z[:, 0, 0])[0]
        nzxy = np.nonzero(z_obj.z[:, 0, 1])[0]
        nzyx = np.nonzero(z_obj.z[:, 1, 0])[0]
        nzyy = np.nonzero(z_obj.z[:, 1, 1])[0]
        ntx = np.nonzero(t_obj.tipper[:, 0, 0])[0]
        nty = np.nonzero(t_obj.tipper[:, 0, 1])[0]

        self.figure.clf()
        self.figure.suptitle(str(self.station), fontdict=fontdict)

        #set the grid of subplots
        if np.all(t_obj.tipper == 0.0) == True:
            self.plot_tipper = False
        else:
            self.plot_tipper = True

        gs = gridspec.GridSpec(3, 4, height_ratios=h_ratio)
        gs.update(wspace=self.plot_settings.subplot_wspace,
                  left=self.plot_settings.subplot_left,
                  top=self.plot_settings.subplot_top,
                  bottom=self.plot_settings.subplot_bottom,
                  right=self.plot_settings.subplot_right,
                  hspace=self.plot_settings.subplot_hspace)

        axrxx = self.figure.add_subplot(gs[0, 0])
        axrxy = self.figure.add_subplot(gs[0, 1], sharex=axrxx)
        axryx = self.figure.add_subplot(gs[0, 2], sharex=axrxx)
        axryy = self.figure.add_subplot(gs[0, 3], sharex=axrxx)

        axpxx = self.figure.add_subplot(gs[1, 0])
        axpxy = self.figure.add_subplot(gs[1, 1], sharex=axrxx)
        axpyx = self.figure.add_subplot(gs[1, 2], sharex=axrxx)
        axpyy = self.figure.add_subplot(gs[1, 3], sharex=axrxx)

        axtxr = self.figure.add_subplot(gs[2, 0], sharex=axrxx)
        axtxi = self.figure.add_subplot(gs[2, 1], sharex=axrxx)
        axtyr = self.figure.add_subplot(gs[2, 2], sharex=axrxx)
        axtyi = self.figure.add_subplot(gs[2, 3], sharex=axrxx)

        self.ax_list = [
            axrxx, axrxy, axryx, axryy, axpxx, axpxy, axpyx, axpyy, axtxr,
            axtxi, axtyr, axtyi
        ]

        # plot data response
        erxx = mtplottools.plot_errorbar(axrxx, period[nzxx], plot_res[nzxx, 0,
                                                                       0],
                                         plot_res_err[nzxx, 0, 0], **kw_xx)
        erxy = mtplottools.plot_errorbar(axrxy, period[nzxy], plot_res[nzxy, 0,
                                                                       1],
                                         plot_res_err[nzxy, 0, 1], **kw_xx)
        eryx = mtplottools.plot_errorbar(axryx, period[nzyx], plot_res[nzyx, 1,
                                                                       0],
                                         plot_res_err[nzyx, 1, 0], **kw_yy)
        eryy = mtplottools.plot_errorbar(axryy, period[nzyy], plot_res[nzyy, 1,
                                                                       1],
                                         plot_res_err[nzyy, 1, 1], **kw_yy)
        #plot phase
        epxx = mtplottools.plot_errorbar(axpxx, period[nzxx], plot_phase[nzxx,
                                                                         0, 0],
                                         plot_phase_err[nzxx, 0, 0], **kw_xx)
        epxy = mtplottools.plot_errorbar(axpxy, period[nzxy], plot_phase[nzxy,
                                                                         0, 1],
                                         plot_phase_err[nzxy, 0, 1], **kw_xx)
        epyx = mtplottools.plot_errorbar(axpyx, period[nzyx], plot_phase[nzyx,
                                                                         1, 0],
                                         plot_phase_err[nzyx, 1, 0], **kw_yy)
        epyy = mtplottools.plot_errorbar(axpyy, period[nzyy], plot_phase[nzyy,
                                                                         1, 1],
                                         plot_phase_err[nzyy, 1, 1], **kw_yy)

        #plot tipper
        if self.plot_tipper == True:
            ertx = mtplottools.plot_errorbar(axtxr, period[ntx],
                                             t_obj.tipper[ntx, 0, 0].real,
                                             t_obj.tipper_err[ntx, 0,
                                                              0], **kw_xx)
            erty = mtplottools.plot_errorbar(axtyr, period[nty],
                                             t_obj.tipper[nty, 0, 1].real,
                                             t_obj.tipper_err[nty, 0,
                                                              1], **kw_yy)

            eptx = mtplottools.plot_errorbar(axtxi, period[ntx],
                                             t_obj.tipper[ntx, 0, 0].imag,
                                             t_obj.tipper_err[ntx, 0,
                                                              0], **kw_xx)
            epty = mtplottools.plot_errorbar(axtyi, period[nty],
                                             t_obj.tipper[nty, 0, 1].imag,
                                             t_obj.tipper_err[nty, 0,
                                                              1], **kw_yy)

        #----------------------------------------------
        # get error bar list for editing later
        if self.plot_tipper == False:
            try:
                self._err_list = [[erxx[1][0], erxx[1][1], erxx[2][0]],
                                  [erxy[1][0], erxy[1][1], erxy[2][0]],
                                  [eryx[1][0], eryx[1][1], eryx[2][0]],
                                  [eryy[1][0], eryy[1][1], eryy[2][0]],
                                  [epxx[1][0], epxx[1][1], epxx[2][0]],
                                  [epxy[1][0], epxy[1][1], epxy[2][0]],
                                  [epyx[1][0], epyx[1][1], epyx[2][0]],
                                  [epyy[1][0], epyy[1][1], epyy[2][0]]]
                line_list = [[erxx[0]], [erxy[0]], [eryx[0]], [eryy[0]]]
            except IndexError:
                print 'Found no Z components for {0}'.format(self.station)
                line_list = [[None], [None], [None], [None]]

                self._err_list = [[None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None]]

        else:
            try:
                line_list = [[erxx[0]], [erxy[0]], [eryx[0]], [eryy[0]],
                             [ertx[0]], [erty[0]]]

                self._err_list = [[erxx[1][0], erxx[1][1], erxx[2][0]],
                                  [erxy[1][0], erxy[1][1], erxy[2][0]],
                                  [eryx[1][0], eryx[1][1], eryx[2][0]],
                                  [eryy[1][0], eryy[1][1], eryy[2][0]],
                                  [epxx[1][0], epxx[1][1], epxx[2][0]],
                                  [epxy[1][0], epxy[1][1], epxy[2][0]],
                                  [epyx[1][0], epyx[1][1], epyx[2][0]],
                                  [epyy[1][0], epyy[1][1], epyy[2][0]],
                                  [ertx[1][0], ertx[1][1], ertx[2][0]],
                                  [eptx[1][0], eptx[1][1], eptx[2][0]],
                                  [erty[1][0], erty[1][1], erty[2][0]],
                                  [epty[1][0], epty[1][1], epty[2][0]]]
            except IndexError:
                print 'Found no Z components for {0}'.format(self.station)
                line_list = [[None], [None], [None], [None], [None], [None]]

                self._err_list = [[None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None],
                                  [None, None, None], [None, None, None]]

        #------------------------------------------
        # make things look nice
        # set titles of the Z components
        label_list = [['$Z_{xx}$'], ['$Z_{xy}$'], ['$Z_{yx}$'], ['$Z_{yy}$']]
        for ax, label in zip(self.ax_list[0:4], label_list):
            ax.set_title(label[0],
                         fontdict={
                             'size': self.plot_settings.fs + 2,
                             'weight': 'bold'
                         })

        # set legends for tipper components
        # fake a line
        l1 = plt.Line2D([0], [0],
                        linewidth=0,
                        color='w',
                        linestyle='None',
                        marker='.')
        t_label_list = ['Re{$T_x$}', 'Im{$T_x$}', 'Re{$T_y$}', 'Im{$T_y$}']
        label_list += [['$T_{x}$'], ['$T_{y}$']]
        for ax, label in zip(self.ax_list[-4:], t_label_list):
            ax.legend([l1], [label],
                      loc='upper left',
                      markerscale=.01,
                      borderaxespad=.05,
                      labelspacing=.01,
                      handletextpad=.05,
                      borderpad=.05,
                      prop={'size': max([self.plot_settings.fs, 5])})

        #--> set limits if input
        if self.plot_settings.res_xx_limits is not None:
            axrxx.set_ylim(self.plot_settings.res_xx_limits)
        if self.plot_settings.res_xy_limits is not None:
            axrxy.set_ylim(self.plot_settings.res_xy_limits)
        if self.plot_settings.res_yx_limits is not None:
            axryx.set_ylim(self.plot_settings.res_yx_limits)
        if self.plot_settings.res_yy_limits is not None:
            axryy.set_ylim(self.plot_settings.res_yy_limits)

        if self.plot_settings.phase_xx_limits is not None:
            axpxx.set_ylim(self.plot_settings.phase_xx_limits)
        if self.plot_settings.phase_xy_limits is not None:
            axpxy.set_ylim(self.plot_settings.phase_xy_limits)
        if self.plot_settings.phase_yx_limits is not None:
            axpyx.set_ylim(self.plot_settings.phase_yx_limits)
        if self.plot_settings.phase_yy_limits is not None:
            axpyy.set_ylim(self.plot_settings.phase_yy_limits)

        #set axis properties
        for aa, ax in enumerate(self.ax_list):
            ax.tick_params(axis='y', pad=self.plot_settings.ylabel_pad)
            ylabels = ax.get_yticks().tolist()
            if aa < 8:
                ylabels[-1] = ''
                ylabels[0] = ''
                ax.set_yticklabels(ylabels)
                plt.setp(ax.get_xticklabels(), visible=False)
                if self.plot_z == True:
                    ax.set_yscale('log', nonposy='clip')

            else:
                ax.set_xlabel('Period (s)', fontdict=fontdict)

            if aa < 4 and self.plot_z is False:
                ax.set_yscale('log', nonposy='clip')

            #set axes labels
            if aa == 0:
                if self.plot_z == False:
                    ax.set_ylabel('App. Res. ($\mathbf{\Omega \cdot m}$)',
                                  fontdict=fontdict)
                elif self.plot_z == True:
                    ax.set_ylabel('Re[Z (mV/km nT)]', fontdict=fontdict)
            elif aa == 4:
                if self.plot_z == False:
                    ax.set_ylabel('Phase (deg)', fontdict=fontdict)
                elif self.plot_z == True:
                    ax.set_ylabel('Im[Z (mV/km nT)]', fontdict=fontdict)
            elif aa == 8:
                ax.set_ylabel('Tipper', fontdict=fontdict)

            if aa > 7:
                if self.plot_settings.tipper_limits is not None:
                    ax.set_ylim(self.plot_settings.tipper_limits)
                else:
                    pass

            ax.set_xscale('log', nonposx='clip')
            ax.set_xlim(xmin=10**(np.floor(np.log10(period[0]))) * 1.01,
                        xmax=10**(np.ceil(np.log10(period[-1]))) * .99)
            ax.grid(True, alpha=.25)

        ##----------------------------------------------
        #plot model response
        if self.modem_resp is not None:
            resp_z_obj = self.modem_resp.mt_dict[self.station].Z
            resp_z_err = np.nan_to_num((z_obj.z - resp_z_obj.z) / z_obj.z_err)
            resp_z_obj.compute_resistivity_phase()

            resp_t_obj = self.modem_resp.mt_dict[self.station].Tipper
            resp_t_err = np.nan_to_num(
                (t_obj.tipper - resp_t_obj.tipper) / t_obj.tipper_err)

            #convert to apparent resistivity and phase
            if self.plot_z == True:
                scaling = np.zeros_like(resp_z_obj.z)
                for ii in range(2):
                    for jj in range(2):
                        scaling[:, ii, jj] = 1. / np.sqrt(resp_z_obj.freq)
                r_plot_res = abs(resp_z_obj.z.real * scaling)
                r_plot_phase = abs(resp_z_obj.z.imag * scaling)

            elif self.plot_z == False:
                r_plot_res = resp_z_obj.resistivity
                r_plot_phase = resp_z_obj.phase

            rms_xx = resp_z_err[nzxx, 0, 0].std()
            rms_xy = resp_z_err[nzxy, 0, 1].std()
            rms_yx = resp_z_err[nzyx, 1, 0].std()
            rms_yy = resp_z_err[nzyy, 1, 1].std()

            #--> make key word dictionaries for plotting
            kw_xx = {
                'color': self.plot_settings.ctem,
                'marker': self.plot_settings.mtem,
                'ms': self.plot_settings.ms,
                'ls': ':',
                'lw': self.plot_settings.lw,
                'e_capsize': self.plot_settings.e_capsize,
                'e_capthick': self.plot_settings.e_capthick
            }

            kw_yy = {
                'color': self.plot_settings.ctmm,
                'marker': self.plot_settings.mtmm,
                'ms': self.plot_settings.ms,
                'ls': ':',
                'lw': self.plot_settings.lw,
                'e_capsize': self.plot_settings.e_capsize,
                'e_capthick': self.plot_settings.e_capthick
            }

            # plot data response
            rerxx = mtplottools.plot_errorbar(axrxx, period[nzxx],
                                              r_plot_res[nzxx, 0,
                                                         0], None, **kw_xx)
            rerxy = mtplottools.plot_errorbar(axrxy, period[nzxy],
                                              r_plot_res[nzxy, 0,
                                                         1], None, **kw_xx)
            reryx = mtplottools.plot_errorbar(axryx, period[nzyx],
                                              r_plot_res[nzyx, 1,
                                                         0], None, **kw_yy)
            reryy = mtplottools.plot_errorbar(axryy, period[nzyy],
                                              r_plot_res[nzyy, 1,
                                                         1], None, **kw_yy)
            #plot phase
            repxx = mtplottools.plot_errorbar(axpxx, period[nzxx],
                                              r_plot_phase[nzxx, 0,
                                                           0], None, **kw_xx)
            repxy = mtplottools.plot_errorbar(axpxy, period[nzxy],
                                              r_plot_phase[nzxy, 0,
                                                           1], None, **kw_xx)
            repyx = mtplottools.plot_errorbar(axpyx, period[nzyx],
                                              r_plot_phase[nzyx, 1,
                                                           0], None, **kw_yy)
            repyy = mtplottools.plot_errorbar(axpyy, period[nzyy],
                                              r_plot_phase[nzyy, 1,
                                                           1], None, **kw_yy)

            #plot tipper
            if self.plot_tipper == True:
                rertx = mtplottools.plot_errorbar(
                    axtxr, period[ntx], resp_t_obj.tipper[ntx, 0, 0].real,
                    None, **kw_xx)
                rerty = mtplottools.plot_errorbar(
                    axtyr, period[nty], resp_t_obj.tipper[nty, 0, 1].real,
                    None, **kw_yy)

                reptx = mtplottools.plot_errorbar(
                    axtxi, period[ntx], resp_t_obj.tipper[ntx, 0, 0].imag,
                    None, **kw_xx)
                repty = mtplottools.plot_errorbar(
                    axtyi, period[nty], resp_t_obj.tipper[nty, 0, 1].imag,
                    None, **kw_yy)

            if self.plot_tipper == False:
                line_list[0] += [rerxx[0]]
                line_list[1] += [rerxy[0]]
                line_list[2] += [reryx[0]]
                line_list[3] += [reryy[0]]
                label_list[0] += ['$Z^m_{xx}$ ' + 'rms={0:.2f}'.format(rms_xx)]
                label_list[1] += ['$Z^m_{xy}$ ' + 'rms={0:.2f}'.format(rms_xy)]
                label_list[2] += ['$Z^m_{yx}$ ' + 'rms={0:.2f}'.format(rms_yx)]
                label_list[3] += ['$Z^m_{yy}$ ' + 'rms={0:.2f}'.format(rms_yy)]
            else:
                line_list[0] += [rerxx[0]]
                line_list[1] += [rerxy[0]]
                line_list[2] += [reryx[0]]
                line_list[3] += [reryy[0]]
                line_list[4] += [rertx[0]]
                line_list[5] += [rerty[0]]
                label_list[0] += ['$Z^m_{xx}$ ' + 'rms={0:.2f}'.format(rms_xx)]
                label_list[1] += ['$Z^m_{xy}$ ' + 'rms={0:.2f}'.format(rms_xy)]
                label_list[2] += ['$Z^m_{yx}$ ' + 'rms={0:.2f}'.format(rms_yx)]
                label_list[3] += ['$Z^m_{yy}$ ' + 'rms={0:.2f}'.format(rms_yy)]
                label_list[4] += [
                    '$T^m_{x}$ ' +
                    'rms={0:.2f}'.format(resp_t_err[ntx, 0, 0].std())
                ]
                label_list[5] += [
                    '$T^m_{y}$' +
                    'rms={0:.2f}'.format(resp_t_err[nty, 0, 1].std())
                ]

            legend_ax_list = self.ax_list[0:4]
            if self.plot_tipper == True:
                legend_ax_list += [self.ax_list[-4], self.ax_list[-2]]

            for aa, ax in enumerate(legend_ax_list):
                ax.legend(
                    line_list[aa],
                    label_list[aa],
                    loc=self.plot_settings.legend_loc,
                    bbox_to_anchor=self.plot_settings.legend_pos,
                    markerscale=self.plot_settings.legend_marker_scale,
                    borderaxespad=self.plot_settings.legend_border_axes_pad,
                    labelspacing=self.plot_settings.legend_label_spacing,
                    handletextpad=self.plot_settings.legend_handle_text_pad,
                    borderpad=self.plot_settings.legend_border_pad,
                    prop={'size': max([self.plot_settings.fs, 5])})

        self.mpl_widget.draw()

    def on_pick(self, event):
        """
        mask a data point when it is clicked on.  
        """
        data_point = event.artist
        data_period = data_point.get_xdata()[event.ind]
        data_value = data_point.get_ydata()[event.ind]

        # get the indicies where the data point has been edited
        try:
            p_index = np.where(
                self.modem_data.period_list == data_period)[0][0]
            s_index = np.where(
                self.modem_data.data_array['station'] == self.station)[0][0]
        except IndexError:
            return

        if self._key == 'tip':
            data_value_2 = self.modem_data.mt_dict[self.station].Tipper.tipper[
                p_index, self._comp_index_x, self._comp_index_y]
            if self._ax_index % 2 == 0:
                data_value_2 = data_value_2.imag
            else:
                data_value_2 = data_value_2.real

        elif self._key == 'z':
            if self.plot_z == True:
                data_value_2 = self.modem_data.mt_dict[self.station].Z.z[
                    p_index, self._comp_index_x, self._comp_index_y]

                if self._ax_index % 2 == 0:
                    data_value_2 = data_value_2.imag
                else:
                    data_value_2 = data_value_2.real
            elif self.plot_z == False and self._ax_index < 4:
                data_value_2 = self.modem_data.mt_dict[self.station].Z.phase[
                    p_index, self._comp_index_x, self._comp_index_y]
            elif self.plot_z == False and self._ax_index >= 4:
                data_value_2 = self.modem_data.mt_dict[
                    self.station].Z.resistivity[p_index, self._comp_index_x,
                                                self._comp_index_y]

        if event.mouseevent.button == 1:
            # mask the point in the data mt_dict

            self.modem_data.data_array[s_index][self._key][
                p_index, self._comp_index_x, self._comp_index_y] = 0 + 0j

            if self._key == 'tip':
                self.modem_data.mt_dict[self.station].Tipper.tipper[
                    p_index, self._comp_index_x, self._comp_index_y] = 0 + 0j
            elif self._key == 'z':
                self.modem_data.mt_dict[self.station].Z.z[
                    p_index, self._comp_index_x, self._comp_index_y] = 0 + 0j

            # plot the points as masked
            self._ax.plot(data_period,
                          data_value,
                          color=(0, 0, 0),
                          marker='x',
                          ms=self.plot_settings.ms * 2,
                          mew=4)

            self._ax2.plot(data_period,
                           data_value_2,
                           color=(0, 0, 0),
                           marker='x',
                           ms=self.plot_settings.ms * 2,
                           mew=4)

            self._ax.figure.canvas.draw()
            self._ax2.figure.canvas.draw()

        # Increase error bars
        if event.mouseevent.button == 3:
            # make sure just checking the top plots

            #put the new error into the error array
            if self._key == 'tip':
                err = self.modem_data.mt_dict[self.station].Tipper.tipper_err[
                    p_index, self._comp_index_x, self._comp_index_y]
                err = err + abs(err) * self.plot_settings.t_err_increase
                self.modem_data.mt_dict[self.station].Tipper.tipper_err[
                    p_index, self._comp_index_x, self._comp_index_y] = err

            if self._key == 'z':
                err = self.modem_data.mt_dict[self.station].Z.z_err[
                    p_index, self._comp_index_x, self._comp_index_y]
                err = err + abs(err) * self.plot_settings.z_err_increase

                self.modem_data.mt_dict[self.station].Z.z_err[
                    p_index, self._comp_index_x, self._comp_index_y] = err

            self.modem_data.data_array[s_index][self._key + '_err'][
                p_index, self._comp_index_x, self._comp_index_y] = err

            # make error bar array
            try:
                e_index = event.ind[0]
                eb = self._err_list[
                    self._ax_index][2].get_paths()[e_index].vertices
            except IndexError:
                return

            # make ecap array
            ecap_l = self._err_list[self._ax_index][0].get_data()[1][e_index]
            ecap_u = self._err_list[self._ax_index][1].get_data()[1][e_index]

            # change apparent resistivity error
            if self._key == 'tip':
                neb_u = eb[0, 1] - self.plot_settings.t_err_increase * abs(
                    eb[0, 1])
                neb_l = eb[1, 1] + self.plot_settings.t_err_increase * abs(
                    eb[1, 1])
                ecap_l = ecap_l - self.plot_settings.t_err_increase * abs(
                    ecap_l)
                ecap_u = ecap_u + self.plot_settings.t_err_increase * abs(
                    ecap_u)
            elif self._key == 'z':
                neb_u = eb[0, 1] - self.plot_settings.z_err_increase * abs(
                    eb[0, 1])
                neb_l = eb[1, 1] + self.plot_settings.z_err_increase * abs(
                    eb[1, 1])
                ecap_l = ecap_l - self.plot_settings.z_err_increase * abs(
                    ecap_l)
                ecap_u = ecap_u + self.plot_settings.z_err_increase * abs(
                    ecap_u)

            #set the new error bar values
            eb[0, 1] = neb_u
            eb[1, 1] = neb_l

            #reset the error bars and caps
            ncap_l = self._err_list[self._ax_index][0].get_data()
            ncap_u = self._err_list[self._ax_index][1].get_data()
            ncap_l[1][e_index] = ecap_l
            ncap_u[1][e_index] = ecap_u

            #set the values
            self._err_list[self._ax_index][0].set_data(ncap_l)
            self._err_list[self._ax_index][1].set_data(ncap_u)
            self._err_list[
                self._ax_index][2].get_paths()[e_index].vertices = eb

            # need to redraw the figure
            self._ax.figure.canvas.draw()

    def in_axes(self, event):
        """
        figure out which axes you just chose the point from
        """

        ax_index_dict = {
            0: (0, 0),
            1: (0, 1),
            2: (1, 0),
            3: (1, 1),
            4: (0, 0),
            5: (0, 1),
            6: (1, 0),
            7: (1, 1),
            8: (0, 0),
            9: (0, 0),
            10: (0, 1),
            11: (0, 1)
        }

        ax_pairs = {
            0: 4,
            1: 5,
            2: 6,
            3: 7,
            4: 0,
            5: 1,
            6: 2,
            7: 3,
            8: 9,
            9: 8,
            10: 11,
            11: 10
        }
        # make the axis an attribute
        self._ax = event.inaxes

        # find the component index so that it can be masked
        for ax_index, ax in enumerate(self.ax_list):
            if ax == event.inaxes:
                self._comp_index_x, self._comp_index_y = ax_index_dict[
                    ax_index]
                self._ax_index = ax_index
                self._ax2 = self.ax_list[ax_pairs[ax_index]]
                if ax_index < 8:
                    self._key = 'z'

                else:
                    self._key = 'tip'
Exemple #42
0
class SectionFrame(wx.Frame):
    def __init__(self):
        """Constructor"""

        wx.Frame.__init__(self, None, wx.ID_ANY, title='Section')

        self.panel = wx.Panel(self, wx.ID_ANY)

        self.figure = Figure()
        self.axes = self.figure.add_axes([0, 0, 1, 1])
        self.canvas = FigureCanvas(self.panel, -1, self.figure)
        self.canvas.mpl_connect('button_press_event', self.onFigureClick)
        self.canvas.mpl_connect('button_release_event', self.onFigureRelease)
        # self.canvas.mpl_connect('motion_notify_event', self.onFigureMotion)

        self.AnimationBtn = wx.Button(self.panel, wx.ID_ANY, "Animation")
        self.AnimationBtn.Bind(wx.EVT_BUTTON, self.onAnimationBtn)
        self.startTimeTxt = wx.TextCtrl(self.panel,
                                        wx.ID_ANY,
                                        "1",
                                        style=wx.TE_CENTRE
                                        | wx.TE_PROCESS_ENTER)
        self.startTimeTxt.Bind(wx.EVT_TEXT_ENTER, self.onstartTimeTxt)
        self.endTimeTxt = wx.TextCtrl(self.panel,
                                      wx.ID_ANY,
                                      "1",
                                      style=wx.TE_CENTRE | wx.TE_PROCESS_ENTER)
        self.endTimeTxt.Bind(wx.EVT_TEXT_ENTER, self.onendTimeTxt)
        self.ZoomInBtn = wx.Button(self.panel, wx.ID_ANY, "Zoom In")
        self.ZoomInBtn.Bind(wx.EVT_BUTTON, self.onZoomInBtn)
        self.ZoomOutBtn = wx.Button(self.panel, wx.ID_ANY, "Zoom Out")
        self.ZoomOutBtn.Bind(wx.EVT_BUTTON, self.onZoomOutBtn)
        self.PrintBtn = wx.Button(self.panel, wx.ID_ANY, "Print")
        self.PrintBtn.Bind(wx.EVT_BUTTON, self.onPrintBtn)

        self.ResetColorBtn = wx.Button(self.panel, wx.ID_ANY, "Reset Color")
        self.ResetColorBtn.Bind(wx.EVT_BUTTON, self.onResetColorBtn)
        self.MinColorTxt = wx.TextCtrl(self.panel,
                                       wx.ID_ANY,
                                       "Min Color",
                                       style=wx.TE_CENTRE
                                       | wx.TE_PROCESS_ENTER)
        self.MinColorTxt.Bind(wx.EVT_TEXT_ENTER, self.onMinColorTxt)
        self.MaxColorTxt = wx.TextCtrl(self.panel,
                                       wx.ID_ANY,
                                       "Max Color",
                                       style=wx.TE_CENTRE
                                       | wx.TE_PROCESS_ENTER)
        self.MaxColorTxt.Bind(wx.EVT_TEXT_ENTER, self.onMaxColorTxt)
        self.__do_layout()

        self.filename = "/Users/slgentil/models/croco/croco_visu/moz_his.nc"
        self.variableName = "u"
        self.croco = Croco(self.filename)
        self.startTimeTxt.SetValue(str(self.croco.times[0]))
        self.startTime = self.croco.times[0]
        self.startTimeIndex = 0
        self.endTimeTxt.SetValue(str(self.croco.times[-1]))
        self.endTime = self.croco.times[-1]
        self.endTimeIndex = self.croco.crocoGrid.ntimes - 1
        self.timeIndex = 0
        self.levelIndex = self.croco.crocoGrid.N - 1
        self.xlim = [
            np.min(self.croco.crocoGrid._lon),
            np.max(self.croco.crocoGrid._lon)
        ]
        self.ylim = [
            np.min(self.croco.crocoGrid._lat),
            np.max(self.croco.crocoGrid._lat)
        ]
        self.updateVariableXY()

    def __do_layout(self):

        topSizer = wx.BoxSizer(wx.VERTICAL)
        canvasSizer = wx.BoxSizer(wx.VERTICAL)
        buttonsSizer = wx.BoxSizer(wx.HORIZONTAL)
        colorSizer = wx.BoxSizer(wx.HORIZONTAL)

        canvasSizer.Add(self.canvas, 0, wx.ALL, 5)
        buttonsSizer.Add(self.AnimationBtn, 0, wx.ALL, 5)
        buttonsSizer.Add(self.startTimeTxt, 1, wx.ALL, 5)
        buttonsSizer.Add(self.endTimeTxt, 1, wx.ALL, 5)
        buttonsSizer.Add(self.ZoomInBtn, 0, wx.ALL, 5)
        buttonsSizer.Add(self.ZoomOutBtn, 0, wx.ALL, 5)
        buttonsSizer.Add(self.PrintBtn, 0, wx.ALL, 5)
        colorSizer.Add(self.ResetColorBtn, 0, wx.ALL, 5)
        colorSizer.Add(self.MinColorTxt, 0, wx.ALL, 5)
        colorSizer.Add(self.MaxColorTxt, 0, wx.ALL, 5)

        topSizer.Add(canvasSizer, 0, wx.CENTER)
        topSizer.Add(buttonsSizer, 0, wx.ALL | wx.EXPAND, 5)
        topSizer.Add(colorSizer, 0, wx.ALL | wx.EXPAND, 5)

        self.panel.SetSizer(topSizer)
        topSizer.Fit(self)

        self.Layout()

    def onFigureClick(self, event):
        self.xPress, self.yPress = event.xdata, event.ydata

    def onFigureRelease(self, event):
        self.xRelease, self.yRelease = event.xdata, event.ydata

    def rect_select_callback(self, eclick, erelease):
        self.xPress, self.yPress = eclick.xdata, eclick.ydata
        self.xRelease, self.yRelease = erelease.xdata, erelease.ydata
        print('rect_select_callback:', self.xPress, self.yPress, self.xRelease,
              self.yRelease)

    #     print(" The button you used were: %s %s" % (eclick.button, erelease.button))

    def onAnimationBtn(self, event):
        os.system("rm -rf ./Figures")
        try:
            os.makedirs('./Figures')
        except:
            pass
        anim = animation.FuncAnimation(self.figure, self.animate, \
                frames = range(self.startTimeIndex,self.endTimeIndex+1), repeat=False, blit = False)
        self.canvas.draw()
        anim.save('./Figures/' + self.variableName + '.mp4')

    def animate(self, i):
        self.timeIndex = i
        self.updateVariableXY(setlim=False)

    def onstartTimeTxt(self, event):
        self.startTime = float(self.startTimeTxt.GetValue())
        self.startTimeIndex = min(
            range(len(self.croco.times[:])),
            key=lambda j: abs(self.startTime - self.croco.times[j]))
        self.startTimeTxt.SetValue(str(self.croco.times[self.startTimeIndex]))

    def onendTimeTxt(self, event):
        self.endTime = float(self.endTimeTxt.GetValue())
        self.endTimeIndex = min(
            range(len(self.croco.times[:])),
            key=lambda j: abs(self.endTime - self.croco.times[j]))
        self.endTimeTxt.SetValue(str(self.croco.times[self.endTimeIndex]))

    def onZoomInBtn(self, event):
        self.xlim = [
            min(self.xPress, self.xRelease),
            max(self.xPress, self.xRelease)
        ]
        self.ylim = [
            min(self.yPress, self.yRelease),
            max(self.yPress, self.yRelease)
        ]
        self.drawxy()

    def onZoomOutBtn(self, event):
        self.xlim = [
            np.min(self.croco.crocoGrid._lon),
            np.max(self.croco.crocoGrid._lon)
        ]
        self.ylim = [
            np.min(self.croco.crocoGrid._lat),
            np.max(self.croco.crocoGrid._lat)
        ]
        self.drawxy()

    def onPrintBtn(self, event):
        filename = self.variableName + ".png"
        self.figure.savefig(filename, dpi=self.figure.dpi)

    def onResetColorBtn(self, event):
        self.clim = [np.min(self.variableXY), np.max(self.variableXY)]
        self.MinColorTxt.SetValue('%.2E' % self.clim[0])
        self.MaxColorTxt.SetValue('%.2E' % self.clim[1])
        self.drawxy()

    def onMinColorTxt(self, event):
        self.clim[0] = float(self.MinColorTxt.GetValue())
        self.drawxy()

    def onMaxColorTxt(self, event):
        self.clim[1] = float(self.MaxColorTxt.GetValue())
        self.drawxy()

    def updateVariableXY(self, setlim=True):
        time = str(self.timeIndex)
        level = str(self.levelIndex)
        try:
            self.variableXY = self.croco.read_nc(self.variableName,
                                                 indices="[" + time + "," +
                                                 level + ",:,:]")
        except Exception:
            try:
                self.variableXY = self.croco.read_nc(self.variableName,
                                                     indices="[" + time +
                                                     ",:,:]")
            except Exception:
                raise Exception
        self.drawxy(setlim=setlim)

    def drawxy(self, setlim=True):
        # self.canvas.Destroy()
        # self.figure = Figure(figsize=(figsize[0],figsize[1]))
        # self.canvas = FigureCanvas(self.PanelCanvas, -1, self.figure)
        # self.canvas.mpl_connect('button_press_event', self.onFigureClick)
        # self.canvas.mpl_connect('button_release_event', self.onFigureRelease)
        self.figure.clear()
        self.figure.clf()
        # depth = float(self.LevelTxt.GetValue())
        depth = 0
        if setlim == True:
            self.clim = [np.min(self.variableXY), np.max(self.variableXY)]

        if depth > 0:
            title = "{:s}, Level={:4d}, Time={:4.1f}".format(
                self.variableName, self.levelIndex,
                self.croco.times[self.timeIndex])
        else:
            title = "{:s}, Depth={:4.1f}, Time={:4.1f}".format(
                self.variableName, depth, self.croco.times[self.timeIndex])
        mypcolor(self,self.croco.crocoGrid._lon,self.croco.crocoGrid._lat,self.variableXY,\
                      title=title,\
                      xlabel='Longitude',\
                      ylabel='Latitude',\
                      xlim=self.xlim,\
                      ylim=self.ylim,\
                      clim=self.clim)
        self.canvas.draw()
        self.canvas.Refresh()
        self.Show()
Exemple #43
0
class FinalProject(wx.Frame):
    title = 'Arndit_Project'

    def __init__(self):
        global offset_diam

        wx.Frame.__init__(self, None, -1, self.title)

        # al init
        offset_diam = float(1.2)

        self.create_menu()
        self.create_status_bar()
        self.create_main_panel()
# Menubar design

    def create_menu(self):

        self.menubar = wx.MenuBar()
        menu_file = wx.Menu()
        menu_edit = wx.Menu()

        m_load = menu_file.Append(-1, "&Load excel File\tCtrl-L",
                                  "Load Raw data from file")  # al
        self.Bind(wx.EVT_MENU, self.on_load_file, m_load)  # al

        m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S",
                                  "Save plot to file")
        self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt)
        menu_file.AppendSeparator()
        m_export = menu_file.Append(-1, "&Export data\tCtrl-X", "Export")
        self.Bind(wx.EVT_MENU, self.on_export_data, m_export)

        m_exit = menu_file.Append(-1, "&Exit\tCtrl-X", "Exit")
        self.Bind(wx.EVT_MENU, self.on_exit, m_exit)
        self.menubar.Append(menu_file, "&File")
        self.SetMenuBar(self.menubar)

# mainpanel design

    def create_main_panel(self):

        global offset_diam
        self.panel = wx.Panel(self)
        self.dpi = 100
        self.fig = Figure((15, 100), dpi=self.dpi)

        # graph canvas
        self.fig.subplots_adjust(
            hspace=0.3, wspace=0.3)  # space at the bottom for axes labels
        self.canvas = FigCanvas(self.panel, -1, self.fig)
        self.axes = self.fig.add_subplot(1, 1, 1)
        self.axes.set_xlabel('X-Axis')  # al
        self.axes.set_ylabel('Y-Axis')  # al

        # control Buttons
        self.refresh = wx.Button(self.panel,
                                 -1,
                                 "Display Graph",
                                 size=(200, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_refresh, self.refresh)
        self.reset = wx.Button(self.panel, -1, "Reset Data", size=(200, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_reset, self.reset)
        self.displayButton = wx.Button(self.panel,
                                       -1,
                                       "Display Data",
                                       size=(200, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_display, self.displayButton)

        # functional buttons
        self.movingAvg = wx.Button(self.panel,
                                   -1,
                                   "Apply Moving Average",
                                   size=(2, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_movingAvg, self.movingAvg)
        self.checkVolatility = wx.Button(self.panel,
                                         -1,
                                         "Volatility check",
                                         size=(200, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_volatile, self.checkVolatility)
        self.cyclic_correlation = wx.Button(self.panel,
                                            -1,
                                            "Cyclic Correlation",
                                            size=(200, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_cyclic_correlation,
                  self.cyclic_correlation)
        self.correlation = wx.Button(self.panel,
                                     -1,
                                     "Apply Correlation",
                                     size=(250, 25))
        self.Bind(wx.EVT_BUTTON, self.on_draw_correlation, self.correlation)

        # Text Panel
        self.my_text = wx.TextCtrl(self.panel,
                                   -1,
                                   style=wx.TE_MULTILINE,
                                   size=(400, 500))

        # Drop down list
        correlation_option = ['high', 'low', 'close', 'stock', 'volatility']
        self.x_box = wx.ComboBox(self.panel,
                                 choices=correlation_option,
                                 size=(150, 20))
        self.text_xbox = wx.StaticText(self.panel,
                                       -1,
                                       'Parameter 1 :      ',
                                       size=(100, 22))
        self.y_box = wx.ComboBox(self.panel,
                                 choices=correlation_option,
                                 size=(150, 20))
        self.text_ybox = wx.StaticText(self.panel,
                                       -1,
                                       'Parameter 2 :      ',
                                       size=(100, 22))

        self.moving_avg_box = wx.ComboBox(self.panel,
                                          choices=correlation_option,
                                          size=(150, 20))
        self.text_mvgavg_box = wx.StaticText(self.panel,
                                             -1,
                                             ' Parameter :    ',
                                             size=(100, 22))

        # moving avg points
        self.avg_points_txt = wx.StaticText(self.panel,
                                            label=" No. of Points :    ",
                                            size=(100, 22))
        self.avg_points_txt_val = wx.TextCtrl(self.panel,
                                              value="1",
                                              size=(150, 20))

        #no of points moving avg
        flags = wx.ALIGN_CENTER

        #text options
        self.movingAvg_Option_text = wx.BoxSizer(wx.HORIZONTAL)
        self.movingAvg_Option_text.Add(self.avg_points_txt,
                                       0,
                                       border=10,
                                       flag=flags)
        self.movingAvg_Option_text.Add(self.avg_points_txt_val,
                                       0,
                                       border=10,
                                       flag=flags)

        # moving average options
        self.movingAvg_Option = wx.BoxSizer(wx.HORIZONTAL)
        self.movingAvg_Option.Add(self.text_mvgavg_box,
                                  0,
                                  border=3,
                                  flag=flags)
        self.movingAvg_Option.Add(self.moving_avg_box, 0, border=3, flag=flags)

        #correlation checkboxes1

        self.correlation_checkbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.correlation_checkbox1.Add(self.text_xbox,
                                       0,
                                       border=10,
                                       flag=flags)
        self.correlation_checkbox1.Add(self.x_box, 0, border=10, flag=flags)

        self.correlation_checkbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.correlation_checkbox2.Add(self.text_ybox,
                                       0,
                                       border=10,
                                       flag=flags)
        self.correlation_checkbox2.Add(self.y_box, 0, border=10, flag=flags)

        #correlation button
        self.correlation_button = wx.BoxSizer(wx.HORIZONTAL)
        self.correlation_button.Add(self.correlation, 0, border=10, flag=flags)

        flags = wx.ALIGN_CENTRE | wx.EXPAND  # wx.ALIGN_LEFT  #
        # taskbarvbox 1
        self.taskbarvbox1 = wx.BoxSizer(wx.VERTICAL)
        self.taskbarvbox1.Add(self.refresh, 0, border=10, flag=flags)
        self.taskbarvbox1.Add(self.reset, 0, border=10, flag=flags)
        self.taskbarvbox1.Add(self.displayButton, 0, border=10, flag=flags)

        # taskbarvbox 2
        self.taskbarvbox2 = wx.BoxSizer(wx.VERTICAL)
        self.taskbarvbox2.Add(self.movingAvg_Option, 0, border=10, flag=flags)
        self.taskbarvbox2.Add(self.movingAvg_Option_text,
                              0,
                              border=10,
                              flag=flags)
        self.taskbarvbox2.Add(self.movingAvg, 0, border=10, flag=flags)

        # taskbarvbox 3
        flags = wx.ALIGN_BOTTOM
        self.taskbarvbox3 = wx.BoxSizer(wx.VERTICAL)
        self.taskbarvbox3.Add(self.checkVolatility, 0, border=10, flag=flags)
        self.taskbarvbox3.Add(self.cyclic_correlation,
                              0,
                              border=10,
                              flag=flags)

        # taskbarvbox 4
        self.taskbarvbox4 = wx.BoxSizer(wx.VERTICAL)
        self.taskbarvbox4.Add(self.correlation_checkbox1,
                              0,
                              border=10,
                              flag=flags)
        self.taskbarvbox4.Add(self.correlation_checkbox2,
                              0,
                              border=10,
                              flag=flags)
        self.taskbarvbox4.Add(self.correlation_button,
                              0,
                              border=10,
                              flag=flags)

        # taskbarvbox 5
        self.taskbarvbox5 = wx.BoxSizer(wx.VERTICAL)
        # self.taskbarvbox5.Add(self.partition, 0, border=10, flag=flags)
        # taskbar
        self.taskbar = wx.BoxSizer(wx.HORIZONTAL)
        self.taskbar.Add(self.taskbarvbox1, 0, border=10, flag=flags)
        self.taskbar.Add(self.taskbarvbox2, 0, border=10, flag=flags)
        self.taskbar.Add(self.taskbarvbox3, 0, border=10, flag=flags)
        self.taskbar.Add(self.taskbarvbox4, 0, border=10, flag=flags)
        self.taskbar.Add(self.taskbarvbox5, 0, border=10, flag=flags)

        # databox
        self.databox = wx.BoxSizer(wx.VERTICAL)
        self.databox.Add(self.my_text, wx.ALL | wx.EXPAND)

        # mainpanel
        flags = wx.ALL | wx.EXPAND
        flags = wx.GROW  # wx.ALIGN_TOP | wx.ALL
        self.mainpanel = wx.BoxSizer(wx.HORIZONTAL)
        self.mainpanel.Add(self.databox, 1, wx.GROW)
        self.mainpanel.Add(self.canvas, 1, wx.GROW)  # al
        self.toolbar = NavigationToolbar(self.canvas)

        # 3 horizontal boxes
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.toolbar, 1, wx.TOP | wx.EXPAND, border=0)  # al
        self.vbox.Add(self.taskbar, 1, border=0)
        self.vbox.Add(self.mainpanel, 1, wx.GROW, border=0)  # al

        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)

# StatusBar design

    def create_status_bar(self):
        self.statusbar = self.CreateStatusBar()

# Refresh button

    def on_draw_refresh(self, event):
        global flag
        self.axes.clear()
        self.canvas.draw()
        self.fig.clf()
        print "Button 1 Clicked"
        print flag
        global x_axis_val
        global y_axis_val
        global volatile_date
        global x_name
        global y_name

        # vlotaility graph
        if flag == 2:
            if (len(sno) > 0):
                print "Drawing plot ..... "
                self.axes = self.fig.add_subplot(1, 1, 1)

                self.axes.plot(x_axis_val,
                               y_axis_val,
                               marker='o',
                               linestyle='--',
                               color='red')
                self.axes.set_xlabel('date')
                self.axes.set_ylabel('volatile_value')
                # if (len(diameter_mm_smooth) > 0):
            #   self.axes.plot(frame_no, diameter_mm_smooth, 'black')
            self.canvas.draw()

        if flag == 3:
            if (len(sno) > 0):
                print "Drawing plot ..... "
                #if((x_axis==0) & (y_axis==1)):
                # print x_axis
                #print y_axis
                self.axes = self.fig.add_subplot(1, 1, 1)
                self.axes.plot(x_axis_val,
                               y_axis_val,
                               marker='o',
                               linestyle=' ',
                               color='red')
                self.axes.set_xlabel(x_name)
                self.axes.set_ylabel(y_name)
            # if (len(diameter_mm_smooth) > 0):
            #   self.axes.plot(frame_no, diameter_mm_smooth, 'black')

            self.canvas.draw()

        if flag == 4:
            if (len(sno) > 0):
                print "Drawing plot ..... "
                #if((x_axis==0) & (y_axis==1)):
                # print x_axis
                #print y_axis
                self.axes = self.fig.add_subplot(1, 1, 1)
                self.axes.plot(x_axis_val,
                               y_axis_val,
                               marker='o',
                               linestyle=' ',
                               color='red')
                self.axes.set_xlabel('Month Number')
                self.axes.set_ylabel('close value')
            # if (len(diameter_mm_smooth) > 0):
            #   self.axes.plot(frame_no, diameter_mm_smooth, 'black')

            self.canvas.draw()

# Display button

    def on_draw_cyclic_correlation(self, event):
        global flag
        flag = 4
        cyclic_correlation()

    def on_draw_display(self, event):
        temp = []
        global mvg_avg
        global volatile_value
        global high_val
        global low_val
        global stock_val
        global sno
        global close_val
        global x_axis
        global y_axis
        global flag
        if flag == 0:

            temp1 = list(high_val)
            temp2 = list(low_val)
            temp0 = list(date_val)
            temp3 = list(close_val)
            temp4 = list(stock_val)
            #print temp1, temp2
            self.my_text.WriteText('Date \t\t High \t Low \t Close \t Stock\n')
            for i in range(0, len(sno)):
                self.my_text.WriteText(
                    str(temp0[i]) + ' \t ' + str(temp1[i]) + ' \t' +
                    str(temp2[i]) + ' \t' + str(temp3[i]) + ' \t' +
                    str(temp4[i]) + '\n')
                #print line
#moving average
        if flag == 1:
            global mvg_avg_name
            self.my_text.WriteText("moving Average(" + mvg_avg_name + ")\n")
            for line in mvg_avg:
                self.my_text.WriteText(str(line) + "\n")
# volatility
        if flag == 2:
            global volatile_date
            global volatile_value
            temp1 = list(volatile_date)
            temp2 = list(volatile_value)
            self.my_text.WriteText('Date \t\t Volatility\n')
            for i in range(0, len(volatile_date)):
                self.my_text.WriteText(
                    str(temp1[i]) + ' \t ' + str(temp2[i]) + '\n')
# correlation
        if flag == 3:
            self.my_text.WriteText('Correlation between ' + str(x_name) +
                                   ' & ' + str(y_name) + ' is : ' +
                                   str(correl_val))
            #if os.path.exists('myfile_correlation.txt'):
            # with open('myfile_correlation.txt') as fobj:
            #  for line in fobj:
            #  self.my_text.WriteText(line)
            #print line
#moving Algorithm
#moving average

    def on_draw_movingAvg(self, event):
        global no_of_points
        global mvg_avg_option
        global mvg_avg_name

        no_of_points = self.avg_points_txt_val.GetValue()
        #print no_of_points
        if (self.moving_avg_box.GetValue() == 'high'):
            mvg_avg_option = high_val
            mvg_avg_name = 'High Value'
        elif (self.moving_avg_box.GetValue() == 'low'):
            mvg_avg_option = low_val
            mvg_avg_name = 'Low Value'
        elif (self.moving_avg_box.GetValue() == 'close'):
            mvg_avg_option = close_val
            mvg_avg_name = 'Close Value'
        elif (self.moving_avg_box.GetValue() == 'stock'):
            mvg_avg_option = stock_val
            mvg_avg_name = 'Stock Value'
        elif (self.moving_avg_box.GetValue() == 'volatility'):
            volatile_check()
            mvg_avg_option = volatile_value
            mvg_avg_name = 'Volatility'
        moving_avg_filter()
        self.my_text.WriteText(
            '**Press Display Data button to see the Moving Average of ' +
            str(mvg_avg_name) + ' of data points ' + str(no_of_points) +
            '\n\n')

        # volatile check
    def on_draw_volatile(self, event):
        global x_axis_val
        global y_axis_val
        x_axis_val = []
        y_axis_val = []
        volatile_check()
        temp1 = list(volatile_value)
        temp2 = list(volatile_date)
        for i in range(0, len(sno)):
            if int(temp1[i]) != 0:
                x_axis_val.append(temp2[i])
                y_axis_val.append(temp1[i])
        print x_axis_val
        print y_axis_val
        self.my_text.WriteText(
            '**Press Display Graph button to see the Graph Volatility vs Date\n**Press Display Data button to see the Data\n\n'
        )
#correlation

    def on_draw_correlation(self, event):
        global x_axis
        global y_axis
        global x_name
        global y_name
        x_name = self.x_box.GetValue()
        y_name = self.y_box.GetValue()
        if (self.x_box.GetValue() == 'high'):
            x_axis = high_val
        elif (self.x_box.GetValue() == 'low'):
            x_axis = low_val
        elif (self.x_box.GetValue() == 'close'):
            x_axis = close_val
        elif (self.x_box.GetValue() == 'stock'):
            x_axis = stock_val
        elif (self.x_box.GetValue() == 'volatility'):
            volatile_check()
            x_axis = volatile_value

        if (self.y_box.GetValue() == 'high'):
            y_axis = high_val
        elif (self.y_box.GetValue() == 'low'):
            y_axis = low_val
        elif (self.y_box.GetValue() == 'close'):
            y_axis = close_val
        elif (self.y_box.GetValue() == 'stock'):
            y_axis = stock_val
        elif (self.y_box.GetValue() == 'volatility'):
            volatile_check()
            y_axis = volatile_value

        correlation()
        self.my_text.WriteText(
            '**Press Display Graph button to see the Graph \n**Press Display Data button to see the Correlation value\n\n'
        )

    def on_draw_reset(self, event):
        global flag
        reset_all_global()
        flag = 0
        FinalProject.on_draw_refresh(self, event)

    def on_load_file(self, event):
        global rd_path
        reset_all_global()
        wr_path = ""
        file_choices = "XLSX (*.xlsx)|*.xlsx"

        dlg = wx.FileDialog(self,
                            message="Load File...",
                            defaultDir=os.getcwd(),
                            defaultFile="",
                            wildcard=file_choices,
                            style=wx.FC_OPEN | wx.FD_FILE_MUST_EXIST)

        if dlg.ShowModal() == wx.ID_OK:
            rd_path = dlg.GetPath()
            print rd_path
            read_file(rd_path)

#            FinalProject.on_draw_button1(self, event)

#   self.editxt2.SetValue(str(offset_diam))

    def on_save_plot(self, event):
        file_choices = "PNG (*.png)|*.png"

        dlg = wx.FileDialog(self,
                            message="Save plot as...",
                            defaultDir=os.getcwd(),
                            defaultFile="plot.png",
                            wildcard=file_choices,
                            style=wx.FC_SAVE)

        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.canvas.print_figure(path, dpi=self.dpi)
            # self.flash_status_message("Saved to %s" % path)

    def on_export_data(self, event):
        global rd_path
        global wr_path

        file_choices = "XLSX (*.xlsx)|*.xlsx"

        dlg = wx.FileDialog(self,
                            message="Export Data File...",
                            defaultDir=os.getcwd(),
                            defaultFile="export_data.txt",
                            wildcard=file_choices,
                            style=wx.FC_SAVE)

        if dlg.ShowModal() == wx.ID_OK:
            wr_path = dlg.GetPath()
            # self.flash_status_message("File Loaded %s" % path)
            export_data(wr_path)

    def on_exit(self, event):
        self.Destroy()
class TRACE_FFT_WINDOW_WIB(Gtk.Window):
    """
  This window displays a live ADC redout and its FFT
  """
    def __init__(self):
        Gtk.Window.__init__(self, title="ADC View Window")

        self.set_default_size(800, 800)

        self.figure = Figure(figsize=(8, 8), dpi=100)

        sw = Gtk.ScrolledWindow()
        self.add(sw)
        # A scrolled window border goes outside the scrollbars and viewport
        sw.set_border_width(10)

        canvas = FigureCanvas(self.figure)  # a Gtk.DrawingArea
        canvas.set_size_request(750, 750)
        sw.add_with_viewport(canvas)

        self.show_all()

        self.sw = sw
        self.canvas = canvas

        self.femb = None
        self.reset()

    def reset(self):
        self.femb = FEMB_UDP()
        self.figure.clf()
        self.ax1 = self.figure.add_subplot(211)
        self.ax2 = self.figure.add_subplot(212)
        self.plot1 = self.ax1.plot([], [])
        self.plot2 = self.ax2.plot([], [])
        self.ani = animation.FuncAnimation(self.figure,
                                           self.plotData,
                                           interval=1000)  #, blit=True)
        self.canvas.draw()

    def plotData(self, iFrame):
        self.ax1.cla()
        self.ax2.cla()
        self.ax1.set_xlabel("Time [us]")
        self.ax1.set_ylabel("Sample Value [ADC Counts]")
        self.ax2.set_xlabel("Frequency [MHz]")
        self.ax2.set_ylabel("|Y(freq)|")
        t, adc, frq, ampl = self.getTraceAndFFT()
        if t == None:
            return None
        self.plot1 = self.ax1.plot(t, adc)
        self.plot2 = self.ax2.plot(frq, ampl, 'r')
        self.canvas.draw()
        return self.plot1

    def getTraceAndFFT(self):
        """
    Gets trace from FEMB and returns 4 1D arrays:
        times, ADC counts, frequencies, Amplitude
    """
        Yfft_total = []
        first = 1
        #data = self.femb.get_data(10)
        data = self.femb.get_data_packets(1)
        if data == None:
            #time.sleep(1.)
            return None, None, None, None
        if len(data) == 0:
            #time.sleep(1.)
            return None, None, None, None
        xpoint = []
        ypoint = []
        num = 0

        print("HERE")
        for samp in data:
            print(samp)

        return None, None, None, None
        for samp in data:
            chNum = ((samp >> 12) & 0xF)
            sampVal = (samp & 0xFFF)
            #print str(chNum) + "\t" + str(sampVal) + "\t" + str( hex(sampVal) )
            #if chNum == 0:
            xpoint.append(num * 0.5)
            ypoint.append(sampVal)
            num = num + 1

        xarr = np.array(xpoint)
        yarr = np.array(ypoint)

        Fs = 2.0
        # sampling rate
        Ts = 1.0 / Fs
        # sampling interval
        t = np.arange(0, 1, Ts)  # time vector

        n = len(yarr)  # length of the signal
        k = np.arange(n)
        T = n / Fs
        frq = k / T  # two sides frequency range
        frq = frq[:n // 2]  # one side frequency range

        Yfft = np.fft.fft(yarr) / n  # fft computing and normalization
        Yfft = Yfft[:n // 2]
        frq = frq[1:]
        Yfft = Yfft[1:]

        #do averaging and normalization, very messy
        pos = 0
        total = 0
        for x in np.nditer(Yfft):
            #print abs(x)
            total = total + abs(x)
            if first == 1:
                Yfft_total.append(abs(x))
            else:
                Yfft_total[pos] = Yfft_total[pos] + abs(x)
            pos = pos + 1

        first = 0
        if total < 0:
            #time.sleep(0.1)
            return None, None, None, None

        pos = 0
        Yfft_norm = []
        for bin in Yfft_total:
            Yfft_norm.append(bin / total)

        return xarr, yarr, frq, Yfft_norm
Exemple #45
0
class GUI(QtGui.QWidget):
    def __init__(self):

        super(GUI, self).__init__()

        self.setWindowTitle('Outline Cells')
        self.cellNames = [
            '1.p', '4.a', '1.pp', '4.aa', '1.ppa', '1.ppp', '4.aaa', '4.aap',
            'b_1', 'b_4'
        ]
        self.initUI()

    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):
        # SET THE GEOMETRY

        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)

        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()

        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)

        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()

        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)

        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS

        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')

        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')

        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(-5)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')

        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')

        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16 - 1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16 - 1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600, 600))
        self.canvas1.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300, 300))
        self.canvas2.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0)
        Col1.addWidget(self._561nmBtn, 4, 0)
        Col1.addWidget(self.CoolLEDBtn, 5, 0)

        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        Col3.addWidget(self.cellTbl)
        Col3.addWidget(self.canvas2)

        self.setFocus()
        self.show()

        # BIND BUTTONS TO FUNCTIONS

        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.loadNewStack)
        self.sl.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        self.fig1.canvas.mpl_connect('button_press_event',
                                     self.onMouseClickOnCanvas1)
        self.fig1.canvas.mpl_connect('scroll_event', self.wheelEvent)

    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):

        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def HLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):

        return width

    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(
            self, 'Select a folder', 'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname(self.pathDial)
        self.setWindowTitle('Outline Cells - ' + self.pathDial)

        ### give error message if there is no CoolLED movie in the selected folder
        if not os.path.isfile(os.path.join(self.pathDial,
                                           'CoolLED_movie.tif')):
            QtGui.QMessageBox.about(
                self, 'Warning!',
                'There is no movie in this folder! Create a movie first!')
            return

        # detect available channels
        self.channels = []
        chns = ['CoolLED', '488nm', '561nm']
        for c in chns:

            if os.path.isfile(os.path.join(self.pathDial, c + '_movie.tif')):

                self.channels.append(c)

        self.currentChannel = self.channels[0]

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame(self.path,
                                        self.worm + '_01params.pickle')
        self.timesDF = load_data_frame(self.path,
                                       self.worm + '_01times.pickle')
        self.gpDF = load_data_frame(self.path,
                                    self.worm + '_02gonadPos.pickle')
        self.cellPosDF = load_data_frame(self.path,
                                         self.worm + '_04cellPos.pickle')

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int(self.paramsDF.tidxHatch)

        ### if the cellOutline pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile(
                os.path.join(self.path, self.worm + '_05cellOut.pickle')):
            self.cellOutDF = load_data_frame(self.path,
                                             self.worm + '_05cellOut.pickle')

        else:
            self.cellOutDF = create_cell_out(self.timesDF, self.cellNames)

        self.analyzedCell = '---'

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))
        self.tp.setValue(first_tidx_pos_all_cells(self.cellPosDF))

        # self.pathDial.show()
        self.updateAllCanvas()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[self.timesDF.tidxRel ==
                               self.tp.value()].squeeze()

        print('Loading... ', self.pathDial, tRow.fName)

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_out(self.cellPosDF,
                                                     self.cellOutDF,
                                                     self.tp.value())

        if len(self.currentCells) > 0:
            ### update current analyzed cell
            if self.analyzedCell not in list(self.currentCells.cname):
                self.analyzedCell = self.currentCells.cname[0]

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        # load all the available stacks
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join(self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile(fileName):
                self.stacks[ch] = load_stack(fileName)

        if len(self.stacks.keys()) > 0:
            # print(self.stacks.keys(), self.stacksStraight)
            self.sl.setMaximum(self.stacks[self.currentChannel].shape[0] - 1)

            self.setBCslidersMinMax()

        if len(self.currentCells) > 0:
            ### update slice
            self.sl.setValue(self.currentCells.ix[self.currentCells.cname ==
                                                  self.analyzedCell, 'Z'])

        # self.updateTable()
        self.updateAllCanvas()

    def saveData(self):

        save_data_frame(self.cellOutDF, self.path,
                        self.worm + '_05cellOut.pickle')
        self.setFocus()

    def updateAllCanvas(self):
        self.updateRadioBtn()
        self.updateCanvas1()
        self.updateCanvas2()

    def radioClicked(self):
        if self._488nmBtn.isChecked():
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')
        elif self._561nmBtn.isChecked():
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')
        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')
        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):

        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime('time', +1)

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime('time', -1)

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime('space', +1)

        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime('space', -1)

        elif event.key() == QtCore.Qt.Key_Space:

            if len(self.currentCells) > 0:
                idx = np.mod(
                    self.currentCells.ix[self.currentCells.cname ==
                                         self.analyzedCell].index + 1,
                    len(self.currentCells))
                self.analyzedCell = self.currentCells.cname.values[idx][0]
                self.sl.setValue(self.currentCells.ix[
                    self.currentCells.cname == self.analyzedCell, 'Z'])

                self.updateAllCanvas()

        self.setFocus()

    def wheelEvent(self, event):
        if self.canvas1.underMouse():
            step = event.step
        else:
            step = event.delta() / abs(event.delta())
        self.sl.setValue(self.sl.value() + step)

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onMouseClickOnCanvas1(self, event):

        pos = np.array([int(event.xdata), int(event.ydata)])

        outline = extract_out(self.currentCells.ix[
            self.currentCells.cname == self.analyzedCell].squeeze())

        if event.button == 1:

            if np.isnan(outline[0, 0]):
                outline = np.array([pos])
            else:
                outline = np.vstack([outline, pos])

        elif event.button == 3:

            if len(outline[:, 0]) == 1:
                outline = np.array([[np.nan, np.nan]])
            else:
                outline = outline[:-1, :]

        idx = self.currentCells.ix[self.currentCells.cname ==
                                   self.analyzedCell].index

        self.currentCells.Xout.values[idx] = [outline[:, 0]]
        self.currentCells.Yout.values[idx] = [outline[:, 1]]

        self.updateCanvas1()
        self.setFocus()
        # print(event.button,event.xdata,event.ydata)

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld1.setMinimum(np.min(self.stacks[self.currentChannel]))
        self.sld2.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld2.setMinimum(np.min(self.stacks[self.currentChannel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.stacks[self.currentChannel]))
        self.sld2.setValue(np.max(self.stacks[self.currentChannel]))

    def updateCanvas1(self):

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        if (len(self.stacks.keys()) == 0) or (len(self.currentCells) == 0):
            # if no images are found, leave the canvas empty
            return

        # extract current cell data
        pos = extract_3Dpos(self.currentCells.ix[self.currentCells.cname ==
                                                 self.analyzedCell].squeeze())

        # plot the image
        imgpxl = 50
        self.ax1.cla()
        imgplot = self.ax1.imshow(
            self.stacks[self.currentChannel][self.sl.value(),
                                             pos[1] - imgpxl / 2:pos[1] +
                                             imgpxl / 2 + 1,
                                             pos[0] - imgpxl / 2:pos[0] +
                                             imgpxl / 2 + 1],
            cmap='gray',
            interpolation='nearest')

        # remove the white borders
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print cell name
        if pos[2] == self.sl.value():
            self.ax1.text(1,
                          2,
                          self.analyzedCell,
                          color='yellow',
                          size='medium',
                          alpha=.8,
                          rotation=0,
                          fontsize=20)
            self.ax1.plot(imgpxl / 2,
                          imgpxl / 2,
                          'x',
                          color='yellow',
                          alpha=.8,
                          ms=5)

        ### draw outline
        outline = extract_out(self.currentCells.ix[
            self.currentCells.cname == self.analyzedCell].squeeze())

        # print(self.currentCells.ix[ self.currentCells.cname == self.analyzedCell ].squeeze())

        if len(outline) > 1:
            outline = np.vstack([outline, outline[0]])

        self.ax1.plot(outline[:, 0],
                      outline[:, 1],
                      '-x',
                      color='yellow',
                      ms=2,
                      alpha=1.,
                      lw=.5)

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(), self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(), self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())

        # # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas2(self):

        # plot the image
        self.ax2.cla()
        imgplot = self.ax2.imshow(
            self.stacks[self.currentChannel][self.sl.value()], cmap='gray')

        # remove the white borders
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # extract current cell data
        if len(self.currentCells) > 0:
            pos = extract_3Dpos(self.currentCells.ix[
                self.currentCells.cname == self.analyzedCell].squeeze())

            for idx, cell in self.currentCells.iterrows():

                if cell.Z == self.sl.value():

                    color = 'red'
                    if cell.cname == self.analyzedCell:
                        color = 'yellow'

                    self.ax2.text(cell.X + 10,
                                  cell.Y + 10,
                                  cell.cname,
                                  color=color,
                                  size='medium',
                                  alpha=.8,
                                  rotation=0)
                    self.ax2.plot(cell.X,
                                  cell.Y,
                                  'o',
                                  color=color,
                                  alpha=.8,
                                  ms=5,
                                  mew=0)

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def changeSpaceTime(self, whatToChange, increment):

        if whatToChange == 'time':

            newCellOutDF = update_cell_out_DF(self.currentCells,
                                              self.cellOutDF, self.tp.value())
            self.cellOutDF = newCellOutDF

            # if they are OK (and not going to negative times), change timepoint
            self.tp.setValue(self.tp.value() + increment)

        if whatToChange == 'space':
            self.sl.setValue(self.sl.value() + increment)
Exemple #46
0
class IesPlotPanel():
    
    def __init__(self,panel,yourself):
        self.dpi = 80
        self.fig = Figure((3.0, 2.0), dpi=self.dpi)
        self.canvas = FigCanvas(panel, -1, self.fig)
        self.gs = gridspec.GridSpec(1,1)
        self.axes = [None]
                
        #self.fig.canvas.mpl_connect('pick_event',self.on_pick)
        
        self.toolbar = NavigationToolbar(self.canvas)  
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.vbox.Add(self.toolbar, 0, wx.EXPAND)
        self.vbox.AddSpacer(10)
        panel.SetSizer(self.vbox)
        self.canvas.draw() 

        self.pickedValue = None
        self.pickingActive = False
        self.pickedAlready = False
        self.tempAnnotation = None

        self.settings = IesSettings.IesSettings('')
        self.currentPlot = IesPlotState.MASS_SPECTRA

        self.lift = 30

        self.picker = None
        self.pickedValue = None

        self.gui = yourself
        
    def setSettings(self,settings):
        """Set the Gui settings class.
        :parameter settings: IesSettings() object
        """
        self.settings = settings

    def getSingleAxis(self):
        """Recreate plotting area with a single set of axes.
        :returns: Matplotlib Axes instance
        """
        self._preparePlottingSections(1,1)
        self.axes = [None]
        self.axes[0] = self.fig.add_subplot(self.gs[0,0])
        self.axes[0].plot([],[])
        return self.axes[0]
    
        
    def _preparePlottingSections(self,rows,columns):
        """Clear currently plotted information and recreate the plot area.
        :parameter rows: Rows of Matplotlib Axes instances
        :parameter columns: Columns of Matplotlib Axes instances
        """
        self.fig.clf(keep_observers=True)
        self.gs = gridspec.GridSpec(rows,columns)

    def getDoubleColumnAxes(self):
        """Recreate plotting area with a two sets of axes (in a column).
        :returns: List of two Matplotlib Axes instances
        """
        self._preparePlottingSections(1,2)
        self.axes = [None,None]
        self.axes[0] = self.fig.add_subplot(self.gs[0])
        self.axes[1] = self.fig.add_subplot(self.gs[1])

        return self.axes[0],self.axes[1]

    def getDoubleRowAxes(self):
        """Recreate plotting area with a two sets of axes (in a row).
        :returns: List of two Matplotlib Axes instances
        """
        self._preparePlottingSections(2,1)
        self.axes = [None,None]
        self.axes[0] = self.fig.add_subplot(self.gs[0])
        self.axes[1] = self.fig.add_subplot(self.gs[1])

        return self.axes[0],self.axes[1]

    def getTripleAxes(self):
        """Recreate plotting area with a three sets of axes. Arranged
        as two side by side with one below.
        :returns: List of three Matplotlib Axes instances
        """
        self._preparePlottingSections(3,2)
        self.axes = [None,None,None]
        self.axes[0] = self.fig.add_subplot(self.gs[0:2,0])
        self.axes[1] = self.fig.add_subplot(self.gs[0:2,1])
        self.axes[2] = self.fig.add_subplot(self.gs[2,:])        

        return self.axes[0],self.axes[1],self.axes[2]
        
    
    def plotMassSpectra(self):
        """Change plot area to single set of axes and plot the stacked
        mass spectra.
        """
        ax = self.getSingleAxis()
        self.settings._forPlotMassSpectra(ax,lift=self.lift)
        self.label1dPlots(ax)
        self.currentPlot = IesPlotState.MASS_SPECTRA
        self.draw()

    def plotMassSpectraWidthLimits(self):
        """Run self.plotMassSpectra() and fill in the m/z value regions which
        are to be used for extracting ATDs.
        """
        self.plotMassSpectra()
        species,z = self.settings.getSpeciesAndCharge()
        
        limits = self.settings._getMzLimits(species,z)
        ylims = self.axes[0].get_ylim()
        self.axes[0].fill_betweenx(ylims,limits[0],limits[1],color='red',alpha=0.3)
        self.axes[0].set_ylim(ylims)
        
    def refresh_plot(self):
        """Update the plotting window, given the current settings.
        """
        self.settings.checkboxStates.printStates()
        plotType = self.settings.checkboxStates.getPlotType()
        self.currentPlot = self.settings.checkboxStates.getEnum()
        
        if plotType == 1:
            ax = self.getSingleAxis()
            if self.currentPlot == IesPlotState.MASS_SPECTRA:
                if self.settings.atrOb:
                    self.plotMassSpectraWidthLimits()
                else:
                    self.plotMassSpectra()
 
            elif self.currentPlot == IesPlotState.ATD:
                self.plotCcsDistributions(ax)

            elif self.currentPlot == IesPlotState.CONTOUR:
                self.plotContourPlots(ax)

            elif self.currentPlot == IesPlotState.NONE:
                self.getSingleAxis()
                
            elif self.currentPlot == IesPlotState.CONFORMATIONS:
                self.plotConformationHeights(ax)
                
        elif plotType == 2:
            if self.currentPlot == IesPlotState.CONTOUR_ATD:
                ax1,ax2 = self.getDoubleColumnAxes()
                self.plotCcsDistributions(ax1)
                self.plotContourPlots(ax2)
            elif self.currentPlot == IesPlotState.CONTOUR_CONFORMATIONS:
                ax1,ax2 = self.getDoubleRowAxes()
                self.plotContourPlots(ax1)
                self.plotConformationHeights(ax2)
            elif self.currentPlot == IesPlotState.ATD_CONFORMATIONS:
                ax1,ax2 = self.getDoubleRowAxes()
                self.plotCcsDistributions(ax1)
                self.plotConformationHeights(ax2)
            else:
                print 'plot type = 2 but this option hasnt been implemented yet'

        elif plotType == 3:
            ax1,ax2,ax3 = self.getTripleAxes()
            self.plotCcsDistributions(ax1)
            self.plotContourPlots(ax2)
            self.plotConformationHeights(ax3)
        else:
            print 'plottype:'
            print plotType
        if self.settings.displayPeaks:
            self.drawCcsLines()
        for ax in self.axes:
            ax.set_yticks([])
        self.draw()
            
    def on_pick(self,event):
        """Clicking on the plotting area (still to be implemented).
        """
        # TODO(gns) - Still to be implemented
        if True: #self.pickingActive:
            #my attempt to make a new function
            plotState = self.settings.checkboxStates.getEnum()
            # print event.mouseevent.data
            # print dir(event.mouseevent)
            # print '==============================='
            # print dir(event)
            # copied directly
            # if self.pickedAlready:
            #     line = self.axMs.lines.pop(len(self.axMs.lines)-1)
            #     self.tempAnnotation.set_visible(False)
            # self.pickedValue = event.mouseevent.xdata
            # yval = self.ms.yvals[utils.closest(self.pickedValue,self.ms.xvals)]
            # peakId = sorted(self.ms.gPeaks.keys())[-1]+1
            # self.axMs.axvline(self.pickedValue,color='k')
            # self.tempAnnotation = self.axMs.annotate(str(peakId),[self.pickedValue,yval])
            # self.draw()
            
            # self.pickedAlready = True
    
      
    def draw(self):
        """Update plotting area.
        """
        self.canvas.draw()

    def plotContourPlots(self,ax):
        """Plot the 3D data as contour plots. Automatically switches between ATD and CCS
        depending on whether a calibration has been added.
        :parameter ax: Matplotlib Axes instance
        """
        if self.settings.calibrationOb:
            # get the data
            ccsAxis, matrices = self.settings.getCcsAxisAndGrid()

            # plot the data
            for i,matrix in enumerate(matrices):
                ax.imshow(matrix, extent=[ccsAxis[0],ccsAxis[-1],i*10,i*10+10],
                          aspect='auto',origin='lower')
                if i:
                    ax.axhline(i*10)

            # plotting parameters
            ax.set_ylabel('Relative $m/z$')
            ax.set_xlabel('CCS ($\AA^2$)')
            ax.set_yticks([])

            ax.autoscale(ax)
            ccsLims = self.autoAxesImshow(ccsAxis,matrices)
            ax.set_xlim(ccsLims)
            self.labelContourPlots(ax)
        else:
            '''see explanation in plotCcsDistributions'''
            tdAxis,matrices = self.settings.getAtdAxisAndGrid()
            for i,matrix in enumerate(matrices):
                ax.imshow(matrix,
                          extent=[tdAxis[0],tdAxis[-1],i*10,i*10+10],
                          aspect='auto',origin='lower')
                if i:
                    ax.axhline(i*10)
            # plotting parameters
            ax.set_ylabel('Relative $m/z$')
            ax.set_xlabel('t$_d$')
            ax.set_yticks([])

            ax.autoscale(ax)
            tdLims = self.autoAxesImshow(tdAxis,matrices)
            ax.set_xlim(tdLims)
            self.labelContourPlots(ax)

    def plotCcsDistributions(self,ax):
        """Plot CCS distributions.
        :parameter ax: Matplotlib Axes instance
        """
        ax.clear()
        if self.settings.calibrationOb:
            ccsAxes,ccsLines = self.settings.getCcsLines()
            # Normalising using base peak
            i = 0
            for ccsAxis,line in zip(ccsAxes,ccsLines):
                line = line/line.max()*100
                ax.plot(ccsAxis,line+(i*self.lift),color='k')
                i += 1
            self.autoAxesCcsDistributions(ax,ccsAxes,ccsLines)
            self.label1dPlots(ax)
            ax.set_ylabel('Intensity')
            ax.set_xlabel('CCS ($\AA^2$)')
        else:
            '''horribly hacked to add the ability to show ATDs
            when there hasn't been a calibration file added.
            This is so that we can compare different files where different 
            wave height and velocity values were used'''
            xaxes,lines = self.settings.getAtdLines()
            for i,(xaxis,line) in enumerate(zip(xaxes,lines)):
                line = line/line.max()*100
                ax.plot(xaxis,line+(i*self.lift),color='k')
            self.autoAxesCcsDistributions(ax,xaxes,lines)
            self.label1dPlots(ax)
            ax.set_ylabel('Intensity')
            ax.set_xlabel('t$_d$')
            
    def calculateAutoAxes(self,ccsAxes,ccsLines):
        """Create automatic x axis limits for CCS distributions.
        :parameter ccsAxes: CCS distribution x axis
        :parameter ccsLines: CCS distribution y axis
        :returns: [lowerLimit,upperLimit]
        """
        minX = min([utils.findFirstNonZeroXvalue(axis,line,zero=2) for axis,line in zip(ccsAxes,ccsLines)])
        #maxX = ax.get_xlim()[1]
        maxX = max([ utils.findLastNonZeroXvalue(axis,line)for axis,line in zip(ccsAxes,ccsLines)])
        return [minX,maxX]
        
    def autoAxesCcsDistributions(self,ax,ccsAxes,ccsLines):
        """Plot CCS distributions with automatic x axis limits.
        :parameter ax: Matplotlib Axes instance
        :parameter ccsAxes: CCS distribution x axis
        :parameter ccsLines: CCS distribution y axis
        """
        minX,maxX = self.calculateAutoAxes(ccsAxes,ccsLines)
        ax.set_xlim([minX,maxX])

    def autoAxesImshow(self,ccsAxis,matrices):
        """Create automatic CCS axis limits for 3D contour plots.
        :parameter ccsAxes: CCS axis
        :parameter matrices: Matrix of intensities
        :returns: [lowerLimit,upperLimit]
        """
        ccsLines = [ np.sum(matrix,axis=0) for matrix in matrices ]
        ccsAxes = [ ccsAxis for x in matrices ]
        minX,maxX = self.calculateAutoAxes(ccsAxes,ccsLines)
        return [minX,maxX]
        
    def label1dPlots(self,ax):
        """Label stacked mass spectra or ATDs/CCSDs (e.g. '5V', '10V' in
        voltage ramp experiments).
        :parameter ax: Matplotlib Axes instance
        """
        # needs a fully populated list of values even if just blank strings
        values = self.settings.values
        yheights = [i*self.lift + (self.lift*0.1) for i in xrange(len(values))]

        xlims = ax.get_xlim()
        x_range = xlims[1]-xlims[0]
        xposition = (x_range*0.95) + xlims[0]
        
        self._labelPlots(ax,'right',xposition,yheights,'k')


    def labelContourPlots(self,ax):
        """Draw individual contour plot labels (e.g. '5 V', '10 V' in
        volage ramps).
        :parameter ax: Matplotlib Axes instance
        """
        yheights = [5 + (10*i) for i in xrange(len(self.settings.values))]
        xlims = ax.get_xlim()
        xpos = xlims[0] + (xlims[1]-xlims[0])*0.05
        alignment = 'left'
        self._labelPlots(ax,alignment,xpos,yheights,'cyan')

    def _labelPlots(self,ax,alignment,xpos,yheights,colour):
        """Draw labels for spectra or contour plots (stacked) in a plot area.
        Function gets the values and units for labels from IesSettings() object.
        :parameter ax: Matplotlib Axes instance
        :parameter alignment: Text alignment for annotation
        :parameter xpos: Horizontal position for the labels
        :parameter yheights: Vertical positions for the labels (list)
        :parameter colour: Matplotlib colour for the labels
        """
        units = self.settings.units
        ints = True
        for i,value in enumerate(self.settings.values):
            if value:
                if value%1 != 0:
                    ints = False
        for i,value in enumerate(self.settings.values):
            if value:
                if ints:
                    s = "%.0f %s" %(value,units)
                else:
                    s = "%s %s" %(value,units)
                ax.annotate(s, (xpos,yheights[i]),
                            horizontalalignment=alignment,color=colour)

             
    #===========================================================================
    # Peak picking
    #===========================================================================

    def oneClickPicking(self,onoff):
        """Turn on one click (to add a peak) mode. This activates the
        peak picking function (self._oneClick()).
        :parameter onoff: Boolean for turning on or off peak picking
        """
        if onoff:
            self.picker = self.fig.canvas.mpl_connect('button_press_event',self._oneClick)
        else:
            self.fig.canvas.mpl_disconnect(self.picker)

    def _oneClick(self,event):
        """Function to process a click in one click per
        peak mode.
        """
        xlabel = event.inaxes.get_xlabel()
        import re
        if re.search('CCS', xlabel):
            ccs = event.xdata
            self.settings.addConformation(ccs)
            self.refresh_plot()
        else:
            # TODO(gns) - Consider removing or turning into a warning dialog
            print 'Axis label not matched'

    def togglePicking(self,onoff):
        """Turn off or on peak picking. In the form of adding a peak
        to the GUI when the toggle is turned back to off.
        :parameter onoff: Boolean 
        """
        if onoff:
            self.picker = self.fig.canvas.mpl_connect('button_press_event',self._togglePicking)
        else:
            self.fig.canvas.mpl_disconnect(self.picker)
            self.pickedValue = None

    def _togglePicking(self,event):
        """Sub function for self.togglePicking().
        """
        #print event.xdata
        xlabel = event.inaxes.get_xlabel()
        import re
        self.settings.removeConformation(self.pickedValue)
        if re.match('CCS', xlabel):
            ccs = event.xdata
            self.pickedValue = ccs
            self.settings.addConformation(ccs)
            self.refresh_plot()
        
        

    def drawCcsLines(self):
        """Draw vertical lines corresponding to the CCS value of the user defined
        conformation positions.
        """
        enum = self.settings.checkboxStates.getEnum()
        ps = IesPlotState
        justax1 = [ps.CONTOUR,ps.ATD,ps.ATD_CONFORMATIONS,ps.CONTOUR_CONFORMATIONS]
        ax1ax2 = [ps.CONTOUR_ATD,ps.CONTOUR_ATD_CONFORMATIONS]
        if enum in justax1 or enum in ax1ax2:        
            for i,ccs in enumerate(self.settings.conformations):
                ccs = round(ccs,0)
                self.axes[0].axvline(ccs,label='%d $\AA^2$'%(int(ccs)),color=utils.colourList[i])
                if enum in ax1ax2:
                    self.axes[1].axvline(ccs,label='%d $\AA^2$'%(int(ccs)),color=utils.colourList[i])
            self.axes[0].legend()
        


    def plotConformationHeights(self,ax):
        """Track the abundance of the different conformations across
        the data files and plot them.
        """
        # gather the data
        ccsAxes,ccsLines = self.settings.getCcsLines()
        ccsDic = OrderedDict()
        for ccs in self.settings.conformations:
            ccsDic[ccs] = []
            for xaxis,line in zip(ccsAxes,ccsLines):
                height = line[utils.closest(xaxis,ccs)]
                ccsDic[ccs].append(height)

        # plot it
        if not '' in self.settings.values and len(self.settings.values):
                valueList = self.settings.values
                ax.set_xlabel(self.settings.units)
        else:
            valueList = [ x for x in range(len(ccsDic.keys())) ]
            ax.set_xlabel('Arbitary progression')

        ax.set_xticks(valueList)

        for i,ccs in enumerate(ccsDic.keys()):
            ax.plot(valueList, ccsDic[ccs], label=str(ccs),color=utils.colourList[i])
class CanvasFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Scrimmage Plotting Tool')
        self.figure = Figure()
        self.ax = self.figure.add_subplot(111)

        self.canvas = FigureCanvas(self, -1, self.figure)

        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()

        self.vsizer = wx.BoxSizer(wx.VERTICAL)

        self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.buttonSizer.Add(wx.Button(self, 101, "Open Frames"), 0)
        self.Bind(wx.EVT_BUTTON, self.open_frames, id=101)
        self.buttonSizer.Add(wx.Button(self, 102, "Set Plot Title"), 0)
        self.Bind(wx.EVT_BUTTON, self.changePlotTitle, id=102)
        self.buttonSizer.Add(wx.Button(self, 103, "Set Y Label"), 0)
        self.Bind(wx.EVT_BUTTON, self.changeYLabel, id=103)
        self.buttonSizer.Add(wx.Button(self, 104, "Set Y Min"), 0)
        self.Bind(wx.EVT_BUTTON, self.setYMin, id=104)
        self.buttonSizer.Add(wx.Button(self, 105, "Set Y Max"), 0)
        self.Bind(wx.EVT_BUTTON, self.setYMax, id=105)
        self.buttonSizer.Add(wx.Button(self, 106, "Set Font Size"), 0)
        self.Bind(wx.EVT_BUTTON, self.setFontSize, id=106)

        self.vsizer.Add(self.buttonSizer, 0)

        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.canvasSizer = wx.BoxSizer(wx.VERTICAL)

        self.canvasSizer.Add(self.canvas, 1, wx.ALL | wx.EXPAND | wx.CENTER, 0)
        self.canvasSizer.Add(self.toolbar, 0, wx.ALL | wx.EXPAND | wx.RIGHT, 0)

        self.logs = dict()

        self.logTree = CT.CustomTreeCtrl(self, agwStyle=wx.TR_DEFAULT_STYLE)
        self.logTreeRoot = self.logTree.AddRoot("Scrimmage Logs")
        self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.logTreeChecked)

        self.keySizer = wx.BoxSizer(wx.VERTICAL)
        self.keySizer.Add(wx.StaticText(self, -1, "Key:"))

        rightColumn = wx.BoxSizer(wx.VERTICAL)
        rightColumn.Add(self.keySizer, 4)

        self.sizer.Add(self.logTree, 2, wx.ALL | wx.EXPAND | wx.CENTER, 5)
        self.sizer.Add(self.canvasSizer, 8, wx.ALL | wx.EXPAND | wx.CENTER, 5)
        self.sizer.Add(rightColumn, 4, wx.ALL | wx.EXPAND | wx.TOP, 5)

        self.vsizer.Add(self.sizer, 20, wx.ALL | wx.EXPAND | wx.TOP, 5)
        self.SetSizer(self.vsizer)
        self.Fit()

        self.plottedItems = list()
        self.plottedButtons = dict()
        self.plottedColors = dict()
        self.closeButtonNum = 0
        self.closeLookup = dict()

        self.timeShift = dict()
        self.timeShiftSliders = dict()

        self.plotTitle = None
        self.ymin = None
        self.ymax = None
        self.ylabel = None

        self.flyingStates = set()
        self.flyingStatesToPlot = set()

    def OnPaint(self, event):
        self.canvas.draw()

    def open_frames(self, event):
        file_dialog = \
            wx.FileDialog(self, "Open Frames",
                          os.environ['HOME'] + '/swarm-log',
                          "", "*.bin;*.pickle",
                          wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if file_dialog.ShowModal() == wx.ID_CANCEL:
            return

        fname = file_dialog.GetPath()
        ext = os.path.splitext(fname)[1]
        dir_name = os.path.dirname(fname)
        log_name = os.path.basename(dir_name)

        if ext == '.pickle':
            contacts_df = pd.read_pickle(fname)
        else:
            contacts_df = sc.frames2pandas(fname)
            contacts_df.to_pickle(os.path.join(dir_name, "frames.pickle"))

        self.logs[log_name] = contacts_df

        log_root = self.logTree.AppendItem(self.logTreeRoot, log_name)
        columns = contacts_df.columns
        for uav_id in contacts_df['id'].unique():
            uav_root = self.logTree.AppendItem(log_root, str(uav_id))
            for column in columns:
                self.logTree.AppendItem(uav_root, column, ct_type=1)

        self.plotChanged()

    def changePlotTitle(self, event):
        dlg = wx.TextEntryDialog(self, "New plot title", "Plot Title")
        if self.plotTitle is not None:
            dlg.SetValue(self.plotTitle)
        if dlg.ShowModal() == wx.ID_OK:
            self.plotTitle = dlg.GetValue()
            self.ax.set_title(self.plotTitle)
            self.figure.canvas.draw()
        dlg.Destroy()

    def changeYLabel(self, event):
        dlg = wx.TextEntryDialog(self, "New y axis label", "Y Label")
        if self.ylabel is not None:
            dlg.SetValue(self.ylabel)
        if dlg.ShowModal() == wx.ID_OK:
            self.ylabel = dlg.GetValue()
            self.ax.set_ylabel(self.ylabel)
            self.figure.canvas.draw()
        dlg.Destroy()

    def setYMin(self, event):
        dlg = wx.TextEntryDialog(self, "New minimum y value", "Y Min")
        ymin, ymax = self.ax.get_ylim()
        dlg.SetValue(str(ymin))
        if dlg.ShowModal() == wx.ID_OK:
            self.ymin = float(dlg.GetValue())
            self.ax.set_ylim(bottom=self.ymin)
            self.figure.canvas.draw()
        dlg.Destroy()

    def setYMax(self, event):
        dlg = wx.TextEntryDialog(self, "New maximum y value", "Y Max")
        ymin, ymax = self.ax.get_ylim()
        dlg.SetValue(str(ymax))
        if dlg.ShowModal() == wx.ID_OK:
            self.ymax = float(dlg.GetValue())
            self.ax.set_ylim(top=self.ymax)
            self.figure.canvas.draw()
        dlg.Destroy()

    def setFontSize(self, event):
        dlg = wx.TextEntryDialog(self, "New font size", "Font Size")
        s = mpl.rc_params()['font.size']
        dlg.SetValue(str(s))
        if dlg.ShowModal() == wx.ID_OK:
            s = float(dlg.GetValue())
            mpl.rcParams.update({'font.size': s})
            self.figure.canvas.draw()
        dlg.Destroy()

    def closeButton(self, event):
        t = self.closeLookup[event.GetId()]
        item, garbage = self.logTree.GetFirstChild(self.logTreeRoot)
        while item.IsOk():
            if self.logTree.GetItemText(item) == t[0]:
                for p in item.GetChildren():
                    if self.logTree.GetItemText(p) == t[1]:
                        for c in p.GetChildren():
                            if self.logTree.GetItemText(c) == t[2]:
                                c.Check(False)
                                self.logTree.RefreshSubtree(c)
                                break
                        break
                break
        self.plottedItems.remove(t)
        self.plotChanged()

    def logTreeChecked(self, event):
        item = event.GetItem()
        parent = item.GetParent()
        grandparent = parent.GetParent()

        meta_data = (self.logTree.GetItemText(grandparent),
                     self.logTree.GetItemText(parent),
                     self.logTree.GetItemText(item))

        if item.IsChecked():
            self.plottedItems.append(meta_data)
            self.plottedButtons[meta_data] = self.closeButtonNum
            self.closeLookup[self.closeButtonNum] = meta_data
            self.closeButtonNum += 1
        else:
            self.plottedItems.remove(meta_data)
        self.plotChanged()

    def plotChanged(self):
        # clear figure in preparation of new/fewer plots
        self.figure.clf()
        self.ax = self.figure.add_subplot(111)

        # reset key
        self.keySizer.DeleteWindows()
        self.keySizer.Add(wx.StaticText(self, -1, "Key:"))

        for item in self.plottedItems:
            log_name, uav_id, stat = item
            df = self.logs[log_name]
            data = df[df['id'] == int(uav_id)][['time', stat]]
            l, = self.ax.plot(data['time'], data[stat])
            self.plottedColors[item] = l.get_color()
            s = wx.BoxSizer(wx.HORIZONTAL)
            r = wx.Panel(self, -1, size=(10, 30))
            r = wx.StaticText(self, -1, "  ")
            # kind of a pain to get the RGB color out of pyplot
            r.SetBackgroundColour(
                tuple(
                    i * 255
                    for i in mpl.colors.ColorConverter.colors[l.get_color()]))
            s.Add(r, 0)
            s.Add(
                wx.StaticText(self,
                              -1,
                              "%s - %s - %s" % item,
                              style=wx.ALIGN_LEFT), 4,
                wx.ALL | wx.EXPAND | wx.LEFT)
            s.Add(wx.Button(self, self.plottedButtons[item], 'Remove'), 0)
            self.Bind(wx.EVT_BUTTON,
                      self.closeButton,
                      id=self.plottedButtons[item])
            self.keySizer.Add(s)
        self.keySizer.Layout()

        self.ax.set_xlabel("Time")
        self.ax.relim()
        self.ax.autoscale_view()

        if self.ymin is not None:
            self.ax.set_ylim(bottom=self.ymin)
        if self.ymax is not None:
            self.ax.set_ylim(top=self.ymax)
        if self.ylabel is not None:
            self.ax.set_ylabel(self.ylabel)
        if self.plotTitle is not None:
            self.ax.set_title(self.plotTitle)

        self.figure.autofmt_xdate()
        self.figure.canvas.draw()
        self.SetSizer(self.vsizer)
class QLabelPlot(QWidget):

    def __init__(self, max_x, max_y, parent=None, saveSpace=False):
        super(QLabelPlot, self).__init__(parent)
        self.__max_x = max_x
        self.__max_y = max_y
        self.saveSpace = saveSpace
        self.dpi = 100

        if matplotlib_v is not None:
            self.initPlot()
            vbox = QVBoxLayout()
            if self.mpl_toolbar is not None:
                vbox.addWidget(self.mpl_toolbar)
            vbox.addWidget(self.canvas)
            self.setLayout(vbox)
        else:
            lbl = QLabel(self)
            lbl.setText("matplotlib not installed")
            vbox = QVBoxLayout()
            vbox.addWidget(lbl)
            self.setLayout(vbox)

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                QSizePolicy.MinimumExpanding)

    def initPlot(self):
            # 100 dpi and a Size of 5 times 4 inches
            self.fig = Figure((4.0, 4.0), dpi=self.dpi)
            self.canvas = FigureCanvas(self.fig)
            self.canvas.setParent(self)
            self.axes = self.fig.add_subplot(111)
            self.fig.subplots_adjust(left=0.0, right=1.0, top=0.9, bottom=0.1) 
    
            self.__setAxes__()

            self.mpl_toolbar = None
            if not self.saveSpace:
                #NavigationToolbar
                self.mpl_toolbar = NavigationToolbar(self.canvas, self)

            #colors and pattern for boxes
            self.__fc_colors=['b', 'g', 'r', 'c', 'm', 'y']
            self.__hatches=[ '/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*' ]
    
    def clear(self):
        self.axes.cla()
        self.fig.clf()
        self.axes = self.fig.add_subplot(111)
        if self.saveSpace:
            self.fig.subplots_adjust(left=0.0, right=1.0, top=1.0, bottom=0.0)

    def __setAxes__(self):
            # do only integer coords
            self.axes.format_coord = self.img_coord

            #set coord ranges
            self.axes.set_ylim([self.__max_y-1+0.5, -0.5])
            self.axes.set_xlim([-0.5, self.__max_x-1+0.5])


    def sizeHint(self):
        if self.saveSpace:
            return QSize(self.__max_x*10+110, self.__max_y*10+110)
        else:
            return QSize(self.__max_x*20+40, self.__max_y*20+80)


    def addImg(self, img):
        self.__img = img
        if matplotlib_v is not None:
            self.axes.cla()
            self.__setAxes__()
            self.axes.imshow(img, interpolation="nearest", cmap=cm.Greys_r)
            self.canvas.draw()

    def appendBoxes(self, boxes):
        if matplotlib_v is not None:
            fc_i = 0;
            h_i = 0;
            if boxes is not None:
                for key in boxes:
                    ((x1, y1), (x2, y2)) = boxes[key]
                    self.axes.fill([x1-0.5+0.01, x2+0.5-0.01, x2+0.5-0.01, x1-0.5+0.01],
                            [y1-0.5+0.01, y1-0.5+0.01, y2+0.5-0.01, y2+0.5-0.01],
                            alpha=0.5, hatch=self.__hatches[h_i], fc=self.__fc_colors[fc_i])
                    fc_i = (fc_i + 1) % len(self.__fc_colors)
                    h_i = (h_i + 1) % len(self.__hatches)
                self.canvas.draw()


    # do int coords only
    def img_coord(self, x, y):
        col = ""
        row = ""
        if x >= -0.5 and x < self.__max_x+0.5:
            col = str(int(x+0.5))
        if y >= -0.5 and y < self.__max_y+0.5:
            row = str(int(y+0.5))
        return ("x=" + col + " y=" + row)
Exemple #49
0
class VNA(QMainWindow, Ui_VNA):

    max_size = 16384

    def __init__(self):
        super(VNA, self).__init__()
        self.setupUi(self)
        # IP address validator
        rx = QRegExp(
            '^(((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(rp\-[a-f,0-9][a-f,0-9][a-f,0-9][a-f,0-9][a-f,0-9][a-f,0-9]\.local))$'
        )
        self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
        # state variables
        self.idle = True
        self.reading = False
        # sweep parameters
        self.sweep_start = 100
        self.sweep_stop = 60000
        self.sweep_size = 600
        self.xaxis, self.sweep_step = np.linspace(self.sweep_start,
                                                  self.sweep_stop,
                                                  self.sweep_size,
                                                  retstep=True)
        self.xaxis *= 1000
        # buffer and offset for the incoming samples
        self.buffer = bytearray(24 * VNA.max_size)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.complex64)
        self.adc1 = np.zeros(VNA.max_size, np.complex64)
        self.adc2 = np.zeros(VNA.max_size, np.complex64)
        self.dac1 = np.zeros(VNA.max_size, np.complex64)
        self.open = np.zeros(VNA.max_size, np.complex64)
        self.short = np.zeros(VNA.max_size, np.complex64)
        self.load = np.zeros(VNA.max_size, np.complex64)
        self.dut = np.zeros(VNA.max_size, np.complex64)
        self.mode = 'dut'
        # create figure
        self.figure = Figure()
        self.figure.set_facecolor('none')
        self.canvas = FigureCanvas(self.figure)
        self.plotLayout.addWidget(self.canvas)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
        # initialize cursor
        self.cursor = None
        # remove subplots action
        actions = self.toolbar.actions()
        self.toolbar.removeAction(actions[7])
        self.plotLayout.addWidget(self.toolbar)
        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)
        # connect signals from buttons and boxes
        self.sweepFrame.setEnabled(False)
        self.dutSweep.setEnabled(False)
        self.connectButton.clicked.connect(self.start)
        self.writeButton.clicked.connect(self.write_cfg)
        self.readButton.clicked.connect(self.read_cfg)
        self.openSweep.clicked.connect(self.sweep_open)
        self.shortSweep.clicked.connect(self.sweep_short)
        self.loadSweep.clicked.connect(self.sweep_load)
        self.dutSweep.clicked.connect(self.sweep_dut)
        self.csvButton.clicked.connect(self.write_csv)
        self.s1pButton.clicked.connect(self.write_s1p)
        self.s2pButton.clicked.connect(self.write_s2p)
        self.startValue.valueChanged.connect(self.set_start)
        self.stopValue.valueChanged.connect(self.set_stop)
        self.sizeValue.valueChanged.connect(self.set_size)
        self.rateValue.addItems(['500', '100', '50', '10', '5', '1'])
        self.rateValue.lineEdit().setReadOnly(True)
        self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
        for i in range(0, self.rateValue.count()):
            self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
        self.rateValue.currentIndexChanged.connect(self.set_rate)
        self.corrValue.valueChanged.connect(self.set_corr)
        self.levelValue.valueChanged.connect(self.set_level)
        self.openPlot.clicked.connect(self.plot_open)
        self.shortPlot.clicked.connect(self.plot_short)
        self.loadPlot.clicked.connect(self.plot_load)
        self.dutPlot.clicked.connect(self.plot_dut)
        self.smithPlot.clicked.connect(self.plot_smith)
        self.impPlot.clicked.connect(self.plot_imp)
        self.rcPlot.clicked.connect(self.plot_rc)
        self.swrPlot.clicked.connect(self.plot_swr)
        self.rlPlot.clicked.connect(self.plot_rl)
        self.gainPlot.clicked.connect(self.plot_gain)
        # create timer
        self.startTimer = QTimer(self)
        self.startTimer.timeout.connect(self.timeout)

    def start(self):
        if self.idle:
            self.connectButton.setEnabled(False)
            self.socket.connectToHost(self.addrValue.text(), 1001)
            self.startTimer.start(5000)
        else:
            self.stop()

    def stop(self):
        self.idle = True
        self.socket.abort()
        self.connectButton.setText('Connect')
        self.connectButton.setEnabled(True)
        self.sweepFrame.setEnabled(False)
        self.selectFrame.setEnabled(True)
        self.dutSweep.setEnabled(False)

    def timeout(self):
        self.display_error('timeout')

    def connected(self):
        self.startTimer.stop()
        self.idle = False
        self.set_start(self.startValue.value())
        self.set_stop(self.stopValue.value())
        self.set_size(self.sizeValue.value())
        self.set_rate(self.rateValue.currentIndex())
        self.set_corr(self.corrValue.value())
        self.set_level(self.levelValue.value())
        self.connectButton.setText('Disconnect')
        self.connectButton.setEnabled(True)
        self.sweepFrame.setEnabled(True)
        self.dutSweep.setEnabled(True)

    def read_data(self):
        if not self.reading:
            self.socket.readAll()
            return
        size = self.socket.bytesAvailable()
        self.progress.setValue((self.offset + size) / 24)
        limit = 24 * (self.sweep_size + 1)
        if self.offset + size < limit:
            self.buffer[self.offset:self.offset +
                        size] = self.socket.read(size)
            self.offset += size
        else:
            self.buffer[self.offset:limit] = self.socket.read(limit -
                                                              self.offset)
            self.adc1 = self.data[0::3]
            self.adc2 = self.data[1::3]
            self.dac1 = self.data[2::3]
            getattr(self, self.mode)[0:self.sweep_size] = self.adc1[
                1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1]
            getattr(self, 'plot_%s' % self.mode)()
            self.reading = False
            self.sweepFrame.setEnabled(True)
            self.selectFrame.setEnabled(True)

    def display_error(self, socketError):
        self.startTimer.stop()
        if socketError == 'timeout':
            QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
        else:
            QMessageBox.information(self, 'VNA',
                                    'Error: %s.' % self.socket.errorString())
        self.stop()

    def set_start(self, value):
        self.sweep_start = value
        self.xaxis, self.sweep_step = np.linspace(self.sweep_start,
                                                  self.sweep_stop,
                                                  self.sweep_size,
                                                  retstep=True)
        self.xaxis *= 1000
        if self.idle: return
        self.socket.write(struct.pack('<I', 0 << 28 | int(value * 1000)))

    def set_stop(self, value):
        self.sweep_stop = value
        self.xaxis, self.sweep_step = np.linspace(self.sweep_start,
                                                  self.sweep_stop,
                                                  self.sweep_size,
                                                  retstep=True)
        self.xaxis *= 1000
        if self.idle: return
        self.socket.write(struct.pack('<I', 1 << 28 | int(value * 1000)))

    def set_size(self, value):
        self.sweep_size = value
        self.xaxis, self.sweep_step = np.linspace(self.sweep_start,
                                                  self.sweep_stop,
                                                  self.sweep_size,
                                                  retstep=True)
        self.xaxis *= 1000
        if self.idle: return
        self.socket.write(struct.pack('<I', 2 << 28 | int(value)))

    def set_rate(self, value):
        if self.idle: return
        rate = [1, 5, 10, 50, 100, 500][value]
        self.socket.write(struct.pack('<I', 3 << 28 | int(rate)))

    def set_corr(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 4 << 28 | int(value)))

    def set_level(self, value):
        if self.idle: return
        self.socket.write(
            struct.pack('<I',
                        5 << 28 | int(32767 * np.power(10.0, value / 20.0))))

    def sweep(self):
        if self.idle: return
        self.sweepFrame.setEnabled(False)
        self.selectFrame.setEnabled(False)
        self.socket.write(struct.pack('<I', 6 << 28))
        self.offset = 0
        self.reading = True
        self.progress = QProgressDialog('Sweep status', 'Cancel', 0,
                                        self.sweep_size + 1)
        self.progress.setModal(True)
        self.progress.setMinimumDuration(1000)
        self.progress.canceled.connect(self.cancel)

    def cancel(self):
        self.offset = 0
        self.reading = False
        self.socket.write(struct.pack('<I', 7 << 28))
        self.sweepFrame.setEnabled(True)
        self.selectFrame.setEnabled(True)

    def sweep_open(self):
        self.mode = 'open'
        self.sweep()

    def sweep_short(self):
        self.mode = 'short'
        self.sweep()

    def sweep_load(self):
        self.mode = 'load'
        self.sweep()

    def sweep_dut(self):
        self.mode = 'dut'
        self.sweep()

    def gain(self):
        size = self.sweep_size
        return self.dut[0:size] / self.short[0:size]

    def impedance(self):
        size = self.sweep_size
        return 50.0 * (self.open[0:size] - self.load[0:size]) * (
            self.dut[0:size] - self.short[0:size]) / (
                (self.load[0:size] - self.short[0:size]) *
                (self.open[0:size] - self.dut[0:size]))

    def gamma(self):
        z = self.impedance()
        return (z - 50.0) / (z + 50.0)

    def plot_gain(self):
        if self.cursor is not None: self.cursor.hide().disable()
        matplotlib.rcdefaults()
        self.figure.clf()
        self.figure.subplots_adjust(left=0.12,
                                    bottom=0.12,
                                    right=0.88,
                                    top=0.98)
        axes1 = self.figure.add_subplot(111)
        axes1.cla()
        axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.tick_params('y', color='blue', labelcolor='blue')
        axes1.yaxis.label.set_color('blue')
        gain = self.gain()
        axes1.plot(self.xaxis,
                   20.0 * np.log10(np.absolute(gain)),
                   color='blue',
                   label='Gain')
        axes2 = axes1.twinx()
        axes2.spines['left'].set_color('blue')
        axes2.spines['right'].set_color('red')
        axes1.set_xlabel('Hz')
        axes1.set_ylabel('Gain, dB')
        axes2.set_ylabel('Phase angle')
        axes2.tick_params('y', color='red', labelcolor='red')
        axes2.yaxis.label.set_color('red')
        axes2.plot(self.xaxis,
                   np.angle(gain, deg=True),
                   color='red',
                   label='Phase angle')
        self.cursor = datacursor(axes=self.figure.get_axes(),
                                 formatter=LabelFormatter(),
                                 display='multiple')
        self.canvas.draw()

    def plot_magphase(self, data):
        if self.cursor is not None: self.cursor.hide().disable()
        matplotlib.rcdefaults()
        self.figure.clf()
        self.figure.subplots_adjust(left=0.12,
                                    bottom=0.12,
                                    right=0.88,
                                    top=0.98)
        axes1 = self.figure.add_subplot(111)
        axes1.cla()
        axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.tick_params('y', color='blue', labelcolor='blue')
        axes1.yaxis.label.set_color('blue')
        axes1.plot(self.xaxis,
                   np.absolute(data),
                   color='blue',
                   label='Magnitude')
        axes2 = axes1.twinx()
        axes2.spines['left'].set_color('blue')
        axes2.spines['right'].set_color('red')
        axes1.set_xlabel('Hz')
        axes1.set_ylabel('Magnitude')
        axes2.set_ylabel('Phase angle')
        axes2.tick_params('y', color='red', labelcolor='red')
        axes2.yaxis.label.set_color('red')
        axes2.plot(self.xaxis,
                   np.angle(data, deg=True),
                   color='red',
                   label='Phase angle')
        self.cursor = datacursor(axes=self.figure.get_axes(),
                                 formatter=LabelFormatter(),
                                 display='multiple')
        self.canvas.draw()

    def plot_open(self):
        self.plot_magphase(self.open[0:self.sweep_size])

    def plot_short(self):
        self.plot_magphase(self.short[0:self.sweep_size])

    def plot_load(self):
        self.plot_magphase(self.load[0:self.sweep_size])

    def plot_dut(self):
        self.plot_magphase(self.dut[0:self.sweep_size])

    def plot_smith_grid(self, axes, color):
        load = 50.0
        ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
        for tick in ticks * load:
            axis = np.logspace(-4, np.log10(1.0e3), 200) * load
            z = tick + 1.0j * axis
            gamma = (z - load) / (z + load)
            axes.plot(gamma.real,
                      gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            axes.plot(gamma.real,
                      -gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            z = axis + 1.0j * tick
            gamma = (z - load) / (z + load)
            axes.plot(gamma.real,
                      gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            axes.plot(gamma.real,
                      -gamma.imag,
                      color=color,
                      linewidth=0.4,
                      alpha=0.3)
            if tick == 0.0:
                axes.text(1.0,
                          0.0,
                          u'\u221E',
                          color=color,
                          ha='left',
                          va='center',
                          clip_on=True,
                          fontsize=18.0)
                axes.text(-1.0,
                          0.0,
                          u'0\u03A9',
                          color=color,
                          ha='left',
                          va='bottom',
                          clip_on=True,
                          fontsize=12.0)
                continue
            lab = u'%d\u03A9' % tick
            x = (tick - load) / (tick + load)
            axes.text(x,
                      0.0,
                      lab,
                      color=color,
                      ha='left',
                      va='bottom',
                      clip_on=True,
                      fontsize=12.0)
            lab = u'j%d\u03A9' % tick
            z = 1.0j * tick
            gamma = (z - load) / (z + load) * 1.05
            x = gamma.real
            y = gamma.imag
            angle = np.angle(gamma) * 180.0 / np.pi - 90.0
            axes.text(x,
                      y,
                      lab,
                      color=color,
                      ha='center',
                      va='center',
                      clip_on=True,
                      rotation=angle,
                      fontsize=12.0)
            lab = u'-j%d\u03A9' % tick
            axes.text(x,
                      -y,
                      lab,
                      color=color,
                      ha='center',
                      va='center',
                      clip_on=True,
                      rotation=-angle,
                      fontsize=12.0)

    def plot_smith(self):
        if self.cursor is not None: self.cursor.hide().disable()
        matplotlib.rcdefaults()
        self.figure.clf()
        self.figure.subplots_adjust(left=0.0, bottom=0.0, right=1.0, top=1.0)
        axes1 = self.figure.add_subplot(111)
        self.plot_smith_grid(axes1, 'blue')
        gamma = self.gamma()
        plot, = axes1.plot(gamma.real, gamma.imag, color='red')
        axes1.axis('equal')
        axes1.set_xlim(-1.12, 1.12)
        axes1.set_ylim(-1.12, 1.12)
        axes1.xaxis.set_visible(False)
        axes1.yaxis.set_visible(False)
        for loc, spine in axes1.spines.items():
            spine.set_visible(False)
        self.cursor = datacursor(plot,
                                 formatter=SmithFormatter(self.xaxis),
                                 display='multiple')
        self.canvas.draw()

    def plot_imp(self):
        self.plot_magphase(self.impedance())

    def plot_rc(self):
        self.plot_magphase(self.gamma())

    def plot_swr(self):
        if self.cursor is not None: self.cursor.hide().disable()
        matplotlib.rcdefaults()
        self.figure.clf()
        self.figure.subplots_adjust(left=0.12,
                                    bottom=0.12,
                                    right=0.88,
                                    top=0.98)
        axes1 = self.figure.add_subplot(111)
        axes1.cla()
        axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.set_xlabel('Hz')
        axes1.set_ylabel('SWR')
        magnitude = np.absolute(self.gamma())
        swr = np.maximum(
            1.0,
            np.minimum(100.0, (1.0 + magnitude) /
                       np.maximum(1.0e-20, 1.0 - magnitude)))
        axes1.plot(self.xaxis, swr, color='blue', label='SWR')
        self.cursor = datacursor(axes=self.figure.get_axes(),
                                 formatter=LabelFormatter(),
                                 display='multiple')
        self.canvas.draw()

    def plot_rl(self):
        if self.cursor is not None: self.cursor.hide().disable()
        matplotlib.rcdefaults()
        self.figure.clf()
        self.figure.subplots_adjust(left=0.12,
                                    bottom=0.12,
                                    right=0.88,
                                    top=0.98)
        axes1 = self.figure.add_subplot(111)
        axes1.cla()
        axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
        axes1.set_xlabel('Hz')
        axes1.set_ylabel('Return loss, dB')
        magnitude = np.absolute(self.gamma())
        axes1.plot(self.xaxis,
                   20.0 * np.log10(magnitude),
                   color='blue',
                   label='Return loss')
        self.cursor = datacursor(axes=self.figure.get_axes(),
                                 formatter=LabelFormatter(),
                                 display='multiple')
        self.canvas.draw()

    def write_cfg(self):
        dialog = QFileDialog(self, 'Write configuration settings', '.',
                             '*.ini')
        dialog.setDefaultSuffix('ini')
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setOptions(QFileDialog.DontConfirmOverwrite)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            settings = QSettings(name[0], QSettings.IniFormat)
            self.write_cfg_settings(settings)

    def read_cfg(self):
        dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
        dialog.setDefaultSuffix('ini')
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            settings = QSettings(name[0], QSettings.IniFormat)
            self.read_cfg_settings(settings)

    def write_cfg_settings(self, settings):
        settings.setValue('addr', self.addrValue.text())
        settings.setValue('start', self.startValue.value())
        settings.setValue('stop', self.stopValue.value())
        settings.setValue('rate', self.rateValue.currentIndex())
        settings.setValue('corr', self.corrValue.value())
        size = self.sizeValue.value()
        settings.setValue('size', size)
        for i in range(0, size):
            settings.setValue('open_real_%d' % i, float(self.open.real[i]))
            settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
        for i in range(0, size):
            settings.setValue('short_real_%d' % i, float(self.short.real[i]))
            settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
        for i in range(0, size):
            settings.setValue('load_real_%d' % i, float(self.load.real[i]))
            settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
        for i in range(0, size):
            settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
            settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

    def read_cfg_settings(self, settings):
        self.addrValue.setText(settings.value('addr', '192.168.1.100'))
        self.startValue.setValue(settings.value('start', 100, type=int))
        self.stopValue.setValue(settings.value('stop', 60000, type=int))
        self.rateValue.setCurrentIndex(settings.value('rate', 0, type=int))
        self.corrValue.setValue(settings.value('corr', 0, type=int))
        size = settings.value('size', 600, type=int)
        self.sizeValue.setValue(size)
        for i in range(0, size):
            real = settings.value('open_real_%d' % i, 0.0, type=float)
            imag = settings.value('open_imag_%d' % i, 0.0, type=float)
            self.open[i] = real + 1.0j * imag
        for i in range(0, size):
            real = settings.value('short_real_%d' % i, 0.0, type=float)
            imag = settings.value('short_imag_%d' % i, 0.0, type=float)
            self.short[i] = real + 1.0j * imag
        for i in range(0, size):
            real = settings.value('load_real_%d' % i, 0.0, type=float)
            imag = settings.value('load_imag_%d' % i, 0.0, type=float)
            self.load[i] = real + 1.0j * imag
        for i in range(0, size):
            real = settings.value('dut_real_%d' % i, 0.0, type=float)
            imag = settings.value('dut_imag_%d' % i, 0.0, type=float)
            self.dut[i] = real + 1.0j * imag

    def write_csv(self):
        dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
        dialog.setDefaultSuffix('csv')
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setOptions(QFileDialog.DontConfirmOverwrite)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            fh = open(name[0], 'w')
            gamma = self.gamma()
            size = self.sizeValue.value()
            fh.write(
                'frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n'
            )
            for i in range(0, size):
                fh.write(
                    '0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n'
                    %
                    (self.xaxis[i], self.open.real[i], self.open.imag[i],
                     self.short.real[i], self.short.imag[i], self.load.real[i],
                     self.load.imag[i], self.dut.real[i], self.dut.imag[i]))
            fh.close()

    def write_s1p(self):
        dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
        dialog.setDefaultSuffix('s1p')
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setOptions(QFileDialog.DontConfirmOverwrite)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            fh = open(name[0], 'w')
            gamma = self.gamma()
            size = self.sizeValue.value()
            fh.write('# GHz S MA R 50\n')
            for i in range(0, size):
                fh.write('0.0%.8d   %8.6f %7.2f\n' %
                         (self.xaxis[i], np.absolute(
                             gamma[i]), np.angle(gamma[i], deg=True)))
            fh.close()

    def write_s2p(self):
        dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
        dialog.setDefaultSuffix('s2p')
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setOptions(QFileDialog.DontConfirmOverwrite)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            fh = open(name[0], 'w')
            gain = self.gain()
            gamma = self.gamma()
            size = self.sizeValue.value()
            fh.write('# GHz S MA R 50\n')
            for i in range(0, size):
                fh.write(
                    '0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n'
                    % (self.xaxis[i], np.absolute(gamma[i]),
                       np.angle(gamma[i], deg=True), np.absolute(
                           gain[i]), np.angle(gain[i], deg=True)))
            fh.close()
Exemple #50
0
class GUI(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.root = master
        self.grid()
        self.data = self.load_data()
        self.car, self.road = self.init_components()
        self.state = State.PLAYING
        self.recorder = Recorder()
        self.recorder.add(self.car)
        self.create_widgets()
        self.clean_fig()
        self.draw_road(self.road.finish_area, self.road.road_edges)
        self.draw_car(self.car.loc(), self.car.car_degree, self.car.radius)

    def load_data(self):
        case_file_path = '../cases/case01.txt'
        d = Data(case_file_path)
        return d.get()

    def init_components(self):
        c = Car(self.data['start_point'], self.data['start_degree'])
        c.update_sensor(self.data['road_edges'])
        r = Road(self.data['finish_area'], self.data['road_edges'])
        return c, r

    def create_widgets(self):
        # 標題
        self.winfo_toplevel().title("Yochien CI HW1")

        # 自走車位置、方向、感測器距離
        _, self.loc = add_text(self, 0, "Car Location", self.car.loc())
        _, self.fl = add_text(self, 1, "Car Sensor Front Left",
                              self.car.sensor_dist['fl'])
        _, self.f = add_text(self, 2, "Car Sensor Front",
                             self.car.sensor_dist['f'])
        _, self.fr = add_text(self, 3, "Car Sensor Front Right",
                              self.car.sensor_dist['fr'])
        _, self.cd = add_text(self, 4, "Car Degree", self.car.car_degree)
        _, self.swd = add_text(self, 5, "Car Steering Wheel Degree",
                               self.car.steering_wheel_degree)
        # 更新車子
        _, self.next = add_button(self, 6, "Start Playing", "Run", self.run)
        # 目前狀態
        _, self.st = add_text(self, 7, "Status", self.state)

        # 地圖與道路
        self.road_fig = Figure(figsize=(5, 5), dpi=120)
        self.road_canvas = FigureCanvasTkAgg(self.road_fig, self)
        self.road_canvas.draw()
        self.road_canvas.get_tk_widget().grid(row=8, column=0, columnspan=3)

    def turn_steering_wheel(self, degree):
        self.car.turn_steering_wheel(degree)

    def run(self):
        while self.state == State.PLAYING:
            self.update()
            sleep(0.02)

    def update(self):
        self.update_state()
        self.update_car()
        self.recorder.add(self.car)

    def update_state(self):
        if self.road.is_crash(self.car):
            self.state = State.CRASH
        elif self.road.is_finish(self.car):
            self.state = State.FINISH
            self.recorder.to_file()

        self.st["text"] = self.state

    def update_car(self):
        fl, f, fr = self.car.update_sensor(self.data['road_edges'])
        fl = Fuzzifier.fl(fl)
        f = Fuzzifier.f(f)
        fr = Fuzzifier.fr(fr)
        self.turn_steering_wheel(Rules.apply(fl, f, fr))

        self.car.next()
        self.loc["text"] = self.car.loc()
        self.cd["text"] = self.car.car_degree
        self.swd["text"] = self.car.steering_wheel_degree
        self.clean_fig()
        self.draw_road(self.road.finish_area, self.road.road_edges)
        self.draw_car(self.car.loc(), self.car.car_degree, self.car.radius)
        self.draw_route()
        self.road_canvas.draw()

    def clean_fig(self):
        # 清空並初始化影像
        self.road_fig.clf()
        self.road_fig.ax = self.road_fig.add_subplot(111)
        self.road_fig.ax.set_aspect(1)
        self.road_fig.ax.set_xlim([-20, 60])
        self.road_fig.ax.set_ylim([-10, 60])

    def draw_road(self, finish_area, road_edges):
        # 車道邊界
        for i in range(len(road_edges) - 1):
            self.road_fig.ax.text(
                road_edges[i][0], road_edges[i][1],
                '({},{})'.format(road_edges[i][0], road_edges[i][1]))
            self.road_fig.ax.plot([road_edges[i][0], road_edges[i + 1][0]],
                                  [road_edges[i][1], road_edges[i + 1][1]],
                                  'k')
        # 終點區域
        a, b = finish_area[0]
        c, d = finish_area[1]
        self.road_fig.ax.plot([a, c], [b, b], 'r')
        self.road_fig.ax.plot([c, c], [b, d], 'r')
        self.road_fig.ax.plot([c, a], [d, d], 'r')
        self.road_fig.ax.plot([a, a], [d, b], 'r')

    def draw_car(self, loc, car_degree, radius):
        # 車子範圍
        self.road_fig.ax.plot(loc[0], loc[1], '.b')
        circle = plt.Circle(loc, radius, color='b', fill=False)
        self.road_fig.ax.add_artist(circle)
        # 感測器
        self.fl["text"], self.f["text"], self.fr[
            "text"] = self.car.update_sensor(self.data['road_edges'])
        for s in self.car.sensor_point:
            self.road_fig.ax.plot([loc[0], self.car.sensor_point[s][0]],
                                  [loc[1], self.car.sensor_point[s][1]], 'r')
            self.road_fig.ax.plot(self.car.sensor_point[s][0],
                                  self.car.sensor_point[s][1], '.b')

    def draw_route(self):
        records = self.recorder.get()
        for r in records:
            self.road_fig.ax.plot(int(float(r[0]) + 0.0001),
                                  int(float(r[1]) + 0.0001), '.y')
Exemple #51
0
class VelPlotWidget(QtGui.QWidget):
    ''' Widget for a velocity plot with interaction.

        19-Dec-2014 by JXP
    '''
    def __init__(self,
                 ispec,
                 z=None,
                 parent=None,
                 llist=None,
                 norm=True,
                 vmnx=[-300., 300.] * u.km / u.s,
                 abs_sys=None):
        '''
        spec = Spectrum1D
        Norm: Bool (False)
          Normalized spectrum?
        abs_sys: AbsSystem
          Absorption system class
        '''
        super(VelPlotWidget, self).__init__(parent)

        # Initialize
        spec, spec_fil = ltgu.read_spec(ispec)

        self.spec = spec
        self.spec_fil = spec_fil
        self.z = z
        self.vmnx = vmnx
        self.norm = norm

        # Abs_System
        self.abs_sys = abs_sys
        if self.abs_sys is None:
            self.abs_sys = GenericAbsSystem((0. * u.deg, 0. * u.deg), self.z,
                                            self.vmnx)
            self.abs_lines = []
        else:
            self.z = self.abs_sys.zabs
            # Line list
            if llist is None:
                self.abs_lines = self.abs_sys.list_of_abslines()
                if len(self.abs_lines) > 0:
                    lwrest = [iline.wrest for iline in self.abs_lines]
                else:
                    lwrest = None
                if lwrest is not None:
                    llist = ltgu.set_llist(
                        lwrest)  # Not sure this is working..

        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        self.psdict = {}  # Dict for spectra plotting
        self.psdict[
            'xmnx'] = self.vmnx.value  # Too much pain to use units with this
        self.psdict['ymnx'] = [-0.1, 1.1]
        self.psdict['nav'] = ltgu.navigate(0, 0, init=True)

        # Status Bar?
        #if not status is None:
        #    self.statusBar = status

        # Line List
        if llist is None:
            self.llist = ltgu.set_llist('Strong')
        else:
            self.llist = llist
        self.llist['z'] = self.z

        # Indexing for line plotting
        self.idx_line = 0

        self.init_lines()

        # Create the mpl Figure and FigCanvas objects.
        #
        self.dpi = 150
        self.fig = Figure((8.0, 4.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)

        self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas.setFocus()
        self.canvas.mpl_connect('key_press_event', self.on_key)
        self.canvas.mpl_connect('button_press_event', self.on_click)

        # Sub_plots
        self.sub_xy = [3, 4]

        self.fig.subplots_adjust(hspace=0.0, wspace=0.1)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.canvas)

        self.setLayout(vbox)

        # Draw on init
        self.on_draw()

    # Load them up for display
    def init_lines(self):
        wvmin = np.min(self.spec.dispersion)
        wvmax = np.max(self.spec.dispersion)
        #
        wrest = self.llist[self.llist['List']].wrest
        wvobs = (1 + self.z) * wrest
        gdlin = np.where((wvobs > wvmin) & (wvobs < wvmax))[0]
        self.llist['show_line'] = gdlin

        # Update/generate lines [will not update]
        for idx in gdlin:
            self.generate_line((self.z, wrest[idx]))

    def grab_line(self, wrest):
        """ Grab a line from the list
        Parameters
        ----------
        wrest

        Returns
        -------
        iline : AbsLine object
        """
        awrest = [iline.wrest for iline in self.abs_lines]
        try:
            idx = awrest.index(wrest)
        except ValueError:
            return None
        else:
            return self.abs_lines[idx]

    def generate_line(self, inp):
        ''' Generate a new line, if it doesn't exist
        Parameters:
        ----------
        inp: tuple
          (z,wrest)
        '''
        # Generate?
        if self.grab_line(inp[1]) is None:
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            newline = AbsLine(inp[1], linelist=self.llist[self.llist['List']])
            print('VelPlot: Generating line {:g}'.format(inp[1]))
            newline.analy['vlim'] = self.vmnx / 2.
            newline.attrib['z'] = self.abs_sys.zabs
            newline.analy['do_analysis'] = 1  # Init to ok
            # Spec file
            if self.spec_fil is not None:
                newline.analy['datafile'] = self.spec_fil
            # Append
            self.abs_lines.append(newline)

    def remove_line(self, wrest):
        """ Remove a line, if it exists
        Parameters
        ----------
        wrest : Quantity
        """
        awrest = [iline.wrest for iline in self.abs_lines]
        try:
            idx = awrest.index(wrest)
        except ValueError:
            return None
        else:
            _ = self.abs_lines.pop(idx)

    # Key stroke
    def on_key(self, event):

        # Init
        rescale = True
        fig_clear = False
        wrest = None
        flg = 0
        sv_idx = self.idx_line

        ## Change rows/columns
        if event.key == 'k':
            self.sub_xy[0] = max(0, self.sub_xy[0] - 1)
        if event.key == 'K':
            self.sub_xy[0] = self.sub_xy[0] + 1
        if event.key == 'c':
            self.sub_xy[1] = max(0, self.sub_xy[1] - 1)
        if event.key == 'C':
            self.sub_xy[1] = max(0, self.sub_xy[1] + 1)

        ## NAVIGATING
        if event.key in self.psdict['nav']:
            flg = ltgu.navigate(self.psdict, event)
        if event.key == '-':
            self.idx_line = max(0, self.idx_line -
                                self.sub_xy[0] * self.sub_xy[1])  # Min=0
            if self.idx_line == sv_idx:
                print('Edge of list')
        if event.key == '=':
            self.idx_line = min(
                len(self.llist['show_line']) - self.sub_xy[0] * self.sub_xy[1],
                self.idx_line + self.sub_xy[0] * self.sub_xy[1])
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            if self.idx_line == sv_idx:
                print('Edge of list')

        ## Reset z
        if event.key == 'z':
            newz = ltu.z_from_v(self.z, event.xdata)
            self.z = newz
            self.abs_sys.zabs = newz
            # Drawing
            self.psdict['xmnx'] = self.vmnx.value

        # Single line command
        if event.key in [
                '1', '2', 'B', 'U', 'L', 'N', 'V', 'A', 'x', 'X', '^', '&'
        ]:
            try:
                wrest = event.inaxes.get_gid()
            except AttributeError:
                return
            else:
                absline = self.grab_line(wrest)
                kwrest = wrest.value

        ## Velocity limits
        unit = u.km / u.s
        if event.key == '1':
            absline.analy['vlim'][0] = event.xdata * unit
        if event.key == '2':
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            absline.analy['vlim'][1] = event.xdata * unit
        if event.key == '!':
            for iline in self.abs_sys.lines:
                iline.analy['vlim'][0] = event.xdata * unit
        if event.key == '@':
            for iline in self.abs_sys.lines:
                iline.analy['vlim'][1] = event.xdata * unit
        ## Line type
        if event.key == 'A':  # Add to lines
            self.generate_line((self.z, wrest))
        if event.key == 'x':  # Remove line
            if self.remove_line(wrest):
                print('VelPlot: Removed line {:g}'.format(wrest))
        if event.key == 'X':  # Remove all lines
            # Double check
            gui = xguiu.WarningWidg(
                'About to remove all lines. \n  Continue??')
            gui.exec_()
            if gui.ans is False:
                return
            #
            self.abs_lines = []  # Flush??
        # Kinematics
        if event.key == '^':  # Low-Ion
            try:
                fkin = absline.analy['flag_kin']
            except KeyError:
                fkin = 0
            fkin += (-1)**(fkin % 2**1 >= 2**0) * 2**0
            absline.analy['flag_kin'] = fkin
        if event.key == '&':  # High-Ion
            try:
                fkin = absline.analy['flag_kin']
            except KeyError:
                fkin = 0
            fkin += (-1)**(fkin % 2**2 >= 2**1) * 2**1
            absline.analy['flag_kin'] = fkin
        # Toggle blend
        if event.key == 'B':
            try:
                feye = absline.analy['flg_eye']
            except KeyError:
                feye = 0
            feye = (feye + 1) % 2
            absline.analy['flg_eye'] = feye
        # Toggle NG
        if event.key == 'N':
            try:
                fanly = absline.analy['do_analysis']
            except KeyError:
                fanly = 1
            if fanly == 0:
                fanly = 1
            else:
                fanly = 0
            absline.analy['do_analysis'] = fanly
        if event.key == 'V':  # Normal
            absline.analy['flg_limit'] = 1
        if event.key == 'L':  # Lower limit
            absline.analy['flg_limit'] = 2
        if event.key == 'U':  # Upper limit
            absline.analy['flg_limit'] = 3

        # AODM plot
        if event.key == ':':  #
            # Grab good lines
            from xastropy.xguis import spec_guis as xsgui
            gdl = [
                iline.wrest for iline in self.abs_sys.lines
                if iline.analy['do_analysis'] > 0
            ]
            # Launch AODM
            if len(gdl) > 0:
                gui = xsgui.XAODMGui(self.spec,
                                     self.z,
                                     gdl,
                                     vmnx=self.vmnx,
                                     norm=self.norm)
                gui.exec_()
            else:
                print('VelPlot.AODM: No good lines to plot')

            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()

        if not wrest is None:  # Single window
            flg = 3
        if event.key in [
                'c', 'C', 'k', 'K', 'W', '!', '@', '=', '-', 'X', 'z', 'R'
        ]:  # Redraw all
            flg = 1
        if event.key in ['Y']:
            rescale = False
        if event.key in ['k', 'c', 'C', 'K', 'R']:
            fig_clear = True

        if flg == 1:  # Default is not to redraw
            self.on_draw(rescale=rescale, fig_clear=fig_clear)
        elif flg == 2:  # Layer (no clear)
            self.on_draw(replot=False, rescale=rescale)
        elif flg == 3:  # Layer (no clear)
            self.on_draw(in_wrest=wrest, rescale=rescale)

    # Click of main mouse button
    def on_click(self, event):
        try:
            print('button={:d}, x={:f}, y={:f}, xdata={:f}, ydata={:f}'.format(
                event.button, event.x, event.y, event.xdata, event.ydata))
        except ValueError:
            return
        if event.button == 1:  # Draw line
            self.ax.plot([event.xdata, event.xdata],
                         self.psdict['ymnx'],
                         ':',
                         color='green')
            self.on_draw(replot=False)

            # Print values
            try:
                self.statusBar().showMessage('x,y = {:f}, {:f}'.format(
                    event.xdata, event.ydata))
            except AttributeError:
                return

    def on_draw(self,
                replot=True,
                in_wrest=None,
                rescale=True,
                fig_clear=False):
        """ Redraws the figure
        """
        #
        if replot is True:
            if fig_clear:
                self.fig.clf()
            # Loop on windows
            all_idx = self.llist['show_line']
            nplt = self.sub_xy[0] * self.sub_xy[1]
            if len(all_idx) <= nplt:
                self.idx_line = 0
            subp = np.arange(nplt) + 1
            subp_idx = np.hstack(
                subp.reshape(self.sub_xy[0], self.sub_xy[1]).T)
            #print('idx_l={:d}, nplt={:d}, lall={:d}'.format(self.idx_line,nplt,len(all_idx)))
            for jj in range(min(nplt, len(all_idx))):
                try:
                    idx = all_idx[jj + self.idx_line]
                except IndexError:
                    continue  # Likely too few lines
                #print('jj={:d}, idx={:d}'.format(jj,idx))
                # Grab line
                wrest = self.llist[self.llist['List']].wrest[idx]
                kwrest = wrest.value  # For the Dict
                # Single window?
                if in_wrest is not None:
                    if np.abs(wrest - in_wrest) > (1e-3 * u.AA):
                        continue

                # Abs_Sys: Color the lines
                if self.abs_sys is not None:
                    absline = self.grab_line(wrest)

                # Generate plot
                self.ax = self.fig.add_subplot(self.sub_xy[0], self.sub_xy[1],
                                               subp_idx[jj])
                self.ax.clear()
                #QtCore.pyqtRemoveInputHook()
                #xdb.set_trace()
                #QtCore.pyqtRestoreInputHook()

                # Zero line
                self.ax.plot([0., 0.], [-1e9, 1e9], ':', color='gray')
                # Velocity
                wvobs = (1 + self.z) * wrest
                velo = (self.spec.dispersion / wvobs - 1.) * const.c.to('km/s')

                # Plot
                self.ax.plot(velo, self.spec.flux, 'k-', drawstyle='steps-mid')

                # GID for referencing
                self.ax.set_gid(wrest)

                # Labels
                #if jj >= (self.sub_xy[0]-1)*(self.sub_xy[1]):
                if (((jj + 1) % self.sub_xy[0]) == 0) or ((jj + 1)
                                                          == len(all_idx)):
                    self.ax.set_xlabel('Relative Velocity (km/s)')
                else:
                    self.ax.get_xaxis().set_ticks([])
                lbl = self.llist[self.llist['List']].name[idx]
                # Kinematics
                kinl = ''
                if absline is not None:
                    if (absline.analy['flag_kin'] % 2) >= 1:
                        kinl = kinl + 'L'
                    if (absline.analy['flag_kin'] % 4) >= 2:
                        kinl = kinl + 'H'
                self.ax.text(0.1,
                             0.05,
                             lbl + kinl,
                             color='blue',
                             transform=self.ax.transAxes,
                             size='x-small',
                             ha='left')

                # Reset window limits
                #QtCore.pyqtRemoveInputHook()
                #xdb.set_trace()
                #QtCore.pyqtRestoreInputHook()
                self.ax.set_xlim(self.psdict['xmnx'])

                # Rescale?
                if (rescale is True) & (self.norm is False):
                    gdp = np.where((velo.value > self.psdict['xmnx'][0])
                                   & (velo.value < self.psdict['xmnx'][1]))[0]
                    if len(gdp) > 5:
                        per = xstats.basic.perc(self.spec.flux[gdp])
                        self.ax.set_ylim((0., 1.1 * per[1]))
                    else:
                        self.ax.set_ylim(self.psdict['ymnx'])
                else:
                    self.ax.set_ylim(self.psdict['ymnx'])

                # Fonts
                xputils.set_fontsize(self.ax, 6.)

                clr = 'black'
                if absline is not None:
                    try:
                        vlim = absline.analy['vlim']
                    except KeyError:
                        pass
                    # Color coding
                    try:  # .clm style
                        flag = absline.analy['FLAGS'][0]
                    except KeyError:
                        flag = None
                    else:
                        if flag <= 1:  # Standard detection
                            clr = 'green'
                        elif flag in [2, 3]:
                            clr = 'blue'
                        elif flag in [4, 5]:
                            clr = 'purple'
                    # ABS ID
                    try:  # NG?
                        flagA = absline.analy['do_analysis']
                    except KeyError:
                        flagA = None
                    else:
                        if (flagA > 0) & (clr == 'black'):
                            clr = 'green'
                    try:  # Limit?
                        flagL = absline.analy['flg_limit']
                    except KeyError:
                        flagL = None
                    else:
                        if flagL == 2:
                            clr = 'blue'
                        if flagL == 3:
                            clr = 'purple'
                    try:  # Blends?
                        flagE = absline.analy['flg_eye']
                    except KeyError:
                        flagE = None
                    else:
                        if flagE == 1:
                            clr = 'orange'
                    if flagA == 0:
                        clr = 'red'

                    pix = np.where((velo > vlim[0]) & (velo < vlim[1]))[0]
                    self.ax.plot(velo[pix],
                                 self.spec.flux[pix],
                                 '-',
                                 drawstyle='steps-mid',
                                 color=clr)
        # Draw
        self.canvas.draw()
Exemple #52
0
class ProbeGraphDisplay(object):
    """The ProbeGraphDisplay controls one tab of the Area Probe Graphs.
    The ProbeGraphDisplay handles generating a displaying a single graph.
    """

    # the most data we are willing to plot in a scatter plot
    # this limit was determined experimentally on Eva's laptop for glance, may need to revisit this
    MAX_SCATTER_PLOT_DATA = 1e7

    # the default number of bins for the histogram and density scatter plot
    DEFAULT_NUM_BINS = 100

    # the display name of the probe, should be unique across all probes
    myName = None

    # plotting related controls
    figure = None
    canvas = None
    toolbar = None
    yCheckBox = None
    xDropDown = None
    yDropDown = None

    # internal objects to reference for info and data
    polygon = None
    point = None
    manager = None
    workspace = None
    queue = None
    document = None

    # internal values that control the behavior of plotting and controls
    xSelectedUUID = None
    ySelectedUUID = None
    uuidMap = None  # this is needed because the drop downs can't properly handle objects as ids
    _stale = True  # whether or not the plot needs to be redrawn

    def __init__(self, manager, qt_parent, workspace, queue, document,
                 name_str):
        """build the graph tab controls
        :return:
        """

        # hang on to our name
        self.myName = name_str

        # save the workspace and queue for use later
        self.manager = manager
        self.workspace = workspace
        self.queue = queue
        self.document = document

        # a figure instance to plot on
        self.figure = Figure(figsize=(3, 3), dpi=72)
        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setMinimumSize(100, 100)
        # make sure our figure is clear
        self.clearPlot()

        # make a matplotlib toolbar to attach to the graph
        self.toolbar = NavigationToolbar(self.canvas, qt_parent)

        # create our selection controls

        # the label for the x selection
        xLabel = QtWidgets.QLabel("X layer:")

        # the check box that turns on and off comparing to a y layer
        self.yCheckBox = QtWidgets.QCheckBox("vs Y layer:")
        self.yCheckBox.setToolTip(
            "Plot X layer data vs Y layer when this is checked.")
        self.yCheckBox.stateChanged.connect(self.vsChecked)

        # the drop down for selecting the x layer
        self.xDropDown = QtWidgets.QComboBox(qt_parent)
        self.xDropDown.setToolTip("The X layer data to use for plotting.")
        self.xDropDown.activated.connect(self.xSelected)

        # the drop down for selecting the y layer
        self.yDropDown = QtWidgets.QComboBox(qt_parent)
        self.yDropDown.setDisabled(True)
        self.yDropDown.setToolTip("The Y layer data to use for plotting.")
        self.yDropDown.activated.connect(self.ySelected)

        # set the layout
        # Note: add in a grid is (widget, row#, col#) or (widget, row#, col#, row_span, col_span)
        layout = QtWidgets.QGridLayout()
        layout.addWidget(self.toolbar, 1, 1, 1, 3)
        layout.addWidget(self.canvas, 2, 1, 1, 3)
        layout.addWidget(xLabel, 3, 1)
        layout.addWidget(self.xDropDown, 3, 2, 1, 2)
        layout.addWidget(self.yCheckBox, 4, 1)
        layout.addWidget(self.yDropDown, 4, 2, 1, 2)
        qt_parent.setLayout(layout)

    def set_possible_layers(self, uuid_list, do_rebuild_plot=False):
        """Given a list of layer UUIDs, set the names and UUIDs in the drop downs
        """

        # make a uuid map because the mapping in a combo box doesn't work with objects
        self.uuidMap = {}

        # clear out the current lists
        self.xDropDown.clear()
        self.yDropDown.clear()

        # fill up our lists of layers
        for uuid in uuid_list:
            layer = self.document[uuid]
            layer_name = layer.get(Info.DISPLAY_NAME, "??unknown layer??")
            if layer.get(Info.KIND, None) == Kind.RGB:  # skip RGB layers
                continue
            uuid_string = str(uuid)
            self.xDropDown.addItem(layer_name, uuid_string)
            self.yDropDown.addItem(layer_name, uuid_string)

            self.uuidMap[uuid_string] = uuid

        # if possible, set the selections back to the way they were
        need_rebuild = False
        xIndex = self.xDropDown.findData(str(self.xSelectedUUID))
        if xIndex >= 0:
            # Selection didn't change
            self.xDropDown.setCurrentIndex(xIndex)
        elif self.xDropDown.count() > 0:
            # Setting to a new layer
            need_rebuild = True
            self.xSelectedUUID = self.uuidMap[self.xDropDown.itemData(0)]
            self.xDropDown.setCurrentIndex(0)
        else:
            # we had something selected but now there is nothing new to select
            need_rebuild = need_rebuild or self.xSelectedUUID is not None
            self.xSelectedUUID = None
        yIndex = self.yDropDown.findData(str(self.ySelectedUUID))
        if yIndex >= 0:
            # Selection didn't change
            self.yDropDown.setCurrentIndex(yIndex)
        elif self.yDropDown.count() > 0:
            # Setting to a new layer
            need_rebuild = need_rebuild or self.yCheckBox.isChecked()
            self.ySelectedUUID = self.uuidMap[self.yDropDown.itemData(0)]
            self.yDropDown.setCurrentIndex(0)
        else:
            # we had something selected but now there is nothing new to select
            need_rebuild = need_rebuild or self.ySelectedUUID is not None
            self.ySelectedUUID = None

        # refresh the plot
        self._stale = need_rebuild
        if do_rebuild_plot:
            # Rebuild the plot (stale is used to determine if actual rebuild is needed)
            self.rebuildPlot()

    def set_default_layer_selections(self, *layer_uuids):
        # only set the defaults if we don't have a polygon yet
        if self.polygon is not None:
            return

        if len(layer_uuids) >= 1:
            xIndex = self.xDropDown.findData(str(layer_uuids[0]))
            if xIndex >= 0:
                self.xDropDown.setCurrentIndex(xIndex)
                self.xSelectedUUID = layer_uuids[0]
            else:
                LOG.error("Tried to set probe graph to non-existent layer: %s",
                          layer_uuids[0])

        if len(layer_uuids) >= 2:
            yIndex = self.xDropDown.findData(str(layer_uuids[1]))
            if yIndex >= 0:
                self.yDropDown.setCurrentIndex(yIndex)
                self.ySelectedUUID = layer_uuids[1]
            else:
                LOG.error("Tried to set probe graph to non-existent layer: %s",
                          layer_uuids[1])

    @property
    def checked(self):
        return self.yCheckBox.isChecked()

    @checked.setter
    def checked(self, is_checked):
        return self.yCheckBox.setChecked(is_checked)

    def xSelected(self):
        """The user selected something in the X layer list.
        """
        oldXStr = str(self.xSelectedUUID)
        newXStr = self.xDropDown.itemData(self.xDropDown.currentIndex())
        self.xSelectedUUID = self.uuidMap[newXStr]

        # regenerate the plot
        if oldXStr != newXStr:
            self._stale = True
            self.rebuildPlot()

    def ySelected(self):
        """The user selected something in the Y layer list."""
        oldYStr = str(self.ySelectedUUID)
        newYStr = self.yDropDown.itemData(self.yDropDown.currentIndex())
        self.ySelectedUUID = self.uuidMap[newYStr]

        # regenerate the plot
        if (oldYStr != newYStr) and self.yCheckBox.isChecked():
            self._stale = True
            self.rebuildPlot()

    def vsChecked(self):
        """The vs check box was checked!"""
        # look at the state of the vs box and enable/disable the y drop down accordingly
        doPlotVS = self.yCheckBox.isChecked()
        self.yDropDown.setDisabled(not doPlotVS)

        # regenerate the plot
        self._stale = True
        self.rebuildPlot()

    def setPolygon(self, polygonPoints):
        """Set the polygon selection for this graph."""

        self.polygon = polygonPoints

        # regenerate the plot
        self._stale = True
        self.rebuildPlot()

        # return our name to be used for the polygon name
        return self.myName

    def setPoint(self, coordinates, rebuild=True):
        self.point = coordinates
        self._stale = True
        # sometimes we set the point to be redrawn later
        if rebuild:
            self.rebuildPlot()

    def getName(self):
        """Accessor method for the graph's name."""
        return self.myName

    def rebuildPlot(self):
        """Given what we currently know about the selection area and selected bands, rebuild our plot

        Note: This should be called only when the selections change in some way.
        """
        if not self._stale:
            LOG.debug("Plot doesn't need to be rebuilt")
            return

        # should be be plotting vs Y?
        doPlotVS = self.yCheckBox.isChecked()
        task_name = "%s_%s_region_plotting" % (self.xSelectedUUID,
                                               self.ySelectedUUID)
        self.queue.add(task_name,
                       self._rebuild_plot_task(self.xSelectedUUID,
                                               self.ySelectedUUID,
                                               self.polygon,
                                               self.point,
                                               plot_versus=doPlotVS),
                       "Creating plot for region probe data",
                       interactive=True)
        # Assume that the task gets resolved otherwise we might try to draw multiple times
        self._stale = False

    def _rebuild_plot_task(self,
                           x_uuid,
                           y_uuid,
                           polygon,
                           point_xy,
                           plot_versus=False):

        # if we are plotting only x and we have a selected x and a polygon
        if not plot_versus and x_uuid is not None and polygon is not None:
            yield {
                TASK_DOING: 'Probe Plot: Collecting polygon data...',
                TASK_PROGRESS: 0.0
            }

            # get the data and info we need for this plot
            data_polygon = self.workspace.get_content_polygon(x_uuid, polygon)
            unit_info = self.document[x_uuid][Info.UNIT_CONVERSION]
            data_polygon = unit_info[1](data_polygon)
            title = self.document[x_uuid][Info.DISPLAY_NAME]

            # get point probe value
            if point_xy:
                x_point = self.workspace.get_content_point(x_uuid, point_xy)
                x_point = unit_info[1](x_point)
            else:
                x_point = None

            # plot a histogram
            yield {
                TASK_DOING: 'Probe Plot: Creating histogram plot',
                TASK_PROGRESS: 0.25
            }
            self.plotHistogram(data_polygon, title, x_point)

        # if we are plotting x vs y and have x, y, and a polygon
        elif plot_versus and x_uuid is not None and y_uuid is not None and polygon is not None:
            yield {
                TASK_DOING: 'Probe Plot: Collecting polygon data (layer 1)...',
                TASK_PROGRESS: 0.0
            }

            # get the data and info we need for this plot
            x_info = self.document[x_uuid]
            y_info = self.document[y_uuid]
            name1 = x_info[Info.DISPLAY_NAME]
            name2 = y_info[Info.DISPLAY_NAME]
            hires_uuid = self.workspace.lowest_resolution_uuid(x_uuid, y_uuid)
            # hires_coord_mask are the lat/lon coordinates of each of the
            # pixels in hires_data. The coordinates are (lat, lon) to resemble
            # the (Y, X) indexing of numpy arrays
            hires_coord_mask, hires_data = self.workspace.get_coordinate_mask_polygon(
                hires_uuid, polygon)
            hires_conv_func = self.document[hires_uuid][
                Info.UNIT_CONVERSION][1]
            x_conv_func = x_info[Info.UNIT_CONVERSION][1]
            y_conv_func = y_info[Info.UNIT_CONVERSION][1]
            hires_data = hires_conv_func(hires_data)
            yield {
                TASK_DOING: 'Probe Plot: Collecting polygon data (layer 2)...',
                TASK_PROGRESS: 0.15
            }
            if hires_uuid == x_uuid:
                # the hires data was from the X UUID
                data1 = hires_data
                data2 = self.workspace.get_content_coordinate_mask(
                    y_uuid, hires_coord_mask)
                data2 = y_conv_func(data2)
            else:
                # the hires data was from the Y UUID
                data2 = hires_data
                data1 = self.workspace.get_content_coordinate_mask(
                    x_uuid, hires_coord_mask)
                data1 = x_conv_func(data1)
            yield {
                TASK_DOING: 'Probe Plot: Creating scatter plot...',
                TASK_PROGRESS: 0.25
            }

            if point_xy:
                x_point = self.workspace.get_content_point(x_uuid, point_xy)
                x_point = x_conv_func(x_point)
                y_point = self.workspace.get_content_point(y_uuid, point_xy)
                y_point = y_conv_func(y_point)
            else:
                x_point = None
                y_point = None

            # plot a scatter plot
            good_mask = ~(np.isnan(data1) | np.isnan(data2))
            data1 = data1[good_mask]
            data2 = data2[good_mask]
            self.plotDensityScatterplot(data1, name1, data2, name2, x_point,
                                        y_point)

        # if we have some combination of selections we don't understand, clear the figure
        else:
            yield {
                TASK_DOING: 'Probe Plot: Clearing plot figure...',
                TASK_PROGRESS: 0.0
            }
            self.clearPlot()

        yield {TASK_DOING: 'Probe Plot: Drawing plot...', TASK_PROGRESS: 0.95}
        self.manager.drawChildGraph.emit(self.myName)
        yield {TASK_DOING: 'Probe Plot: Done', TASK_PROGRESS: 1.0}

    def draw(self):
        self.canvas.draw()

    def plotHistogram(self, data, title, x_point, numBins=100):
        """Make a histogram using the given data and label it with the given title
        """
        self.figure.clf()
        axes = self.figure.add_subplot(111)
        bars = axes.hist(data[~np.isnan(data)], bins=self.DEFAULT_NUM_BINS)
        if x_point is not None:
            # go through each rectangle object and make the one that contains x_point 'red'
            # default color is blue so red should stand out
            for bar in bars[2][::-1]:
                if bar.xy[0] <= x_point:
                    bar.set_color('red')
                    break
        axes.set_title(title)

    def plotScatterplot(self, dataX, nameX, dataY, nameY):
        """Make a scatter plot of the x and y data
        """

        # we should have the same size data here
        assert (dataX.size == dataY.size)

        if dataX.size > self.MAX_SCATTER_PLOT_DATA:
            LOG.info(
                "Too much data in selected region to generate scatter plot.")
            self.clearPlot()
            # self.plotDensityScatterplot(dataX, nameX, dataY, nameY)

        else:
            self.figure.clf()
            axes = self.figure.add_subplot(111)
            axes.scatter(dataX, dataY, color='b', s=1, alpha=0.5)
            axes.set_xlabel(nameX)
            axes.set_ylabel(nameY)
            axes.set_title(nameX + " vs " + nameY)
            self._draw_xy_line(axes)

    def plotDensityScatterplot(self, dataX, nameX, dataY, nameY, pointX,
                               pointY):
        """Make a density scatter plot for the given data
        """

        # clear the figure and make a new subplot
        self.figure.clf()
        axes = self.figure.add_subplot(111)

        # figure out the range of the data
        # you might not be comparing the same units
        xmin_value = np.min(dataX)
        xmax_value = np.max(dataX)
        ymin_value = np.min(dataY)
        ymax_value = np.max(dataY)
        # bounds should be defined in the form [[xmin, xmax], [ymin, ymax]]
        bounds = [[xmin_value, xmax_value], [ymin_value, ymax_value]]

        # make the binned density map for this data set
        density_map, _, _ = np.histogram2d(dataX,
                                           dataY,
                                           bins=self.DEFAULT_NUM_BINS,
                                           range=bounds)
        # mask out zero counts; flip because y goes the opposite direction in an imshow graph
        density_map = np.flipud(
            np.transpose(np.ma.masked_array(density_map,
                                            mask=density_map == 0)))

        # display the density map data
        img = axes.imshow(
            density_map,
            extent=[xmin_value, xmax_value, ymin_value, ymax_value],
            aspect='auto',
            interpolation='nearest',
            norm=LogNorm())
        if pointX is not None:
            axes.set_autoscale_on(False)
            axes.plot(pointX,
                      pointY,
                      marker='o',
                      markerfacecolor='white',
                      markeredgecolor='black',
                      markersize=10,
                      markeredgewidth=1.)
            axes.set_autoscale_on(True)

        colorbar = self.figure.colorbar(img)
        colorbar.set_label('log(count of data points)')

        # set the various text labels
        axes.set_xlabel(nameX)
        axes.set_ylabel(nameY)
        axes.set_title(nameX + " vs " + nameY)

        # draw the x vs y line
        self._draw_xy_line(axes)

    def clearPlot(self):
        """Clear our plot
        """

        self.figure.clf()

    def _draw_xy_line(self, axes):

        # get the bounds for our calculations and so we can reset the viewing window later
        x_bounds = axes.get_xbound()
        y_bounds = axes.get_ybound()

        # draw the x=y line
        perfect = [
            max(x_bounds[0], y_bounds[0]),
            min(x_bounds[1], y_bounds[1])
        ]
        axes.plot(perfect, perfect, '--', color='k', label='X = Y')

        # reset the bounds
        axes.set_xbound(x_bounds)
        axes.set_ybound(y_bounds)
Exemple #53
0
class Application:

    pontos = [[0.42, 18.9394688], [0.92, 2.0833332], [1.42, 20.7794668],
              [1.92, 4.9233332], [2.42, 24.6194668]]
    title = "teste"
    offset = 10

    def __init__(self, main):
        self.fontePadrao = ("Arial", "10")

        self.primeiroContainer = Frame(main)
        self.primeiroContainer["pady"] = 10
        self.primeiroContainer.pack()

        self.segundoContainer = Frame(main)
        self.segundoContainer["padx"] = 20
        self.segundoContainer.pack()

        self.terceiroContainer = Frame(main)
        self.terceiroContainer["padx"] = 20
        self.terceiroContainer.pack()

        self.quartoContainer = Frame(main)
        self.quartoContainer["pady"] = 20
        self.quartoContainer.pack()

        self.quintoContainer = Frame(main)
        self.quintoContainer["padx"] = 20
        self.quintoContainer.pack()

        self.sextoContainer = Frame(main)
        self.sextoContainer["pady"] = 20
        self.sextoContainer.pack()

        self.adicionarPontosTitulo = Label(self.primeiroContainer,
                                           text="Adicionar Pontos")
        self.adicionarPontosTitulo["font"] = ("Arial", "10", "bold")
        self.adicionarPontosTitulo.pack()

        self.XLabel = Label(self.segundoContainer,
                            text="X",
                            font=self.fontePadrao)
        self.XLabel.pack(side=LEFT)

        self.X = Entry(self.segundoContainer)
        self.X["width"] = 10
        self.X["font"] = self.fontePadrao
        self.X.pack(side=LEFT)

        self.YLabel = Label(self.segundoContainer,
                            text="Y",
                            font=self.fontePadrao)
        self.YLabel.pack(side=LEFT)

        self.Y = Entry(self.segundoContainer)
        self.Y["width"] = 10
        self.Y["font"] = self.fontePadrao
        self.Y.pack(side=LEFT)

        self.adicionar = Button(self.terceiroContainer)
        self.adicionar["text"] = "Adicionar"
        self.adicionar["font"] = ("Calibri", "8")
        self.adicionar["width"] = 12
        self.adicionar["command"] = self.adicionarPontos
        self.adicionar.pack(side=BOTTOM)

        self.pontosTitulo = Label(self.quartoContainer, text="Pontos")
        self.pontosTitulo["font"] = ("Arial", "10", "bold")
        self.pontosTitulo.pack()

        self.pointsLabel = Label(self.quartoContainer,
                                 text=self.verificarPontos(),
                                 font=self.fontePadrao)
        self.pointsLabel.pack()

        self.limpar = Button(self.quartoContainer)
        self.limpar["text"] = "Limpar"
        self.limpar["font"] = ("Calibri", "8")
        self.limpar["width"] = 12
        self.limpar["command"] = self.limparPontos
        self.limpar.pack(side=BOTTOM)

        #

        self.adicionarPontosTitulo = Label(self.quintoContainer,
                                           text="Algoritmos")
        self.adicionarPontosTitulo["font"] = ("Arial", "10", "bold")
        self.adicionarPontosTitulo.pack()

        self.lagrange = Button(self.quintoContainer)
        self.lagrange["text"] = "Lagrange"
        self.lagrange["font"] = ("Calibri", "8")
        self.lagrange["width"] = 12
        self.lagrange["command"] = self.lagrangeAlg
        self.lagrange.pack(side=LEFT)

        self.newton = Button(self.quintoContainer)
        self.newton["text"] = "Newton"
        self.newton["font"] = ("Calibri", "8")
        self.newton["width"] = 12
        self.newton["command"] = self.newtonAlg
        self.newton.pack(side=LEFT)

        self.NG = Button(self.quintoContainer)
        self.NG["text"] = "Newton Gregory"
        self.NG["font"] = ("Calibri", "8")
        self.NG["width"] = 12
        self.NG["command"] = self.newtonGregoryAlg
        self.NG.pack(side=LEFT)

        self.allMethods = Button(self.quintoContainer)
        self.allMethods["text"] = "Todos"
        self.allMethods["font"] = ("Calibri", "8")
        self.allMethods["width"] = 12
        self.allMethods["command"] = self.all
        self.allMethods.pack(side=LEFT)

        #
        self.canvasFig = plt.figure(1)
        self.Fig = Figure(figsize=(4, 3), dpi=100)
        self.FigSubPlot = self.Fig.add_subplot(111)
        x = []
        y = []
        self.line1, = self.FigSubPlot.plot(x, y, label='orig')
        self.line2, = self.FigSubPlot.plot(x, y, label='interp1')
        # self.line4, = FigSubPlot.plot(x,y, label='interp2')
        # self.line5, = FigSubPlot.plot(x,y, label='interp3')
        self.line3, = self.FigSubPlot.plot(x, y, 'ro')
        self.canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(
            self.Fig, master=self.sextoContainer)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

    def all(self):

        arr = np.array(self.pontos)
        X = arr[:, 0].tolist()
        Y = arr[:, 1].tolist()
        h = X[1] - X[0]

        t = linspace(-2, 6, 100)
        o = self.original(t)

        lagrange = self.pol(t, X, Y)
        newton = self.N(t, X, Y)
        newtonGregory = self.polNG(len(X) - 1, t, X, Y, h)

        self.Fig.clf()
        self.FigSubPlot = self.Fig.add_subplot(111)
        self.FigSubPlot.plot(t, o, label='Original')
        self.FigSubPlot.plot(t, lagrange, label='Lagrange')
        self.FigSubPlot.plot(t, newton, label='Newton')
        self.FigSubPlot.plot(t, newtonGregory, label='NG')
        self.FigSubPlot.plot(X, Y, 'ro')

        self.canvas.figure.suptitle("Todos os Métodos")
        self.canvas.figure.legend(loc='upper right')
        ax = self.canvas.figure.axes[0]
        ax.set_xlim(t.min(), t.max())
        ax.set_ylim(o.min() - self.offset, o.max() + self.offset)
        self.canvas.draw()

    def lagrangeAlg(self):

        arr = np.array(self.pontos)
        X = arr[:, 0].tolist()
        Y = arr[:, 1].tolist()

        t = linspace(-2, 6, 100)
        o = self.original(t)

        lagrange = self.pol(t, X, Y)

        self.Fig.clf()
        self.FigSubPlot = self.Fig.add_subplot(111)
        self.FigSubPlot.plot(t, o, label='Original')
        self.FigSubPlot.plot(t, lagrange, label='lagrange')
        self.FigSubPlot.plot(X, Y, 'ro')

        self.canvas.figure.suptitle("Lagrange")
        self.canvas.figure.legend(loc='upper right')
        ax = self.canvas.figure.axes[0]
        ax.set_xlim(t.min(), t.max())
        ax.set_ylim(o.min() - self.offset, o.max() + self.offset)
        self.canvas.draw()

    def numerator(self, x, k, X):
        p = 1.
        for i in range(len(X)):
            if i != k:
                p *= (x - X[i])
        return p

    def denominator(self, x, k, X):
        p = 1.
        for i in range(len(X)):
            if i != k:
                p *= (X[k] - X[i])
        return p

    def L(self, k, x, X):
        return self.numerator(x, k, X) / self.denominator(x, k, X)

    def pol(self, x, X, Y):
        sum = 0.
        for i in range(len(X)):
            sum += Y[i] * self.L(i, x, X)
        return sum

    ###

    def newtonAlg(self):

        arr = np.array(self.pontos)
        X = arr[:, 0].tolist()
        Y = arr[:, 1].tolist()

        t = linspace(-2, 6, 100)
        o = self.original(t)

        newton = self.N(t, X, Y)

        self.Fig.clf()
        self.FigSubPlot = self.Fig.add_subplot(111)
        self.FigSubPlot.plot(t, o, label='Original')
        self.FigSubPlot.plot(t, newton, label='Newton')
        self.FigSubPlot.plot(X, Y, 'ro')

        self.canvas.figure.suptitle("Newton")
        self.canvas.figure.legend(loc='upper right')
        ax = self.canvas.figure.axes[0]
        ax.set_xlim(t.min(), t.max())
        ax.set_ylim(o.min() - self.offset, o.max() + self.offset)
        self.canvas.draw()

    def n(self, j, xc, x):
        n = 1
        for i in range(j):
            n *= (xc - x[i])
        return n

    def a(self, j, l, x, y):
        if j == 0:
            return y[0]
        elif j - l == 1:
            return (y[j] - y[l]) / (x[j] - x[l])
        else:
            return (self.a(j, l + 1, x, y) - self.a(j - 1, l, x, y)) / (x[j] -
                                                                        x[l])

    def N(self, xc, x, y):
        N = 0
        for j in range(len(x)):
            N += self.a(j, 0, x, y) * self.n(j, xc, x)
        return N

    ###

    def newtonGregoryAlg(self):

        arr = np.array(self.pontos)
        X = arr[:, 0].tolist()
        Y = arr[:, 1].tolist()
        h = X[1] - X[0]

        t = linspace(-2, 6, 100)
        o = self.original(t)

        newtonGregory = self.polNG(len(X) - 1, t, X, Y, h)

        self.Fig.clf()
        self.FigSubPlot = self.Fig.add_subplot(111)
        self.FigSubPlot.plot(t, o, label='Original')
        self.FigSubPlot.plot(t, newtonGregory, label='NG')
        self.FigSubPlot.plot(X, Y, 'ro')

        self.canvas.figure.suptitle("Newton-Gregory")
        self.canvas.figure.legend(loc='upper right')
        ax = self.canvas.figure.axes[0]
        ax.set_xlim(t.min(), t.max())
        ax.set_ylim(o.min() - self.offset, o.max() + self.offset)
        self.canvas.draw()

    def delta(self, r, x, X, Y, h):
        if r == 0:
            index = X.index(round(x, 2))
            return Y[index]
        else:
            return self.delta(r - 1, x + h, X, Y, h) - self.delta(
                r - 1, x, X, Y, h)

    def production(self, x, n, X):
        sum = 1
        for i in range(n):
            sum *= x - X[i]
        return sum

    def polNG(self, k, x, X, Y, h):
        sum = self.delta(0, X[0], X, Y, h)
        for n in range(k):
            sum += self.production(x, n + 1, X) * self.delta(
                n + 1, X[0], X, Y,
                h) / (math.factorial(n + 1) * math.pow(h, n + 1))
        return sum

    ###

    def adicionarPontos(self):

        x = self.X.get()
        y = self.Y.get()

        if x == "":
            x = "0."
        if y == "":
            y = "0."

        self.pontos.append([float(x), float(y)])

        self.pointsLabel["text"] = self.verificarPontos()

        self.X.delete(0, END)
        self.Y.delete(0, END)

    def limparPontos(self):
        self.pontos = []
        self.pointsLabel["text"] = self.verificarPontos()

    def verificarPontos(self):

        st = ""

        if self.pontos != []:
            for pair in self.pontos:
                st += "(" + str(pair[0]) + ", " + str(pair[1]) + ") "

            return st.strip()
        else:
            return "Nenhum ponto adicionado"

    def original(self, x):
        #Rastrigin's function
        return 10 + x**2 - 10 * np.cos(2 * np.pi * x)
class MyTableWidget(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        # Initialize tabs ----------------------------------
        self.tabs = QTabWidget()
        self.Load_data = QWidget()  # create tab 1
        self.SettRzPlot_tab = QWidget()  # create tab 2
        self.Rz_tab = QWidget()  # create tab 3
        self.tabs.resize(300, 200)

        # Add tabs to the Main WIndow
        self.tabs.addTab(self.Load_data, "Load data")  # tab 1
        self.tabs.addTab(self.SettRzPlot_tab, "Rz plot Settings")  # tab 2
        self.tabs.addTab(self.Rz_tab, "Rz plot")  # tab 3

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
        self.show()
        # ----------------------------------------------------------------------------------

        # Load_data tab - content
        self.data_loaded = False
        layout_load = QtWidgets.QVBoxLayout(self.Load_data)  # main layout
        sublayout_load = QtWidgets.QGridLayout()  # layout for inputs
        layout_load.addLayout(sublayout_load)

        # Input widgets
        # Shot
        self.Shot_lbl_load = QLabel(self.Load_data)
        self.Shot_lbl_load.setText('Shot # ')
        self.Shot_ed_load = QLineEdit(self.Load_data)
        self.Shot_ed_load.setText('25781')
        # Diag
        self.Diag_lbl_load = QLabel(self.Load_data)
        self.Diag_lbl_load.setText('Diag: ')
        self.Diag_load = QComboBox(self.Load_data)
        self.Diag_load.addItems(['ECI', 'TDI'])
        self.Diag_lbl_EQ_load = QLabel(self.Load_data)
        self.Diag_lbl_EQ_load.setText('Equilibrium: ')
        self.Diag_EQ_load = QComboBox(self.Load_data)
        self.Diag_EQ_load.addItems(['EQH'])
        # Load button
        self.Butt_load = QPushButton("Load ECEI and equilibrium data",
                                     self.Load_data)
        self.Butt_load.clicked.connect(self.Load_ECEI_data)
        # Monitor
        self.Monitor_load = QtWidgets.QTextBrowser(self.Load_data)
        self.Monitor_load.setText("Status:\nECEI data is not loaded")

        # Add widgets to layout
        sublayout_load.setSpacing(5)
        sublayout_load.addWidget(self.Shot_lbl_load, 0, 0)
        sublayout_load.addWidget(self.Diag_lbl_load, 1, 0)
        sublayout_load.addWidget(self.Diag_lbl_EQ_load, 2, 0)
        sublayout_load.addWidget(self.Shot_ed_load, 0, 1)
        sublayout_load.addWidget(self.Diag_load, 1, 1)
        sublayout_load.addWidget(self.Diag_EQ_load, 2, 1)
        sublayout_load.addWidget(self.Butt_load, 3, 1)

        sublayout_2_load = QtWidgets.QGridLayout()  # layout for inputs
        layout_load.addLayout(sublayout_2_load)
        sublayout_2_load.addWidget(self.Monitor_load, 1, 0)

        # stretch free space (compress widgets at the top)
        layout_load.addStretch()

        # ----------------------------------------------------------------------------------
        # Rz plot tab - content
        # Create layouts
        layout_RzPl = QtWidgets.QVBoxLayout(self.Rz_tab)  # main layout
        sublayout_RzPl = QtWidgets.QGridLayout()  # layout for inputs
        layout_RzPl.addLayout(sublayout_RzPl)

        # Input widgets
        # labels
        self.tB_lbl_RzPl = QLabel(self.Rz_tab)
        self.tB_lbl_RzPl.setText('tB [s]:')
        self.tE_lbl_RzPl = QLabel(self.Rz_tab)
        self.tE_lbl_RzPl.setText('tE [s]:')
        self.tCnt_lbl_RzPl = QLabel(self.Rz_tab)
        self.tCnt_lbl_RzPl.setText('tCenter [s] (optional):')
        self.dt_lbl_RzPl = QLabel(self.Rz_tab)
        self.dt_lbl_RzPl.setText('dt [s](optional) :')
        # filter labels
        self.Fourier_lbl0_RzPl = QLabel(self.Rz_tab)
        self.Fourier_lbl0_RzPl.setText('Fourier lowpass f [kHz]:')
        self.Fourier2_lbl0_RzPl = QLabel(self.Rz_tab)
        self.Fourier2_lbl0_RzPl.setText('Fourier highpass f [kHz]:')
        self.SavGol_lbl0_RzPl = QLabel(self.Rz_tab)
        self.SavGol_lbl0_RzPl.setText('SavGol win_len:')
        self.SavGol_lbl1_RzPl = QLabel(self.Rz_tab)
        self.SavGol_lbl1_RzPl.setText('SavGol pol_ord:')
        self.Binning_lbl_RzPl = QLabel(self.Rz_tab)
        self.Binning_lbl_RzPl.setText('Binning [kHz]:')
        self.Contour_lbl_RzPl = QLabel(self.Rz_tab)
        self.Contour_lbl_RzPl.setText('Contour [1 or 0]')
        self.NNcont_lbl_RzPl = QLabel(self.Rz_tab)
        self.NNcont_lbl_RzPl.setText('NNcont:')
        self.tplot_lbl_RzPl = QLabel(self.Rz_tab)
        self.tplot_lbl_RzPl.setText('t_plot [s](within tB and tE):')
        self.dtplot_lbl_RzPl = QLabel(self.Rz_tab)
        self.dtplot_lbl_RzPl.setText('dt_plot [s]:')
        self.FourMult_lbl_RzPl = QLabel(self.Rz_tab)
        self.FourMult_lbl_RzPl.setText('Fourier multiple f [kHz]:')

        # plot params labels
        self.vmin_lbl_RzPl = QLabel(self.Rz_tab)
        self.vmin_lbl_RzPl.setText('vmin:')
        self.vmax_lbl_RzPl = QLabel(self.Rz_tab)
        self.vmax_lbl_RzPl.setText('vmax:')
        self.chzz_lbl_RzPl = QLabel(self.Rz_tab)
        self.chzz_lbl_RzPl.setText('Remove LOS:')
        self.chRR_lbl_RzPl = QLabel(self.Rz_tab)
        self.chRR_lbl_RzPl.setText('Remove R chs:')

        # velocimetry specific labels
        self.rhop_lbl_RzPl = QLabel(self.Rz_tab)
        self.rhop_lbl_RzPl.setText('rho_pol:')

        # line edits
        # time edits
        self.tB_ed_RzPl = QLineEdit(self.Rz_tab)
        self.tB_ed_RzPl.setText('4.488525')
        self.tB_ed_RzPl.setMinimumSize(QtCore.QSize(55, 0))
        self.tE_ed_RzPl = QLineEdit(self.Rz_tab)
        self.tE_ed_RzPl.setText('4.489525')
        self.tE_ed_RzPl.setMinimumSize(QtCore.QSize(55, 0))
        self.tCnt_ed_RzPl = QLineEdit(self.Rz_tab)
        self.tCnt_ed_RzPl.setMinimumSize(QtCore.QSize(50, 0))
        self.dt_ed_RzPl = QLineEdit(self.Rz_tab)
        self.dt_ed_RzPl.setText('0.001')
        self.dt_ed_RzPl.setMinimumSize(QtCore.QSize(100, 0))
        self.Butt_dt_RzPl = QPushButton("Calc t", self.Rz_tab)
        self.Butt_dt_RzPl.clicked.connect(lambda: self.tBE_from_tCnt(9))
        # plot params edits
        self.vmin_ed_RzPl = QLineEdit(self.Rz_tab)
        self.vmin_ed_RzPl.setText('None')
        self.vmin_ed_RzPl.setMinimumSize(QtCore.QSize(40, 0))
        self.vmax_ed_RzPl = QLineEdit(self.Rz_tab)
        self.vmax_ed_RzPl.setText('None')
        self.vmax_ed_RzPl.setMinimumSize(QtCore.QSize(40, 0))
        self.chzz_ed_RzPl = QLineEdit(self.Rz_tab)
        self.chzz_ed_RzPl.setMinimumSize(QtCore.QSize(100, 0))
        self.chRR_ed_RzPl = QLineEdit(self.Rz_tab)
        self.chRR_ed_RzPl.setMinimumSize(QtCore.QSize(100, 0))
        # Filters edits
        self.Fourier_cut_RzPl = QLineEdit(self.Rz_tab)
        self.Fourier_cut_RzPl.setText('30.0')
        self.Fourier2_cut_RzPl = QLineEdit(self.Rz_tab)
        self.Fourier2_cut_RzPl.setText('2.0')
        self.SavGol_ed0_RzPl = QLineEdit(self.Rz_tab)
        self.SavGol_ed0_RzPl.setText('11')
        self.SavGol_ed0_RzPl.setMinimumSize(QtCore.QSize(20, 0))
        self.SavGol_ed1_RzPl = QLineEdit(self.Rz_tab)
        self.SavGol_ed1_RzPl.setText('3')
        self.Binning_ed_RzPl = QLineEdit(self.Rz_tab)
        self.Binning_ed_RzPl.setText('60.0')
        self.Binning_ed_RzPl.setMinimumSize(QtCore.QSize(40, 0))
        self.Contour_ed_RzPl = QLineEdit(self.Rz_tab)
        self.Contour_ed_RzPl.setText('0')
        self.NNcont_ed_RzPl = QLineEdit(self.Rz_tab)
        self.NNcont_ed_RzPl.setText('60')
        self.tplot_ed_RzPl = QLineEdit(self.Rz_tab)
        self.tplot_ed_RzPl.setText('4.488550')
        self.tplot_ed_RzPl.setMinimumSize(QtCore.QSize(50, 0))
        self.dtplot_ed_RzPl = QLineEdit(self.Rz_tab)
        self.dtplot_ed_RzPl.setText('5.0e-6')
        self.dtplot_ed_RzPl.setMinimumSize(QtCore.QSize(50, 0))
        self.FourMult_ed_RzPl = QLineEdit(self.Rz_tab)
        self.FourMult_ed_RzPl.setText('13.0,15.0;26,30')
        self.FourMult_ed_RzPl.setMinimumSize(QtCore.QSize(100, 0))
        # velocimetry specific line edits
        self.rhop_ed_RzPl = QLineEdit(self.Rz_tab)
        self.rhop_ed_RzPl.setText('0.3')
        self.sendpoints_butt_RzPl = QPushButton("Send t,R,z,r", self.Rz_tab)
        self.sendpoints_butt_RzPl.clicked.connect(self.send_points)
        self.clearpoints_butt_RzPl = QPushButton("Clear table", self.Rz_tab)
        self.clearpoints_butt_RzPl.clicked.connect(self.clear_table)

        # what to plot (type of filter)
        self.ImgType_plot_RzPl = QComboBox(self.Rz_tab)
        self.ImgType_plot_RzPl.addItems([
            'no Image filter', 'Gaussian', 'Median', 'Bilateral',
            'Conservative_smoothing'
        ])
        self.type_plot_RzPl = QComboBox(self.Rz_tab)
        self.type_plot_RzPl.addItems([
            'no 1D filter', 'Fourier highpass', 'Fourier lowpass',
            'Fourier both', 'Fourier multiple', 'SavGol', 'Binning'
        ])
        self.Interp_plot_RzPl = QComboBox(self.Rz_tab)
        self.Interp_plot_RzPl.addItems(
            ['no interpolation', 'with interpolation', 'set to zero'])
        # self.Interp_plot_RzPl.setMaximumSize(QtCore.QSize(90, 0))
        self.Save_plot_RzPl = QComboBox(self.Rz_tab)
        self.Save_plot_RzPl.addItems(
            ['do not save', 'save as pdf', 'save as png'])
        # plot buttom
        self.MinusTplot_butt_RzPl = QPushButton("< -dt", self.Rz_tab)
        self.PlusTplot_butt_RzPl = QPushButton("+dt >", self.Rz_tab)
        self.tplot_butt_RzPl = QPushButton("plot time", self.Rz_tab)
        self.MinusTplot_butt_RzPl.clicked.connect(lambda: self.f_Rz_plot(1))
        self.PlusTplot_butt_RzPl.clicked.connect(lambda: self.f_Rz_plot(2))
        self.tplot_butt_RzPl.clicked.connect(lambda: self.f_Rz_plot(3))

        # Add widgets to layout
        # First row
        sublayout_RzPl.setSpacing(2)
        sublayout_RzPl.addWidget(self.tB_lbl_RzPl, 0, 0)
        sublayout_RzPl.addWidget(self.tB_ed_RzPl, 0, 1)
        sublayout_RzPl.addWidget(self.tE_lbl_RzPl, 0, 2)
        sublayout_RzPl.addWidget(self.tE_ed_RzPl, 0, 3)
        sublayout_RzPl.addWidget(self.tCnt_lbl_RzPl, 0, 4)
        sublayout_RzPl.addWidget(self.tCnt_ed_RzPl, 0, 5)
        sublayout_RzPl.addWidget(self.dt_lbl_RzPl, 0, 6)
        sublayout_RzPl.addWidget(self.dt_ed_RzPl, 0, 7)
        sublayout_RzPl.addWidget(self.Butt_dt_RzPl, 0, 8)
        # Second row
        sublayout_RzPl.addWidget(self.Fourier2_lbl0_RzPl, 1, 0)
        sublayout_RzPl.addWidget(self.Fourier2_cut_RzPl, 1, 1)
        sublayout_RzPl.addWidget(self.Fourier_lbl0_RzPl, 1, 2)
        sublayout_RzPl.addWidget(self.Fourier_cut_RzPl, 1, 3)
        sublayout_RzPl.addWidget(self.FourMult_lbl_RzPl, 1, 4)
        sublayout_RzPl.addWidget(self.FourMult_ed_RzPl, 1, 5)
        ######
        sublayout_RzPl.addWidget(self.SavGol_lbl0_RzPl, 1, 6)
        sublayout_RzPl.addWidget(self.SavGol_ed0_RzPl, 1, 7)
        sublayout_RzPl.addWidget(self.SavGol_lbl1_RzPl, 1, 8)
        sublayout_RzPl.addWidget(self.SavGol_ed1_RzPl, 1, 9)
        sublayout_RzPl.addWidget(self.Binning_lbl_RzPl, 1, 10)
        sublayout_RzPl.addWidget(self.Binning_ed_RzPl, 1, 11)
        ######
        sublayout_RzPl.addWidget(self.chzz_lbl_RzPl, 2, 0)
        sublayout_RzPl.addWidget(self.chzz_ed_RzPl, 2, 1)
        sublayout_RzPl.addWidget(self.chRR_lbl_RzPl, 2, 2)
        sublayout_RzPl.addWidget(self.chRR_ed_RzPl, 2, 3)
        ######
        sublayout_RzPl.addWidget(self.vmin_lbl_RzPl, 2, 4)
        sublayout_RzPl.addWidget(self.vmin_ed_RzPl, 2, 5)
        sublayout_RzPl.addWidget(self.vmax_lbl_RzPl, 2, 6)
        sublayout_RzPl.addWidget(self.vmax_ed_RzPl, 2, 7)
        sublayout_RzPl.addWidget(self.Contour_lbl_RzPl, 2, 8)
        sublayout_RzPl.addWidget(self.Contour_ed_RzPl, 2, 9)
        sublayout_RzPl.addWidget(self.NNcont_lbl_RzPl, 2, 10)
        sublayout_RzPl.addWidget(self.NNcont_ed_RzPl, 2, 11)
        #####
        ######
        # Third row
        sublayout_RzPl.addWidget(self.tplot_lbl_RzPl, 3, 0)
        sublayout_RzPl.addWidget(self.tplot_ed_RzPl, 3, 1)
        sublayout_RzPl.addWidget(self.dtplot_lbl_RzPl, 3, 2)
        sublayout_RzPl.addWidget(self.dtplot_ed_RzPl, 3, 3)
        # Fourth row
        sublayout_RzPl.addWidget(self.rhop_lbl_RzPl, 4, 0)
        sublayout_RzPl.addWidget(self.rhop_ed_RzPl, 4, 1)
        sublayout_RzPl.addWidget(self.sendpoints_butt_RzPl, 4, 2)
        sublayout_RzPl.addWidget(self.clearpoints_butt_RzPl, 4, 3)
        # Plot control
        sublayout_RzPl.addWidget(self.ImgType_plot_RzPl, 1, 12)
        sublayout_RzPl.addWidget(self.type_plot_RzPl, 2, 12)
        sublayout_RzPl.addWidget(self.Save_plot_RzPl, 3, 7)
        sublayout_RzPl.addWidget(self.Interp_plot_RzPl, 3, 8)
        sublayout_RzPl.addWidget(self.MinusTplot_butt_RzPl, 3, 10)
        sublayout_RzPl.addWidget(self.PlusTplot_butt_RzPl, 3, 11)
        sublayout_RzPl.addWidget(self.tplot_butt_RzPl, 3, 12)

        # Add matplotlib plot
        self.figure_RzPl = Figure(figsize=(5, 3), constrained_layout=False)
        self.static_canvas_RzPl = FigureCanvas(self.figure_RzPl)
        layout_RzPl.addWidget(self.static_canvas_RzPl,
                              QtCore.Qt.AlignTop)  # align the plot up
        layout_RzPl.addStretch()  # stretch plot in all free space
        self.toolbar = NavigationToolbar(
            self.static_canvas_RzPl, self.Rz_tab,
            coordinates=True)  # add toolbar below the plot
        layout_RzPl.addWidget(self.toolbar)
        self._static_ax = self.static_canvas_RzPl.figure.subplots()  # add axes

        # velcimetry data
        self.Monitor_RzPl = QtWidgets.QTextBrowser(self.Rz_tab)
        self.Monitor_RzPl.setText("NN\tt\tR\tz\tr\n")
        self.counter = 1
        self.Monitor_RzPl.setMaximumSize(QtCore.QSize(1920, 50))
        sublayout2_RzPl = QtWidgets.QVBoxLayout()  # layout for monitor
        layout_RzPl.addLayout(sublayout2_RzPl)
        sublayout2_RzPl.addWidget(self.Monitor_RzPl, 0)

        # ----------------------------------------------------------------------------------
        # SettRz tab - content
        # Create layouts
        layout_RzSet = QtWidgets.QVBoxLayout(
            self.SettRzPlot_tab)  # main layout
        sublayout_RzSet = QtWidgets.QGridLayout()  # layout for inputs
        layout_RzSet.addLayout(sublayout_RzSet)

        # Input widgets
        # labels
        self.one_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.one_lbl_RzSet.setText('Gaussian filter:')
        self.two_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.two_lbl_RzSet.setText('Median filter:')
        self.three_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.three_lbl_RzSet.setText('Bilateral filter:')
        self.four_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.four_lbl_RzSet.setText('Conservative smoothing filter:')
        # filters parameters
        self.BilKernSize_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.BilKernSize_lbl_RzSet.setText('Kernel size:')
        self.BilS0_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.BilS0_lbl_RzSet.setText('s0:')
        self.BilS1_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.BilS1_lbl_RzSet.setText('s1:')
        self.MedKernSize_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.MedKernSize_lbl_RzSet.setText('Kernel size:')
        self.ConsSize_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.ConsSize_lbl_RzSet.setText('Neighborhood size:')
        self.GausSigma_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.GausSigma_lbl_RzSet.setText('sigma:')

        # Line edits (inputs)
        self.GausSigma_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.GausSigma_ed_RzSet.setText('1.0')
        self.BilKern_type_RzSet = QComboBox(self.SettRzPlot_tab)
        self.BilKern_type_RzSet.addItems(['disk', 'square'])
        self.BilKernSize_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.BilKernSize_ed_RzSet.setText('1')
        self.BilS0_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.BilS0_ed_RzSet.setText('100')
        self.BilS1_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.BilS1_ed_RzSet.setText('100')

        self.MedKern_type_RzSet = QComboBox(self.SettRzPlot_tab)
        self.MedKern_type_RzSet.addItems(['disk', 'square'])
        self.MedKernSize_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.MedKernSize_ed_RzSet.setText('1')
        self.ConsSize_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.ConsSize_ed_RzSet.setText('2')

        sublayout_RzSet.setSpacing(2)
        # First row
        sublayout_RzSet.addWidget(self.one_lbl_RzSet, 0, 0)
        sublayout_RzSet.addWidget(self.GausSigma_lbl_RzSet, 0, 2)
        sublayout_RzSet.addWidget(self.GausSigma_ed_RzSet, 0, 3)
        # Second row
        sublayout_RzSet.addWidget(self.two_lbl_RzSet, 1, 0)
        sublayout_RzSet.addWidget(self.MedKern_type_RzSet, 1, 1)
        sublayout_RzSet.addWidget(self.MedKernSize_lbl_RzSet, 1, 2)
        sublayout_RzSet.addWidget(self.MedKernSize_ed_RzSet, 1, 3)
        # Third row
        sublayout_RzSet.addWidget(self.three_lbl_RzSet, 2, 0)
        sublayout_RzSet.addWidget(self.BilKern_type_RzSet, 2, 1)
        sublayout_RzSet.addWidget(self.BilKernSize_lbl_RzSet, 2, 2)
        sublayout_RzSet.addWidget(self.BilKernSize_ed_RzSet, 2, 3)
        sublayout_RzSet.addWidget(self.BilS0_lbl_RzSet, 2, 4)
        sublayout_RzSet.addWidget(self.BilS0_ed_RzSet, 2, 5)
        sublayout_RzSet.addWidget(self.BilS1_lbl_RzSet, 2, 6)
        sublayout_RzSet.addWidget(self.BilS1_ed_RzSet, 2, 7)
        # Fourth row
        sublayout_RzSet.addWidget(self.four_lbl_RzSet, 3, 0)
        sublayout_RzSet.addWidget(self.ConsSize_lbl_RzSet, 3, 2)
        sublayout_RzSet.addWidget(self.ConsSize_ed_RzSet, 3, 3)

        sublayout1_RzSet = QtWidgets.QVBoxLayout()  # one more layout for title
        layout_RzSet.addLayout(sublayout1_RzSet)

        self.Info1_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.Info1_lbl_RzSet.setText(
            '====== Matrix for interpolation (scipy.interpolate.interp2d, type = cubic) or "set to zero" options ======'
        )
        sublayout1_RzSet.addWidget(self.Info1_lbl_RzSet)

        sublayout2_RzSet = QtWidgets.QGridLayout(
        )  # one more layout for interpolation
        layout_RzSet.addLayout(sublayout2_RzSet)

        LOSlabels = {}
        self.LOSlabels = {}
        for i_L in range(20):
            LOSlabels['%d' % (i_L)] = (i_L, 0)
        for sText, pos in LOSlabels.items():
            # QLabels
            self.LOSlabels[sText] = QLabel("LOS: %d" % (int(sText) + 1))
            sublayout2_RzSet.addWidget(self.LOSlabels[sText], pos[0] + 1,
                                       pos[1])

        checks = {}
        self.checks = {}
        for i_L in range(20):
            for i_R in range(8):
                checks['%d,%d' % (i_L, i_R)] = (i_L, i_R)
        for sText, pos in checks.items():
            # QCheckBoxes
            self.checks[sText] = QCheckBox("%d,%d" % (pos[0] + 1, pos[1] + 1))
            sublayout2_RzSet.addWidget(self.checks[sText], pos[0] + 1,
                                       pos[1] + 1)
        sublayout2_RzSet.setSpacing(2)

        sublayout3_RzSet = QtWidgets.QHBoxLayout()  # one more layout for path
        layout_RzSet.addLayout(sublayout3_RzSet)

        self.path_lbl_RzSet = QLabel(self.SettRzPlot_tab)
        self.path_lbl_RzSet.setText(
            'Path to save Rz plots (path should end with "/" symbol):')

        self.path_ed_RzSet = QLineEdit(self.SettRzPlot_tab)
        self.path_ed_RzSet.setText('/afs/ipp/home/o/osam/Documents/output/')
        sublayout3_RzSet.addWidget(self.path_lbl_RzSet)
        sublayout3_RzSet.addWidget(self.path_ed_RzSet)

        layout_RzSet.addStretch(
        )  # stretch free space (compress widgets at the top)
# ----------------------------------------------------------------------------------

# ----------------------------------------------------------------------------------
# ---------------METHODS-------------

    def tBE_from_tCnt(self, number):
        try:
            if (number == 9):
                t = float(self.tCnt_ed_RzPl.text())
                dt = float(self.dt_ed_RzPl.text())
                tB = t - dt / 2.0
                tE = t + dt / 2.0
                self.tB_ed_RzPl.setText('%0.7g' % (tB))
                self.tE_ed_RzPl.setText('%0.7g' % (tE))
                self.tplot_ed_RzPl.setText('%0.7g' % (np.mean([tB, tE])))
                self.f_Rz_plot(3)

        except Exception as exc:
            print("!!! Incorrect input. ERROR: %s" % (exc))
        pass

    def Load_ECEI_data(self):
        try:
            self.Shot = int(self.Shot_ed_load.text())
            self.Diag = self.Diag_load.currentText()
            self.Diag_EQ = self.Diag_EQ_load.currentText()
            self.Monitor_load.setText("Status:\nLoading %s: #%d ... " %
                                      (self.Diag, self.Shot))
            allow_to_load = True
        except Exception as exc:
            print("!!! Incorrect input. ERROR: %s" % (exc))
            self.Monitor_load.setText("Status:\nPlease enter shot number.")
            allow_to_load = False

        if (self.Diag_EQ == 'EQH') & (allow_to_load):
            try:
                # load EQH
                self.Monitor_load.setText("")
                EQ = EQH.EQH()
                EQ.Load(self.Shot)
                self.EQ_rhopM = EQ.rhopM
                self.EQ_time = EQ.time
                self.EQ_R = EQ.R
                self.EQ_z = EQ.z
                self.EQ_Rmag = EQ.Rmag
                self.EQ_zmag = EQ.zmag
                self.Monitor_load.insertPlainText(
                    "EQH data has been loaded succesfully.\n")
            except Exception as exc:
                traceback.print_exc()
                print("!!! Coudn't load EQH. ERROR: %s" % (exc))
                self.Monitor_load.setText(
                    "Status:\nError in loading ECI data.")
                self.Monitor_load.insertPlainText("!!! EQH data NOT loaded.")
                print("+++ EQH has been loaded +++")

        if (self.Diag == 'TDI') & (allow_to_load):
            try:
                TD = TDI.TDI()
                TD.Load(self.Shot)
                TD.Load_FakeRz()
                self.ECEId = TD.ECEId.copy()
                self.ECEId_time = TD.time.copy()
                self.ECEId_RR = TD.RR_fake.copy()
                self.ECEId_zz = TD.zz_fake.copy()
                self.ECEId_R = TD.R_fake.copy()
                self.ECEId_z = TD.z_fake.copy()
                self.Monitor_load.insertPlainText(
                    "Status:\nTDI #%d\ntB = %g, tE = %g s\nLoaded succesfully."
                    % (self.Shot, TD.time[0], TD.time[-1]))

                self.data_loaded = True
                print("+++ The data has been loaded succesfully. +++")
            except Exception as exc:
                print("!!! Coudn't load TDI. ERROR: %s" % (exc))
                self.Monitor_load.insertPlainText(
                    "Status:\nError in loading ECI data.")

        if (self.Diag == 'ECI') & (allow_to_load):
            try:
                EI = ECI.ECI()
                EI.Load(self.Shot)
                EI.Load_FakeRz()
                self.ECEId = EI.ECEId.copy()
                self.ECEId_time = EI.time.copy()
                self.ECEId_RR = EI.RR_fake.copy()
                self.ECEId_zz = EI.zz_fake.copy()
                self.ECEId_R = EI.R_fake.copy()
                self.ECEId_z = EI.z_fake.copy()
                self.Monitor_load.insertPlainText(
                    "Status:\nECI #%d\ntB = %g, tE = %g s\nLoaded succesfully."
                    % (self.Shot, EI.time[0], EI.time[-1]))
                self.data_loaded = True
                print("+++ The data has been loaded succesfully. +++")
            except Exception as exc:
                print("!!! Coudn't load ECI. ERROR: %s" % (exc))
                self.Monitor_load.insertPlainText(
                    "Status:\nError in loading ECI data.")

    def f_Rz_plot(self, which_plot):
        if (self.data_loaded):  # check whether ECEI data is loaded
            try:
                import matplotlib.pyplot as plt
                plt.rcParams.update({'font.size': 10})
                # data preparation
                self.tB_ed_RzPl
                tB = float(self.tB_ed_RzPl.text())
                tE = float(self.tE_ed_RzPl.text())
                if (which_plot == 1):
                    tplot_old = float(self.tplot_ed_RzPl.text())
                    dtplot = float(self.dtplot_ed_RzPl.text())
                    tplot = tplot_old - dtplot
                    self.tplot_ed_RzPl.setText("%0.7g" % tplot)
                if (which_plot == 2):
                    tplot_old = float(self.tplot_ed_RzPl.text())
                    dtplot = float(self.dtplot_ed_RzPl.text())
                    tplot = tplot_old + dtplot
                    self.tplot_ed_RzPl.setText("%0.7g" % tplot)
                if (which_plot == 3):
                    tplot = float(self.tplot_ed_RzPl.text())
                    self.counter_save = 0

                self.tplot = tplot
                dtplot = float(self.dtplot_ed_RzPl.text())
                contour_check = self.Contour_ed_RzPl.text()
                mf = my_funcs.my_funcs()
                mf.CutDataECEI(self.ECEId_time, self.ECEId, tBegin=tB, tEnd=tE)
                mf.relECEI(mf.ECEId_C)

                mf.cutDataEQH(self.EQ_time, self.EQ_rhopM, self.EQ_R,
                              self.EQ_z, self.EQ_Rmag, self.EQ_zmag, tplot)
                time_plot, data_plot = mf.time_C, mf.ECEId_rel

                filter_status = "None"

                if (self.type_plot_RzPl.currentText() == 'Fourier lowpass'):
                    f_cut = float(self.Fourier_cut_RzPl.text()) * 1.0e3
                    noise_ampl = 1.0
                    mf.Fourier_analysis_ECEI_lowpass(time_plot, data_plot,
                                                     noise_ampl, f_cut)
                    data_plot = mf.ECEId_fft_f_ifft
                    filter_status = "Fourier lowpass, freq_cut = %g kHz" % (
                        f_cut * 1.0e-3)

                if (self.type_plot_RzPl.currentText() == 'Fourier highpass'):
                    f_cut = float(self.Fourier2_cut_RzPl.text()) * 1.0e3
                    noise_ampl = 1.0
                    mf.Fourier_analysis_ECEI_highpass(time_plot, data_plot,
                                                      noise_ampl, f_cut)
                    data_plot = mf.ECEId_fft_f_ifft
                    filter_status = "Fourier highpass, freq_cut = %g kHz" % (
                        f_cut * 1.0e-3)

                if (self.type_plot_RzPl.currentText() == 'Fourier both'):
                    f_cut_lp = float(self.Fourier_cut_RzPl.text()) * 1.0e3
                    noise_ampl_lp = 1.0
                    f_cut_hp = float(self.Fourier2_cut_RzPl.text()) * 1.0e3
                    noise_ampl_hp = 1.0
                    mf.Fourier_analysis_ECEI_lowpass(time_plot, data_plot,
                                                     noise_ampl_lp, f_cut_lp)
                    data_plot = mf.ECEId_fft_f_ifft.copy()
                    mf.Fourier_analysis_ECEI_highpass(time_plot, data_plot,
                                                      noise_ampl_hp, f_cut_hp)
                    data_plot = mf.ECEId_fft_f_ifft.copy()
                    filter_status = "Fourier high and low pass, freq_cut_hp = %g kHz, freq_cut_lp = %g kHz" % (
                        f_cut_hp * 1.0e-3, f_cut_lp * 1.0e-3)

                if (self.type_plot_RzPl.currentText() == 'Fourier multiple'):
                    string = self.FourMult_ed_RzPl.text()
                    freq_num = len(string.split(";"))
                    f_hp = np.zeros(freq_num)
                    f_lp = np.zeros(freq_num)
                    for i in range(freq_num):
                        f_hp[i] = string.split(";")[i].split(",")[0]
                        f_hp[i] *= 1.0e3
                        f_lp[i] = string.split(";")[i].split(",")[1]
                        f_lp[i] *= 1.0e3
                    mf.Fourier_analysis_ECEI_multiple(time_plot, data_plot,
                                                      f_hp, f_lp)
                    data_plot = mf.ECEId_fft_f_ifft
                    filter_status = "Fourier multiple, freqs: %s kHz" % (
                        string)

                if (self.type_plot_RzPl.currentText() == 'SavGol'):
                    win_len = int(self.SavGol_ed0_RzPl.text())
                    pol_ord = int(self.SavGol_ed1_RzPl.text())
                    mf.SavGol_filter_ECEI(data_plot, win_len, pol_ord)
                    data_plot = mf.ECEId_savgol
                    filter_status = "Savgol, win_len = %g, pol_ord = %g" % (
                        win_len, pol_ord)

                if (self.type_plot_RzPl.currentText() == 'Binning'):
                    binning_freq = float(self.Binning_ed_RzPl.text())
                    time_plot, data_plot = mf.dataBinningECEI(
                        time_plot, data_plot, binning_freq)
                    filter_status = "Binning, freq = %g kHz" % (binning_freq)

                RR_plot, zz_plot = self.ECEId_RR, self.ECEId_zz

                removeLOS_ch = self.chzz_ed_RzPl.text()
                if removeLOS_ch:
                    removeLOS_ch = np.array(
                        self.chzz_ed_RzPl.text().split(','))
                    removeLOS_ch = removeLOS_ch.astype(int) - 1
                else:
                    removeLOS_ch = []
                removeRR_ch = self.chRR_ed_RzPl.text()
                if removeRR_ch:
                    removeRR_ch = np.array(self.chRR_ed_RzPl.text().split(','))
                    removeRR_ch = removeRR_ch.astype(int) - 1
                else:
                    removeRR_ch = []

                NN_LOS, NN_R = data_plot.shape[1], data_plot.shape[2]
                ch_zz = np.arange(NN_LOS)
                ch_zz = np.delete(ch_zz, removeLOS_ch)
                ch_RR = np.arange(NN_R)
                ch_RR = np.delete(ch_RR, removeRR_ch)

                trace_1D = data_plot[:, 6, 3]
                # remove channels
                RR_plot = np.delete(RR_plot, removeLOS_ch, axis=0)
                RR_plot = np.delete(RR_plot, removeRR_ch, axis=1)
                zz_plot = np.delete(zz_plot, removeLOS_ch, axis=0)
                zz_plot = np.delete(zz_plot, removeRR_ch, axis=1)
                data_plot = np.delete(data_plot, removeLOS_ch, axis=1)
                data_plot = np.delete(data_plot, removeRR_ch, axis=2)

                check_vmin_vmax = 0
                if (self.vmin_ed_RzPl.text().replace('-', '',
                                                     1).replace('.', '',
                                                                1).isdigit()):
                    vmin = float(self.vmin_ed_RzPl.text())
                    check_vmin_vmax = 1
                else:
                    vmin = None

                if (self.vmax_ed_RzPl.text().replace('.', '', 1).isdigit()):
                    vmax = float(self.vmax_ed_RzPl.text())
                    check_vmin_vmax = 1
                else:
                    vmax = None

                if (self.NNcont_ed_RzPl.text().replace('.', '', 1).isdigit()):
                    NN_cont = int(self.NNcont_ed_RzPl.text())
                else:
                    NN_cont = 20

                # find time index of plot
                idx_tplot = mf.find_nearest_idx(time_plot, tplot)
                time_plot_t, data_plot_t = time_plot[idx_tplot], data_plot[
                    idx_tplot, :, :]

                if (self.Interp_plot_RzPl.currentText() == 'with interpolation'
                    ):
                    interp_mask = np.full((NN_LOS, NN_R), False)
                    for i_L in range(NN_LOS):
                        for i_R in range(NN_R):
                            interp_mask[i_L,
                                        i_R] = self.checks['%d,%d' %
                                                           (i_L,
                                                            i_R)].isChecked()

                    interp_mask = np.delete(interp_mask, removeLOS_ch, axis=0)
                    interp_mask = np.delete(interp_mask, removeRR_ch, axis=1)
                    data_to_interp = data_plot_t.copy()
                    data_to_interp[interp_mask] = np.NaN
                    data_plot_t = mf.nan_interp_2d(data_to_interp)

                if (self.Interp_plot_RzPl.currentText() == 'set to zero'):
                    interp_mask = np.full((NN_LOS, NN_R), False)
                    for i_L in range(NN_LOS):
                        for i_R in range(NN_R):
                            interp_mask[i_L,
                                        i_R] = self.checks['%d,%d' %
                                                           (i_L,
                                                            i_R)].isChecked()

                    interp_mask = np.delete(interp_mask, removeLOS_ch, axis=0)
                    interp_mask = np.delete(interp_mask, removeRR_ch, axis=1)
                    data_plot_t[interp_mask] = 0.0

                if (self.ImgType_plot_RzPl.currentText() == 'Gaussian'):
                    sigma = float(self.GausSigma_ed_RzSet.text())
                    data_plot_t = mf.gaussian_filter(data_plot_t, sigma)
                    filter_status += "; Img filt: Gaussian, sigma=%g" % (sigma)

                if (self.ImgType_plot_RzPl.currentText() == 'Bilateral'):
                    kernel = self.BilKern_type_RzSet.currentText()
                    kern_size = int(self.BilKernSize_ed_RzSet.text())
                    s0 = int(self.BilS0_ed_RzSet.text())
                    s1 = int(self.BilS1_ed_RzSet.text())
                    data_plot_t = mf.bilateral_filter(data_plot_t, kernel,
                                                      kern_size, s0, s1)
                    filter_status += "; Img filt: Bilateral, %s, kern_size=%g, s0=%g, s1=%g" % (
                        kernel, kern_size, s0, s1)

                if (self.ImgType_plot_RzPl.currentText() == 'Median'):
                    kernel = self.MedKern_type_RzSet.currentText()
                    kern_size = int(self.MedKernSize_ed_RzSet.text())
                    data_plot_t = mf.median_filter(data_plot_t, kernel,
                                                   kern_size)
                    filter_status += "; Img filt: Median, %s, kern_size=%g" % (
                        kernel, kern_size)

                if (self.ImgType_plot_RzPl.currentText() ==
                        'Conservative_smoothing'):
                    size_filt = int(self.ConsSize_ed_RzSet.text())
                    data_plot_t = mf.conservative_smoothing_filter(
                        data_plot_t, size_filt)
                    filter_status += "; Img filt: Conservative smoothing, filt_size=%g" % (
                        size_filt)

                # plotting
                # initiate plot
                self.figure_RzPl.clf()  # clear previous figure and axes
                self._static_ax = self.static_canvas_RzPl.figure.subplots(
                    1, 2, sharex=False, sharey=False)  # add axes
                if (check_vmin_vmax == 1):
                    levels_to_plot = np.linspace(vmin, vmax, NN_cont)
                if (check_vmin_vmax == 0):
                    levels_to_plot = NN_cont
                contours = self._static_ax[0].contourf(RR_plot,
                                                       zz_plot,
                                                       data_plot_t,
                                                       vmin=vmin,
                                                       vmax=vmax,
                                                       levels=levels_to_plot,
                                                       cmap='jet')
                cbar = self.figure_RzPl.colorbar(contours,
                                                 ax=self._static_ax[0],
                                                 pad=0.07)
                cbar.ax.set_ylabel('deltaTrad/<Trad>', rotation=90)
                if contour_check == '1':
                    self._static_ax[0].contour(RR_plot,
                                               zz_plot,
                                               data_plot_t,
                                               vmin=vmin,
                                               vmax=vmax,
                                               levels=levels_to_plot,
                                               cmap='binary')
                # cbar.ax.tick_params(labelsize=8, rotation=90)
                self._static_ax[0].plot(RR_plot, zz_plot, "ko", ms=2)

                if (self.Interp_plot_RzPl.currentText() == 'set to zero') | (
                        self.Interp_plot_RzPl.currentText()
                        == 'with interpolation'):
                    self._static_ax[0].plot(RR_plot[interp_mask],
                                            zz_plot[interp_mask],
                                            "wo",
                                            ms=6)

                self._static_ax[0].set_xlabel("R [m]")
                self._static_ax[0].set_ylabel("z [m]")

                for i, txt in enumerate(ch_zz):
                    self._static_ax[0].annotate(txt + 1,
                                                (RR_plot[i, 0], zz_plot[i, 0]),
                                                fontsize=8)

                for i, txt in enumerate(ch_RR):
                    self._static_ax[0].annotate(txt + 1,
                                                (RR_plot[0, i], zz_plot[0, i]),
                                                fontsize=8)

                # EQ contours
                contours_rhop = self._static_ax[0].contour(
                    mf.RR_t, mf.zz_t, mf.rhopM_t, 50)
                self._static_ax[0].clabel(contours_rhop,
                                          inline=True,
                                          fontsize=10)
                self._static_ax[0].plot(mf.Rmag_t, mf.zmag_t, 'bo')
                self._static_ax[0].set_xlim([mf.Rmag_t, RR_plot[0, -1]])
                self._static_ax[0].set_ylim([zz_plot[0, 0], zz_plot[-1, 0]])

                rhop_to_plot = float(self.rhop_ed_RzPl.text())
                equ_data = equ.equ_map(self.Shot, 'EQH', 'AUGD')
                data_rz = equ_data.rho2rz(rhop_to_plot, tplot, 'rho_pol')
                R_from_rhop = data_rz[0][0][0]
                z_from_rhop = data_rz[1][0][0]
                self.Rmag_t = mf.Rmag_t
                self.zmag_t = mf.zmag_t
                r_rhop = np.sqrt((self.Rmag_t - R_from_rhop[0])**2 +
                                 (self.zmag_t - z_from_rhop[0])**2)
                self._static_ax[0].plot(R_from_rhop,
                                        z_from_rhop,
                                        'g-',
                                        linewidth=4.0)

                self.my_line, = self._static_ax[0].plot(
                    [self.Rmag_t, R_from_rhop[0]],
                    [self.zmag_t, z_from_rhop[0]],
                    marker='o',
                    color='b')
                self._static_ax[0].set_title(
                    "t = %0.7g s, rhop(green) = %0.2g, r_rhop = %0.4g m" %
                    (time_plot_t, rhop_to_plot, r_rhop))
                # 1D plot
                self._static_ax[1].plot(time_plot, trace_1D)
                self._static_ax[1].set_xlabel("t [s]")
                self._static_ax[1].set_ylabel("deltaTrad/<Trad>")
                self._static_ax[1].set_title(
                    "LOS = 7, R_ch = 4, dt resolut = %g s" %
                    (time_plot[1] - time_plot[0]))
                self._static_ax[1].axvline(x=time_plot_t, color="k")

                self.figure_RzPl.suptitle("ECEI, Shot #%d, Filter: %s" %
                                          (self.Shot, filter_status),
                                          fontsize=10)
                if (self.Save_plot_RzPl.currentText() == 'save as pdf') | (
                    (self.Save_plot_RzPl.currentText() == 'save as pdf') &
                    (self.counter_save == 0)):
                    path_to_save = self.path_ed_RzSet.text()
                    self.figure_RzPl.savefig(path_to_save + 'p_%03d.pdf' %
                                             (self.counter_save),
                                             bbox_inches='tight')
                    self.counter_save += 1
                if (self.Save_plot_RzPl.currentText() == 'save as png') | (
                    (self.Save_plot_RzPl.currentText() == 'save as pdf') &
                    (self.counter_save == 0)):
                    path_to_save = self.path_ed_RzSet.text()
                    self.figure_RzPl.savefig(path_to_save + 'p_%03d.png' %
                                             (self.counter_save),
                                             bbox_inches='tight')
                    self.counter_save += 1
                click_coord = self.static_canvas_RzPl.mpl_connect(
                    'button_press_event', self.mouse_click_Rz)
                self.static_canvas_RzPl.draw()
                # self.sync_tabs(9)
                print("+++ The data has been plotted succesfully. +++")

            except Exception as exc:
                traceback.print_exc()
                print("!!! Cannot plot. ERROR: %s" % (exc))
        else:
            print("Please load the ECEI data (first tab)")

    def mouse_click_Rz(self, event):
        if (event.dblclick == True) & (event.button == 1):
            ix, iy = event.xdata, event.ydata
            self.tplot_ed_RzPl.setText("%0.7g" % (ix))
            self.f_Rz_plot(3)

        if (event.dblclick == True) & (event.button == 3):
            ix, iy = event.xdata, event.ydata
            self.r_rhop_blue = np.sqrt((self.Rmag_t - ix)**2 +
                                       (self.zmag_t - iy)**2)
            self.R_blue = ix
            self.z_blue = iy
            self.my_line.remove()
            self.my_line, = self._static_ax[0].plot([self.Rmag_t, ix],
                                                    [self.zmag_t, iy],
                                                    marker='o',
                                                    color='b')
            self._static_ax[0].set_xlabel(
                "R [m]; blue: R = %0.4g m, z = %0.4g m, r_rhop = %0.4g m" %
                (self.R_blue, self.z_blue, self.r_rhop_blue))

    def sync_tabs(self, number):
        try:

            if (number == 9):
                tB_ed = self.tB_ed_RzPl.text()
                tE_ed = self.tE_ed_RzPl.text()
                tCnt_ed = self.tCnt_ed_RzPl.text()
                dt_ed = self.dt_ed_RzPl.text()
                Fourier_cut = self.Fourier_cut_RzPl.text()
                Fourier2_cut = self.Fourier2_cut_RzPl.text()
                Savgol_ed0 = self.SavGol_ed0_RzPl.text()
                Savgol_ed1 = self.SavGol_ed1_RzPl.text()
                Binning_ed = self.Binning_ed_RzPl.text()
            # 9
            self.tB_ed_RzPl.setText(tB_ed)
            self.tE_ed_RzPl.setText(tE_ed)
            self.tCnt_ed_RzPl.setText(tCnt_ed)
            self.dt_ed_RzPl.setText(dt_ed)
            self.Fourier_cut_RzPl.setText(Fourier_cut)
            self.Fourier2_cut_RzPl.setText(Fourier2_cut)
            self.SavGol_ed0_RzPl.setText(Savgol_ed0)
            self.SavGol_ed1_RzPl.setText(Savgol_ed1)
            self.Binning_ed_RzPl.setText(Binning_ed)

        except Exception as exc:
            print("!!! Couldn't synchronize tabs. ERROR: %s" % (exc))

    def send_points(self):
        try:
            self.Monitor_RzPl.moveCursor(QTextCursor.End)
            self.Monitor_RzPl.insertPlainText(
                "%d\t%0.7g\t%0.4g\t%0.4g\t%0.4g\n" %
                (self.counter, self.tplot, self.R_blue, self.z_blue,
                 self.r_rhop_blue))
            self.counter += 1
        except Exception as exc:
            traceback.print_exc()
            print("!!! Cannot plot. ERROR: %s" % (exc))

    def clear_table(self):
        try:
            self.Monitor_RzPl.setText("NN\tt\tR\tz\tr\n")
            self.counter = 1
        except Exception as exc:
            traceback.print_exc()
            print("!!! Cannot plot. ERROR: %s" % (exc))
Exemple #55
0
class Plot(FigureCanvas):
	def __init__(self,t_from,t_to):
		self.figure = Figure(figsize=(10,2), dpi=80)
		self.t_from = t_from
		self.t_to = t_to
		self.t_diff = math.fabs(t_from - t_to)

		self.axis = None
	
		FigureCanvas.__init__(self,self.figure)
	
	# Set new time bounds.
	# Return false if time wasn't changed, and so graph do not require
	# reploting.
	def setNewTime(self,t_from,t_to):
		if (self.t_from == t_from and self.t_to == t_to):
			return False
		if (self.axis):
			self.figure.clf()
			self.axis.clear()
			self.axis = None
		self.t_from=t_from
		self.t_to=t_to
		# get time differences
		self.t_diff = math.fabs(self.t_from - self.t_to)
		return True

	def setAxisLocators(self, axis):
		# half a day..
		if (self.t_diff <= 43200):
			axis.xaxis.set_major_locator(mdates.HourLocator())
			axis.xaxis.set_minor_locator(mdates.MinuteLocator(interval=1))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%H'))
		elif (self.t_diff <= 86400):
			axis.xaxis.set_major_locator(mdates.HourLocator(interval=2))
			axis.xaxis.set_minor_locator(mdates.MinuteLocator(interval=15))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%H'))
		elif (self.t_diff <= 86400 * 2):
			axis.xaxis.set_major_locator(mdates.HourLocator(interval=4))
			axis.xaxis.set_minor_locator(mdates.MinuteLocator(interval=30))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%H'))
		elif (self.t_diff <= 86400 * 10):
			axis.xaxis.set_major_locator(mdates.DayLocator())
			axis.xaxis.set_minor_locator(mdates.HourLocator(interval=6))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%d'))
		elif (self.t_diff <= 86400 * 33):
			axis.xaxis.set_major_locator(mdates.DayLocator(interval=2))
			axis.xaxis.set_minor_locator(mdates.HourLocator(interval=12))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%d'))
		else:
			axis.xaxis.set_minor_locator(mdates.DayLocator(interval=5))
			axis.xaxis.set_major_locator(mdates.MonthLocator(interval=2))
			axis.xaxis.set_major_formatter(mdates.DateFormatter('%m'))

	# Returns new axis instance
	# Either create axis from figure, or creat new yaxis with twinx method
	def getAxis(self):
		if (self.axis != None):
			rax = self.axis.twinx()
			self.setAxisLocators(rax)
			return rax

		self.axis = self.figure.add_subplot(111)

		self.axis.grid(True)

		self.setAxisLocators(self.axis)

		self.next_color = 0

		return self.axis

	# Return next color..
	def getNextColor(self):
		color = "brgym"
		c = color[self.next_color]
		self.next_color += 1
		return c

	# Add varible to plot.
	# Adjust scaling, so if dateaxis is too long, it will use averages
	def addVariable(self, label, varid, scale = 'linear'):
		if (self.t_diff <= 86400 * 5):
		  	return self.addExactVariable(label, varid, scale)
		else:
		  	return self.addAveragevariable(label, varid, scale)

	# Adds average variables
	def addAveragevariable(self, label, varid, scale = 'linear'):
		result = rts2XmlServer().rts2.records.averages(varid, self.t_from, self.t_to)
		if (len(result) == 0):
			return
		
		ta = marray('d')
		sa = marray('d')
		mi = marray('d')
		ma = marray('d')

		for x in result:
			ta.append(date2num(x[0]))
			sa.append(x[1])
			mi.append(x[2])
			ma.append(x[3])

		ax = self.getAxis()
		c = self.getNextColor()
		
		ax.plot_date(ta,sa, '-', color=c)
		ax.set_yscale(scale)

		ax.set_ylabel(label, color=c)
		for tl in ax.get_yticklabels():
		  	tl.set_color(c)

		if (matplotlib.__version__ >= '0.98.4'):
			ax.fill_between(ta,mi,ma,alpha=0.5,facecolor='gray')
		else:
			ax.plot_date(ta,mi,'g-')
			ax.plot_date(ta,ma,'g-')
	
	# Plot exactly all numbers from variable.
	# Please note that this might be time consuming if
	# there are much more points..
	def addExactVariable(self, label, varid, scale = 'linear'):
		result = rts2XmlServer().rts2.records.get(varid, self.t_from, self.t_to)
		if (len(result) == 0):
			print "0 records ", varid, self.t_from, self.t_to
			return

		ta = marray('d')
		sa = marray('d')

		for x in result:
			ta.append(date2num(x[0]))
			sa.append(x[1])

		ax = self.getAxis()

		c = self.getNextColor()

		ax.plot_date(ta,sa, c + '-')
		ax.set_yscale(scale)

		ax.set_ylabel(label, color=c)
		for tl in ax.get_yticklabels():
			tl.set_color(c)
Exemple #56
0
class NetworkUI(QDialog):
    def __init__(self, parent=None):
        super(NetworkUI, self).__init__(parent)

        self.title = 'Schema Network Interface'
        self.left = 500
        self.top = 100
        self.width = 1400
        self.height = 900
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        #self.setFixedSize(self.width, self.height)

        # Network display
        self.figure = Figure(figsize=(8, 10))
        self.canvas = FigureCanvas(self.figure)

        # Network info
        self.info = QLabel(
            'Current Trial: 0 \nSchema Objects: \nSchema: \nLC_Max: ')

        # Controls
        self.controlsBox = QGroupBox()
        self.controlsLayout = QHBoxLayout()
        self.buttonPlot = QPushButton('Consolidate')
        #self.buttonPlot.clicked.connect(self.plot)
        self.buttonSave = QPushButton('Save')
        self.buttonLoad = QPushButton('Load')
        self.textFilename = QLineEdit()
        self.controlsLayout.addWidget(self.buttonPlot)
        self.controlsLayout.addWidget(self.buttonSave)
        self.controlsLayout.addWidget(self.buttonLoad)
        self.controlsLayout.addWidget(self.textFilename)
        self.controlsBox.setLayout(self.controlsLayout)

        # set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.info)
        layout.addWidget(self.controlsBox)
        self.setLayout(layout)

    def plot(self):
        ''' plot some random stuff '''
        # random data
        data = [random.random() for i in range(10)]

        # create an axis
        ax = self.figure.add_subplot(111)

        # discards the old graph
        ax.clear()

        # plot data
        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()

    def update_info(self, schema_objects, schema, lc_max):
        schema_objects_string = ''
        for so in schema_objects:
            schema_objects_string = schema_objects_string + so + ' '
        self.info.setText('Current Trial: 0 \nSchema Objects: ' +
                          schema_objects_string + '\nSchema:' + str(schema) +
                          '\nLC_Max: ' + str(lc_max))

    def visualize(self, n, w):
        self.figure.clf()
        n_context = n['n_context']
        n_flavor = n['n_flavor']
        n_multimodal = n['n_multimodal']
        n_well = n['n_well']
        n_context_pattern = n['n_context_pattern']
        n_vhipp = n['n_vhipp']
        n_dhipp = n['n_dhipp']
        familiarity = n['familiarity']
        noveltyy = n['noveltyy']
        w_pattern_context = w['w_pattern_context']
        w_context_multimodal = w['w_context_multimodal']
        w_flavor_multimodal = w['w_flavor_multimodal']
        w_multimodal_well = w['w_multimodal_well']
        w_vhipp_multimodal = w['w_vhipp_multimodal']
        w_well_dhipp = w['w_well_dhipp']
        w_flavor_dhipp = w['w_flavor_dhipp']
        w_vhipp_dhipp = w['w_vhipp_dhipp']
        w_context_vhipp = w['w_context_vhipp']
        w_context_familiarity = w['w_context_familiarity']
        w_dhipp_novelty = w['w_dhipp_novelty']

        gs = gridspec.GridSpec(5,
                               10,
                               width_ratios=[1, 4, 1, 4, 1, 4, 1, 1, 1, 1],
                               height_ratios=[4, 1, 4, 4, 4])

        ax_context = self.figure.add_subplot(gs[22])
        ax_context.set_title('mPFC')
        ax_context.get_xaxis().set_ticks([])
        ax_context.get_yaxis().set_ticks([])
        ax_flavor = self.figure.add_subplot(gs[42])
        ax_flavor.set_title('cue')
        ax_flavor.get_xaxis().set_ticks([])
        ax_flavor.get_yaxis().set_ticks([])
        ax_multimodal = self.figure.add_subplot(gs[44])
        ax_multimodal.set_title('AC')
        ax_multimodal.get_xaxis().set_ticks([])
        ax_multimodal.get_yaxis().set_ticks([])
        ax_well = self.figure.add_subplot(gs[46])
        ax_well.set_title('action')
        ax_well.get_xaxis().set_ticks([])
        ax_well.get_yaxis().set_ticks([])
        ax_cp = self.figure.add_subplot(gs[20])
        ax_cp.set_title('pattern')
        ax_cp.get_xaxis().set_ticks([])
        ax_cp.get_yaxis().set_ticks([])
        ax_vhipp = self.figure.add_subplot(gs[24])
        ax_vhipp.set_title('vHPC')
        ax_vhipp.get_xaxis().set_ticks([])
        ax_vhipp.get_yaxis().set_ticks([])
        ax_dhipp = self.figure.add_subplot(gs[26])
        ax_dhipp.set_title('dHPC')
        ax_dhipp.get_xaxis().set_ticks([])
        ax_dhipp.get_yaxis().set_ticks([])
        ax_familiarity = self.figure.add_subplot(gs[5])
        ax_familiarity.set_title('familiarity')
        ax_familiarity.get_xaxis().set_ticks([])
        ax_familiarity.get_yaxis().set_ticks([])
        ax_noveltyy = self.figure.add_subplot(gs[3])
        ax_noveltyy.set_title('novelty')
        ax_noveltyy.get_xaxis().set_ticks([])
        ax_noveltyy.get_yaxis().set_ticks([])
        ax_p_c = self.figure.add_subplot(gs[21])
        ax_p_c.set_title('pattern to mPFC')
        ax_p_c.get_xaxis().set_ticks([])
        ax_p_c.get_yaxis().set_ticks([])
        ax_c_m = self.figure.add_subplot(gs[33])
        ax_c_m.set_title('mPFC to AC')
        ax_c_m.get_xaxis().set_ticks([])
        ax_c_m.get_yaxis().set_ticks([])
        ax_f_m = self.figure.add_subplot(gs[43])
        ax_f_m.set_title('cue to AC')
        ax_f_m.get_xaxis().set_ticks([])
        ax_f_m.get_yaxis().set_ticks([])
        ax_m_w = self.figure.add_subplot(gs[45])
        ax_m_w.set_title('AC to action')
        ax_m_w.get_xaxis().set_ticks([])
        ax_m_w.get_yaxis().set_ticks([])
        ax_v_m = self.figure.add_subplot(gs[34])
        ax_v_m.set_title('vHPC to AC')
        ax_v_m.get_xaxis().set_ticks([])
        ax_v_m.get_yaxis().set_ticks([])
        ax_x_d = self.figure.add_subplot(gs[25])
        ax_x_d.set_title('vHPC, cue, action to dHPC')
        ax_x_d.get_xaxis().set_ticks([])
        ax_x_d.get_yaxis().set_ticks([])
        ax_c_v = self.figure.add_subplot(gs[23])
        ax_c_v.set_title('mPFC to vHPC')
        ax_c_v.get_xaxis().set_ticks([])
        ax_c_v.get_yaxis().set_ticks([])
        ax_c_f = self.figure.add_subplot(gs[15])
        ax_c_f.set_title('mPFC to familiarity')
        ax_c_f.get_xaxis().set_ticks([])
        ax_c_f.get_yaxis().set_ticks([])
        ax_d_n = self.figure.add_subplot(gs[13])
        ax_d_n.set_title('dHPC to novelty')
        ax_d_n.get_xaxis().set_ticks([])
        ax_d_n.get_yaxis().set_ticks([])

        ax_context.imshow(n_context, interpolation='none', aspect='auto')
        ax_flavor.imshow(n_flavor, interpolation='none', aspect='auto')
        ax_multimodal.imshow(n_multimodal, interpolation='none', aspect='auto')
        ax_well.imshow(n_well, interpolation='none', aspect='auto')
        ax_cp.imshow(n_context_pattern, interpolation='none', aspect='auto')
        ax_vhipp.imshow(n_vhipp, interpolation='none', aspect='auto')
        ax_dhipp.imshow(n_dhipp, interpolation='none', aspect='auto')
        ax_familiarity.imshow(familiarity, interpolation='none', aspect='auto')
        ax_noveltyy.imshow(noveltyy, interpolation='none', aspect='auto')
        ax_p_c.imshow(w_pattern_context, interpolation='none', aspect='auto')
        ax_c_m.imshow(w_context_multimodal,
                      interpolation='none',
                      aspect='auto')
        ax_f_m.imshow(w_flavor_multimodal, interpolation='none', aspect='auto')
        ax_m_w.imshow(w_multimodal_well, interpolation='none', aspect='auto')
        ax_v_m.imshow(w_vhipp_multimodal, interpolation='none', aspect='auto')
        ax_x_d.imshow(np.concatenate(
            (w_well_dhipp, w_flavor_dhipp, w_vhipp_dhipp), axis=1),
                      interpolation='none',
                      aspect='auto')
        ax_c_v.imshow(w_context_vhipp, interpolation='none', aspect='auto')
        ax_c_f.imshow(w_context_familiarity,
                      interpolation='none',
                      aspect='auto')
        ax_d_n.imshow(w_dhipp_novelty, interpolation='none', aspect='auto')
        # refresh canvas
        self.canvas.draw()
Exemple #57
0
class VelPlotWidget(QtGui.QWidget):
    """ Widget for a velocity plot with interaction.
    Akin to XIDL/x_velplot

        19-Dec-2014 by JXP
    """
    def __init__(self, ispec, z, abs_lines=None, parent=None, llist=None, norm=True,
                 vmnx=[-300., 300.]*u.km/u.s):
        '''
        spec : XSpectrum1D
        z : float
        abs_lines: list, optional
          List of AbsLines
        llist : LineList, optional
          Input line list.  Defaults to 'Strong'
        norm : bool, optional
          Normalized spectrum?
        vmnx : Quantity array, optional
          Starting velocity range for the widget
        '''
        super(VelPlotWidget, self).__init__(parent)
        self.help_message = """
Click on any white region within the velocity plots
for the following keystroke commands to work:

i,o       : zoom in/out x limits
I,O       : zoom in/out x limits (larger re-scale)
y         : zoom out y limits
t,b       : set y top/bottom limit
l,r       : set left/right x limit
[,]       : pan left/right
C,c       : add/remove column
K,k       : add/remove row
=,-       : move to next/previous page
1,2       : Modify velocity region of the single line (left, right sides)
!,@       : Modify velocity region of all lines (left, right)
A,x       : Add/remove select line from analysis list
X         : Remove all lines from analysis list
^,&       : Flag line to be analyzed for low/high-ion kinematics
B         : Toggle as blend/no-blend  (orange color = blend)
N         : Toggle as do/do-not include for analysis  (red color = exclude)
V         : Indicate as a normal value
L         : Indicate as a lower limit
U         : Indicate as a upper limit
?         : Print this
        """

        # Initialize
        spec, spec_fil = ltgu.read_spec(ispec)

        self.spec = spec
        self.spec_fil = spec_fil
        self.z = z
        self.vmnx = vmnx
        self.norm = norm

        # Abs Lines
        if abs_lines is None:
            self.abs_lines = []
        else:
            self.abs_lines = abs_lines

        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        self.psdict = {} # Dict for spectra plotting
        self.psdict['x_minmax'] = self.vmnx.value # Too much pain to use units with this
        self.psdict['y_minmax'] = [-0.1, 1.1]
        self.psdict['nav'] = ltgu.navigate(0,0,init=True)

        # Line List
        if llist is None:
            self.llist = ltgu.set_llist('Strong')
        else:
            self.llist = llist
        self.llist['z'] = self.z

        # Indexing for line plotting
        self.idx_line = 0
        self.init_lines()

        # Create the mpl Figure and FigCanvas objects.
        self.dpi = 150
        self.fig = Figure((8.0, 4.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)

        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas.setFocus()
        self.canvas.mpl_connect('key_press_event', self.on_key)
        self.canvas.mpl_connect('button_press_event', self.on_click)

        # Sub_plots (Initial)
        self.sub_xy = [3,4]
        self.fig.subplots_adjust(hspace=0.0, wspace=0.1)

        # Layout
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.canvas)
        self.setLayout(vbox)

        # Print help message
        print(self.help_message)

        # Draw on init
        self.on_draw()

    # Load them up for display
    def init_lines(self):
        wvmin = np.min(self.spec.wavelength)
        wvmax = np.max(self.spec.wavelength)
        #
        wrest = self.llist[self.llist['List']].wrest
        wvobs = (1+self.z) * wrest
        gdlin = np.where( (wvobs > wvmin) & (wvobs < wvmax) )[0]
        self.llist['show_line'] = gdlin

        # Update/generate lines [will not update]
        if len(self.abs_lines) == 0:
            for idx in gdlin:
                self.generate_line((self.z,wrest[idx]))

    def grab_line(self, wrest):
        """ Grab a line from the list
        Parameters
        ----------
        wrest

        Returns
        -------
        iline : AbsLine object
        """
        awrest = [iline.wrest for iline in self.abs_lines]
        try:
            idx = awrest.index(wrest)
        except ValueError:
            return None
        else:
            return self.abs_lines[idx]

    def generate_line(self, inp):
        """ Add a new line to the list, if it doesn't exist
        Parameters:
        ----------
        inp: tuple
          (z,wrest)
        """
        # Generate?
        if self.grab_line(inp[1]) is None:
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            newline = AbsLine(inp[1],linelist=self.llist[self.llist['List']],
                              z=self.z)
            print('VelPlot: Generating line {:g}'.format(inp[1]))
            newline.limits.set(self.vmnx/2.)
            newline.analy['do_analysis'] = 1  # Init to ok
            # Spec file
            if self.spec_fil is not None:
                newline.analy['datafile'] = self.spec_fil
            # Append
            self.abs_lines.append(newline)

    def remove_line(self, wrest):
        """ Remove a line, if it exists
        Parameters
        ----------
        wrest : Quantity
        """
        awrest = [iline.wrest for iline in self.abs_lines]
        try:
            idx = awrest.index(wrest)
        except ValueError:
            return None
        else:
            _ = self.abs_lines.pop(idx)

    # Key stroke
    def on_key(self,event):

        # Init
        rescale = True
        fig_clear = False
        wrest = None
        flg = 0
        sv_idx = self.idx_line

        ## Change rows/columns
        if event.key == 'k':
            self.sub_xy[0] = max(0, self.sub_xy[0]-1)
        if event.key == 'K':
            self.sub_xy[0] = self.sub_xy[0]+1
        if event.key == 'c':
            self.sub_xy[1] = max(0, self.sub_xy[1]-1)
        if event.key == 'C':
            self.sub_xy[1] = max(0, self.sub_xy[1]+1)

        ## NAVIGATING
        if event.key in self.psdict['nav']:
            flg = ltgu.navigate(self.psdict,event)
        if event.key == '-':
            self.idx_line = max(0, self.idx_line-self.sub_xy[0]*self.sub_xy[1]) # Min=0
            if self.idx_line == sv_idx:
                print('Edge of list')
        if event.key == '=':
            self.idx_line = min(len(self.llist['show_line'])-self.sub_xy[0]*self.sub_xy[1],
                                self.idx_line + self.sub_xy[0]*self.sub_xy[1])
            if self.idx_line == sv_idx:
                print('Edge of list')

        ## Reset z
        if event.key == 'z':
            newz = ltu.z_from_v(self.z, event.xdata)
            self.z = newz
            # Drawing
            self.psdict['x_minmax'] = self.vmnx.value

        # Single line command
        if event.key in ['1','2','B','U','L','N','V','A', 'x', 'X',
                         '^', '&']:
            try:
                wrest = event.inaxes.get_gid()
            except AttributeError:
                return
            else:
                absline = self.grab_line(wrest)

        ## Velocity limits
        unit = u.km/u.s
        if event.key == '1':
            absline.limits.set((event.xdata, absline.limits.vlim[1].value)*unit)
        if event.key == '2':
            absline.limits.set((absline.limits.vlim[0].value, event.xdata)*unit)
        if event.key == '!':  # Set all lines to this value
            for iline in self.abs_lines:
                iline.limits.set((event.xdata, iline.limits.vlim[1].value)*unit)
        if event.key == '@':
            for iline in self.abs_lines:
                iline.limits.set((iline.limits.vlim[0].value, event.xdata)*unit)
        ## Line type
        if event.key == 'A': # Add to lines
            self.generate_line((self.z,wrest))
        if event.key == 'x': # Remove line
            if self.remove_line(wrest):
                print('VelPlot: Removed line {:g}'.format(wrest))
        if event.key == 'X': # Remove all lines
            # Double check
            gui = simple_widgets.WarningWidg('About to remove all lines. \n  Continue??')
            gui.exec_()
            if gui.ans is False:
                return
            #
            self.abs_lines = []  # Flush??
        # Kinematics
        if event.key == '^':  # Low-Ion
            try:
                fkin = absline.analy['flag_kin']
            except KeyError:
                fkin = 0
            fkin += (-1)**(fkin % 2**1 >= 2**0) * 2**0
            absline.analy['flag_kin'] = fkin
        if event.key == '&':  # High-Ion
            try:
                fkin = absline.analy['flag_kin']
            except KeyError:
                fkin = 0
            fkin += (-1)**(fkin % 2**2 >= 2**1) * 2**1
            absline.analy['flag_kin'] = fkin
        # Toggle blend
        if event.key == 'B':
            try:
                feye = absline.analy['flg_eye']
            except KeyError:
                feye = 0
            feye = (feye + 1) % 2
            absline.analy['flg_eye']  = feye
        # Toggle NG
        if event.key == 'N':
            try:
                fanly = absline.analy['do_analysis']
            except KeyError:
                fanly = 1
            if fanly == 0:
                fanly = 1
            else:
                fanly = 0
            absline.analy['do_analysis']  = fanly
        if event.key == 'V':  # Normal
            absline.analy['flg_limit'] = 1
        if event.key == 'L':  # Lower limit
            absline.analy['flg_limit'] = 2
        if event.key == 'U':  # Upper limit
            absline.analy['flg_limit'] = 3

        '''
        # AODM plot
        if event.key == ':':  #
            # Grab good lines
            from xastropy.xguis import spec_guis as xsgui
            gdl = [iline.wrest for iline in self.abs_sys.lines
                if iline.analy['do_analysis'] > 0]
            # Launch AODM
            if len(gdl) > 0:
                gui = xsgui.XAODMGui(self.spec, self.z, gdl, vmnx=self.vmnx, norm=self.norm)
                gui.exec_()
            else:
                print('VelPlot.AODM: No good lines to plot')
        '''

        if wrest is not None:  # Single window
            flg = 3
        if event.key in ['c','C','k','K','W','!', '@', '=', '-', 'X', 'z','R']: # Redraw all
            flg = 1
        if event.key in ['Y']:
            rescale = False
        if event.key in ['k','c','C','K', 'R']:
            fig_clear = True

        # Print help message
        if event.key == '?':
            print(self.help_message)


        if flg == 1: # Default is not to redraw
            self.on_draw(rescale=rescale, fig_clear=fig_clear)
        elif flg == 2:  # Layer (no clear)
            self.on_draw(replot=False, rescale=rescale)
        elif flg == 3:  # Layer (no clear)
            self.on_draw(in_wrest=wrest, rescale=rescale)

    # Click of main mouse button
    def on_click(self,event):
        try:
            print('button={:d}, x={:f}, y={:f}, xdata={:f}, ydata={:f}'.format(
                event.button, event.x, event.y, event.xdata, event.ydata))
        except ValueError:
            return
        if event.button == 1: # Draw line
            self.ax.plot( [event.xdata,event.xdata], self.psdict['y_minmax'], ':', color='green')
            self.on_draw(replot=False)

            # Print values
            try:
                self.statusBar().showMessage('x,y = {:f}, {:f}'.format(event.xdata,event.ydata))
            except AttributeError:
                return

    def on_draw(self, replot=True, in_wrest=None, rescale=True, fig_clear=False):
        """ Redraws the figure
        """
        #
        if replot is True:
            if fig_clear:
                self.fig.clf()
            # Loop on windows
            all_idx = self.llist['show_line']
            nplt = self.sub_xy[0]*self.sub_xy[1]
            if len(all_idx) <= nplt:
                self.idx_line = 0
            subp = np.arange(nplt) + 1
            subp_idx = np.hstack(subp.reshape(self.sub_xy[0],self.sub_xy[1]).T)
            for jj in range(min(nplt, len(all_idx))):
                try:
                    idx = all_idx[jj+self.idx_line]
                except IndexError:
                    continue # Likely too few lines
                # Grab line
                wrest = self.llist[self.llist['List']].wrest[idx]
                # Single window?
                if in_wrest is not None:
                    if np.abs(wrest-in_wrest) > (1e-3*u.AA):
                        continue

                # AbsLine for this window
                absline = self.grab_line(wrest)

                # Generate plot
                self.ax = self.fig.add_subplot(self.sub_xy[0],self.sub_xy[1], subp_idx[jj])
                self.ax.clear()

                # Zero line
                self.ax.plot( [0., 0.], [-1e9, 1e9], ':', color='gray')
                # Velocity
                wvobs = (1+self.z) * wrest
                velo = (self.spec.wavelength/wvobs - 1.)*const.c.to('km/s')

                # Plot
                self.ax.plot(velo, self.spec.flux, 'k-',drawstyle='steps-mid')

                # GID for referencing
                self.ax.set_gid(wrest)

                # Labels
                if (((jj+1) % self.sub_xy[0]) == 0) or ((jj+1) == len(all_idx)):
                    self.ax.set_xlabel('Relative Velocity (km/s)')
                else:
                    self.ax.get_xaxis().set_ticks([])
                lbl = self.llist[self.llist['List']].name[idx]
                # Kinematics
                kinl = ''
                if absline is not None:
                    if (absline.analy['flag_kin'] % 2) >= 1:
                        kinl = kinl + 'L'
                    if (absline.analy['flag_kin'] % 4) >= 2:
                        kinl = kinl + 'H'
                if absline is not None:
                    lclr = 'blue'
                else:
                    lclr = 'gray'
                self.ax.text(0.1, 0.05, lbl+kinl, color=lclr, transform=self.ax.transAxes,
                             size='x-small', ha='left')

                # Reset window limits
                #QtCore.pyqtRemoveInputHook()
                #xdb.set_trace()
                #QtCore.pyqtRestoreInputHook()
                self.ax.set_xlim(self.psdict['x_minmax'])

                # Rescale?
                if (rescale is True) & (self.norm is False):
                    gdp = np.where( (velo.value > self.psdict['x_minmax'][0]) &
                                    (velo.value < self.psdict['x_minmax'][1]))[0]
                    if len(gdp) > 5:
                        per = np.percentile(self.spec.flux[gdp],
                                            [50-68/2.0, 50+68/2.0])
                        self.ax.set_ylim((0., 1.1*per[1]))
                    else:
                        self.ax.set_ylim(self.psdict['y_minmax'])
                else:
                    self.ax.set_ylim(self.psdict['y_minmax'])

                # Fonts
                for item in ([self.ax.title, self.ax.xaxis.label, self.ax.yaxis.label] +
                         self.ax.get_xticklabels() + self.ax.get_yticklabels()):
                    item.set_fontsize(6)


                clr='black'
                if absline is not None:
                    if absline.limits.is_set():
                        vlim = absline.limits.vlim
                    else:
                        pass
                    #try:
                    #    vlim = absline.analy['vlim']
                    #except KeyError:
                    #    pass
                    # Color coding
                    try:  # .clm style
                        flag = absline.analy['FLAGS'][0]
                    except KeyError:
                        flag = None
                    else:
                        if flag <= 1: # Standard detection
                            clr = 'green'
                        elif flag in [2,3]:
                            clr = 'blue'
                        elif flag in [4,5]:
                            clr = 'purple'
                    # ABS ID
                    try: # NG?
                        flagA = absline.analy['do_analysis']
                    except KeyError:
                        flagA = None
                    else:
                        if (flagA>0) & (clr == 'black'):
                            clr = 'green'
                    try: # Limit?
                        flagL = absline.analy['flg_limit']
                    except KeyError:
                        flagL = None
                    else:
                        if flagL == 2:
                            clr = 'blue'
                        if flagL == 3:
                            clr = 'purple'
                    try: # Blends?
                        flagE = absline.analy['flg_eye']
                    except KeyError:
                        flagE = None
                    else:
                        if flagE == 1:
                            clr = 'orange'
                    if flagA == 0:
                        clr = 'red'

                    pix = np.where( (velo > vlim[0]) & (velo < vlim[1]))[0]
                    self.ax.plot(velo[pix], self.spec.flux[pix], '-',
                                 drawstyle='steps-mid', color=clr)
        # Draw
        self.canvas.draw()
Exemple #58
0
class GUI(QtGui.QWidget):
    def __init__(self):

        super(GUI, self).__init__()

        self.setWindowTitle('Label Cells')
        self.cellNames = [
            '1.p', '4.a', '1.pp', '4.aa', '1.ppa', '1.ppp', '4.aaa', '4.aap',
            'b_1', 'b_4'
        ]
        self.initUI()

    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):

        # SET THE GEOMETRY

        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)

        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()

        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)

        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()

        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)

        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS

        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')

        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')

        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')

        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')

        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16 - 1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16 - 1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600, 600))
        self.canvas1.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300, 300))
        self.canvas2.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0)
        Col1.addWidget(self._561nmBtn, 4, 0)
        Col1.addWidget(self.CoolLEDBtn, 5, 0)

        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        Col3.addWidget(self.cellTbl)
        Col3.addWidget(self.canvas2)

        self.setFocus()
        self.show()

        # BIND BUTTONS TO FUNCTIONS

        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.loadNewStack)
        self.sl.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        self.fig1.canvas.mpl_connect('button_press_event',
                                     self.onMouseClickOnCanvas1)
        self.fig1.canvas.mpl_connect('scroll_event', self.wheelEvent)

    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):

        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def HLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):

        return width

    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(
            self, 'Select a folder', 'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname(self.pathDial)
        self.setWindowTitle('Mark Cells - ' + self.pathDial)

        ### give error message if there is no CoolLED movie in the selected folder
        if not os.path.isfile(os.path.join(self.pathDial,
                                           'CoolLED_movie.tif')):
            QtGui.QMessageBox.about(
                self, 'Warning!',
                'There is no movie in this folder! Create a movie first!')
            return

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame(self.path,
                                        self.worm + '_01params.pickle')
        self.timesDF = load_data_frame(self.path,
                                       self.worm + '_01times.pickle')
        self.gpDF = load_data_frame(self.path,
                                    self.worm + '_02gonadPos.pickle')

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int(self.paramsDF.tidxHatch)

        ### if the cellPos pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile(
                os.path.join(self.path, self.worm + '_04cellPos.pickle')):
            self.cellPosDF = load_data_frame(self.path,
                                             self.worm + '_04cellPos.pickle')

        else:
            self.cellPosDF = create_cell_pos(self.timesDF, self.cellNames)

        ### load all movies (without timestamps, we will add it later on)
        self.LEDmovie = load_stack(
            os.path.join(self.pathDial, 'CoolLED_movie.tif'))

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))
        self.tp.setValue(0)

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos(self.cellPosDF,
                                                     self.tp.value())

        # detect available channels
        self.channels = []
        chns = ['CoolLED', '488nm', '561nm']
        for c in chns:

            if os.path.isfile(os.path.join(self.pathDial, c + '_movie.tif')):

                self.channels.append(c)
        self.currentChannel = self.channels[0]

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        self.loadNewStack()

        # self.pathDial.show()
        self.updateAllCanvas()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[self.timesDF.tidxRel ==
                               self.tp.value()].squeeze()

        print('Loading... ', self.pathDial, tRow.fName)

        # load all the available stacks
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join(self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile(fileName):
                self.stacks[ch] = load_stack(fileName)

        if len(self.stacks.keys()) > 0:
            # print(self.stacks.keys(), self.stacksStraight)
            self.sl.setMaximum(self.stacks[self.currentChannel].shape[0] - 1)

            self.setBCslidersMinMax()

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos(self.cellPosDF,
                                                     self.tp.value())

        # self.updateTable()
        self.updateAllCanvas()

    def saveData(self):

        if self.checkConsistencyCellNames():
            save_data_frame(self.cellPosDF, self.path,
                            self.worm + '_04cellPos.pickle')
        else:
            QtGui.QMessageBox.about(self, 'Warning!',
                                    'There is a mistake in the cell labels!')
        self.setFocus()

    def updateAllCanvas(self):
        self.updateRadioBtn()
        self.updateCanvas1()
        self.updateCanvas2()

    def radioClicked(self):
        if self._488nmBtn.isChecked():
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')
        elif self._561nmBtn.isChecked():
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')
        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')
        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):

        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime('time', +1)

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime('time', -1)

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime('space', +1)

        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime('space', -1)

        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)

        self.setFocus()

    def wheelEvent(self, event):
        if self.canvas1.underMouse():
            step = event.step
        else:
            step = event.delta() / abs(event.delta())
        self.sl.setValue(self.sl.value() + step)

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):

        motherCells = [QtCore.Qt.Key_1, QtCore.Qt.Key_4, QtCore.Qt.Key_B]
        daughterCells = [QtCore.Qt.Key_A, QtCore.Qt.Key_P]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacks[self.currentChannel][self.sl.value()].shape
        canshape = self.canvas1.size()
        cf = imgshape[0] / canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([int(refpos.x() * cf), int(refpos.y() * cf)])
        refpos = np.append(refpos, self.sl.value())

        ### find the closest cell to the cursor
        idx = closer_cell(refpos.astype(np.uint16), self.currentCells)

        ### assign the name to the cell
        if any([event.key() == cn for cn in motherCells]):
            # if labeling bckg, add the 1 or 2 to the name
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()
            else:
                # if not, rename the cell from scratch
                if event.key() == QtCore.Qt.Key_B:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '_'
                else:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '.'

        # add the anterior/posterior to the cell name
        elif any([event.key() == cp for cp in daughterCells]):
            # don't do it if labeling background (bckg doesn't have a/p!)
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                return
            else:
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()

        # remove the last entry of the name with backspace
        elif event.key() == QtCore.Qt.Key_Backspace:
            self.currentCells.ix[idx,
                                 'cname'] = self.currentCells.ix[idx,
                                                                 'cname'][:-1]

        self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas1(self, event):

        refpos = np.array([event.xdata, event.ydata, self.sl.value()])

        if event.button == 1:

            # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
            newcell = create_single_cell_pos(refpos.astype(np.uint16),
                                             self.tp.value())
            self.currentCells = pd.concat([self.currentCells, newcell])

        elif event.button == 3:

            # remove a cell (the closest to the cursor at the moment of right-click)
            idx = closer_cell(refpos.astype(np.uint16), self.currentCells)
            self.currentCells = self.currentCells.drop([idx])

        self.currentCells = self.currentCells.reset_index(drop=True)

        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld1.setMinimum(np.min(self.stacks[self.currentChannel]))
        self.sld2.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld2.setMinimum(np.min(self.stacks[self.currentChannel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.stacks[self.currentChannel]))
        self.sld2.setValue(np.max(self.stacks[self.currentChannel]))

    def updateCanvas1(self):

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        if len(self.stacks.keys()) == 0:
            # if no images are found, leave the canvas empty
            return

        # plot the image
        self.ax1.cla()
        imgplot = self.ax1.imshow(
            self.stacks[self.currentChannel][self.sl.value()], cmap='gray')

        # remove the white borders and plot outline and spline
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # cell text on the image
        for idx, cell in self.currentCells.iterrows():

            if cell.Z == self.sl.value():

                self.ax1.text(cell.X,
                              cell.Y + 18,
                              cell.cname,
                              color='red',
                              size='medium',
                              alpha=.8,
                              rotation=0)
                self.ax1.plot(cell.X,
                              cell.Y,
                              'o',
                              color='red',
                              alpha=.8,
                              mew=0)

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(), self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(), self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas2(self):

        # plot the image
        self.ax2.cla()
        imgplot = self.ax2.imshow(self.LEDmovie[self.tp.value() +
                                                self.hatchingtidx],
                                  cmap='gray')

        # remove the white borders and plot outline and spline
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print gonad position
        gonadPos = extract_pos(self.gpDF.ix[
            self.gpDF.tidx == self.tp.value()].squeeze()) / self.compression
        self.ax2.plot(gonadPos[0],
                      gonadPos[1],
                      'o',
                      color='red',
                      ms=10,
                      mew=0,
                      alpha=.5,
                      lw=0)

        # print time
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.ax2.text(5,
                      25,
                      '%.2f' %
                      self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                                      'timesRel'].values[0],
                      color='red')

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def checkConsistencyCellNames(self):
        ### check consistency of cell names
        tp = self.tp.value()

        # if no cells are labeled (currentCells df is empty), remove all labeled cells in the cellPosDF and return
        if len(self.currentCells) == 0:
            newCellPosDF = update_cell_pos_DF(self.currentCells,
                                              self.cellPosDF, tp)
            correctCellNames = True

        if len(self.currentCells) > 0:

            correctCellNames = check_cell_names(self.currentCells,
                                                self.cellNames)

            # if cells are not properly labeled, give a Warning
            if not correctCellNames:
                QtGui.QMessageBox.about(
                    self, 'Warning!', 'There is a mistake in the cell labels!')

            # else, update final cellPosDF and return OK
            else:
                newCellPosDF = update_cell_pos_DF(self.currentCells,
                                                  self.cellPosDF, tp)
                self.cellPosDF = newCellPosDF

        return correctCellNames

    def changeSpaceTime(self, whatToChange, increment):

        if whatToChange == 'time':

            # before changinf timepoint, print labeled cells and check if they are OK
            print(self.currentCells)

            # if they are OK (and not going to negative times), change timepoint
            if self.checkConsistencyCellNames() and (self.tp.value() +
                                                     increment) >= 0:
                self.tp.setValue(self.tp.value() + increment)

        if whatToChange == 'space':
            self.sl.setValue(self.sl.value() + increment)
Exemple #59
0
class AEViewer:
    def __init__(self):
        self.root = tk.Tk()
        self.root.wm_title("AEViewer")
        self.make_menu()

        frame = tk.Frame(self.root)
        frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.fig = Figure(figsize=(8,6), dpi=100)
        canvas = FigureCanvasTkAgg(self.fig, frame)
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(canvas, frame)

        canvas.mpl_connect('key_press_event', self.on_key_press)
        canvas.mpl_connect('scroll_event', self.on_scroll)
        
        self.progressbar = ttk.Progressbar(self.root, orient='horizontal', mode='determinate', )
        self.progressbar.pack(side=tk.BOTTOM, fill=tk.X)
        
        self.data = None
        self.root.update() # needed on windows for events to work

    def on_scroll(self, event):
        ax = event.inaxes
        if ax is None:
            return
    
        if event.key == 'shift':
            dir = {'up': -0.2, 'down': 0.2}[event.button]
            a,b = ax.viewLim.intervalx
            ax.set_xlim([a+dir*(b-a),
                         b+dir*(b-a)])
        else:
            scale = {'up': 0.8, 'down': 1.25}[event.button]
            x = event.xdata
            a,b = ax.viewLim.intervalx
            ax.set_xlim([x+scale*(a-x),
                         x+scale*(b-x)])
        ax.figure.canvas.draw()

    def on_key_press(self, event):
        if event.key == 'a' or event.key == "alt+a" and event.inaxes:
            ax = event.inaxes
            ax.relim()
            l = 1.1*max(abs(ax.dataLim.y0), abs(ax.dataLim.y1))
            ax.set_ylim(-l,l)
            ax.figure.canvas.draw()
        else:
            key_press_handler(event, event.canvas, self.toolbar)

    def progress(self, percent, time):
        self.progressbar["value"] = percent
        self.progressbar.update()

    def make_menu(self):
        menubar = tk.Menu(self.root)

        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Open", command=self.open)
        filemenu.add_command(label="Metadata", command=self.meta)
        filemenu.add_command(label="Save", command=self.save)
        filemenu.add_separator()
        filemenu.add_command(label="Quit", command=self.quit)
        menubar.add_cascade(label="File", menu=filemenu)

        menubar.add_command(label="Events", command=self.events)

        helpmenu = tk.Menu(menubar, tearoff=0)
        helpmenu.add_command(label="About", command=self.about)
        menubar.add_cascade(label="Help", menu=helpmenu)

        self.root.config(menu=menubar)


    def open(self, fname=None):
        
        self.fig.clf()
        try:
            self.data = ae.open(fname, parent=self.root)
            print "f = ae.open({!r})".format(self.data.fname)
        except ValueError:
            self.data = None
            return 
        self.data.progress = self.progress
        
        ax = self.fig.gca()
        for ch in range(self.data.channels):
            self.data.plot(channel=ch, label="ch#{}".format(ch), ax=ax)
        ae.xpan(ax=ax)
        ax.legend()
        ax.grid()
        ax.set_xlabel("time [{}]".format(self.data.timeunit))
        ax.set_ylabel("amplitude [{}]".format(self.data.dataunit))

    def quit(self):
        self.root.quit()     # stops mainloop
        self.root.destroy()  # this is necessary on Windows to prevent
                             # Fatal Python Error: PyEval_RestoreThread: NULL tstate
    
    def about(self):
        from ae.version import version
        tkMessageBox.showinfo("About AEViewer", "AEViewer {}\nCopyright © 2014 Jozef Vesely".format(version))

    def save(self):
        if self.data is None:
            return
        ax = self.fig.gca()
        start,end = ax.get_xlim()

        d = Dialog(self.root, "Save data", [
            ("Start [{}]:".format(self.data.timeunit), start),
            ("End [{}]:".format(self.data.timeunit), end),
            ("Channel:", 0),
            ("WAV Rate [1/{}]:".format(self.data.timeunit), int(1/self.data.timescale))
            ])
        if d.result is None:
            return
        
        fname = tkFileDialog.asksaveasfilename(parent=self.root, 
                    filetypes=[('Envelope', '.txt .dat'), ('WAV','.wav'), ('BDAT','.bdat')])
        if not fname:
            return 
        
        start, end, channel, rate = d.result

        if fname[-4:] in [".txt", ".dat"]:
            from numpy import savetxt, transpose
            x,y = self.data.resample( (start,end), channel=channel, num=10000)
            savetxt(fname, transpose([x,y]))

        elif fname[-4:] == ".wav":
            r = int(start/self.data.timescale), int(end/self.data.timescale)
            self.data.save_wav(fname, range=r, channel=channel, rate=rate)

        elif fname[-5:] == ".bdat":
            r = int(start/self.data.timescale), int(end/self.data.timescale)
            self.data.save_bdat(fname, range=r, channel=channel)


    def meta(self):
        if self.data is None:
            return 

        win = tk.Toplevel(self.root)
        win.wm_title("Metadata")

        text = tk.Text(win)
        text.insert(tk.END, str(self.data.meta))
        text.config(state=tk.DISABLED)
        text.pack(fill=tk.BOTH, expand=1)
 
    def events(self):
        if self.data is None:
            return
        
        _, samples = self.data.iter_blocks(stop=1000).next()
        thresh = samples.std()*self.data.datascale[0]*5
        from math import log10
        thresh = round(thresh,int(-log10(thresh)+2))
        
        d = Dialog(self.root, "Get Events", [
            ("Threshold [{}]:".format(self.data.dataunit), thresh),
            ("HDT [{}]:".format(self.data.timeunit), 0.001),
            ("Dead time [{}]:".format(self.data.timeunit), 0.001),
            ("Pre-trigger [{}]:".format(self.data.timeunit), 0.001),
            ("Channel:", 0),
            ("Limit [{}, 0=disabled]:".format(self.data.timeunit), 0.),
            ])

        if d.result is None:
            return
        print "e = f.get_events{}".format(tuple(d.result))
        events = self.data.get_events(*d.result)

        EventsTable(self.root, events)
Exemple #60
0
class Scene:
    """A virtual landscape for a volume rendering.

    The Scene class is meant to be the primary container for the
    new volume rendering framework. A single scene may contain
    several Camera and RenderSource instances, and is the primary
    driver behind creating a volume rendering.

    This sets up the basics needed to add sources and cameras.
    This does very little setup, and requires additional input
    to do anything useful.

    Parameters
    ----------
    None

    Examples
    --------

    This example shows how to create an empty scene and add a VolumeSource
    and a Camera.

    >>> import yt
    >>> from yt.visualization.volume_rendering.api import (
    ...     Camera, Scene, create_volume_source)
    >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
    >>> sc = Scene()
    >>> source = create_volume_source(ds.all_data(), "density")
    >>> sc.add_source(source)
    >>> cam = sc.add_camera()
    >>> im = sc.render()

    Alternatively, you can use the create_scene function to set up defaults
    and then modify the Scene later:

    >>> import yt
    >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

    >>> sc = yt.create_scene(ds)
    >>> # Modify camera, sources, etc...
    >>> im = sc.render()

    """

    _current = None
    _camera = None
    _unit_registry = None

    def __init__(self):
        r"""Create a new Scene instance"""
        super().__init__()
        self.sources = OrderedDict()
        self._last_render = None
        # A non-public attribute used to get around the fact that we can't
        # pass kwargs into _repr_png_()
        self._sigma_clip = None

    def get_source(self, source_num=0):
        """Returns the volume rendering source indexed by ``source_num``"""
        return list(self.sources.values())[source_num]

    def __getitem__(self, item):
        if item in self.sources:
            return self.sources[item]
        return self.get_source(item)

    @property
    def opaque_sources(self):
        """
        Iterate over opaque RenderSource objects,
        returning a tuple of (key, source)
        """
        for k, source in self.sources.items():
            if isinstance(source, OpaqueSource) or issubclass(
                    OpaqueSource, type(source)):
                yield k, source

    @property
    def transparent_sources(self):
        """
        Iterate over transparent RenderSource objects,
        returning a tuple of (key, source)
        """
        for k, source in self.sources.items():
            if not isinstance(source, OpaqueSource):
                yield k, source

    def add_source(self, render_source, keyname=None):
        """Add a render source to the scene.

        This will autodetect the type of source.

        Parameters
        ----------
        render_source:
            :class:`yt.visualization.volume_rendering.render_source.RenderSource`
            A source to contribute to the volume rendering scene.

        keyname: string (optional)
            The dictionary key used to reference the source in the sources
            dictionary.
        """
        if keyname is None:
            keyname = "source_%02i" % len(self.sources)

        data_sources = (VolumeSource, MeshSource, GridSource)

        if isinstance(render_source, data_sources):
            self._set_new_unit_registry(
                render_source.data_source.ds.unit_registry)

        line_annotation_sources = (GridSource, BoxSource,
                                   CoordinateVectorSource)

        if isinstance(render_source, line_annotation_sources):
            lens_str = str(self.camera.lens)
            if "fisheye" in lens_str or "spherical" in lens_str:
                raise NotImplementedError(
                    "Line annotation sources are not supported for %s." %
                    (type(self.camera.lens).__name__), )

        if isinstance(render_source, (LineSource, PointSource)):
            if isinstance(render_source.positions, YTArray):
                render_source.positions = (self.arr(
                    render_source.positions).in_units("code_length").d)

        self.sources[keyname] = render_source

        return self

    def __setitem__(self, key, value):
        return self.add_source(value, key)

    def _set_new_unit_registry(self, input_registry):
        self.unit_registry = UnitRegistry(add_default_symbols=False,
                                          lut=input_registry.lut)

        # Validate that the new unit registry makes sense
        current_scaling = self.unit_registry["unitary"][0]
        if current_scaling != input_registry["unitary"][0]:
            for source in self.sources.items():
                data_source = getattr(source, "data_source", None)
                if data_source is None:
                    continue
                scaling = data_source.ds.unit_registry["unitary"][0]
                if scaling != current_scaling:
                    raise NotImplementedError(
                        "Simultaneously rendering data from datasets with "
                        "different units is not supported")

    def render(self, camera=None):
        r"""Render all sources in the Scene.

        Use the current state of the Scene object to render all sources
        currently in the scene.  Returns the image array.  If you want to
        save the output to a file, call the save() function.

        Parameters
        ----------
        camera: :class:`Camera`, optional
            If specified, use a different :class:`Camera` to render the scene.

        Returns
        -------
        A :class:`yt.data_objects.image_array.ImageArray` instance containing
        the current rendering image.

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> # Modify camera, sources, etc...
        >>> im = sc.render()
        >>> sc.save(sigma_clip=4.0, render=False)

        Altneratively, if you do not need the image array, you can just call
        ``save`` as follows.

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> # Modify camera, sources, etc...
        >>> sc.save(sigma_clip=4.0)

        """
        mylog.info("Rendering scene (Can take a while).")
        if camera is None:
            camera = self.camera
        assert camera is not None
        self._validate()
        bmp = self.composite(camera=camera)
        self._last_render = bmp
        return bmp

    def _render_on_demand(self, render):
        # checks for existing render before rendering, in most cases we want to
        # render every time, but in some cases pulling the previous render is
        # desirable (e.g., if only changing sigma_clip or
        # saving after a call to sc.show()).

        if self._last_render is not None and not render:
            mylog.info("Found previously rendered image to save.")
            return

        if self._last_render is None:
            mylog.warning("No previously rendered image found, rendering now.")
        elif render:
            mylog.warning(
                "Previously rendered image exists, but rendering anyway. "
                "Supply 'render=False' to save previously rendered image directly."
            )
        self.render()

    def _get_render_sources(self):
        return [
            s for s in self.sources.values() if isinstance(s, RenderSource)
        ]

    def _setup_save(self, fname, render):

        self._render_on_demand(render)

        rensources = self._get_render_sources()
        if fname is None:
            # if a volume source present, use its affiliated ds for fname
            if len(rensources) > 0:
                rs = rensources[0]
                basename = rs.data_source.ds.basename
                if isinstance(rs.field, str):
                    field = rs.field
                else:
                    field = rs.field[-1]
                fname = f"{basename}_Render_{field}"
            # if no volume source present, use a default filename
            else:
                fname = "Render_opaque"

        fname = validate_image_name(fname)
        mylog.info("Saving rendered image to %s", fname)
        return fname

    def save(self, fname=None, sigma_clip=None, render=True):
        r"""Saves a rendered image of the Scene to disk.

        Once you have created a scene, this saves an image array to disk with
        an optional filename. This function calls render() to generate an
        image array, unless the render parameter is set to False, in which case
        the most recently rendered scene is used if it exists.

        Parameters
        ----------
        fname: string, optional
            If specified, save the rendering as to the file "fname".
            If unspecified, it creates a default based on the dataset filename.
            The file format is inferred from the filename's suffix. Supported
            fomats are png, pdf, eps, and ps.
            Default: None
        sigma_clip: float, optional
            Image values greater than this number times the standard deviation
            plus the mean of the image will be clipped before saving. Useful
            for enhancing images as it gets rid of rare high pixel values.
            Default: None

            floor(vals > std_dev*sigma_clip + mean)
        render: boolean, optional
            If True, will always render the scene before saving.
            If False, will use results of previous render if it exists.
            Default: True

        Returns
        -------
            Nothing

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> # Modify camera, sources, etc...
        >>> sc.save("test.png", sigma_clip=4)

        When saving multiple images without modifying the scene (camera,
        sources,etc.), render=False can be used to avoid re-rendering.
        This is useful for generating images at a range of sigma_clip values:

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> # save with different sigma clipping values
        >>> sc.save("raw.png")  # The initial render call happens here
        >>> sc.save("clipped_2.png", sigma_clip=2, render=False)
        >>> sc.save("clipped_4.png", sigma_clip=4, render=False)

        """
        fname = self._setup_save(fname, render)

        # We can render pngs natively but for other formats we defer to
        # matplotlib.
        if fname.endswith(".png"):
            self._last_render.write_png(fname, sigma_clip=sigma_clip)
        else:
            from matplotlib.figure import Figure

            shape = self._last_render.shape
            fig = Figure((shape[0] / 100.0, shape[1] / 100.0))
            canvas = get_canvas(fig, fname)

            ax = fig.add_axes([0, 0, 1, 1])
            ax.set_axis_off()
            out = self._last_render
            nz = out[:, :, :3][out[:, :, :3].nonzero()]
            max_val = nz.mean() + sigma_clip * nz.std()
            alpha = 255 * out[:, :, 3].astype("uint8")
            out = np.clip(out[:, :, :3] / max_val, 0.0, 1.0) * 255
            out = np.concatenate([out.astype("uint8"), alpha[..., None]],
                                 axis=-1)
            # not sure why we need rot90, but this makes the orientation
            # match the png writer
            ax.imshow(np.rot90(out), origin="lower")
            canvas.print_figure(fname, dpi=100)

    def save_annotated(
        self,
        fname=None,
        label_fmt=None,
        text_annotate=None,
        dpi=100,
        sigma_clip=None,
        render=True,
    ):
        r"""Saves the most recently rendered image of the Scene to disk,
        including an image of the transfer function and and user-defined
        text.

        Once you have created a scene and rendered that scene to an image
        array, this saves that image array to disk with an optional filename.
        If an image has not yet been rendered for the current scene object,
        it forces one and writes it out.

        Parameters
        ----------
        fname: string, optional
            If specified, save the rendering as a bitmap to the file "fname".
            If unspecified, it creates a default based on the dataset filename.
            Default: None
        sigma_clip: float, optional
            Image values greater than this number times the standard deviation
            plus the mean of the image will be clipped before saving. Useful
            for enhancing images as it gets rid of rare high pixel values.
            Default: None

            floor(vals > std_dev*sigma_clip + mean)
        dpi: integer, optional
            By default, the resulting image will be the same size as the camera
            parameters.  If you supply a dpi, then the image will be scaled
            accordingly (from the default 100 dpi)
        label_fmt : str, optional
           A format specifier (e.g., label_fmt="%.2g") to use in formatting
           the data values that label the transfer function colorbar.
        text_annotate : list of iterables
           Any text that you wish to display on the image.  This should be an
           list containing a tuple of coordinates (in normalized figure
           coordinates), the text to display, and, optionally, a dictionary of
           keyword/value pairs to pass through to the matplotlib text()
           function.

           Each item in the main list is a separate string to write.
        render: boolean, optional
            If True, will render the scene before saving.
            If False, will use results of previous render if it exists.
            Default: True

        Returns
        -------
            Nothing


        Examples
        --------

        >>> sc.save_annotated(
        ...     "fig.png",
        ...     text_annotate=[
        ...         [
        ...             (0.05, 0.05),
        ...             f"t = {ds.current_time.d}",
        ...             dict(horizontalalignment="left"),
        ...         ],
        ...         [
        ...             (0.5, 0.95),
        ...             "simulation title",
        ...             dict(color="y", fontsize="24", horizontalalignment="center"),
        ...         ],
        ...     ],
        ... )

        """
        fname = self._setup_save(fname, render)

        # which transfer function?
        rs = self._get_render_sources()[0]
        tf = rs.transfer_function
        label = rs.data_source.ds._get_field_info(rs.field).get_label()

        ax = self._show_mpl(self._last_render.swapaxes(0, 1),
                            sigma_clip=sigma_clip,
                            dpi=dpi)
        self._annotate(ax.axes, tf, rs, label=label, label_fmt=label_fmt)

        # any text?
        if text_annotate is not None:
            f = self._render_figure
            for t in text_annotate:
                xy = t[0]
                string = t[1]
                if len(t) == 3:
                    opt = t[2]
                else:
                    opt = dict()

                # sane default
                if "color" not in opt:
                    opt["color"] = "w"

                ax.axes.text(xy[0],
                             xy[1],
                             string,
                             transform=f.transFigure,
                             **opt)

        self._render_figure.canvas = get_canvas(self._render_figure, fname)
        self._render_figure.tight_layout()
        self._render_figure.savefig(fname, facecolor="black", pad_inches=0)

    def _show_mpl(self, im, sigma_clip=None, dpi=100):
        from matplotlib.figure import Figure

        s = im.shape
        self._render_figure = Figure(figsize=(s[1] / float(dpi),
                                              s[0] / float(dpi)))
        self._render_figure.clf()
        ax = self._render_figure.add_subplot(111)
        ax.set_position([0, 0, 1, 1])

        if sigma_clip is not None:
            nz = im[im > 0.0]
            nim = im / (nz.mean() + sigma_clip * np.std(nz))
            nim[nim > 1.0] = 1.0
            nim[nim < 0.0] = 0.0
            del nz
        else:
            nim = im
        axim = ax.imshow(nim[:, :, :3] / nim[:, :, :3].max(),
                         interpolation="bilinear")

        return axim

    def _annotate(self, ax, tf, source, label="", label_fmt=None):
        ax.get_xaxis().set_visible(False)
        ax.get_xaxis().set_ticks([])
        ax.get_yaxis().set_visible(False)
        ax.get_yaxis().set_ticks([])
        cb = self._render_figure.colorbar(ax.images[0],
                                          pad=0.0,
                                          fraction=0.05,
                                          drawedges=True)
        tf.vert_cbar(
            ax=cb.ax,
            label=label,
            label_fmt=label_fmt,
            resolution=self.camera.resolution[0],
            log_scale=source.log_field,
        )

    def _validate(self):
        r"""Validate the current state of the scene."""

        for source in self.sources.values():
            source._validate()
        return

    def composite(self, camera=None):
        r"""Create a composite image of the current scene.

        First iterate over the opaque sources and set the ZBuffer.
        Then iterate over the transparent sources, rendering from the value
        of the zbuffer to the front of the box. Typically this function is
        accessed through the .render() command.

        Parameters
        ----------
        camera: :class:`Camera`, optional
            If specified, use a specific :class:`Camera` to render the scene.

        Returns
        -------
        im: :class:`ImageArray`
            ImageArray instance of the current rendering image.

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> # Modify camera, sources, etc...
        >>> im = sc.composite()

        """
        if camera is None:
            camera = self.camera
        empty = camera.lens.new_image(camera)
        opaque = ZBuffer(empty, np.full(empty.shape[:2], np.inf))

        for _, source in self.opaque_sources:
            source.render(camera, zbuffer=opaque)
            im = source.zbuffer.rgba

        for _, source in self.transparent_sources:
            im = source.render(camera, zbuffer=opaque)
            opaque.rgba = im

        # rotate image 180 degrees so orientation agrees with e.g.
        # a PlotWindow plot
        return np.rot90(im, k=2)

    def add_camera(self,
                   data_source=None,
                   lens_type="plane-parallel",
                   auto=False):
        r"""Add a new camera to the Scene.

        The camera is defined by a position (the location of the camera
        in the simulation domain,), a focus (the point at which the
        camera is pointed), a width (the width of the snapshot that will
        be taken, a resolution (the number of pixels in the image), and
        a north_vector (the "up" direction in the resulting image). A
        camera can use a variety of different Lens objects.

        If the scene already has a camera associated with it, this function
        will create a new camera and discard the old one.

        Parameters
        ----------
        data_source: :class:`AMR3DData` or :class:`Dataset`, optional
            This is the source to be rendered, which can be any arbitrary yt
            data object or dataset.
        lens_type: string, optional
            This specifies the type of lens to use for rendering. Current
            options are 'plane-parallel', 'perspective', and 'fisheye'. See
            :class:`yt.visualization.volume_rendering.lens.Lens` for details.
            Default: 'plane-parallel'
        auto: boolean
            If True, build smart defaults using the data source extent. This
            can be time-consuming to iterate over the entire dataset to find
            the positional bounds. Default: False

        Examples
        --------

        In this example, the camera is set using defaults that are chosen
        to be reasonable for the argument Dataset.

        >>> import yt
        >>> from yt.visualization.volume_rendering.api import Camera, Scene
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
        >>> sc = Scene()
        >>> sc.add_camera()

        Here, we set the camera properties manually:

        >>> import yt
        >>> from yt.visualization.volume_rendering.api import Camera, Scene
        >>> sc = Scene()
        >>> cam = sc.add_camera()
        >>> cam.position = np.array([0.5, 0.5, -1.0])
        >>> cam.focus = np.array([0.5, 0.5, 0.0])
        >>> cam.north_vector = np.array([1.0, 0.0, 0.0])

        Finally, we create a camera with a non-default lens:

        >>> import yt
        >>> from yt.visualization.volume_rendering.api import Camera
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
        >>> sc = Scene()
        >>> sc.add_camera(ds, lens_type="perspective")

        """
        self._camera = Camera(self, data_source, lens_type, auto)
        return self.camera

    def camera():
        doc = r"""The camera property.

        This is the default camera that will be used when rendering. Can be set
        manually, but Camera type will be checked for validity.
        """

        def fget(self):
            return self._camera

        def fset(self, value):
            value.width = self.arr(value.width)
            value.focus = self.arr(value.focus)
            value.position = self.arr(value.position)
            self._camera = value

        def fdel(self):
            del self._camera
            self._camera = None

        return locals()

    camera = property(**camera())

    def unit_registry():
        def fget(self):
            ur = self._unit_registry
            if ur is None:
                ur = UnitRegistry()
                # This will be updated when we add a volume source
                ur.add("unitary", 1.0, length)
            self._unit_registry = ur
            return self._unit_registry

        def fset(self, value):
            self._unit_registry = value
            if self.camera is not None:
                self.camera.width = YTArray(
                    self.camera.width.in_units("unitary"), registry=value)
                self.camera.focus = YTArray(
                    self.camera.focus.in_units("unitary"), registry=value)
                self.camera.position = YTArray(
                    self.camera.position.in_units("unitary"), registry=value)

        def fdel(self):
            del self._unit_registry
            self._unit_registry = None

        return locals()

    unit_registry = property(**unit_registry())

    def set_camera(self, camera):
        r"""

        Set the camera to be used by this scene.

        """
        self.camera = camera

    def get_camera(self):
        r"""

        Get the camera currently used by this scene.

        """
        return self.camera

    def annotate_domain(self, ds, color=None):
        r"""

        Modifies this scene by drawing the edges of the computational domain.
        This adds a new BoxSource to the scene corresponding to the domain
        boundaries and returns the modified scene object.

        Parameters
        ----------

        ds : :class:`yt.data_objects.static_output.Dataset`
            This is the dataset object corresponding to the
            simulation being rendered. Used to get the domain bounds.
        color : array_like of shape (4,), optional
            The RGBA value to use to draw the domain boundaries.
            Default is black with an alpha of 1.0.

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> sc.annotate_domain(ds)
        >>> im = sc.render()

        """
        box_source = BoxSource(ds.domain_left_edge,
                               ds.domain_right_edge,
                               color=color)
        self.add_source(box_source)
        return self

    def annotate_grids(self,
                       data_source,
                       alpha=0.3,
                       cmap=None,
                       min_level=None,
                       max_level=None):
        r"""

        Modifies this scene by drawing the edges of the AMR grids.
        This adds a new GridSource to the scene that represents the AMR grid
        and returns the resulting Scene object.

        Parameters
        ----------

        data_source: :class:`~yt.data_objects.api.DataContainer`
            The data container that will be used to identify grids to draw.
        alpha : float
            The opacity of the grids to draw.
        cmap : color map name
            The color map to use to map resolution levels to color.
        min_level : int, optional
            Minimum level to draw
        max_level : int, optional
            Maximum level to draw


        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> sc.annotate_grids(ds.all_data())
        >>> im = sc.render()

        """
        if cmap is None:
            cmap = ytcfg.get("yt", "default_colormap")
        grids = GridSource(
            data_source,
            alpha=alpha,
            cmap=cmap,
            min_level=min_level,
            max_level=max_level,
        )
        self.add_source(grids)
        return self

    def annotate_mesh_lines(self, color=None, alpha=1.0):
        """

        Modifies this Scene by drawing the mesh line boundaries
        on all MeshSources.

        Parameters
        ----------
        color : array_like of shape (4,), optional
            The RGBA value to use to draw the mesh lines.
            Default is black with an alpha of 1.0.
        alpha : float, optional
            The opacity of the mesh lines. Default is 255 (solid).

        """
        for _, source in self.opaque_sources:
            if isinstance(source, MeshSource):
                source.annotate_mesh_lines(color=color, alpha=alpha)
        return self

    def annotate_axes(self, colors=None, alpha=1.0):
        r"""

        Modifies this scene by drawing the coordinate axes.
        This adds a new CoordinateVectorSource to the scene
        and returns the modified scene object.

        Parameters
        ----------
        colors: array-like of shape (3,4), optional
            The RGBA values to use to draw the x, y, and z vectors. The default
            is  [[1, 0, 0, alpha], [0, 1, 0, alpha], [0, 0, 1, alpha]] where
            ``alpha`` is set by the parameter below. If ``colors`` is set then
            ``alpha`` is ignored.
        alpha : float, optional
            The opacity of the vectors.

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> sc.annotate_axes(alpha=0.5)
        >>> im = sc.render()

        """
        coords = CoordinateVectorSource(colors, alpha)
        self.add_source(coords)
        return self

    def show(self, sigma_clip=None):
        r"""This will send the most recently rendered image to the IPython
        notebook.

        If yt is being run from within an IPython session, and it is able to
        determine this, this function will send the current image of this Scene
        to the notebook for display. If there is no current image, it will
        run the render() method on this Scene before sending the result to the
        notebook.

        If yt can't determine if it's inside an IPython session, this will raise
        YTNotInsideNotebook.

        Examples
        --------

        >>> import yt
        >>> ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

        >>> sc = yt.create_scene(ds)
        >>> sc.show()

        """
        if "__IPYTHON__" in dir(builtins):
            from IPython.display import display

            self._sigma_clip = sigma_clip
            display(self)
        else:
            raise YTNotInsideNotebook

    _arr = None

    @property
    def arr(self):
        """Converts an array into a :class:`yt.units.yt_array.YTArray`

        The returned YTArray will be dimensionless by default, but can be
        cast to arbitrary units using the ``units`` keyword argument.

        Parameters
        ----------

        input_array : Iterable
            A tuple, list, or array to attach units to
        units: String unit specification, unit symbol object, or astropy
            units object
        input_units : deprecated in favor of 'units'
            The units of the array. Powers must be specified using python syntax
            (cm**3, not cm^3).
        dtype : string or NumPy dtype object
            The dtype of the returned array data

        Examples
        --------

        >>> a = sc.arr([1, 2, 3], "cm")
        >>> b = sc.arr([4, 5, 6], "m")
        >>> a + b
        YTArray([ 401.,  502.,  603.]) cm
        >>> b + a
        YTArray([ 4.01,  5.02,  6.03]) m

        Arrays returned by this function know about the scene's unit system

        >>> a = sc.arr(np.ones(5), "unitary")
        >>> a.in_units("Mpc")
        YTArray([ 1.00010449,  1.00010449,  1.00010449,  1.00010449,
                 1.00010449]) Mpc

        """
        if self._arr is not None:
            return self._arr
        self._arr = functools.partial(YTArray, registry=self.unit_registry)
        return self._arr

    _quan = None

    @property
    def quan(self):
        """Converts an scalar into a :class:`yt.units.yt_array.YTQuantity`

        The returned YTQuantity will be dimensionless by default, but can be
        cast to arbitrary units using the ``units`` keyword argument.

        Parameters
        ----------

        input_scalar : an integer or floating point scalar
            The scalar to attach units to
        units : String unit specification, unit symbol object, or astropy
            units
        input_units : deprecated in favor of 'units'
            The units of the quantity. Powers must be specified using python
            syntax (cm**3, not cm^3).
        dtype : string or NumPy dtype object
            The dtype of the array data.

        Examples
        --------

        >>> a = sc.quan(1, "cm")
        >>> b = sc.quan(2, "m")
        >>> a + b
        201.0 cm
        >>> b + a
        2.01 m

        Quantities created this way automatically know about the unit system
        of the scene

        >>> a = ds.quan(5, "unitary")
        >>> a.in_cgs()
        1.543e+25 cm

        """
        if self._quan is not None:
            return self._quan
        self._quan = functools.partial(YTQuantity, registry=self.unit_registry)
        return self._quan

    def _repr_png_(self):
        if self._last_render is None:
            self.render()
        png = self._last_render.write_png(filename=None,
                                          sigma_clip=self._sigma_clip,
                                          background="black")
        self._sigma_clip = None
        return png

    def __repr__(self):
        disp = "<Scene Object>:"
        disp += "\nSources: \n"
        for k, v in self.sources.items():
            disp += f"    {k}: {v}\n"
        disp += "Camera: \n"
        disp += f"    {self.camera}"
        return disp