From 3ec305496851a7779decf7c4ebfddabebfaeb64c Mon Sep 17 00:00:00 2001 From: gac-alvra Date: Fri, 13 Feb 2026 18:02:14 +0100 Subject: [PATCH] switched diode, added title (to easily see which diode) --- panel_ppPrime.py | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 panel_ppPrime.py diff --git a/panel_ppPrime.py b/panel_ppPrime.py new file mode 100644 index 0000000..aa84266 --- /dev/null +++ b/panel_ppPrime.py @@ -0,0 +1,164 @@ +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 + +def unpumped(events, *arrays): + laser = events[:, 18] + darkShot = events[:, 21] + background_shots = np.logical_and.reduce((laser, darkShot)) + return [a[background_shots] for a in arrays] + +def pumped(events, *arrays): + fel = events[:, 13] + laser = events[:, 18] + darkShot = events[:, 21] + pumped_shots = np.logical_and.reduce((laser, np.logical_not(darkShot))) + return [a[pumped_shots] for a in arrays] + + +# config +nshots = 50 +qlength = 100 + +# channels + +#chname_diode = "SARES11-GES1:PR1_CH2_VAL_GET" #Prime Keysight CH2 +chname_diode = "SARES11-GES1:PR1_CH1_VAL_GET" #Prime Keysight CH1 +#chname_diode = "SARES12-GES1:PR1_CH1_VAL_GET" #Flex Keysight +#chname_diode = "SLAAR11-LSCP1-FNS:CH0:VAL_GET" #Laser IoXos + +chname_i0 = "SAROP11-PBPS122:INTENSITY" +chname_events = "SAR-CVME-TIFALL4:EvtSet" + +# create channels +ch_diode = BS(chname_diode) +ch_i0 = BS(chname_i0) +ch_events = BS(chname_events) + +iso_format = "%Y-%m-%d %H:%M:%S" + +class MainPanel(wx.Panel): + + def __init__(self, parent): + super().__init__(parent) + + self.evts = np.empty((nshots,256)) + self.diode = np.empty(nshots) + self.i0 = np.empty(nshots) + self.diode_p_norm = np.empty(nshots) + self.diode_u_norm = np.empty(nshots) + + self.diodes_p = deque(maxlen=qlength) + self.diodes_pstd = deque(maxlen=qlength) + self.diodes_u = deque(maxlen=qlength) + self.diodes_ustd = deque(maxlen=qlength) + self.pp = deque(maxlen=qlength) + self.ppstd = deque(maxlen=qlength) + + self.plot_diodes = plot_diodes = PlotPanel(self, figsize=(6,3)) + self.plot_pp = plot_pp = PlotPanel(self, figsize=(6,3)) + + plots1 = (plot_diodes,) + plots2 = (plot_pp,) + + hb_plot1 = make_filled_hbox(plots1) + hb_plot2 = make_filled_hbox(plots2) + + btn_clearQ = wx.Button(self, label="Clear plots") + btns = (btn_clearQ,) + hb_btns = make_filled_hbox(btns) + + widgets = (hb_plot1, hb_plot2, 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.diode = np.empty(nshots) + self.i0 = np.empty(nshots) + + for i in range(nshots): + tempa = ch_events.get() + self.evts[i] = tempa + tempb = ch_diode.get() + self.diode[i] = tempb + tempc = ch_i0.get() + self.i0[i] = tempc + next(bsstream) + wx.GetApp().Yield() + + self.diode_p = pumped(self.evts, self.diode) + self.diode_u = unpumped(self.evts, self.diode) + self.i0_p = pumped(self.evts, self.i0) + self.i0_u = unpumped(self.evts, self.i0) + + self.diode_p_norm = np.asarray(self.diode_p)/np.asarray(self.i0_p) + self.diode_u_norm = np.asarray(self.diode_u)/np.asarray(self.i0_u) + pump = np.nanmean(self.diode_p_norm) + unpump = np.nanmean(self.diode_u_norm) + pump_e = np.nanstd(self.diode_p_norm) + unpump_e = np.nanstd(self.diode_u_norm) + pp_e = np.sqrt((pump_e/pump)**2+(unpump_e/unpump)**2) + + self.diodes_p.append(pump) + self.diodes_pstd.append(pump_e) + self.diodes_u.append(unpump) + self.diodes_ustd.append(unpump_e) + #self.pp.append(-np.log10(pump/unpump)) + self.pp.append(pump - unpump) + + #self.ppstd.append(pp_e/((pump/unpump)*np.log(10))) + self.ppstd.append(np.sqrt(pump**2+unpump**2)) + + self.draw_plot() + + def draw_plot(self): + self.plot_diodes.clear() + self.plot_pp.clear() + + self.plot_diodes.set_xlabel('time ago, a.u.') + self.plot_diodes.set_ylabel('intensity, a.u.') + self.plot_diodes.set_title(chname_diode) + + self.plot_pp.set_xlabel('time ago, a.u.') + self.plot_pp.set_ylabel('Absorbance') + + self.plot_diodes.plot(np.arange(0, len(self.diodes_p)), self.diodes_p, '-', color='royalblue', label='on') + self.plot_diodes.plot(np.arange(0, len(self.diodes_u)), self.diodes_u, '-', color='orange', label='off') + self.plot_diodes.legend(loc='lower left') + self.plot_pp.plot(np.arange(0, len(self.pp)), self.pp, '-', color='green') + #self.plot_pp.fill_between(np.arange(0, len(self.pp)), np.asarray(self.ppstd)+np.asarray(self.pp), -np.asarray(self.ppstd)+np.asarray(self.pp), color='lightgreen') + #self.plot_pp.set_ylim(-1) + self.plot_pp.grid() + + self.plot_diodes.draw() + self.plot_pp.draw() + + def on_click_clearQ(self, _event): + + self.diodes_p.clear() + self.diodes_u.clear() + self.pp.clear() + self.ppstd.clear()