added possibility to plot multiple images
This commit is contained in:
@ -26,7 +26,7 @@ class BECAdapter:
|
||||
self.scan_nr = None
|
||||
self.scan_running = False
|
||||
|
||||
self.eaccount = "e20642" # for jeff: 20633
|
||||
self.eaccount = "e20633" # for jeff: 20633
|
||||
|
||||
# To decide what should be plotted
|
||||
self.monitor = monitor
|
||||
@ -114,13 +114,17 @@ class BECAdapter:
|
||||
self.grum_client_monitor.append_data( "monitor", point)
|
||||
|
||||
def plot_img_from_h5(self):
|
||||
|
||||
while True:
|
||||
|
||||
# if self.last_plotted_scan_nr !=0:
|
||||
print('Check for new reconstruction')
|
||||
self.update_latest_reconstructed()
|
||||
self.update_latest_reconstructed() # uncomment for it to work properly
|
||||
# self.latest_reconstructed += 4
|
||||
|
||||
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)
|
||||
@ -139,6 +143,8 @@ class BECAdapter:
|
||||
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:
|
||||
|
@ -4,10 +4,11 @@ import pyqtgraph as pg
|
||||
|
||||
from . import assets
|
||||
from .dictlist import DictList
|
||||
from .dictlist.dictlistitem import DictListItem
|
||||
from .exampledata import exampledata
|
||||
from .h5filedlg import open_h5_files_dialog, save_h5_file_dialog
|
||||
from .io import write_dict, read_dict
|
||||
from .mdi import MDIArea, MDISubMultiPlot, MDISubPlot, MDISubImage, MDIWindowMode
|
||||
from .mdi import MDIArea, MDISubMultiPlot, MDISubPlot, MDISubImage, MDIWindowMode, MDISubMultiImage
|
||||
from .menus import BarMenu
|
||||
from .plotdesc import PlotDescription
|
||||
from .imgdesc import ImageDescription
|
||||
@ -93,6 +94,7 @@ class MainWindow(QMainWindow):
|
||||
rst.server.register_function(self.extend_data)
|
||||
rst.server.register_function(self.set_data)
|
||||
rst.server.register_function(self.new_image)
|
||||
rst.server.register_function(self.plot_images_from_list) # function for CSAXS beamtime
|
||||
|
||||
self.sig_make_new_plot.connect(self.on_make_new_plot)
|
||||
self.sig_make_new_image.connect(self.on_make_new_image)
|
||||
@ -116,46 +118,7 @@ class MainWindow(QMainWindow):
|
||||
if not self.mdi.findSubWindow(name):
|
||||
self.sig_make_new_plot.emit(name, desc)
|
||||
|
||||
# else:
|
||||
# print("else")
|
||||
# if desc.title:
|
||||
|
||||
# print("---------------------------------------------")
|
||||
# print("self mdi exist, new title:", desc.title)
|
||||
# sub = self.mdi.findSubWindow(name)
|
||||
# print(sub.pw.plotItem.titleLabel)
|
||||
# print(sub.pw.plotItem.titleLabel.text)
|
||||
# vbox = sub.pw.getViewBox()
|
||||
# vbox.removeItem(sub.pw.plotItem.titleLabel)
|
||||
# #maybe add title? or just settitle?
|
||||
# vbox.addItem(pg.LabelItem(desc.title, size='50pt'))
|
||||
# # sub.pw.plotItem.titleLabel.setText(desc.title)
|
||||
# print("------------------------------------")
|
||||
|
||||
# print("clearing")
|
||||
# if desc.title:
|
||||
# sub.pw.clear()
|
||||
# print("setting new title: ", desc.title)
|
||||
# sub.pw.setTitle(desc.title)
|
||||
# vbox = sub.pw.getView()
|
||||
# vbox.addItem(pg.LabelItem(desc.title, size='50pt'))
|
||||
# vbox.addItem(pg.titel)
|
||||
|
||||
# allchildren = vbox.allChildren()
|
||||
# for child in allchildren:
|
||||
# print(child)
|
||||
# if isinstance(child, pg.graphicsItems.ViewBox.ChildGroup):
|
||||
# print("Found childGroup")
|
||||
# allgrandchildren = vbox.allChildren(child)
|
||||
# for grandchild in allgrandchildren:
|
||||
# print(grandchild)
|
||||
# # print("Removing label")
|
||||
# # vbox.removeItem(child)
|
||||
# print("-------------done-------------")
|
||||
# vbox.addItem(pg.LabelItem(desc.title, size='50pt'))
|
||||
# sub.pw.setTitle(desc.title)
|
||||
|
||||
def append_data(self, name, point): #, title=None):
|
||||
def append_data(self, name, point):
|
||||
"""
|
||||
Append a new data point <point> to the (existing) plot <name>.
|
||||
The point is forwarded to the append method of PlotDescription.
|
||||
@ -163,8 +126,6 @@ class MainWindow(QMainWindow):
|
||||
item = self.lst.get(name)
|
||||
desc = item.value
|
||||
desc.append(point)
|
||||
# if title:
|
||||
# desc.changeTitle(title)
|
||||
self.sync_item_and_plots(item)
|
||||
|
||||
def extend_data(self, name, data):
|
||||
@ -208,6 +169,21 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
self.sig_make_new_image.emit(name, desc)
|
||||
|
||||
def plot_images_from_list(self, image_desc_list):
|
||||
"""
|
||||
Plot images from list
|
||||
"""
|
||||
images = []
|
||||
i =1
|
||||
for img in image_desc_list:
|
||||
self.new_image(img[0], img[1])
|
||||
# desc = ImageDescription(img[0], **img[1])
|
||||
# dlistitem = DictListItem(f"Phase: {i}", desc)
|
||||
# images.append(dlistitem)
|
||||
# i+=1
|
||||
|
||||
# self.plot_multiple_images(images)
|
||||
|
||||
|
||||
# Signal callbacks
|
||||
|
||||
@ -227,6 +203,8 @@ class MainWindow(QMainWindow):
|
||||
if len(selected) == 1:
|
||||
item = selected[0]
|
||||
self.plot_single_item(item)
|
||||
elif type(selected[0].value) == ImageDescription:
|
||||
self.plot_multiple_images(selected)
|
||||
else:
|
||||
self.plot_multiple_items(selected)
|
||||
|
||||
@ -310,6 +288,23 @@ class MainWindow(QMainWindow):
|
||||
name = " | ".join(names)
|
||||
self.activate_or_make_subwin(MDISubMultiPlot, name, descs)
|
||||
|
||||
def plot_multiple_images(self, images):
|
||||
if type(images[0]) == list:
|
||||
print('it is a list')
|
||||
|
||||
else:
|
||||
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?
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
from .mdiarea import MDIArea, MDIWindowMode
|
||||
from .mdisubplot import MDISubPlot, MDISubMultiPlot
|
||||
from .mdisubimg import MDISubImage
|
||||
from .mdisubimg import MDISubImage, MDISubMultiImage
|
||||
|
||||
|
||||
|
@ -1,12 +1,19 @@
|
||||
import pyqtgraph as pg
|
||||
from .mdisubwin import MDISubWindow
|
||||
from ..theme import pg_plot_style
|
||||
from PyQt5.QtWidgets import QMainWindow, QWidget, QPushButton, QGridLayout, QVBoxLayout, QApplication, QSlider
|
||||
from PyQt5.QtCore import Qt, QThread, QTimer
|
||||
|
||||
class MDISubImageBase(MDISubWindow):
|
||||
def __init__(self, name, *args, **kwargs):
|
||||
super().__init__(name, *args, **kwargs)
|
||||
|
||||
|
||||
class MDISubImage(MDISubWindow):
|
||||
class MDISubImage(MDISubImageBase):
|
||||
|
||||
def __init__(self, name, desc, *args, **kwargs):
|
||||
super().__init__(name, *args, **kwargs)
|
||||
|
||||
self.pw = pw = pg.ImageView()
|
||||
self.setWidget(pw)
|
||||
|
||||
@ -14,7 +21,6 @@ class MDISubImage(MDISubWindow):
|
||||
pw.scene.sigMouseMoved.connect(self.on_hover)
|
||||
|
||||
style = pg_plot_style()
|
||||
|
||||
# cm = pg.colormap.get('CET-C1')
|
||||
# pw.setColorMap(cm)
|
||||
|
||||
@ -23,7 +29,6 @@ class MDISubImage(MDISubWindow):
|
||||
|
||||
self.image = desc.data
|
||||
|
||||
|
||||
def on_hover(self, event):
|
||||
coord = self.pw.imageItem.mapFromScene(event)
|
||||
x = coord.x()
|
||||
@ -38,4 +43,52 @@ class MDISubImage(MDISubWindow):
|
||||
self.setToolTip(f"x = {x}\ny = {y}\nz = {z}")
|
||||
|
||||
|
||||
class MDISubMultiImage(MDISubImageBase):
|
||||
|
||||
def __init__(self, name, descs, *args, **kwargs):
|
||||
super().__init__(name, *args, **kwargs)
|
||||
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.layout = QGridLayout(self.central_widget)
|
||||
self.layout.addWidget(self.button_next,1,2)
|
||||
self.layout.addWidget(self.button_previous, 1,0)
|
||||
self.layout.addWidget(self.pw, 0,0, 1,3)
|
||||
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)
|
||||
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]
|
||||
|
||||
style = pg_plot_style()
|
||||
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.pw.setImage(self.descriptions[1].data)
|
||||
self.slider.setValue(self.slider.value()+1)
|
||||
|
||||
def update_img_previous(self):
|
||||
self.pw.setImage(self.descriptions[0].data)
|
||||
self.slider.setValue(self.slider.value()-1)
|
||||
|
||||
def update_img(self, value):
|
||||
self.pw.setImage(self.descriptions[value].data)
|
||||
|
76
grum/plot_multiple_phases.py
Normal file
76
grum/plot_multiple_phases.py
Normal file
@ -0,0 +1,76 @@
|
||||
from grum.rpc import RPCClient
|
||||
from os import listdir
|
||||
from os.path import isfile, join
|
||||
import h5py
|
||||
import numpy as np
|
||||
|
||||
class plotPhases:
|
||||
def __init__(self, start, end, step=1):
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.step =step
|
||||
self.eaccount = "e20633" # for jeff: 20633
|
||||
self.grum_client = RPCClient("localhost", 8000) # this is outgoing
|
||||
self.image_description_list = []
|
||||
|
||||
|
||||
def plot_all_phases(self):
|
||||
|
||||
for scan_nr in range(self.start, self.end + 1, self.step):
|
||||
print("retrieving data for scan: ", scan_nr)
|
||||
ending_path = self._get_scan_dir(1000, scan_nr, 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_phase = self.get_recon_phase(hf)
|
||||
|
||||
xlab = str(scan_nr)
|
||||
self.image_description_list.append([f"Phase: {scan_nr}", {'image': recon_img_phase, "xlabel": xlab}])
|
||||
|
||||
print("calling plot images from list")
|
||||
self.grum_client.plot_images_from_list(self.image_description_list)
|
||||
|
||||
def get_recon_phase(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_object = np.array(recon_object)
|
||||
# recon_object_abs = np.abs(recon_object)
|
||||
recon_object_angle = np.angle(recon_object)
|
||||
|
||||
# recon_object_abs = np.rot90(recon_object_abs,3)
|
||||
recon_object_angle = np.rot90(recon_object_angle, 3)
|
||||
|
||||
# recon_img_abs = recon_object_abs.tolist()
|
||||
recon_img_angle = recon_object_angle.tolist()
|
||||
# return recon_img_abs, recon_img_angle
|
||||
return recon_img_angle
|
||||
|
||||
def get_recon_file(self, mypath):
|
||||
files = [f for f in listdir(mypath) if isfile(join(mypath, f))]
|
||||
for file in files:
|
||||
if file.endswith("recons.h5"):
|
||||
return file
|
||||
print("no file fro this scan nr")
|
||||
return None
|
||||
|
||||
def _get_scan_dir(self, scan_bundle, scan_number, leading_zeros=None):
|
||||
if leading_zeros is None:
|
||||
leading_zeros = len(str(scan_bundle))
|
||||
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__":
|
||||
start = 10296
|
||||
end = 10300
|
||||
step = 1
|
||||
print('starts plotting phase for scans: ',start, ' to ', end)
|
||||
|
||||
pp = plotPhases(start, end)
|
||||
pp.plot_all_phases()
|
2
setup.py
2
setup.py
@ -12,7 +12,7 @@ if __name__ == "__main__":
|
||||
# subprocess.run(f"pip install -e {bec_utils}", shell=True, check=True)
|
||||
|
||||
setup(
|
||||
install_requires=["pyqt5==5.12", "pyqtgraph", "h5py", "PyQtWebEngine==5.12"], #this version works for comp1 CSAXS, no later version
|
||||
install_requires=["pyqt5==5.12", "pyqtgraph", "h5py", "PyQtWebEngine==5.12", "Pillow"], #this version works for comp1 CSAXS, no later version
|
||||
entry_points={"console_scripts": ["grum=grum:main"]},
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user