cleanup after beamtime

This commit is contained in:
e20631
2023-05-09 10:05:38 +02:00
parent 1bd1029cfd
commit b464daffca
7 changed files with 78 additions and 208 deletions

View File

@ -13,29 +13,31 @@ class BECAdapter:
def __init__(self, redis_connector, recon = False, monitor=False, motor_pos = False) -> None:
super().__init__()
self.redis_connector = redis_connector # this is incoming
# self.file_reader = .... # add file reader here
self.grum_client_monitor = RPCClient("localhost", 8000) # this is outgoing
self.grum_client_motor_pos_static = RPCClient("localhost", 8000) # this is outgoing
self.grum_client_motor_pos_moving = RPCClient("localhost", 8000) # this is outgoing
self.grum_client_recon_abs = RPCClient("localhost", 8000) # this is outgoing
self.grum_client_recon_phase = RPCClient("localhost", 8000) # this is outgoing
self.last_plotted_scan_nr = 0
self.latest_reconstructed = 5379
self.scan_nr = None
self.scan_running = False
host = "localhost"
port = 8000
self.redis_connector = redis_connector
self.eaccount = "e20631" #change for each new beamtime
# To decide what should be plotted
self.monitor = monitor
self.motor_pos = motor_pos
self.recon = recon
if self.recon:
self.grum_client_recon_abs = RPCClient(host, port)
self.grum_client_recon_phase = RPCClient(host, port)
self.last_plotted_scan_nr = 0
self.latest_reconstructed = 5000
if self.monitor:
self.grum_client_monitor.new_plot( "monitor",{'xlabel':'time', 'ylabel':"sls_ring_current", "time": True, "frmt":"Line" })
self.grum_client_monitor = RPCClient(host ,port)
self.grum_client_monitor.new_plot("monitor",{'xlabel':'time', 'ylabel':"sls_ring_current", "time": True, "frmt":"Line" })
if self.motor_pos:
self.grum_client_motor_pos_static = RPCClient(host, port)
self.grum_client_motor_pos_moving = RPCClient(host, port)
self.scan_nr = None
self.scan_running = False
self.grum_client_motor_pos_static.new_plot("Motor position static", {'xlabel':'average_x_st_fzp', 'ylabel':"average_y_st_fzp" , "frmt": "Dots"})
self.grum_client_motor_pos_moving.new_plot("Motor position move", {'xlabel':'average_x_st_fzp', 'ylabel':"average_y_st_fzp" , 'frmt':"Motor pos move"})
@ -116,38 +118,26 @@ class BECAdapter:
def plot_img_from_h5(self):
while True:
# if self.last_plotted_scan_nr !=0:
print('Check for new reconstruction')
self.update_latest_reconstructed() # uncomment for it to work properly
# self.latest_reconstructed += 4
self.update_latest_reconstructed()
print('latest_reconstructed: ', self.latest_reconstructed)
print("last plotted scan nr: ", self.last_plotted_scan_nr)
if self.latest_reconstructed > self.last_plotted_scan_nr:
ending_path = self._get_scan_dir(1000, self.latest_reconstructed, leading_zeros = 5)
mypath = "/sls/X12SA/data/" + self.eaccount + "/Data10/analysis/" + ending_path
recon_file = self.get_recon_file(mypath)
with h5py.File(mypath + '/' + recon_file, 'r') as hf:
recon_img_abs, recon_img_phase = self.get_recon_imgs(hf)
# PLOT
# print("max(recon_img_abs)", max(max(recon_img_abs)))
# print("max(recon_img_phase)", max(max(recon_img_phase)))
print('plotting new image with scan_nr: ', self.latest_reconstructed)
xlab = str(self.latest_reconstructed)
if self.recon:
self.grum_client_recon_abs.new_image( "Absorption", {'image': recon_img_abs, "xlabel": xlab, "levels":[0.9, 1.1]})
self.grum_client_recon_abs.new_image( "Absorption", {'image': recon_img_abs, "xlabel": xlab}) #, "levels":[0.9, 1.1]})
# self.grum_client_recon_phase.new_image( f"Phase for scan_nr: {self.latest_reconstructed}", {'image': recon_img_angle, "xlabel": xlab}) #, "colormap":"CET-C1"})
self.grum_client_recon_phase.new_image( "Phase", {'image': recon_img_phase, "xlabel": xlab, "levels": [-1,1]}) #, "colormap":"CET-C1"})
self.grum_client_recon_phase.new_image( "Phase", {'image': recon_img_phase, "xlabel": xlab})#, "levels": [-1,1]}) #, "colormap":"CET-C1"})
self.last_plotted_scan_nr = self.latest_reconstructed
time.sleep(10)
# if self.latest_reconstructed > 9245:
# break
def get_recon_file(self, mypath):
files = [f for f in listdir(mypath) if isfile(join(mypath, f))]
for file in files:
@ -156,12 +146,8 @@ class BECAdapter:
return None
def get_recon_imgs(self, hf):
recon = hf.get('reconstruction')
recon_object = hf.get('reconstruction/object')
recon_probes = hf.get('reconstruction/probes')
recon_probes_1 = recon_probes[0]
recon_probes_2 = recon_probes[1]
# recon_probes = hf.get('reconstruction/probes')
recon_object =np.array(recon_object)
recon_object_abs = np.abs(recon_object)
@ -175,11 +161,11 @@ class BECAdapter:
return recon_img_abs, recon_img_phase
def update_latest_reconstructed(self):
mypath = '/sls/X12SA/Data10/' + self.eaccount + '/analysis/online/ptycho/gallery'
# mypath = '/sls/X12SA/Data10/' + self.eaccount + '/analysis/online/ptycho/gallery'
mypath = '/sls/X12SA/data/' +self.eaccount+ '/Data10/specES1/ptycho_reconstruct/done' # ptycho_reconstruct argument?
file_list = listdir(mypath)
scans = [file_name.split('_')[0] for file_name in file_list]
self.latest_reconstructed = max([int(scan[1:6]) for scan in scans])
# print('Latest reconstructed: ', self.latest_reconstructed)
scans = [file_name.split('_')[1] for file_name in file_list] #0 if you do gallery, 1 if you do done
self.latest_reconstructed = max([int(scan[0:5]) for scan in scans]) # 1:6 for gallery, 0:5 for done
def _get_scan_dir(self, scan_bundle, scan_number, leading_zeros=None):
if leading_zeros is None:
@ -187,7 +173,6 @@ class BECAdapter:
floor_dir = scan_number // scan_bundle * scan_bundle
return f"S{floor_dir:0{leading_zeros}d}-{floor_dir+scan_bundle-1:0{leading_zeros}d}/S{scan_number:0{leading_zeros}d}"
if __name__ == "__main__":
print('starts BECAdapter')
print("initializing redis-connector")

