from collections import deque import random import wx import numpy as np import epics from datetime import datetime from slic.gui.widgets import LabeledMathEntry from slic.gui.widgets import make_filled_hbox, make_filled_vbox, EXPANDING from slic.gui.widgets.plotting import PlotPanel from bstrd import BS, bsstream # config nshots = 1000 x_axis=np.arange(0,100,0.05) quantile = 0.9 # channels ch_xpos = 'SAROP11-PBPS122:XPOS' ch_ypos = 'SAROP11-PBPS122:YPOS' ch_intensity = 'SAROP11-PBPS122:INTENSITY' bs_xpos = BS(ch_xpos) bs_ypos = BS(ch_ypos) bs_intensity = BS(ch_intensity) iso_format = "%Y-%m-%d %H:%M:%S" def filter_outliers(quantile, a): low = np.nanquantile(a, 0.5 - quantile/2) high = np.nanquantile(a, 0.5 + quantile/2) cond_low = a > low cond_high = a < high cond = cond_low & cond_high return a[cond] class MainPanel(wx.Panel): def __init__(self, parent): super().__init__(parent) self.x = np.empty(nshots) self.y = np.empty(nshots) self.powerx50Hztimeseries = deque(maxlen=1000) self.powerxlowfreqtimeseries = deque(maxlen=1000) self.powerxtrainfrequencies = deque(maxlen=1000) self.powerx33hz = deque(maxlen=1000) self.plot_xy = plot_xy = PlotPanel(self, figsize=(6,2)) self.plot_fft = plot_fft = PlotPanel(self, figsize=(6,2)) self.plot_timeseries = plot_timeseries = PlotPanel(self, figsize=(6,2)) plots1 = (plot_xy, plot_fft, plot_timeseries) vb_plots1 = make_filled_vbox(plots1) widgets = (vb_plots1,) box = make_filled_vbox(widgets, border=1) self.SetSizerAndFit(box) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_update, self.timer) self.timer.Start(100) def on_update(self, _event): self.time = datetime.now().strftime(iso_format) self.x = np.empty(nshots) self.y = np.empty(nshots) for i in range(nshots): tempa = bs_xpos.get() self.x[i] = tempa tempb = bs_ypos.get() self.y[i] = tempb next(bsstream) wx.GetApp().Yield() self.x = filter_outliers(quantile, self.x) self.y = filter_outliers(quantile, self.y) if (len(np.asarray(self.x)) > 1): self.valsdiode = np.hstack((self.x-np.mean(self.x), np.zeros_like(self.x))) self.vals2diode = np.hstack((self.y - np.mean(self.y), np.zeros_like(self.y))) self.powerx = np.abs(np.fft.fft(self.valsdiode))**2 self.powery = np.abs(np.fft.fft(self.vals2diode))**2 self.powerxlowfreqtimeseries.append(np.sum(self.powerx[0:200])) self.powerx50Hztimeseries.append(np.sum(self.powerx[900:1100])) self.powerxtrainfrequencies.append(np.sum(self.powerx[250:400])) else: print("{} Where are my X-rays?".format(self.time)) self.draw_plot() def draw_plot(self): self.plot_xy.clear() self.plot_fft.clear() self.plot_timeseries.clear() self.plot_xy.set_xlabel('shots at 100 Hz') self.plot_xy.set_ylabel('position in mm') self.plot_xy.set_xlim(0,min(len(self.x),len(self.y))) self.plot_xy.grid(True, linestyle='--') self.plot_xy.plot(self.valsdiode + 0.05) self.plot_xy.plot(self.vals2diode - 0.05) self.plot_fft.set_xlabel('frequency, Hz') self.plot_fft.set_ylabel('power, a.u.') self.plot_fft.set_xlim(0,55) self.plot_fft.grid(True, linestyle='--') self.plot_fft.axhline(y=-5, xmin=0, xmax=0.175, color='r') self.plot_fft.axhline(y=-5, xmin=0.8, xmax=1, color='k') self.plot_fft.axhline(y=-5, xmin=0.25, xmax=0.35, color='g') x_axis1=np.linspace(0,100,len(self.powerx)) x_axis2=np.linspace(0,100,len(self.powery)) self.plot_fft.plot(x_axis1, self.powerx) self.plot_fft.plot(x_axis2, self.powery) self.plot_timeseries.set_xlabel('time ago, a.u.') self.plot_timeseries.set_ylabel('power, a.u.') self.plot_timeseries.set_ylim(0, 2000) self.plot_timeseries.grid(True, linestyle='--') self.plot_timeseries.plot(self.powerxlowfreqtimeseries, color='r') self.plot_timeseries.plot(self.powerx50Hztimeseries, color='k') self.plot_timeseries.plot(self.powerxtrainfrequencies, color='g') self.plot_xy.draw() self.plot_fft.draw() self.plot_timeseries.draw()