0
0
forked from SwissFEL/c365
Files
c365/panel_pbps110.py
Claudio Cirelli 57c5012e45 change permissions
2026-02-20 15:16:38 +01:00

210 lines
7.8 KiB
Python
Executable File

from collections import deque
import random
import wx
import numpy as np
import epics
from datetime import datetime
#from epics.wx import MotorPanel
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 = 100
qlength = 100
histlength = 100
quantile = 0.8
# channels
chname_pbpsint = "SAROP11-PBPS110:INTENSITY"
chname_pbpsx = "SAROP11-PBPS110:XPOS"
chname_pbpsy = "SAROP11-PBPS110:YPOS"
chname_events = "SAR-CVME-TIFALL4:EvtSet"
# create channels
ch_int = BS(chname_pbpsint)
ch_x = BS(chname_pbpsx)
ch_y = BS(chname_pbpsy)
ch_events = BS(chname_events)
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.evts = np.empty((nshots,256))
self.int = np.empty(nshots)
self.x = np.empty(nshots)
self.y = np.empty(nshots)
self.ints = deque(maxlen=qlength)
self.intstds = deque(maxlen=qlength)
self.inthist = deque(maxlen=histlength)
self.xs = deque(maxlen=qlength)
self.xstds = deque(maxlen=qlength)
self.xhist = deque(maxlen=histlength)
self.ys = deque(maxlen=qlength)
self.ystds = deque(maxlen=qlength)
self.yhist = deque(maxlen=histlength)
self.plot_ints = plot_ints = PlotPanel(self, figsize=(6,3))
self.plot_histI = plot_histI = PlotPanel(self, figsize=(2,3))
self.plot_posXs = plot_posXs = PlotPanel(self, figsize=(6,3))
self.plot_histX = plot_histX = PlotPanel(self, figsize=(2,3))
self.plot_posYs = plot_posYs = PlotPanel(self, figsize=(6,3))
self.plot_histY = plot_histY = PlotPanel(self, figsize=(2,3))
plots1 = (plot_ints, plot_histI)
plots2 = (plot_posXs, plot_histX)
plots3 = (plot_posYs, plot_histY)
hb_plot1 = make_filled_hbox(plots1)
hb_plot2 = make_filled_hbox(plots2)
hb_plot3 = make_filled_hbox(plots3)
btn_clearQ = wx.Button(self, label="Clear plots")
btns = (btn_clearQ,)
hb_btns = make_filled_hbox(btns)
widgets = (hb_plot1, hb_plot2, hb_plot3, hb_btns)
box = make_filled_vbox(widgets, border=1)
self.SetSizerAndFit(box)
btn_clearQ.Bind(wx.EVT_BUTTON, self.on_click_clearQ)
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.evts = np.empty((nshots,256))
self.int = np.empty(nshots, dtype=object)
self.x = np.empty(nshots, dtype=object)
self.y = np.empty(nshots, dtype=object)
for i in range(nshots):
tempa = ch_events.get()
self.evts[i] = tempa
tempb = ch_int.get()
self.int[i] = tempb
tempc = ch_x.get()
self.x[i] = tempc
tempd = ch_y.get()
self.y[i] = tempd
next(bsstream)
wx.GetApp().Yield()
self.x = filter_outliers(quantile, self.x)
self.y = filter_outliers(quantile, self.y)
self.ints.append(np.mean(self.int))
self.intstds.append(np.std(self.int))
self.xs.append(np.mean(self.x))
self.xstds.append(np.std(self.x))
self.ys.append(np.mean(self.y))
self.ystds.append(np.std(self.y))
self.inthist.extend(self.int)
self.xhist.extend(self.x)
self.yhist.extend(self.y)
self.draw_plot()
def draw_plot(self):
self.plot_ints.clear()
self.plot_histI.clear()
self.plot_posXs.clear()
self.plot_histX.clear()
self.plot_posYs.clear()
self.plot_histY.clear()
self.plot_ints.set_xlabel('time ago, a.u.')
self.plot_ints.set_ylabel('intensity, a.u.')
self.plot_histI.set_xlabel('intensity, a.u.')
self.plot_histI.set_xlim(-0.1, 3)
self.plot_posXs.set_xlabel('time ago, a.u.')
self.plot_posXs.set_ylabel('position X, mm')
self.plot_histX.set_xlabel('position X, mm')
self.plot_histX.set_xlim(-0.2, 0.2)
self.plot_posYs.set_xlabel('time ago, a.u.')
self.plot_posYs.set_ylabel('position Y, mm')
self.plot_histY.set_xlabel('position Y, mm')
self.plot_histY.set_xlim(-0.2, 0.2)
self.plot_ints.fill_between(np.arange(0, len(self.ints)), np.asarray(self.intstds)+np.asarray(self.ints), -np.asarray(self.intstds)+np.asarray(self.ints), color='gold')
self.plot_ints.plot(np.arange(0, len(self.ints)), self.ints, '-', color='orangered')
self.plot_ints.axhline(y=1, color='k', linestyle="--")
self.plot_posXs.fill_between(np.arange(0, len(self.xs)), np.asarray(self.xstds)+np.asarray(self.xs), -np.asarray(self.xstds)+np.asarray(self.xs), color='lightskyblue')
self.plot_posXs.plot(np.arange(0, len(self.xs)), self.xs, '-', color='dodgerblue')
self.plot_posXs.axhline(y=0, color='k', linestyle="--")
self.plot_posYs.fill_between(np.arange(0, len(self.ys)), np.asarray(self.ystds)+np.asarray(self.ys), -np.asarray(self.ystds)+np.asarray(self.ys), color='lightgreen')
self.plot_posYs.plot(np.arange(0, len(self.ys)), self.ys, '-', color='green')
self.plot_posYs.axhline(y=0, color='k', linestyle="--")
#if (len(self.int) > 0):
#self.plot_histI.hist(self.int, facecolor='orangered')#, edgecolor='black')
#self.plot_histI.hist(np.ravel(self.inthist), facecolor='orangered', edgecolor='black')
self.inthist2plot = np.array(self.inthist, dtype=object)
self.xhist2plot = np.array(self.xhist, dtype=object)
self.yhist2plot = np.array(self.yhist, dtype=object)
self.plot_histI.hist(np.ravel(self.inthist2plot), facecolor='orangered', edgecolor='black')
self.plot_histI.axvline(x=np.mean(self.inthist), color='k', linestyle="--")
self.plot_histI.set_title('Intensity: {:.4f} a.u.'.format(np.mean(np.ravel(self.inthist2plot))))
#self.plot_histX.hist(np.ravel(self.xhist), facecolor='dodgerblue', edgecolor='black')
self.plot_histX.hist(np.ravel(self.xhist2plot), facecolor='dodgerblue', edgecolor='black')
self.plot_histX.set_title('Position X: {:.2f} +/- {:.2f} um'.format(np.mean(np.ravel(self.xhist2plot))*1000, np.std(self.xhist)*1000))
self.plot_histX.axvline(x=np.mean(self.xhist), color='k', linestyle="--")
#self.plot_histY.hist(np.ravel(self.yhist), facecolor='green', edgecolor='black')
self.plot_histY.hist(np.ravel(self.yhist2plot), facecolor='green', edgecolor='black')
self.plot_histY.set_title('Position Y: {:.2f} +/- {:.2f} um'.format(np.mean(np.ravel(self.yhist2plot))*1000, np.std(self.yhist)*1000))
self.plot_histY.axvline(x=np.mean(self.yhist), color='k', linestyle="--")
self.plot_ints.draw()
self.plot_posXs.draw()
self.plot_posYs.draw()
self.plot_histI.draw()
self.plot_histX.draw()
self.plot_histY.draw()
print ('{} -- X = {:.2f} -- Y = {:.2f} -- Int = {:.4f}'.format(self.time, np.mean(np.ravel(self.xhist2plot))*1000, np.mean(np.ravel(self.yhist2plot))*1000, np.mean(np.ravel(self.inthist2plot))))
def on_click_clearQ(self, _event):
self.ints.clear()
self.intstds.clear()
self.xs.clear()
self.xstds.clear()
self.ys.clear()
self.ystds.clear()