View File

@ -14,6 +14,7 @@ class ImageDescription:
self.image = image
self.colormap = colormap
self.levels = levels
@property
def data(self):
return np.asarray(self.image)
@ -22,7 +23,6 @@ class ImageDescription:
def data(self, value):
self.image = value
def append(self, xy):
print("ignored image append")
@ -32,10 +32,10 @@ class ImageDescription:
def make_plot(self, plotwidget, style):
if self.levels:
res = plotwidget.setImage(self.data, levels = self.levels)
res = plotwidget.setImage(self.data, levels = self.levels) #Set levels for histogram
else:
res = plotwidget.setImage(self.data)
# plotwidget.colormap()
if self.title:
plotwidget.setTitle(self.title)

View File

@ -170,9 +170,6 @@ class MainWindow(QMainWindow):
self.sig_make_new_image.emit(name, desc)
def append_image_to_list(self, img):
"""
Append image to list
"""
desc = self.add_new_desc_to_list(img[0], img[1], Desc=ImageDescription)
# Signal callbacks
@ -193,7 +190,7 @@ class MainWindow(QMainWindow):
if len(selected) == 1:
item = selected[0]
self.plot_single_item(item)
elif type(selected[0].value) == ImageDescription:
elif type(selected[0].value) == ImageDescription: #TODO: what should be the typecheck?
self.plot_multiple_images(selected)
else:
self.plot_multiple_items(selected)
@ -280,19 +277,14 @@ class MainWindow(QMainWindow):
def plot_multiple_images(self, images):
print("this is imgdesc now: ", images)
for i in images:
i.timestamps.access.update()
i.set_alarm(False)
descs = {i.key: i.value for i in images}
names = descs.keys()
name = " | ".join(names)
print(names)
self.activate_or_make_subwin(MDISubMultiImage, name, descs)
#TODO: the following two could be methods to MDIArea?
def activate_or_make_subwin(self, MDISubType, name, *args, **kwargs):

View File

