cleanup after beamtime
This commit is contained in:
@ -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")
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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'))
|
||||
|
@ -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()
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user