@ -15,8 +15,6 @@ class MDISubImage(MDISubImageBase):
super().__init__(name, *args, **kwargs)
self.pw = pw = pg.ImageView()
# self.pw.setLevels(1,2) # changing levels for histogram levels colors
# self.pw.getHistogramWidget().setLevels(500, 501)
self.setWidget(pw)
# connect to plot mouse-over event
@ -28,7 +26,6 @@ class MDISubImage(MDISubImageBase):
plot = desc.make_plot(self.pw, style)
self.plots = {name: plot}
self.image = desc.data
def on_hover(self, event):
@ -49,18 +46,28 @@ class MDISubMultiImage(MDISubImageBase):
def __init__(self, name, descs, *args, **kwargs):
super().__init__(name, *args, **kwargs)
self.pw = pw = pg.ImageView()
self.central_widget = QWidget()
# self.layout = QGridLayout()
self.button_next = QPushButton('Next', self.central_widget)
self.button_previous = QPushButton('Previous', self.central_widget)
self.pw = pw = pg.ImageView()
self.slider = QSlider(Qt.Horizontal)
self.slider.setRange(0,len(descs)-1)
self._create_layout()
self._connect_signals()
names = [names for names, _ in descs.items()]
self.descriptions = [desc for _, desc in descs.items()]
desc = self.descriptions[0]
style = pg_plot_style()
plot = desc.make_plot(self.pw, style)
self.plots = {name: plot}
self.image = desc.data
def _create_layout(self):
self.layout = QGridLayout(self.central_widget)
self.layout.addWidget(self.button_next,1,2)
self.layout.addWidget(self.button_previous, 1,0)
@ -68,45 +75,23 @@ class MDISubMultiImage(MDISubImageBase):
self.layout.addWidget(self.slider, 1,1)
self.setWidget(self.central_widget)
self.button_next.clicked.connect(self.update_img_next)
self.button_previous.clicked.connect(self.update_img_previous)
def _connect_signals(self):
self.button_next.clicked.connect(lambda:self.update_slider(1))
self.button_previous.clicked.connect(lambda:self.update_slider(-1))
self.slider.valueChanged.connect(self.update_img)
names = [names for names, _ in descs.items()]
self.descriptions = [desc for _, desc in descs.items()]
desc = self.descriptions[0]
plot = desc.make_plot(self.pw, style)
self.plots = {name: plot}
self.image = desc.data
# self.update_timer = QTimer()
# self.update_timer.timeout.connect(self.update_movie)
def update_img_next(self):
self.slider.setValue(self.slider.value()+1)
self.pw.setImage(self.descriptions[self.slider.value()].data)
self.set_title()
def update_img_previous(self):
self.slider.setValue(self.slider.value()-1)
self.pw.setImage(self.descriptions[self.slider.value()].data)
self.set_title()
def update_slider(self, value):
self.slider.setValue(self.slider.value()+value)
def update_img(self, value):
self.pw.setImage(self.descriptions[value].data)
self.set_title()
self.set_title_in_image()
def set_title(self):
vbox = self.pw.getView()
allchildren = vbox.allChildren()
for child in allchildren:
if isinstance(child, pg.LabelItem):
vbox.removeItem(child)
vbox.addItem(pg.LabelItem(self.descriptions[self.slider.value()].xlabel, size='50pt'))
def set_title_in_image(self):
if self.descriptions[self.slider.value()].xlabel:
vbox = self.pw.getView()
allchildren = vbox.allChildren()
for child in allchildren:
if isinstance(child, pg.LabelItem):
vbox.removeItem(child)
vbox.addItem(pg.LabelItem(self.descriptions[self.slider.value()].xlabel, size='50pt'))

View File

@ -6,14 +6,16 @@ import numpy as np
import argparse
class plotPhases:
"""
A possibility to plot reconstructions in a scan number range
"""
def __init__(self, start, end, step=1):
self.start = start
self.end = end
self.step =step
self.eaccount = "e20631"
self.grum_client = RPCClient("localhost", 8000) # this is outgoing
self.image_description_list = []
# self.image_description_list = []
def plot_all_phases(self):
@ -35,7 +37,6 @@ class plotPhases:
def get_recon_phase(self, hf):
recon = hf.get('reconstruction')
recon_object = hf.get('reconstruction/object')
recon_object = np.array(recon_object)
@ -50,7 +51,7 @@ class plotPhases:
for file in files:
if file.endswith("recons.h5"):
return file
print("no file fro this scan nr")
print("no file for this scan nr")
return None
def _get_scan_dir(self, scan_bundle, scan_number, leading_zeros=None):
@ -61,19 +62,17 @@ class plotPhases:
if __name__ == "__main__":
start = 10296
end = 10300
start = 5037 # default
end = 5038 # default
step = 1
parser = argparse.ArgumentParser(description="description", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("-s", "--startstop", nargs =2, help="set start, end")
parser.add_argument("-s", "--startend", nargs =2, help="set start, end")
clargs = parser.parse_args()
if clargs:
start = int(clargs.startstop[0])
end = int(clargs.startstop[1])
start = int(clargs.startend[0])
end = int(clargs.startend[1])
print('starts plotting phase for scans: ',start, ' to ', end)
pp = plotPhases(start, end)
pp.plot_all_phases()

View File

@ -1,88 +0,0 @@
from abc import ABC, abstractmethod
from bec_utils import BECMessage, MessageEndpoints
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtCore import QObject, pyqtSignal
from bec_utils import BECMessage
pyqtWrapperType = type(QObject)
class FinalMeta(pyqtWrapperType, ABC):
pass
class ConnectorBase(QObject, metaclass=FinalMeta):
msg_update = pyqtSignal(BECMessage.ScanStatusMessage)
@abstractmethod
def start_scan_sub(self):
""" """
class BECConnector(ConnectorBase):
msg_update = pyqtSignal(BECMessage.ScanStatusMessage)
def __init__(self, redis_connector) -> None:
super().__init__()
self.connector = redis_connector
self.producer = self.connector.producer()
self._scan_sub = None
def start_scan_sub(self):
self._scan_sub = self.connector.consumer(
MessageEndpoints.scan_status(), cb=self.scan_status_update, parent=self
)
self._scan_sub.start()
@staticmethod
def scan_status_update(msg, parent):
# print("scan_status_update", msg)
msg = BECMessage.ScanStatusMessage.loads(msg.value)
parent.msg_update.emit(msg)
class DataAccess(QObject):
new_mon_value = pyqtSignal(str)
used_devices_updated = pyqtSignal(bool)
new_scan_started = pyqtSignal(bool)
new_scan_msg = pyqtSignal(BECMessage.BECMessage)
msg_queue_update = pyqtSignal(BECMessage.BECMessage)
new_position_umv = pyqtSignal(bool)
def __init__(self, connector: ConnectorBase):
super().__init__()
self.connector = connector
self.start_all_subscriptions(self.connector)
self.scan_nr = ""
self.connect_pyqtSignals()
print('data_access initialized')
def start_all_subscriptions(self, conn):
conn.start_scan_sub()
def on_msg_update(self, msg: BECMessage.ScanStatusMessage):
"""
This function is run whenever there is a new message.
Args:
msg (BECMessage.ScanStatusMessage): A scan status message
"""
print("on_msg_update called")
if msg.content["status"] == "open":
self.get_scan_info(msg)
# self.reset_plot_data()
self.new_scan_started.emit(True)
else:
print("scan ended")
def get_scan_info(self, msg):
print(
"--------------------------------------------------------------------------------------------"
)
print("New scan started")
self.scan_nr = msg.content["info"]["scan_number"]
print(
"--------------------------------------------------------------------------------------------"
)
def connect_pyqtSignals(self):
self.connector.msg_update.connect(self.on_msg_update)

View File

@ -21,28 +21,19 @@ class PlotDescription:
def data(self, value):
self.xs, self.ys = value
def append(self, xy):
x, y = xy
self.xs.append(x)
self.ys.append(y)
# def changeTitle(self, title):
# self.title = title
def extend(self, data):
xs, ys = data
self.xs.extend(xs)
self.ys.extend(ys)
def make_plot(self, plotwidget, style):
if self.format == "Line":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen="w") #, **style)
elif self.format == "Dots":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen=None, symbol="o", symbolSize = 5) #, **style)
elif self.format == "Motor pos move":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen='r', symbol="o", symbolSize = 10)
if self.format:
res = plot_with_format()
else:
res = plotwidget.plot(self.xs, self.ys, name=self.name, **style)
@ -61,9 +52,15 @@ class PlotDescription:
return res
def to_dict(self):
return {k: v for k, v in self.__dict__.items() if not k.startswith("_") and k != "name" and v is not None}
def plot_with_format():
if self.format == "Line":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen="w")
elif self.format == "Dots":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen=None, symbol="o", symbolSize = 5)
elif self.format == "Motor pos move":
res = plotwidget.plot(self.xs, self.ys, name=self.name, pen='r', symbol="o", symbolSize = 10)
else:
res = plotwidget.plot(self.xs, self.ys, name=self.name, **style)