diff --git a/EmblModule.py b/EmblModule.py
deleted file mode 100755
index 7f54300..0000000
--- a/EmblModule.py
+++ /dev/null
@@ -1,445 +0,0 @@
-import logging
-import numpy
-import os
-import random
-import struct
-import time
-
-import yaml
-#from scipy.misc import bytescale
-
-import zmq
-from os.path import join
-from pathlib import Path
-
-#import qsingleton #ZAC: orig. code
-#from CoordinatesModel import CoordinatesModel #ZAC: orig. code
-from app_config import AppCfg #settings, option, appsconf
-
-EMBL_RESULTS_TIMEOUT = "embl/results_timeout"
-
-EMBL_SAVE_FILES = "embl/save_files"
-
-#embl = appsconf["embl"]
-
-#import imageio
-import numpy as np
-from PyQt5 import QtCore
-from PyQt5.QtCore import pyqtSignal, Qt, QObject, pyqtSlot, QPoint
-from PyQt5.QtGui import QStandardItemModel, QCursor
-from PyQt5.QtWidgets import (
- QWidget,
- QVBoxLayout,
- QHeaderView,
- QPushButton,
- QFormLayout,
- QDoubleSpinBox,
- QLabel,
- QTableWidgetItem,
- QLineEdit,
- QTableWidget,
- QTextEdit,
- QProgressBar,
- QHBoxLayout,
- QSpinBox,
- QTabWidget,
- QTableView,
- QMenu,
- QProgressDialog,
-)
-
-#import storage
-from app_utils import assert_motor_positions
-
-#folders = storage.Folders()
-
-import logging
-logger = logging.getLogger(__name__)
-
-
-class EmblTaskResultTimeoutException(Exception):
- pass
-
-
-ZPOS, FPATH = range(2)
-
-# record separator
-RS = 0x1e
-
-
-#class EmblMessage(QObject, metaclass=qsingleton.Singleton): #ZAC: orig. code
-class EmblMessage(QObject):
-
- def __init__(self, parent=None, **kwargs):
- super(EmblMessage, self).__init__(parent, **kwargs)
- return #ZAC: orig. code
- if not embl["enabled"]:
- return
- context = zmq.Context()
- logger.info("Connecting to server...")
- self.socket = context.socket(zmq.REQ)
- uri = embl["uri"]
- logger.info(f"EMBL alignment server at: {uri}")
- self.socket.connect(uri)
-
- def make_PAR(self, min: float, max: float, step: float, ppm: int, beam_xy: tuple):
- puckid, sampleid = folders._prefix.split("_")
- beam_x, beam_y = beam_xy
- msg = (
- f"PAR{RS:c}{min}{RS:c}{max}{RS:c}{step}{RS:c}{ppm}{RS:c}{beam_x:.0f}{RS:c}{beam_y:.0f}{RS:c}{puckid}{RS:c}{sampleid}"
- )
- logger.debug(f"PAR = {msg}")
- self.socket.send_string(msg)
- ans = self.socket.recv_string()
-
- def make_IMG(self, pos: float, img):
- width, height = img.shape
- msg = f"IMG{RS:c}{pos:.3f}{RS:c}{width}{RS:c}{height}"
- logger.info(f"sending img header: {msg}")
- self.socket.send_string(msg)
- self.socket.recv_string()
- logger.info(
- f"about to send img shape={img.shape} type={img.dtype} pos = {pos} mm"
- )
- self.socket.send(numpy.ascontiguousarray(img))
- logger.info(f"waiting for recv")
- ans = self.socket.recv_string()
- logger.info(f"received!")
-
- def finished(self):
- self.make_STS("Finished")
-
- def aborted(self):
- self.make_STS("Aborted")
-
- def make_STS(self, status):
- msg = f"STS{RS:c}{status}"
- self.socket.send_string(msg)
- ans = self.socket.recv_string()
-
- def make_RES(self):
- n = 1
- timeout = settings.value(EMBL_RESULTS_TIMEOUT, type=float) + time.time()
- result = "failed"
- while time.time() < timeout:
- time.sleep(2.0)
- logger.info(f"#{n}.requesting RES")
- self.socket.send_string("RES")
- result = self.socket.recv_string()
- logger.info(f" RES = {result}")
- if "Pending" != result:
- break
- n += 1
- return result
-
-
-embl_tube = EmblMessage()
-
-
-class EmblWidget(QWidget):
-
- def __init__(self, parent):
- super(EmblWidget, self).__init__(parent)
-
- #parent.pixelsPerMillimeter.connect(self.save_ppm)
- #parent.beamCameraCoordinatesChanged.connect(self.save_beam_coordinates)
- self.setLayout(QVBoxLayout())
-
- w = QWidget()
- self.layout().addWidget(w)
- w.setLayout(QFormLayout())
- w.layout().setLabelAlignment(Qt.AlignRight)
-
- self._startZ = QDoubleSpinBox()
- self._startZ.setValue(0.6)
- self._startZ.setSuffix(" mm")
- self._startZ.setRange(-5, 5)
- self._startZ.setSingleStep(0.1)
- self._startZ.setDecimals(3)
-
- self._endZ = QDoubleSpinBox()
- self._endZ.setValue(1.4)
- self._endZ.setSuffix(" mm")
- self._endZ.setRange(-5, 5)
- self._endZ.setSingleStep(0.1)
- self._endZ.setDecimals(3)
-
- self._stepZ = QDoubleSpinBox()
- self._stepZ.setValue(0.050)
- self._stepZ.setSuffix(" mm")
- self._stepZ.setRange(0.005, 1.000)
- self._stepZ.setSingleStep(0.010)
- self._stepZ.setDecimals(3)
-
- self._resultsTimeout = QDoubleSpinBox()
- self._resultsTimeout.setRange(1., 2000.)
- self._resultsTimeout.setValue(60)
- self._resultsTimeout.setSuffix(" seconds")
- self._resultsTimeout.setDecimals(0)
-
- self._factors = QLineEdit("1 1 1")
- but = QPushButton("update results")
- but.clicked.connect(self.apply_factors)
-
- w.layout().addRow(QLabel("Start Z"), self._startZ)
- w.layout().addRow(QLabel("End Z"), self._endZ)
- w.layout().addRow(QLabel("Step"), self._stepZ)
- w.layout().addRow(QLabel("Task Result Timeout"), self._resultsTimeout)
- w.layout().addRow(QLabel("Factors"), self._factors)
- w.layout().addRow(QLabel("Apply Factors"), but)
-
-
- but = QPushButton("Scan Z")
- but.clicked.connect(self.executeScan)
- but.setAccessibleName("emblScanZ")
- self.layout().addWidget(but)
-
- tabs = QTabWidget(self)
- self.layout().addWidget(tabs)
-
- self._table = QTableWidget()
- self._table.setColumnCount(2)
- self._table.setHorizontalHeaderLabels(("Z (mm)", "File Path"))
- self._table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
- self.layout().addWidget(self._table)
- tabs.addTab(self._table, "Z Scans")
- tabs.setAccessibleName("embl_tabs")
- tabs.setObjectName("embl_tabs")
-
- view = self._results_view = QTableView(self)
- #view.setModel(CoordinatesModel()) #ZAC: orig. code
- view.verticalHeader().show()
- view.horizontalHeader().show()
- view.setContextMenuPolicy(Qt.CustomContextMenu)
- view.customContextMenuRequested.connect(self.results_menu)
- tabs.addTab(view, "Results")
- self._tabs = tabs
-
- def apply_factors(self):
- self.populate_results(self._results)
-
- @pyqtSlot(float)
- def save_ppm(self, ppm: float):
- self._ppm = int(ppm)
-
- @pyqtSlot(float, float)
- def save_beam_coordinates(self, bx: float, by: float):
- logger.debug(f"saving beam_xy {bx} & {by}")
- self._beam_xy = (int(bx), int(by))
-
- @pyqtSlot(QPoint)
- def results_menu(self, at_point):
- table = self.sender()
- model = table.model()
-
- index = table.indexAt(at_point)
- if not index.isValid():
- return
- coords = model.coords_at(index)
- logger.debug(f"coord: {coords}")
- menu = QMenu(table)
-
- gotoAction = menu.addAction("Go here")
- if menu.exec_(QCursor.pos()) is gotoAction:
- logger.info(f"going to: {index.row()} => {coords}")
- self.goto_position(coords)
-
- def configure(self, motors, camera, zoom_device):
- self._camera = camera
- self._zoom_device = zoom_device
- self.motors = motors
-
- def executeScan(self):
- fx, fy, cx, cz, omega = self.motors
-
- x, y, z = fx.get_position(), fy.get_position(), cz.get_position()
- logger.info(f"scan started at gonio: x,y,z = {x}, {y}, {z}")
-
- self._table.setRowCount(0) # clear previous information
-
- zs = self._startZ.value()
- ze = self._endZ.value()
- step = self._stepZ.value()
- scan_config = {
- "z-start": zs,
- "z-end": ze + step, # inclusive last value
- "z-step": step,
- "ppm": self._ppm,
- "beam_xy": self._beam_xy,
- }
-
- self._gonio_at_start = (x, y, ze + step)
-
- base_Z = self.motors[3] # base_Z
- camera = self._camera
-
- zvals = np.arange(zs, ze, step)
- numZs = len(zvals)
-
- dlg = QProgressDialog(self)
- dlg.setWindowModality(Qt.WindowModal)
- dlg.setMinimumDuration(0)
- dlg.setCancelButton(None)
- dlg.setRange(0, 0)
- dlg.setLabelText(f"EMBL Z-Scan
")
- dlg.setAutoClose(True)
- dlg.show()
- dlg.setValue(random.randint(1, 20))
- self._progress_dialog = dlg
-
- self._acq_thread = AcquisitionThread(base_Z, camera, scan_config)
- self._acq_thread.image_acquired.connect(self.addImage)
- self._acq_thread.acquisition_finished.connect(self.acquisition_finished)
- self._acq_thread.results_fetched.connect(self.populate_results)
- self._acq_thread.message.connect(
- lambda msg: dlg.setLabelText(f"EMBL Z-Scan
{msg}")
- )
- self._acq_thread.start()
-
- def createModel(self, parent):
- model = QStandardItemModel(0, 2, parent)
- model.setHeaderData(ZPOS, QtCore.Qt.Horizontal, "Z (mm)")
- model.setHeaderData(FPATH, QtCore.Qt.Horizontal, "Image Path")
- self._model = model
- return model
-
- def addImage(self, idx, zpos, fpath):
- logger.info("zpos = {}, fpath = {}".format(zpos, fpath))
- rows = self._table.rowCount()
- # table.setRowCount(rows + 1)
- self._table.insertRow(rows)
- item = QTableWidgetItem()
- item.setText("{:.03f}".format(zpos))
- self._table.setItem(rows, ZPOS, item)
- item = QTableWidgetItem()
- item.setText(str(fpath))
- self._table.setItem(rows, FPATH, item)
- self._table.resizeColumnsToContents()
-
- def acquisition_finished(self):
- self._progress_dialog.reset()
-
- def goto_position(self, coords):
- fx, fy, cx, cz, o = self.motors
- tx, ty, bb, tz, to = coords
-
- logger.info(f"moving gonio to: {tx}, {ty}, {tz}")
- fx.move(tx, wait=True, ignore_limits=True)
- fy.move(ty, wait=True, ignore_limits=True)
- cz.move(tz, wait=True, ignore_limits=True)
-
- @pyqtSlot(str)
- def populate_results(self, results):
- """Results.txt
- 60.624%363.4026940025185%-768.32%-1052.52
-
- angle between sample and camera, x, y, z
-
- :return:
- """
- if "no results" in results:
- return
-
- s1, s2, s3 = [int(c) for c in self._factors.text().split()]
-
- self._results = results
- self.coords = []
- ox, oy, oz = self._gonio_at_start
-
- oz = self._endZ.value()
-
- for n, line in enumerate(results.split("\n")):
- # o, z, y, x = [float(n) for n in line.split("%")]
- omega, x, y, z = [float(n) for n in line.split("%")]
- no, nx, ny, nz = [omega, ox + s1*x, oy + s2*y, oz + s3*z]
-
- self.coords.append([nx, ny, 0, nz, no])
- model = self._results_view.model()
- model.update_coordinates(self.coords)
- self._tabs.setCurrentIndex(1)
-
-
-class AcquisitionThread(QtCore.QThread):
-
- image_acquired = pyqtSignal(int, float, str)
- results_fetched = pyqtSignal(str)
- message = pyqtSignal(str)
- acquisition_finished = pyqtSignal()
-
- def __init__(self, z_motor, camera, scan_config):
- QtCore.QThread.__init__(self)
- self._scanconfig = scan_config
- logger.debug(f"scanconfig: {scan_config}")
- self.z_motor = z_motor
- self.camera = camera
-
- def save_params(self, params):
- fname = Path(folders.res_folder) / "z_scan" / "parameters.yaml"
-
- try:
- with open(fname, "w") as fp:
- yaml.dump(params, fp)
- except:
- logger.warning(f"failed to save z-scan parameter file: {fname}")
-
- def save_image(self, n, z, img):
- if not option(EMBL_SAVE_FILES):
- return
- zp = f"{n:02d}_Z{z:.3f}".replace(".", "p") + ".png"
- fname = Path(folders.res_folder) / "z_scan" / zp
- try:
- imageio.imsave(fname, img)
- except:
- logger.error(f"failed to write: {fname}")
- return f"failed to write image {n}"
- return fname
-
- def save_result(self, result):
- if not option(EMBL_SAVE_FILES):
- return
- fname = Path(folders.res_folder) / "z_scan" / "result.txt"
- with open(fname, "w") as fp:
- fp.write(result)
-
- def make_folders(self):
- if not option(EMBL_SAVE_FILES):
- return
- fold = Path(folders.res_folder) / "z_scan"
- fold.mkdir(parents=True, exist_ok=True)
-
- def run(self):
- self.make_folders()
- cnf = self._scanconfig
- zmin, zmax, zstep = cnf["z-start"], cnf["z-end"], cnf["z-step"]
- zvals = np.arange(zmin, zmax, zstep)
- num = len(zvals)
-
- logger.debug(
- f"Z-scan: min/max/step {zmin}/{zmax}/{zstep} ppm={cnf['ppm']} beam_xy={cnf['beam_xy']}"
- )
- logger.info(f"Z-vals: {', '.join([f'{z:.2f}' for z in zvals])}")
- self.save_params(cnf)
- embl_tube.make_PAR(zmin, zmax, zstep, cnf["ppm"], cnf["beam_xy"])
-
- for n, z in enumerate(zvals):
- idx = n + 1
- self.message.emit(f"{idx}/{num} Z ➠ {z:.2f}")
- self.z_motor.move(z, ignore_limits=True, wait=True)
- assert_motor_positions([(self.z_motor, z, 0.1)], timeout=3.)
- self.message.emit(f"{idx}/{num} acquiring")
- img = self.camera.get_image()
- self.message.emit(f"{idx}/{num} acquired")
- img = np.rot90(img, 1)
- img = bytescale(img)
- fname = self.save_image(idx, z, img)
- self.image_acquired.emit(idx, z, str(fname)) # just to populate table
- self.message.emit(f"{idx}/{num} sending")
- embl_tube.make_IMG(z, img)
- self.message.emit(f"{idx}/{num} sent")
- self.message.emit(f"acquisition finished")
- embl_tube.finished()
- self.message.emit(f"waiting for results")
- result = embl_tube.make_RES()
- self.save_result(result)
- self.results_fetched.emit(result)
- self.acquisition_finished.emit()
diff --git a/HelicalTable.py b/HelicalTable.py
deleted file mode 100644
index 8c07bba..0000000
--- a/HelicalTable.py
+++ /dev/null
@@ -1,256 +0,0 @@
-import sys
-import os
-import logging
-import csv
-from PyQt5 import QtCore, QtGui
-
-import numpy as np
-
-logger = logging.getLogger("helical")
-
-from PyQt5.QtWidgets import (
- QTableWidget,
- QApplication,
- QMainWindow,
- QTableWidgetItem,
- QFileDialog,
- QHeaderView,
- QAbstractItemView,
- QMenu)
-from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal, QPoint, pyqtSlot
-
-DATA_ITEM = 1
-
-START_OMEGA_0 = 0
-START_OMEGA_120 = 1
-START_OMEGA_240 = 2
-STOP_OMEGA_0 = 3
-STOP_OMEGA_120 = 4
-STOP_OMEGA_240 = 5
-
-ROLE_XTAL_START = 1 + Qt.UserRole
-ROLE_XTAL_END = 2 + Qt.UserRole
-
-
-class HelicalTableWidget(QTableWidget):
- gonioMoveRequest = pyqtSignal(float, float, float, float, float)
- def __init__(self):
- super().__init__()
- self.check_change = True
- self._scanAngularStep = 0.1
- self._scanHorizontalCount = 5
- self._scanVerticalCount = 10
- self._current_xtal = None
- self._start_angle = 0.0
- self.init_ui()
-
- def startAngle(self) -> float:
- return self._start_angle
-
- @pyqtSlot(float)
- def setStartAngle(self, angle:float):
- self._start_angle = angle
-
- def init_ui(self):
- self.setColumnCount(6)
- self.setEditTriggers(QAbstractItemView.NoEditTriggers)
- self.resizeColumnsToContents()
- self.setSelectionMode(QAbstractItemView.SingleSelection)
- self.setSelectionBehavior(QAbstractItemView.SelectItems)
- labels = [
- "0\nbx, bz\n(mm)",
- "120\nbx, bz\n(mm)",
- "240\nbx, bz\n(mm)",
- "0\nbx, bz\n(mm)",
- "120\nbx, bz\n(mm)",
- "240\nbx, bz\n(mm)",
- ]
- self.setHorizontalHeaderLabels(labels)
-
- self.verticalHeader().resizeSections(QHeaderView.ResizeToContents)
- self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
-
- self.cellChanged.connect(self.c_current)
- self.show()
-
- def display_coords(self, x, y):
- row = self.rowAt(y)
- col = self.columnAt(x)
- coords = self.gonio_coords_at(row, col)
- omega = col % 3 * 120
- data = coords[omega]
- logger.info("gonio at {}, {}: {}".format(row, col, data))
-
- def goto_gonio_position(self, x, y):
- row = self.rowAt(y)
- col = self.columnAt(x)
- coords = self.gonio_coords_at(row, col)
- omega = col % 3 * 120
- data = coords[omega]
- logger.info("move gonio to: {}".format(row, col, data))
- self.gonioMoveRequest.emit(*data)
-
- def remove_xtal(self, x, y):
- row = self.rowAt(y)
- col = self.columnAt(x)
- logger.info("rowCount() = {}, removing row: {}".format(self.rowCount(), row))
- self.removeRow(row)
- if self.rowCount() == 0:
- self._current_xtal = None
- logger.info("rowCount() = {}".format(self.rowCount()))
-
- def contextMenuEvent(self, event):
- logger.info(event.pos())
- x = event.pos().x()
- y = event.pos().y()
- menu = QMenu(self)
- gotoAction = menu.addAction("Move Gonio Here")
- gotoAction.triggered.connect(lambda b: self.goto_gonio_position(x, y))
- removeAction = menu.addAction("Remove this line")
- removeAction.triggered.connect(lambda b: self.remove_xtal(x, y))
- menu.popup(QtGui.QCursor.pos())
-
- def setScanHorizontalCount(self, count: int):
- logger.debug("horizontal count: {}".format(count))
- self._scanHorizontalCount = count
-
- def scanHorizontalCount(self) -> int:
- return self._scanHorizontalCount
-
- def setScanVerticalCount(self, count: int):
- logger.debug("vertical count: {}".format(count))
- self._scanVerticalCount = count
-
- def scanVerticalCount(self) -> int:
- return self._scanVerticalCount
-
- def setScanAngularStep(self, step: float):
- self._scanAngularStep = step
-
- def scanAngularStep(self) -> float:
- return self._scanAngularStep
-
- def scanTotalRange(self) -> float:
- return self._scanVerticalCount * self._scanHorizontalCount * self._scanAngularStep
-
- def gonio_coords_at(self, row, col):
- role = ROLE_XTAL_START if col < 3 else ROLE_XTAL_END
- coords = self.item(row, DATA_ITEM).data(role)
- return coords
-
- def add_xtal(self):
- row = self.rowCount()
- self.setRowCount(row + 1)
- self._current_xtal = row
- print(row)
- for n in range(self.columnCount()):
- self.setItem(row, n, QTableWidgetItem("unset"))
-
-
- def set_xtal_start(self, data: list):
- """sets data to start position
-
- data = [fx, fy, bx, bz, omega]
-
- """
- self.set_data_point(ROLE_XTAL_START, data)
-
- def set_xtal_end(self, data: list):
- self.set_data_point(ROLE_XTAL_END, data)
-
- def set_data_point(self, role: int, data: list):
- if self._current_xtal is None:
- self.add_xtal()
- row, col = self._current_xtal, DATA_ITEM
-
- try:
- coords = self.item(row, DATA_ITEM).data(role)
- except:
- print("empty coords; initializing...")
- coords = None
-
- if coords is None:
- coords = {}
-
- fx, fy, bx, bz, omega = data
- o = int(omega)
- coords[o] = data
- print("coords = {}".format(coords))
-
- if role == ROLE_XTAL_END:
- col = 3
- else:
- col = 0
-
- for n in range(3):
- omega = n * 120
- try:
- fx, fy, bx, bz, omega = coords[omega]
- info = "{bx:.3f} mm\n{bz:.3f} mm".format(bx=bx, bz=bz)
- except:
- info = "unset"
- # self.item(row, col + n).setData(Qt.DisplayRole, info)
- self.item(row, col + n).setText(info)
- self.item(row, col + n).setToolTip(info)
-
- self.item(row, DATA_ITEM).setData(role, coords)
-
- def c_current(self):
- if self.check_change:
- row = self.currentRow()
- col = self.currentColumn()
- value = self.item(row, col)
- # value = value.text()
-
- def load_datapoints(self):
- self.check_change = False
- path = QFileDialog.getOpenFileName(
- self, "Open CSV", os.getenv("HOME"), "CSV(*.csv)"
- )
- if path[0] != "":
- with open(path[0], newline="") as csv_file:
- self.setRowCount(0)
- self.setColumnCount(10)
- my_file = csv.reader(csv_file, delimiter=",", quotechar="|")
- for row_data in my_file:
- row = self.rowCount()
- self.insertRow(row)
- if len(row_data) > 10:
- self.setColumnCount(len(row_data))
- for column, stuff in enumerate(row_data):
- item = QTableWidgetItem(stuff)
- self.setItem(row, column, item)
- self.check_change = True
-
- def get_data(self, as_numpy=False):
- """return a list of tuples with all defined data
-
- [
- (is_fiducial(boolean), x, y, gonio_x, gonio_y),...
- ]
- """
- data = []
-
- for row in range(self.rowCount()):
- start = self.item(row, DATA_ITEM).data(ROLE_XTAL_START)
- end = self.item(row, DATA_ITEM).data(ROLE_XTAL_END)
-
- data.append([start, end])
- # if as_numpy:
- # data = np.asarray(data)
- return data
-
-
-if __name__ == "__main__":
-
- class Sheet(QMainWindow):
- def __init__(self):
- super().__init__()
-
- self.form_widget = HelicalTableWidget()
- self.setCentralWidget(self.form_widget)
- self.show()
-
- app = QApplication(sys.argv)
- sheet = Sheet()
- sys.exit(app.exec_())
diff --git a/Makefile b/Makefile
index 4c6784e..fb6d60c 100644
--- a/Makefile
+++ b/Makefile
@@ -22,12 +22,6 @@ init:
-ssh $(REMOTE) 'git clone -o psigithub git@git.psi.ch:epics_support_apps/PBTools.git $(APP)/SwissMX/PBTools'
-ssh $(REMOTE) 'git clone -o psigithub git@git.psi.ch:epics_support_apps/ppmac.git $(APP)/SwissMX/PBTools/ppmac'
-rsync -vai simCamImg $(REMOTE):$(APP)/SwissMX/
-# -rsync -vai ../../PBTools $(REMOTE):$(APP)/SwissMX/
-# -ssh $(REMOTE) 'git clone -o psigithub git@git.psi.ch:epics_support_apps/PBTools.git $(APP)/PBTools'
-# ssh $(REMOTE) 'pip3.6 install --user pandas zmq qtawesome'
-# ssh $(REMOTE) '/opt/gfa/python-3.8/latest/bin/pip install --user pandas zmq qtawesome'
-# ssh $(REMOTE) 'pip3.6 install --prefix /sf/cristallina/applications/SwissMX/module pandas zmq qtawesome'
-# ssh $(REMOTE) '/opt/gfa/python-3.8/latest/bin/pip install --prefix /sf/cristallina/applications/SwissMX/module pandas zmq qtawesome'
update:
ssh $(REMOTE) 'cd $(APP)/SwissMX && git fetch psigithub && git reset psigithub/master --hard'
diff --git a/ModuleFixTarget.py b/ModuleFixTarget.py
index 2e01ba2..85d2f52 100644
--- a/ModuleFixTarget.py
+++ b/ModuleFixTarget.py
@@ -13,54 +13,17 @@ This contains a Widget to handle FixTargetFrames and fiducials, calculate final
#https://stackoverflow.com/questions/27909658/json-encoder-and-decoder-for-complex-numpy-arrays
-# import yaml
-# class Dice(tuple):
-# def __new__(cls, a, b):
-# return tuple.__new__(cls, [a, b])
-# def __repr__(self):
-# return "Dice(%s,%s)" % self
-# d=Dice(3,6)
-# print(d)
-# print(yaml.dump(d))
-# def dice_representer(dumper, data):
-# return dumper.represent_scalar(u'!dice', u'%sd%s' % data)
-# yaml.add_representer(Dice, dice_representer)
-# def dice_constructor(loader, node):
-# value = loader.construct_scalar(node)
-# a, b = map(int, value.split('d'))
-# return Dice(a, b)
-# yaml.add_constructor(u'!dice', dice_constructor)
-# print(yaml.load("initial hit points: !dice 8d4"))
-
import logging
_log=logging.getLogger(__name__)
-import json, base64 #, os, pickle, yaml
+import json, base64
import numpy as np
import pyqtUsrObj as UsrGO
import pyqtgraph as pg
-from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal, pyqtSlot
+from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal
from PyQt5.QtWidgets import (
- QTableWidgetItem,
- QFileDialog,
- QGroupBox,
- QWidget,
- QGridLayout,
- QTableWidget,
- QAbstractItemView,
- QItemDelegate,
- QVBoxLayout,
- QLabel,
- QPushButton,
- QApplication,
- QMainWindow,
- QHeaderView,
- QLineEdit,
- QSpinBox,
- QMessageBox,
- QAction,
- QComboBox,
- QCheckBox)
+ QFileDialog, QWidget, QGridLayout, QItemDelegate, QVBoxLayout, QPushButton, QApplication,
+ QMainWindow, QLineEdit, QMessageBox, QAction, QComboBox)
class MyJsonEncoder(json.JSONEncoder):
@@ -109,8 +72,6 @@ class MarkerDelegate(QItemDelegate):
return comboBox
def setEditorData(self, editor, index):
- # pos = comboBox.findText(index.model().data(index), Qt.MatchExactly)
- # comboBox.setCurrentIndex(pos)
editor.setText("{}".format(index.model().data(index)))
def setModelData(self, editor, model, index):
@@ -158,27 +119,11 @@ class WndFixTarget(QWidget):
btnSv.clicked.connect(lambda: self.save_file())
bl.addWidget(btnSv, 0, 1)
- # but = QPushButton("Random Data")
- # but.clicked.connect(self.generate_random_data)
- # bl.addWidget(but, 4, 0)
- # self._num_random_points = QSpinBox()
- # self._num_random_points.setMinimum(2)
- # self._num_random_points.setMaximum(10000)
- # self._num_random_points.setValue(10)
- # self._num_random_points.setSuffix(" points")
- # bl.addWidget(self._num_random_points, 4, 1)
-
btnDump = QPushButton("dump")
btnDump.clicked.connect(self.dump_data)
bl.addWidget(btnDump, 0, 2)
self._cbType=cb=QComboBox()
- #cb.addItem("C")
- #cb.addItem("C++")
- #cb.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget()", "Grid()"])
-
-
- #cb.currentIndexChanged.connect(self.selectionchange)
bl.addWidget(cb, 1,0,1,1)
self._txtParam=param=QLineEdit()
@@ -196,23 +141,7 @@ class WndFixTarget(QWidget):
bl.addWidget(btnFit, 2, 1,1,1)
layout.addWidget(frame)
- #self.markersTable.itemSelectionChanged.connect(self.selection_changed)
- #self.markersTable.setContextMenuPolicy(Qt.ActionsContextMenu)
- #deleteRowAction = QAction("Delete this row", self)
- #deleteRowAction.triggered.connect(self.delete_selected)
- #self.markersTable.addAction(deleteRowAction)
-
- #moveRequestAction = QAction("Move Here", self)
- #moveRequestAction.triggered.connect(self.request_stage_movement)
- #self.markersTable.addAction(moveRequestAction)
-
- #layout.addWidget(self.markersTable, stretch=2)
- #self.connect_all_signals()
-
- #self._yamlFn=fn=os.path.expanduser('~/.config/PSI/SwissMX.yaml')
-
- #self._tree=tree=pg.DataTreeWidget(data=self._data)
self._data=data
self._tree=tree=pg.DataTreeWidget(data=data)
layout.addWidget(tree, stretch=2)
diff --git a/PrelocatedCoordinatesModel.py b/PrelocatedCoordinatesModel.py
deleted file mode 100644
index 176767f..0000000
--- a/PrelocatedCoordinatesModel.py
+++ /dev/null
@@ -1,709 +0,0 @@
-# coding=utf-8
-import logging
-import os
-from os.path import join
-from typing import List
-
-import numpy as np
-try:
- import pandas as pd
-except ImportError as e:
- print (f'{e} import failed')
-#import transformations as tfs
-
-from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal, pyqtSlot
-from PyQt5.QtWidgets import (
- QTableWidgetItem,
- QFileDialog,
- QGroupBox,
- QWidget,
- QGridLayout,
- QTableWidget,
- QAbstractItemView,
- QItemDelegate,
- QVBoxLayout,
- QLabel,
- QPushButton,
- QApplication,
- QMainWindow,
- QHeaderView,
- QLineEdit,
- QSpinBox,
- QMessageBox,
- QAction,
- QCheckBox)
-
-logger = logging.getLogger(__name__)
-
-# from coord_library import conversions
-#import conversions #ZAC: orig. code
-from app_config import AppCfg
-
-#from storage import Folders #ZAC: orig. code
-#folders = Folders() #ZAC: orig. code
-
-XY_Coord = List[float]
-
-DATA_ITEM = 1
-ORIGINAL_X = 1
-ORIGINAL_Y = 2
-GONIO_X = 3
-GONIO_Y = 4
-
-
-RoleGoniometerCoord_X = 1 + Qt.UserRole
-RoleGoniometerCoord_Y = 2 + Qt.UserRole
-RoleCameraCoord_X = 3 + Qt.UserRole
-RoleCameraCoord_Y = 4 + Qt.UserRole
-RoleOriginalCoord_X = 5 + Qt.UserRole
-RoleOriginalCoord_Y = 6 + Qt.UserRole
-
-
-def sort_cmass_3d(coord):
- """sorts the 3D coordinates (np array 3 columns) with respect to their distane to the center of mass in 3d"""
- cm = conversions.find_geo_center(coord)
- # print cm
- moved_coord = conversions.center_coord(coord, cm)
- sorted_moved_coord = conversions.sort_center_3d(moved_coord)
- minus_cm = np.multiply(cm, -1)
- return conversions.center_coord(sorted_moved_coord, minus_cm)
-
-
-def sort_cmass(coord):
- """sorts the 2D coordinates (np array 2 columns) with respect to their distane to the center of mass"""
- cm = conversions.find_geo_center(coord)
- # print cm
- moved_coord = conversions.center_coord(coord, cm)
- sorted_moved_coord = conversions.sort_center(moved_coord)
- minus_cm = np.multiply(cm, -1)
- return conversions.center_coord(sorted_moved_coord, minus_cm)
-
-
-class MarkerDelegate(QItemDelegate):
- def createEditor(self, parent, option, index):
- comboBox = QLineEdit(parent)
- comboBox.editingFinished.connect(self.emitCommitData)
- return comboBox
-
- def setEditorData(self, editor, index):
- # pos = comboBox.findText(index.model().data(index), Qt.MatchExactly)
- # comboBox.setCurrentIndex(pos)
- editor.setText("{}".format(index.model().data(index)))
-
- def setModelData(self, editor, model, index):
- print("model {}".format(model))
- print(
- "delegate setData: {}x{} => {}".format(
- index.row(), index.column(), editor.text()
- )
- )
- model.setData(index, editor.text())
- model.setData(index, float(editor.text()), Qt.UserRole)
-
- def emitCommitData(self):
- print("imagedelegate emitting")
- self.commitData.emit(self.sender())
-
-
-class PrelocatedCoordinates(QWidget):
- prefixSelected = pyqtSignal(str)
- dataFileLoaded = pyqtSignal(str)
- prelocatedDataUpdated = pyqtSignal()
- markersDeleted = pyqtSignal()
- markerAdded = pyqtSignal(bool, list) # emits is_fiducial(boolean), [x, y, cx, cy]
- selectedRowChanged = pyqtSignal(int)
- moveFastStageRequest = pyqtSignal(float, float)
-
- def __init__(self, parent=None):
- super(PrelocatedCoordinates, self).__init__(parent)
- self._xtals_transformed = True
-
- self._current_row = None
-
- layout = QVBoxLayout()
-
- self.setLayout(layout)
- frame = QWidget()
- bl = QGridLayout()
- frame.setLayout(bl)
-
- self._label_prefix = QLabel("not set")
- self._label_datafile = QLabel("not loaded")
- self._label_datafile.setWordWrap(True)
- bl.addWidget(QLabel("Prefix"), 0, 0)
- bl.addWidget(self._label_prefix, 0, 1)
- bl.addWidget(QLabel("Data File"), 1, 0)
- bl.addWidget(self._label_datafile, 1, 1)
-
- but1 = QPushButton("Load Datafile")
- but1.clicked.connect(lambda: self.loadMarkers(None))
- bl.addWidget(but1, 2, 0)
-
- but1 = QPushButton("Save Datafile")
- but1.clicked.connect(lambda: self.saveDataAs())
- bl.addWidget(but1, 2, 1)
-
- but2 = QPushButton("Clear Data")
- but2.clicked.connect(self.clearMarkers)
- bl.addWidget(but2, 3, 0)
-
- # but = QPushButton("Random Data")
- # but.clicked.connect(self.generate_random_data)
- # bl.addWidget(but, 4, 0)
- # self._num_random_points = QSpinBox()
- # self._num_random_points.setMinimum(2)
- # self._num_random_points.setMaximum(10000)
- # self._num_random_points.setValue(10)
- # self._num_random_points.setSuffix(" points")
- # bl.addWidget(self._num_random_points, 4, 1)
-
- but = QPushButton("dump numpy")
- but.clicked.connect(self.dump_numpy)
- bl.addWidget(but, 5, 0)
-
-
- # but = QPushButton("Dump to console")
- # but.clicked.connect(self.dump_data)
- # bl.addWidget(but, 10, 0, 1, 1)
-
- but = QCheckBox("collect fiducials")
- but.setChecked(False)
- but.setToolTip("Collect or not the fiducial positions.")
- self._collect_fiducials = False
- but.stateChanged.connect(self.set_collect_fiducials)
- bl.addWidget(but, 10, 0, 1, 1)
-
-
- but = QCheckBox("draw crystal marks")
- but.setChecked(False)
- self._draw_crystal_marks = False
- but.stateChanged.connect(self.set_draw_crystal_marks)
- bl.addWidget(but, 10, 1, 1, 1)
-
-
- but = QPushButton("Transform")
- but.clicked.connect(self.transform_non_fiducials_in_model)
- bl.addWidget(but, 20, 0, 2, 2)
-
- layout.addWidget(frame)
- self.markersTable = QTableWidget()
- self.markersTable.setSelectionMode(QAbstractItemView.SingleSelection)
- self.markersTable.setSelectionBehavior(QAbstractItemView.SelectRows)
- self.markersTable.setItemDelegate(MarkerDelegate(self))
-
- # self.markersTable.horizontalHeader().setDefaultSectionSize(80)
- self.markersTable.setColumnCount(5)
- self.markersTable.setHorizontalHeaderLabels(
- ("Fiducial?", "orig X", "orig Y", "X", "Y")
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(
- 0, QHeaderView.ResizeToContents
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(
- 1, QHeaderView.ResizeToContents
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(
- 2, QHeaderView.ResizeToContents
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(
- 3, QHeaderView.ResizeToContents
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(
- 4, QHeaderView.ResizeToContents
- )
- self.markersTable.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
-
- self.markersTable.itemSelectionChanged.connect(self.selection_changed)
-
- self.markersTable.setContextMenuPolicy(Qt.ActionsContextMenu)
-
- deleteRowAction = QAction("Delete this row", self)
- deleteRowAction.triggered.connect(self.delete_selected)
- self.markersTable.addAction(deleteRowAction)
-
- moveRequestAction = QAction("Move Here", self)
- moveRequestAction.triggered.connect(self.request_stage_movement)
- self.markersTable.addAction(moveRequestAction)
-
- layout.addWidget(self.markersTable, stretch=2)
- self.connect_all_signals()
-
- def delete_selected(self):
- row = self._current_row
- try:
- row += 0
- except:
- logger.warning("select a row first")
- QMessageBox.warning(
- self,
- "Select a marker first",
- "You must select a marker first before updating its goniometer position",
- )
- return
- self.markersTable.removeRow(row)
- self.prelocatedDataUpdated.emit()
-
- def selection_changed(self):
- row = self.markersTable.currentRow()
- if row < 0:
- return
- self._current_row = row
- self.selectedRowChanged.emit(row)
- logger.debug("selection changed: current row {}".format(row))
-
- def connect_all_signals(self):
- self.prefixSelected.connect(lambda t: self._label_prefix.setText(t))
- self.dataFileLoaded.connect(lambda t: self._label_datafile.setText(t))
-
- def markerItemChanged(self, item):
- print(item.row(), item.column())
-
- def set_fiducial_coords(self, camx, camy, gx, gy):
- tbl = self.markersTable
- row = self._current_row
- try:
- row += 0
- except:
- logger.warning("select a row first")
- QMessageBox.warning(
- self,
- "Select a marker first",
- "You must select a marker first before updating its goniometer position",
- )
- return
-
- origx = tbl.item(row, ORIGINAL_X).data(RoleOriginalCoord_X)
- origy = tbl.item(row, ORIGINAL_Y).data(RoleOriginalCoord_Y)
-
- item = tbl.item(row, DATA_ITEM)
- item.setData(RoleCameraCoord_X, camx)
- item.setData(RoleCameraCoord_Y, camy)
- item.setData(RoleGoniometerCoord_X, gx)
- item.setData(RoleGoniometerCoord_Y, gy)
- # item.setData(RoleOriginalCoord_X, origx)
- # item.setData(RoleOriginalCoord_Y, origy)
- # logger.debug(': [{}] = Original: {}, {} | Camera: {}, {} | Gonio: {}, {}'.format(1+row, origx, origy, camx, camy, gx, gy))
- logger.debug(f": [{1+row}] = Original: {origx}, {origy} | Camera: {camx}, {camy} | Gonio: {gx}, {gy}")
-
-
- tbl.item(row, GONIO_X).setData(Qt.DisplayRole, f"{gx:8.5f} mm\n{camx:8.1f} px")
- tbl.item(row, GONIO_Y).setData(Qt.DisplayRole, f"{gy:8.5f} mm\n{camy:8.1f} px")
-
- # mark row as a fiducial
- tbl.item(row, 0).setCheckState(Qt.Checked)
- tbl.item(row, 0).setData(Qt.UserRole, True)
- tbl.selectRow(row + 1)
- self.prelocatedDataUpdated.emit()
-
- def set_selected_gonio_coords(self, xy: XY_Coord):
- tbl = self.markersTable
- row = self._current_row
- try:
- row += 0
- except:
- logger.warning("select a row first")
- QMessageBox.warning(
- self,
- "Select a marker first",
- "You must select a marker first before updating its goniometer position",
- )
- return
-
- for n, v in enumerate(xy):
- idx = 3 + n
- tbl.setCurrentCell(row, idx) # gonio X
- logger.debug("item: [{},{}] = {}".format(row, idx, v))
- item = tbl.currentItem()
- item.setData(Qt.EditRole, "{:.3f}".format(v))
- item.setData(Qt.UserRole, v)
-
- # mark row as a fiducial
- tbl.setCurrentCell(row, 0)
- tbl.currentItem().setCheckState(Qt.Checked)
- tbl.currentItem().setData(Qt.UserRole, True)
-
- def set_data_goniometer(self, row: int, xy: XY_Coord):
- tbl = self.markersTable
-
- row = self._current_row
- try:
- row += 0
- except:
- logger.warning("select a row first")
- QMessageBox.warning(
- self,
- "Select a marker first",
- "You must select a marker first before updating its goniometer position",
- )
- return
-
- for n, v in enumerate(xy):
- idx = 3 + n
- tbl.setCurrentCell(row, idx) # gonio X
- item = tbl.currentItem()
- item.setData(Qt.EditRole, "{:.3f}".format(v))
- item.setData(Qt.UserRole, v)
-
- @pyqtSlot(int)
- def set_draw_crystal_marks(self, val):
- logger.info(f"{'' if val else 'not '}drawing crystal markers")
- self._draw_crystal_marks = val
-
- @pyqtSlot(int)
- def set_collect_fiducials(self, val):
- logger.info(f"{'' if val else 'not '}collecting fiducials")
- self._collect_fiducials = val
-
- def get_collection_targets(self):
- return self.get_data(fiducials=self._collect_fiducials)
-
-
- def get_data(self, fiducials=True, crystals=True, as_numpy=False):
- """return a list of tuples with all defined data
-
- [
- (is_fiducial(boolean), x, y, gonio_x, gonio_y),...
- ]
- """
- data = []
- item = self.markersTable.item
-
- for row in range(self.markersTable.rowCount()):
- is_fiducial = Qt.Checked == item(row, 0).checkState()
- ditem = item(row, DATA_ITEM)
-
- x = ditem.data(RoleGoniometerCoord_X)
- y = ditem.data(RoleGoniometerCoord_Y)
- cx = ditem.data(RoleCameraCoord_X)
- cy = ditem.data(RoleCameraCoord_Y)
- origx = ditem.data(RoleOriginalCoord_X)
- origy = ditem.data(RoleOriginalCoord_Y)
-
- if is_fiducial and fiducials:
- data.append([is_fiducial, x, y, cx, cy, origx, origy])
- if not is_fiducial and crystals:
- data.append([is_fiducial, x, y, cx, cy, origx, origy])
-
- if as_numpy:
- data = np.asarray(data)
- return data
-
- def get_original_coordinates(self, fiducials=True):
- """return a numpy array with the original prelocated coordinates of the fiducial entries"""
- data = self.get_data(fiducials=fiducials, crystals=not fiducials, as_numpy=True)
- data = data[:, 5:]
- zeros = np.zeros(data.shape)
- zeros[:, 1] = 1
- return np.concatenate((data, zeros), axis=1)
-
- def get_goniometer_coordinates(self, fiducials=True):
- """return a numpy array with the goniometer coordinates of the fiducial entries"""
- data = self.get_data(fiducials=fiducials, crystals=not fiducials, as_numpy=True)
- data = data[:, 1:3]
- zeros = np.zeros(data.shape)
- zeros[:, 1] = 1
- return np.concatenate((data, zeros), axis=1)
-
- def get_camera_coordinates(self, fiducials=True):
- """return a numpy array with the goniometer coordinates of the fiducial entries"""
- data = self.get_data(fiducials=fiducials, crystals=not fiducials, as_numpy=True)
- data = data[:, 3:5]
- zeros = np.zeros(data.shape)
- zeros[:, 1] = 1
- return np.concatenate((data, zeros), axis=1)
-
- def dump_matrix(self, M):
- scale, shear, angles, translate, perspective = tfs.decompose_matrix(M)
- angles_deg = [a * 180 / np.pi for a in angles]
-
- print("Transformation matrix Aerotech => SwissMX")
- print(M)
- print((" scale {:9.4f} {:9.4f} {:9.4f}".format(*scale)))
- print((" shear {:9.4f} {:9.4f} {:9.4f}".format(*shear)))
- print((" angles rad {:9.4f} {:9.4f} {:9.4f}".format(*angles)))
- print((" angles deg {:9.4f} {:9.4f} {:9.4f}".format(*angles_deg)))
- print((" translate {:9.4f} {:9.4f} {:9.4f}".format(*translate)))
- print(("perspective {:9.4f} {:9.4f} {:9.4f}".format(*perspective)))
-
- def transform_non_fiducials_in_model(self):
- forg = self.get_original_coordinates(fiducials=True)
- fgon = self.get_goniometer_coordinates(fiducials=True)
- fcam = self.get_camera_coordinates(fiducials=True)
-
- gmat = sort_cmass_3d(fgon)
- omat = sort_cmass_3d(forg)
-
- try:
- M_org2gon = tfs.superimposition_matrix(omat.T, gmat.T, scale=True)
- M_org2cam = tfs.superimposition_matrix(forg.T, fcam.T, scale=True)
- except:
- QMessageBox.warning(self.parent(), title="failed to find superimposition matrix", text="Failed to find superimposition matrix.\n\tPlease try again.")
- return
-
- # scale, shear, angles, translate, perspective = tfs.decompose_matrix(M_org2gon)
-
- org_data = self.get_original_coordinates(fiducials=False)
-
- gon_data = np.dot(M_org2gon, org_data.T)
- cam_data = np.dot(M_org2cam, org_data.T)
-
- tbl = self.markersTable
- num_fiducials = forg.shape[0]
-
- gon_data = (gon_data.T)[:, 0:2] # only X,Y matters
- cam_data = (cam_data.T)[:, 0:2] # only X,Y matters
- combined = np.concatenate((gon_data, cam_data), axis=1)
-
- item = self.markersTable.item # function alias
- for row, data in enumerate(
- combined, num_fiducials
- ): # enumeration starts at *num_fiducials*
- gx, gy, cx, cy = data
- ditem = item(row, DATA_ITEM)
- ditem.setData(RoleCameraCoord_X, cx)
- ditem.setData(RoleCameraCoord_Y, cy)
- ditem.setData(RoleGoniometerCoord_X, gx)
- ditem.setData(RoleGoniometerCoord_Y, gy)
- item(row, GONIO_X).setData(Qt.DisplayRole, f"{gx:8.5f} mm\n{cx:8.1f} px")
- item(row, GONIO_Y).setData(Qt.DisplayRole, f"{gy:8.5f} mm\n{cy:8.1f} px")
- self._xtals_transformed = True
- self.prelocatedDataUpdated.emit()
-
- def request_stage_movement(self):
- logger = logging.getLogger("preloc.move_stage")
- row = self._current_row
- x = self.markersTable.item(row, DATA_ITEM).data(RoleGoniometerCoord_X)
- y = self.markersTable.item(row, DATA_ITEM).data(RoleGoniometerCoord_Y)
- logger.info(f"request move gonio to {x:.3f}, {y:.3f} mm")
- self.moveFastStageRequest.emit(x, y)
-
- def dump_numpy(self):
- R = tfs.random_rotation_matrix(np.random.random(3))
- d = self.get_goniometer_coordinates()
- print("dumping")
- print(d)
- dR = np.dot(R, d)
- print(dR.T)
-
- def get_fiducials(self, as_numpy=False):
- return self.get_data(crystals=False, as_numpy=as_numpy)
-
- def get_crystals(self, as_numpy=False):
- return self.get_data(fiducials=False, as_numpy=as_numpy)
-
- def dump_data(self):
- for ref, x, y, cx, cy, ox, oy in self.get_data():
- print(f"fiducial:{ref} [{x}, {y}, {cx}, {cy}]")
-
- def append_data(self, data: List):
- """append data (a list of values) to the model
-
- len(data) == 2 => (X, Y) from prelocated coordinate
- len(data) == 4 => (X, Y, GX, GY) plus gonio coordinates
- len(data) == 5 => (fiducial?, X, Y, GX, GY) plus fiducial
- """
- row = self.markersTable.rowCount()
- self.markersTable.setRowCount(row + 1)
-
- data = list(data)
- if len(data) == 2:
- data.extend([0, 0])
- if len(data) == 4:
- data.insert(0, False) # fiducial flag
- self.addSingleMarker(row, data)
- self.prelocatedDataUpdated.emit()
-
- def clearMarkers(self):
- self.markersTable.setRowCount(0)
- self.markersDeleted.emit()
-
- def generate_random_data(self):
- import io
-
- data = io.StringIO()
- npoints = self._num_random_points.value()
- for n in range(npoints):
- x, y, a, b = (
- np.random.randint(0, 2000),
- np.random.randint(0, 2000),
- np.random.randint(-4000, 4000) / 1000.,
- np.random.randint(-4000, 4000) / 1000.,
- )
- data.write("{}\t{}\t{}\t{}\n".format(x, y, a, b))
- data.seek(0)
- data.name = "random.csv"
- self.loadMarkers(data)
-
- def saveDataAs(self, filename=None):
- # filename = folders.get_file("prelocated-save.dat")
- data_folder = settings.value("folders/last_prelocation_folder")
- if filename is None:
- filename, _ = QFileDialog.getSaveFileName(
- parent=None,
- caption="Open CSV data file",
- directory=data_folder,
- filter="CSV Data Files (*.csv);;All Files (*)",
- )
-
- if not filename:
- return
-
- settings.setValue("folders/last_prelocation_folder", QFileInfo(filename).canonicalPath())
- logger.info("Saving data in {}".format(filename))
- data = self.get_data(as_numpy=True)
- df = pd.DataFrame(data)
- df.to_csv(filename, float_format="%.6f")
-
- def addSingleMarker(self, row, marker):
- is_fiducial, origx, origy, gx, gy = marker
- logger.debug(f": [{1+row}] | Original: {origx}, {origy} | Gonio: {gx}, {gy}")
- item0 = QTableWidgetItem()
- item0.setData(Qt.UserRole, is_fiducial)
- item0.setFlags(item0.flags() & ~Qt.ItemIsEditable)
- item0.setCheckState(Qt.Checked if is_fiducial else Qt.Unchecked)
- item0.setTextAlignment(Qt.AlignCenter)
-
- item1 = QTableWidgetItem("{:.1f}".format(origx))
- item1.setTextAlignment(Qt.AlignRight)
-
- item2 = QTableWidgetItem("{:.1f}".format(origy))
- item2.setTextAlignment(Qt.AlignRight)
-
- item3 = QTableWidgetItem("{:.3f} mm".format(gx))
- item3.setFlags(item3.flags() & ~Qt.ItemIsEditable)
- item3.setTextAlignment(Qt.AlignRight)
-
- item4 = QTableWidgetItem("{:.3f} mm".format(gy))
- item4.setFlags(item4.flags() & ~Qt.ItemIsEditable)
- item4.setTextAlignment(Qt.AlignRight)
-
- self.markersTable.setItem(row, 0, item0)
- self.markersTable.setItem(row, ORIGINAL_X, item1)
- self.markersTable.setItem(row, ORIGINAL_Y, item2)
- self.markersTable.setItem(row, GONIO_X, item3)
- self.markersTable.setItem(row, GONIO_Y, item4)
- self.markerAdded.emit(is_fiducial, [origx, origy, gx, gy])
-
- item = self.markersTable.item(row, DATA_ITEM)
- item.setData(RoleCameraCoord_X, origx) # initially set to original
- item.setData(RoleCameraCoord_Y, origy) # initially set to original
- item.setData(RoleGoniometerCoord_X, gx)
- item.setData(RoleGoniometerCoord_Y, gy)
- item.setData(RoleOriginalCoord_X, origx)
- item.setData(RoleOriginalCoord_Y, origy)
-
- def loadMarkers(self, filename=None):
- logger = logging.getLogger("preloc.loadMarkers")
- #def_folder = join(folders.pgroup_folder, "preloc_sheets") #ZAC: orig. code
- def_folder =''
- data_folder = settings.value("folders/last_prelocation_folder", def_folder)
-
- if filename is None:
- filename, _ = QFileDialog.getOpenFileName(
- self,
- "Open CSV data file",
- data_folder,
- "Any file.. (*.txt);;CSV Data Files (*.csv);;All Files (*)",
- )
-
- # filename = folders.get_file("preloc-in.csv")
-
-
- if not filename: # cancelled dialog
- return
-
-
- try:
- settings.setValue("folders/last_prelocation_folder", QFileInfo(filename).canonicalPath())
- settings.setValue("folders/last_prelocation_sheet", QFileInfo(filename).absolutePath())
- except TypeError as e:
- pass
-
- self.clearMarkers()
-
- logger.info(f"loading prelocated coords from {filename}")
- df = pd.read_csv(filename, comment="#", header=None, delim_whitespace=False, delimiter="[\t,;]")
-
- try:
- prefix = QFileInfo(filename).baseName()
- except:
- prefix = filename.name
- filename = prefix
-
- logger.info(f"prefix => {prefix}")
-
- gonio_coords_available = True
- for data in df.as_matrix(): # FIXME FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.
- row = self.markersTable.rowCount()
- self.markersTable.setRowCount(row + 1)
- original = np.copy(data)
- data = list(data)
-
- if len(data) in [2, 3]:
- gonio_coords_available = False
- data.extend([0, 0])
-
- if len(data) == 4:
- data.insert(0, False) # fiducial flag
- elif len(data) == 5: # fiducial already there, convert to bool
- data[0] = bool(data[0])
- else:
- QMessageBox.warning(
- self,
- "Wrong number of points in data file",
- "I was expecting either 2, 3, 4 or 5 data points per line."
- "\n\nFailed around a line with: {}".format(list(original)),
- )
-
- self.addSingleMarker(row, data)
-
- self._xtals_transformed = False
- self.prefixSelected.emit(prefix)
-
- # only emit this signal if goniometer coordinates already read from file
- if gonio_coords_available:
- logger.debug(f"dataFileLoaded.emit => {filename}")
- self.dataFileLoaded.emit(filename)
-
-
-"""
-Signals QTableWidget
-void cellActivated(int row, int column)
-void cellChanged(int row, int column)
-void cellClicked(int row, int column)
-void cellDoubleClicked(int row, int column)
-void cellEntered(int row, int column)
-void cellPressed(int row, int column)
-void currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
-void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
-void itemActivated(QTableWidgetItem *item)
-void itemChanged(QTableWidgetItem *item)
-void itemClicked(QTableWidgetItem *item)
-void itemDoubleClicked(QTableWidgetItem *item)
-void itemEntered(QTableWidgetItem *item)
-void itemPressed(QTableWidgetItem *item)
-void itemSelectionChanged()
-"""
-
-
-class MainWindow(QMainWindow):
- def __init__(self, parent=None):
- super(MainWindow, self).__init__(parent)
- self.centralWidget = QWidget()
-
- self.markwi = PrelocatedCoordinates(parent=self)
-
- self.setCentralWidget(self.centralWidget)
- mainLayout = QVBoxLayout()
- mainLayout.addWidget(self.markwi)
- self.centralWidget.setLayout(mainLayout)
-
-
-if __name__ == "__main__":
-
- import sys
-
- app = QApplication(sys.argv)
- mainWin = MainWindow()
- mainWin.show()
- sys.exit(app.exec_())
diff --git a/app_config.py b/app_config.py
index 4b9b22f..2a69b6a 100644
--- a/app_config.py
+++ b/app_config.py
@@ -6,14 +6,11 @@
# #yaml is fixed and not altened by program
import logging
-import re
-
_log = logging.getLogger(__name__)
-from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication, QMainWindow
-import json
+import json,re
import numpy as np
class MyJsonEncoder(json.JSONEncoder):
@@ -636,206 +633,15 @@ verbose bits:
for i,k in lut:
cld[i].setValue(twk[k].get_val())
- #def cb_save(self):
- # self._state=p.saveState()
-
- #def cb_restore(self):
- # p=self._p
- # add=p['Save/Restore functionality', 'Restore State', 'Add missing items']
- # rem=p['Save/Restore functionality', 'Restore State', 'Remove extra items']
- # p.restoreState(self._state, addChildren=add, removeChildren=rem)
-
-# ----------------------------- OBSOLETE -----------------------------
-
-#inst_folder = Path(__file__).absolute().parent
-#config_file = inst_folder / "swissmx.yaml"
-#configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
-#endstation = configs["configure_for"]
-#appsconf = configs[endstation]
-#simulated = appsconf.get("simulate", False)
-#logger.info(f"configuring for endstation: {endstation.upper()}")
-
-#if simulated:
-# logger.warning("SIMULATION is ACTIVE")
-#css_file = inst_folder / "swissmx.css"
-
-
-
-#def font(name: str) -> str:
-# p = Path(__file__).absolute().parent / "fonts" / name
-# return str(p)
-
-
-#def logo(size: int = 0) -> str:
-# p = Path(__file__).absolute().parent / "logos" / "logo.png"
-# if size:
-# p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png"
-# return str(p)
-
-
-# def dlg_geometry(self,obj):
-# SPN=GenericDialog.Spinner
-# app=QApplication.instance()
-# cfg=app._cfg
-# w, h = map(float,cfg.value(AppCfg.GEO_BEAM_SZ))
-# d = GenericDialog.GenericDialog(
-# title="geometry",
-# message="Enter the size of the beam in microns",
-# inputs={
-# "bw": ("beam width um" ,w,SPN(w, min=1, max=200, suffix=" \u00B5m"),),
-# "bh": ("beam height um",h,SPN(h, min=1, max=200, suffix=" \u00B5m"),),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("Updating beamsize to {}".format(results))
-# bm_sz= (results["bw"], results["bh"])
-# _log.debug("types {}".format(type(w)))
-# cfg.setValue(AppCfg.GEO_BEAM_SZ, bm_sz)
-# cfg.sync()
-# bm=obj._goBeamMarker
-# bm.setSize(bm_sz)
-# #self._beammark.set_beam_size((w, h))
-#
-# def dlg_collimator_reference_positions(self):
-# SPN=GenericDialog.Spinner
-# app=QApplication.instance()
-# cfg=app._cfg
-# x_out = cfg.value(AppCfg.COL_DX , 0.0,type=float)
-# y_out = cfg.value(AppCfg.COL_DY , 0.0,type=float)
-# x_in = cfg.value(AppCfg.COL_X_IN, 0.0,type=float)
-# y_in = cfg.value(AppCfg.COL_Y_IN, 0.0,type=float)
-# d = GenericDialog.GenericDialog(
-# title="Collimator configuration",
-# message="Enter reference positions for the collimator",
-# inputs={
-# AppCfg.COL_DX: ("Collimator out deltaX", x_out, SPN(x_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
-# AppCfg.COL_DY: ("Collimator out deltaY", y_out, SPN(y_out, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
-# AppCfg.COL_X_IN: ("Collimator in X", x_in, SPN(x_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
-# AppCfg.COL_Y_IN: ("Collimator in Y", y_in, SPN(y_in, decimals=3, min=-15.9, max=15.9, suffix=" mm"),),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("setting collimator reference positions {}".format(results))
-# for k, v in results.items():
-# cfg.setValue(k, v)
-# cfg.sync()
-#
-# def dlg_backlight_positions(self):
-# SPN=GenericDialog.Spinner
-# app=QApplication.instance()
-# cfg=app._cfg
-# p_in = cfg.value(AppCfg.BKLGT_IN,0,type=int)
-# p_out = cfg.value(AppCfg.BKLGT_OUT,0,type=int)
-# d = GenericDialog.GenericDialog(
-# title="Back Light configuration",
-# message="Enter reference positions for the backlight",
-# inputs={
-# AppCfg.BKLGT_IN: ("In position" , p_in , SPN(p_in, min=-30000, max=10), ),
-# AppCfg.BKLGT_OUT: ("Out position", p_out, SPN(p_out, min=-1000, max=10), ),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("setting back light reference positions {}".format(results))
-# for k, v in results.items():
-# cfg.setValue(k, v)
-# cfg.sync()
-#
-# def dlg_cryojet_positions(self):
-# p_in = settings.value(CRYOJET_NOZZLE_IN, type=float)
-# p_out = settings.value(CRYOJET_NOZZLE_OUT, type=float)
-# motion_enabled = option(CRYOJET_MOTION_ENABLED)
-# d = GenericDialog(
-# title="Cryojet Nozzle Configuration",
-# message="Enter reference positions for the cryojet nozzle position",
-# inputs={
-# CRYOJET_NOZZLE_IN: ("In position", p_in, Spinner(p_in, min=3, max=15)),
-# CRYOJET_NOZZLE_OUT: ("Out position",p_out,Spinner(p_out, min=-1000, max=10),),
-# CRYOJET_MOTION_ENABLED: ("Move Cryojet in Transitions",motion_enabled,Checkbox(motion_enabled, "move cryojet"),),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("setting cryojet reference positions {}".format(results))
-# for k, v in results.items():
-# settings.setValue(k, v)
-# settings.sync()
-#
-# def dlg_deltatau_parameters(self):
-# SPN=GenericDialog.Spinner
-# CB=GenericDialog.Checkbox
-# app=QApplication.instance()
-# cfg=app._cfg
-# #dt1 = cfg.value(AppCfg.DT_HOST,'SAR-CPPM-EXPMX1')
-# dt1 = cfg.value(AppCfg.DT_HOST)
-# dt2 = cfg.value(AppCfg.DT_VEL_SCL, 1, type=float)
-# dt3 = cfg.option(AppCfg.DT_SHOW_PLOTS)
-#
-# d = GenericDialog.GenericDialog(
-# title="Delta Tau Parameters",
-# message="These parameters affect the data collection.",
-# inputs={
-# AppCfg.DT_HOST:("host name (host[:port:port_gather])", dt1, QLineEdit(),),
-# AppCfg.DT_VEL_SCL: ("Velocity Scale (1=optimal, 0=zero vel at target)", dt2,SPN(dt2, min=0, max=1, suffix=""),),
-# AppCfg.DT_SHOW_PLOTS: ("show plots after collection", dt3,CB(dt3, "active"),),
-# #DELTATAU_SORT_POINTS: ("Sort pointshoot/prelocated coords", b,CB(b, "sort points"),),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("setting delta tau parameters {}".format(results))
-# for k, v in results.items():
-# cfg.setValue(k, v)
-# cfg.sync()
-#
-# def dlg_tell_mount_positions(self):
-# AUTODRY_ENABLED = "tell/autodry_enabled"
-# AUTODRY_MAXMOUNTS = "tell/autodry_max_number_of_mounts"
-# AUTODRY_MAXTIME = "tell/autodry_max_time"
-#
-# SECS_HOURS = 60 * 60
-#
-# enabled = option(AUTODRY_ENABLED)
-# maxtime = settings.value(AUTODRY_MAXTIME, type=float) / SECS_HOURS
-# maxmounts = settings.value(AUTODRY_MAXMOUNTS, type=int)
-#
-# d = GenericDialog.GenericDialog(
-# title="TELL Settings",
-# message="These control some features of the TELL sample changer",
-# inputs={
-# AUTODRY_ENABLED: ("Auto dry", enabled,
-# Checkbox(enabled, "enabled")),
-# AUTODRY_MAXMOUNTS: ("Max. num. mounts between dry",maxmounts,
-# Spinner(maxmounts, decimals=0, min=1, max=100, suffix=" mounts"),),
-# AUTODRY_MAXTIME: ("Max. time between dry",maxtime,
-# Spinner(maxtime, decimals=1, min=0.5, max=5, suffix=" hours"),),
-# },
-# )
-# if d.exec():
-# results = d.results
-# _log.info("setting tell parameters {}".format(results))
-# for k, v in results.items():
-# if k == AUTODRY_MAXTIME:
-# v = v * SECS_HOURS
-# settings.setValue(k, v)
-# settings.sync()
-
-# ----------------------------------------------
-
-## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
-
import sys
+ from PyQt5 import QtCore
app=QApplication([])
app._cfg=AppCfg()
-
w=WndParameter(None)
w.show()
-
-
+ ## Start Qt event loop unless running in interactive mode or using pyside.
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QApplication.instance().exec_()
diff --git a/app_utils.py b/app_utils.py
index f5e4278..cb6424b 100644
--- a/app_utils.py
+++ b/app_utils.py
@@ -1,9 +1,7 @@
-import time
-
import logging
-
_log=logging.getLogger(__name__)
+import time
from epics.ca import pend_event
class PositionsNotReached(Exception):
diff --git a/backlight.py b/backlight.py
index b34fc5d..38d4223 100755
--- a/backlight.py
+++ b/backlight.py
@@ -10,9 +10,6 @@ import logging
_log=logging.getLogger(__name__)
import epics
-#from app_config import settings
-#from app_utils import assert_motor_positions
-
class Backlight(object):
def __init__(self, prefix: str='SAR-EXPMX:MOT_BLGT',pos={'pos_in':-30500,'pos_out':1000,'pos_diode':-30500}):
if prefix is None:
@@ -44,7 +41,6 @@ class Backlight(object):
m.move(target, ignore_limits=True, wait=wait)
-
if __name__ == "__main__":
import time,os
import argparse
diff --git a/camera.py b/camera.py
index 1450a76..1b0de63 100755
--- a/camera.py
+++ b/camera.py
@@ -41,10 +41,9 @@ Best regards
import logging
_log = logging.getLogger(__name__)
-import enum, epics, time
+import time, enum, epics
import numpy as np
-
class Camera(enum.IntEnum):
OFF = 0
RUNNING = 1
@@ -197,10 +196,6 @@ class epics_cam(object):
elif k=='roi':
pv_rxs=self.getPv('REGIONX_START');pv_rxe=self.getPv('REGIONX_END')
pv_rys=self.getPv('REGIONY_START');pv_rye=self.getPv('REGIONY_END')
- #pv_rxs.put(v[0], wait=False)
- #pv_rxe.put(v[0]+v[2], wait=False)
- #pv_rys.put(v[1], wait=False)
- #pv_rye.put(v[1]+v[3], wait=False)
param.append((pv_rxs,v[0]))
param.append((pv_rxe,v[0]+v[2]))
param.append((pv_rys,v[1]))
@@ -277,9 +272,6 @@ class epics_cam(object):
xx, yy = np.meshgrid(x, y)
for i in range(t):
- #imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+.1*i)**2 + np.sin(yy+.01*i)**2)#+xx*t+yy*t)
- #imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+.1*i)**2 + np.sin((1+.1*np.sin(.2*i))*yy+.001*i**2)**2)#+xx*t+yy*t)
- #imgSeq[i,:,:] = 100*np.sqrt(np.sin(xx+2*np.sin(i/t*2*np.pi))**2 + np.sin(yy)**2)
px=2*np.sin(i/t*2*np.pi)
fx=1
py=2*np.sin(i/t*2*np.pi)
@@ -323,7 +315,7 @@ class epics_cam(object):
if __name__ == "__main__":
- import time, os, PIL.Image, platform, subprocess
+ import os, PIL.Image, platform, subprocess
import argparse
logging.basicConfig(level=logging.DEBUG,format='%(name)s:%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
logging.getLogger('PIL').setLevel(logging.INFO)
@@ -337,9 +329,6 @@ if __name__ == "__main__":
else: # linux variants
subprocess.call(('xdg-open', file))
-
-
-
parser = argparse.ArgumentParser()
parser.add_argument("--ui", "-u", help="qt test", type=int, default=0)
parser.add_argument("--sim", "-s", help="simulation mode", type=int, default=None)
@@ -355,20 +344,12 @@ if __name__ == "__main__":
else:
os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
-
if not args.ui:
cam = epics_cam(prefix=args.prefix)
#cam._transformation=np.array(((-1,0),(0,1)),dtype=np.uint8) #ZAC: orig. code
if args.prefix is None:
cam.sim_gen(mode=args.sim)
- #sz=(2448,2048)
- #ctr=(1200,1400)
- #sz=(1200,1000)
- #cam.set_roi(int(ctr[0]-sz[0]/2),int(ctr[0]+sz[0]/2),int(ctr[1]-sz[1]/2),int(ctr[1]+sz[1]/2))
- #cam.set_exposure(3)
- #cam.set_binning(1,1)
-
cam.run()
n = 1
base = "/tmp/image_{:05d}.png"
diff --git a/detector.py b/detector.py
index a199bd5..2762a39 100644
--- a/detector.py
+++ b/detector.py
@@ -1,17 +1,8 @@
import logging
_log=logging.getLogger(__name__)
-#from glob import glob
-
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
-#import eventer
-#import qsingleton
-#from detector_integration_api import DetectorIntegrationClient
-#from app_config import settings, appsconf, simulated
-#config = appsconf['jungfrau']
-#dia_client = DetectorIntegrationClient(config['uri'])
-
class JungfrauWaiter(QObject):
finished = pyqtSignal()
@@ -22,9 +13,11 @@ class JungfrauWaiter(QObject):
def work(self):
pass
+
class JungfrauMissingConfiguration(Exception):
pass
+
class Jungfrau(QObject):
pedestal_selected = pyqtSignal(str)
configured = pyqtSignal()
diff --git a/obsolete.py b/obsolete.py
deleted file mode 100644
index 44b6f12..0000000
--- a/obsolete.py
+++ /dev/null
@@ -1,3050 +0,0 @@
- # **************** OBSOLETE AND/OR OLD STUFF ****************
-
-class WndSwissMx(QMainWindow, Ui_MainWindow):
-
- # **************** OBSOLETE AND/OR OLD STUFF ****************
-
-
-# functions are prefixed with _OLD_
- def _OLD_build_daq_methods_grid_tab(self):
- self._grids = []
- tab = self._tab_daq_method_grid
- layout = tab.layout() # gridlayout
- self._sb_grid_x_step.setValue(30)
- self._sb_grid_y_step.setValue(30)
- self._bt_add_grid.clicked.connect(self._OLD_daq_grid_add_grid)
- self._bt_remove_all_grids.clicked.connect(self._OLD_daq_grid_remove_all)
- self._find_targets_from_microscope_image.clicked.connect(self._OLD_daq_grid_findxtals)
- self.addGridRequest.connect(self._OLD_daq_grid_add_grid)
- self.gridUpdated.connect(self._OLD_daq_grid_update)
-
- def _OLD_build_daq_methods_prelocated_tab(self):
- tab = self._tab_daq_method_prelocated
- self.prelocationModule = PrelocatedCoordinatesModel.PrelocatedCoordinates(parent=self)
- tab.layout().addWidget(self.prelocationModule)
- self.prelocationModule.prefixSelected.connect(lambda prefix: self._le_prefix.setText(prefix))
- self.prelocationModule.dataFileLoaded.connect(self._OLD_daq_method_prelocated_update_markers)
- self.prelocationModule.prelocatedDataUpdated.connect(self._OLD_daq_method_prelocated_update_markers)
- self.prelocationModule.markersDeleted.connect(self._OLD_daq_method_prelocated_remove_markers)
- self.fiducialPositionSelected.connect(self._OLD_daq_method_prelocated_set_fiducial)
- self.appendPrelocatedPosition.connect(self._OLD_daq_method_prelocated_append_data)
- self.prelocationModule.moveFastStageRequest.connect(self._OLD_move_fast_stage)
- self._preloc_inspect_area = QPlainTextEdit()
- tab.layout().addWidget(self._preloc_inspect_area)
-
- def _OLD_build_daq_methods_embl_tab(self):
- app = QApplication.instance()
- self._tab_daq_method_embl.setLayout(QVBoxLayout())
- layout = self._tab_daq_method_embl.layout()
- #motors = self.get_gonio_motors()
- self._embl_module = EmblWidget(self) #ZAC: orig. code
- #self._embl_module.configure(motors, app._camera, app._zoom)
- layout.addWidget(self._embl_module)
-
- def _OLD_create_helical_widgets(self):
- tbox = self._helical_tablebox
- htab = self._helical_scan_table = HelicalTableWidget()
- htab.gonioMoveRequest.connect(self._OLD_move_gonio_to_position)
- tbox.setLayout(QVBoxLayout())
-
- grp = QWidget()
- grp.setLayout(QFormLayout())
- le = QSpinBox()
- le.setRange(1, 100)
- le.setValue(htab.scanHorizontalCount())
- le.valueChanged.connect(lambda cnt: htab.setScanHorizontalCount(cnt))
- grp.layout().addRow("Horizontal Count", le)
-
- le = QSpinBox()
- le.setRange(1, 100)
- le.setValue(htab.scanVerticalCount())
- le.valueChanged.connect(lambda cnt: htab.setScanVerticalCount(cnt))
- grp.layout().addRow("Vertical Count", le)
-
- le = QDoubleSpinBox()
- le.setRange(-180.0, 180.0)
- le.setSingleStep(5.0)
- le.setSuffix(" degrees")
- le.valueChanged.connect(htab.setStartAngle)
- grp.layout().addRow("Start angle", le)
-
- tbox.layout().addWidget(grp)
- widgi = QWidget()
- widgi.setLayout(QHBoxLayout())
- tbox.layout().addWidget(widgi)
-
- but = QPushButton("Add Crystal")
- but.clicked.connect(htab.add_xtal)
- widgi.layout().addWidget(but)
-
- but = QPushButton("Set START")
- but.clicked.connect(lambda: htab.set_xtal_start(self.get_gonio_positions()))
- widgi.layout().addWidget(but)
-
- but = QPushButton("Set END")
- but.clicked.connect(lambda: htab.set_xtal_end(self.get_gonio_positions()))
- widgi.layout().addWidget(but)
-
- tbox.layout().addWidget(htab)
-
- def _OLD_add_beam_marker(self):
- app = QApplication.instance()
- cfg = app._cfg
- w, h = cfg.value(AppCfg.GEO_BEAM_SZ)
- self._beammark = bm = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
- tr=QtGui.QTransform() # prepare ImageItem transformation:
- tr.rotate(30)
- bm.setTransform(tr) # assign transform
- self.vb.addItem(self._beammark)
- bm=UsrGO.BeamMark([50, 120], [30, 20])
- self.vb.addItem(bm)
- vi=UsrGO.Grid((120, -100), (200, 150), (30, 20), 2)
- self.vb.addItem(vi)
-
- def _OLD_camera_pause_toggle(self):
- app=QApplication.instance()
- app._camera.pause()
-
- def _OLD_init_settings_tracker(self):
- app=QApplication.instance()
- cfg=app._cfg
- _log.info("configuring widget persistence")
- fields = {
- # 'folder': (self._label_folder, str),
- "project": (self._le_project, str),
- "prefix": (self._le_prefix, str),
- "actual_prefix": (self._label_actual_prefix, str),
- "exposureTime": (self._dsb_exposure_time, float),
- "oscillationAngle": (self._dsb_oscillation_step, float),
- "blastRadius": (self._dsb_blast_radius, float),
- }
- for key, f_config in fields.items():
- widget, conv = f_config
- value = cfg.value(key)
- try:
- wset, wget = widget.setText, widget.text
- _log.debug("tracking text field {}".format(key))
- except AttributeError:
- _log.debug("tracking {} number field {}".format(conv, key))
- wset, wget = widget.setValue, lambda fget=widget.value: conv(fget())
- except Exception as e:
- _log.error(e)
-
- try:
- wset(conv(value))
- except Exception as e:
- _log.debug(e)
- _log.warning('failed for "{}" updating field of type {} with {}'.format( key, type(widget), value))
- finally:
- # _log.debug('wget = {}; wset = {}'.format(wget, wset))
- widget.editingFinished.connect(lambda w=widget, k=key, func_get=wget: self.persist_setting(k, func_get() ) )
- #self.storage_cascade_prefix(None) #ZAC: orig. code
-
- def _OLD_init_validators(self):
- identifier_regex = QRegExp("[a-z-A-Z_0-9%]+")
- self._le_project.setValidator(QRegExpValidator(identifier_regex, self._le_project))
- self._le_prefix.setValidator(QRegExpValidator(identifier_regex, self._le_prefix))
-
- def _OLD_wire_storage(self):
- self._le_prefix.textChanged.connect(self._OLD_storage_cascade_prefix)
- self._le_prefix.textChanged.connect(lambda newtext: self.prefixChanged.emit(newtext))
- self._le_project.textChanged.connect(self._OLD_storage_cascade_prefix)
- self._le_project.textChanged.connect(lambda newtext: self.projectChanged.emit(newtext))
- self._le_prefix.editingFinished.connect(self._OLD_prepare_daq_folder)
- self._le_project.editingFinished.connect(self._OLD_prepare_daq_folder)
- self.increaseRunNumberRequest.connect(self._OLD_increase_run_number)
-
- def _OLD_storage_cascade_prefix(self, val):
- prefix = self._le_prefix.text()
- if 0 == len(prefix):
- _log.warning("empty prefix is not accepted")
- self._le_prefix.setAccessibleName("invalid_input")
- self._le_prefix.blockSignals(True)
- self._le_prefix.setText("INVALID=>" + prefix)
- QMessageBox.warning(self, "prefix is not valid", "Prefix is not valid!")
- self._le_prefix.blockSignals(False)
-
- return
- else:
- self._le_prefix.setAccessibleName("")
- project = self._le_project.text()
- folders.set_prefix(prefix)
- folders.set_project(project)
- folders.run = settings.value("run_number", type=int)
- self._label_runnumber.setText(f"{folders.run:04d}")
- self._data_folder = folders.raw_folder
- self.folderChanged.emit(folders.raw_folder)
- self._label_actual_prefix.setText(folders.prefix)
- self._label_folder.setText(folders.raw_folder)
-
- def _OLD_increase_run_number(self):
- run = settings.value("run_number", type=int)
- run += 1
- settings.setValue("run_number", run)
- folders.run = run
- self._label_runnumber.setText(f"{run:04d}")
-
- def _OLD_prepare_daq_folder(self):
- global home, folders
- prefix = folders.prefix
- folder = folders.res_folder
- if 0 == len(prefix):
- return
-
- try:
- os.makedirs(folder, 0o750, exist_ok=True)
- except:
- msg = "Failed to create folder: {}".format(folder)
- _log.warning(msg)
- QMessageBox.warning(self, "Screenshot: failed to create folder", "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!",)
- raise
-
- fname = os.path.join(folders.pgroup_folder, ".latest_raw")
- try:
- with open(fname, "w") as f:
- f.write(folders.raw_folder)
- _log.info("wrote: {}".format(fname))
- except:
- _log.warning("failed writing {}".format(fname))
-
- fname = os.path.join(folders.pgroup_folder, ".latest_res")
- try:
- with open(fname, "w") as f:
- f.write(folders.res_folder)
- _log.info("wrote: {}".format(fname))
- except:
- _log.warning("failed writing {}".format(fname))
-
- def _OLD_persist_setting(self, s, v):
- app=QApplication.instance()
- cfg=app._cfg
- _log.debug("persisting {} = {}".format(s, v))
- cfg.setValue(s, v)
-
- def _OLD_method_changed(self, index):
- method = self._tabs_daq_methods.currentWidget().accessibleName()
- _log.info("method now => {}".format(method))
-
-
-
- def _OLD_check_zescape(self):
- msg = zescape.check()
- if msg is None:
- return
- if "current" in msg:
- _log.warning(f"current state: {self._esc_state}")
- zescape.reply(self._esc_state)
- elif "goto" in msg:
- state = msg.split()[1].lower()
- _log.warning(f"TELL requests to go to {state}")
- try:
- if "sampleexchange" in state:
- _log.debug(
- f"moving to mount with offset = {self._pin_mounting_offset}"
- )
- self.move_gonio_to_mount_position(offset=self._pin_mounting_offset)
- elif "samplealignment" in state:
- self.cb_esc_sample_alignment()
- except:
- zescape.reply("Maintenance")
- zescape.reply(self._esc_state)
- else: # JSON
- data = json.loads(msg)
- if "sampleName" in data:
- _log.debug(f"TELL SAMPLE DATA => {data}")
- self.tell2storage(data)
- zescape.reply("ack")
- elif "pin_offset" in data:
- _log.debug(f"TELL pin offset => {data}")
- self._pin_mounting_offset = data["pin_offset"]
- zescape.reply("ack")
- elif "get_pin_offset" in data:
- _log.debug(f"TELL get pin offset => {data}")
- zescape.reply_json({"pin_offset": self._pin_mounting_offset})
-
- def _OLD_tell2storage(self, sample):
- _log.debug(f"2 TELL SAMPLE DATA => {type(sample)}")
- self._le_prefix.setText(sample["sampleName"])
- self._le_project.setText(sample["sampleFolder"])
- tstf = folders.get_prefixed_file("_newsample")
- self.storage_cascade_prefix(None)
- _log.warning(f"sample info: {tstf}")
-
- def _OLD_is_task(self, task):
- return task == self._active_task
-
- def _OLD_get_task_menu(self):
- pass
-
- def _OLD_toggle_shutter(self, **kwargs):
- if self._pv_shutter:
- if 0 == self._pv_shutter.get():
- self._pv_shutter.put(1)
- self._button_shutter.setText("shutter opened\n\u2622")
- else:
- self._pv_shutter.put(0)
- self._button_shutter.setText("shutter closed\n\u2622")
- elif self._has_pulse_picker:
- pulsePicker.toggle()
-
- def _OLD_update_shutter_label(self, pvname, value, char_value, **kwargs):
- if 0 == value:
- self._button_shutter.setText("shutter closed")
- else:
- self._button_shutter.setText("shutter opened")
-
- def _OLD_build_sample_selection_tab(self):
- self._sample_selection = sample_selection.SampleSelection(self)
- self._sample_selection.move_to_mount_position = (self.move_gonio_to_mount_position)
- self._tab_sample_selection.setLayout(QVBoxLayout())
- self._tab_sample_selection.layout().addWidget(self._sample_selection)
- self._tab_sample_selection.layout().addStretch(2)
-
- def _OLD_build_embl_group(self):
- grp = QGroupBox("EMBL Acquisition")
- layout = QFormLayout()
- grp.setLayout(layout)
- layout.addWidget(QLabel("Prefix"))
- self._embl_prefix = QLineEdit("img")
- layout.addWidget(self._embl_prefix)
-
- def _OLD_abort_measurement(self, ev=None):
- if settings.value(ACTIVATE_PULSE_PICKER):
- pulsePicker.close()
- jungfrau_detector.abort()
- delta_tau.abort()
- _log.debug("aborting measurement")
-
- def _OLD_trigger_detector(self, **kwargs):
- if self._pv_shutter is not None:
- self._pv_shutter.put(0)
- # self._eiger_button_collect.show()
- # self._eiger_button_abort.hide()
- # self._eiger_now_collecting_label.setText(
- # "Finished sequence id: {}\n"
- # "Data in: Data10/{}".format(
- # self._detector_sequence_id, self._eiger_now_collecting_file
- # )
- # )
-
- def _OLD_modify_camera_transform(self, t):
- if t == "remove_all":
- sample_camera.set_transformations([])
- elif t == "undo_last":
- sample_camera._transformations.pop()
- #elif type(t) ==type(camera.Transforms): #ZAC: orig. code
- # sample_camera.append_transform(t)
- try:
- label = ", ".join([t.name for t in sample_camera._transformations])
- except:
- label = ""
- self._label_transforms.setText(label)
- #settings.setValue(CAMERA_TRANSFORMATIONS, sample_camera._transformations) #ZAC: orig. code
-
- def _OLD_roi_add_line(self):
- roi = pg.LineSegmentROI(
- [200, 200],
- [300, 300],
- pen="r",
- scaleSnap=True,
- translateSnap=True,
- rotateSnap=True,
- removable=True,
- )
- # roi.sigRegionChanged.connect(self.track_roi)
- roi.sigRemoveRequested.connect(self.remove_roi)
- self.vb.addItem(roi)
- self._rois.append(roi)
-
- def _OLD_roi_add_rect(self):
- roi = pg.RectROI(
- [200, 200],
- [50, 50],
- pen="r",
- scaleSnap=True,
- translateSnap=True,
- rotateSnap=True,
- removable=True,
- )
- roi.sigRegionChanged.connect(self.track_roi)
- roi.sigRemoveRequested.connect(self.remove_roi)
- self.vb.addItem(roi)
- self._rois.append(roi)
-
- def _OLD_remove_roi(self, roi):
- self.vb.removeItem(roi)
- self._rois.remove(roi)
-
- def _OLD_prepare_microscope_page(self):
- layout = self.microscope_page.layout()
- container = QWidget()
- hlay = QHBoxLayout()
- container.setLayout(hlay)
- layout.addWidget(container)
-
- def _OLD_update_beam_marker(self, zoom_lvl):
- w, h = settings.value(BEAM_SIZE)
- try:
- bx = self.beamx_fitter(zoom_lvl)
- by = self.beamy_fitter(zoom_lvl)
- ok = True
- except:
- ok = False
- _log.warning("beam marker not defined")
- return
- _log.debug("updating beam mark to {:.1f}x{:.1f}".format(bx, by))
- self.beamCameraCoordinatesChanged.emit(bx, by)
-
- def _OLD_update_beam_marker_fitters(self):
- if len(self._beam_markers) > 2:
- _log.debug("defining beam marker")
- bx = [(n, x[0]) for n, x in self._beam_markers.items()]
- by = [(n, x[1]) for n, x in self._beam_markers.items()]
- nbx = np.asarray(bx).T
- nby = np.asarray(by).T
- bx_coefs = np.polyfit(nbx[0], nbx[1], 3)
- by_coefs = np.polyfit(nby[0], nby[1], 3)
- _log.debug(".... beam marker X coeficients {}".format(bx_coefs))
- _log.debug(".... beam marker Y coeficients {}".format(by_coefs))
- self.beamx_fitter = np.poly1d(bx_coefs)
- self.beamy_fitter = np.poly1d(by_coefs)
-
-
- def _OLD_append_to_beam_markers(self, x, y, zoom):
- self._beam_markers[zoom] = (x, y)
- _log.info("beam markers {}".format(self._beam_markers))
- settings.setValue(BEAM_MARKER_POSITIONS, self._beam_markers)
- self.update_beam_marker_fitters()
-
- def _OLD_remove_beam_markers(self):
- self._beam_markers = {}
- self.beamx_fitter = None
- self.beamy_fitter = None
-
- def _OLD_track_roi(self, roi):
- x, y = roi.pos()
- w, h = roi.size()
- # area = roi.getArrayRegion(self._im, self.img)
- # sum = np.sum(area)
- # _log.info('{} => sum {}'.format((x,y), sum))
- bx, by = x + w / 2., y + h / 2.
- _log.info("beam pos {}".format((bx, by)))
- _log.info("marker pos = {} ; size = {}".format((x, y), (w, h)))
-
- def _OLD_toggle_mouse_tracking(self):
- if self._mouse_tracking:
- self.disengage_mouse_tracking()
- else:
- self.engage_mouse_tracking()
-
- def _OLD_engage_mouse_tracking(self):
- self.glw.scene().sigMouseMoved.connect(self.cb_mouse_move)
- self.glw.scene().sigMouseMoved.emit()
- self._mouse_tracking = True
-
- def _OLD_disengage_mouse_tracking(self):
- self.glw.scene().sigMouseMoved.disconnect(self.cb_mouse_move)
- self._mouse_tracking = False
- self._lb_coords.setText("")
-
- def _OLD_get_beam_mark_on_camera_xy(self):
- app=QApplication.instance()
- z = app._zoom.get_val()
- try:
- bx = self.beamx_fitter(z)
- by = self.beamy_fitter(z)
- except:
- bx, by = 500, 500
- return (bx, by)
-
- def _OLD_move_gonio_to_position(self, fx, fy, bx, bz, omega):
- self.tweakers["fast_x"].motor.move(fx, wait=False, ignore_limits=True)
- self.tweakers["fast_y"].motor.move(fy, wait=False, ignore_limits=True)
- self.tweakers["base_x"].motor.move(bx, wait=False, ignore_limits=True)
- self.tweakers["base_z"].motor.move(bz, wait=False, ignore_limits=True)
- self.tweakers["omega"].motor.move(omega, wait=False, ignore_limits=True)
-
- def _OLD_get_gonio_motors(self, as_json=False):
- if as_json:
- return {
- "fast_x": self.tweakers["fast_x"].motor,
- "fast_y": self.tweakers["fast_y"].motor,
- "base_x": self.tweakers["base_x"].motor,
- "base_z": self.tweakers["base_z"].motor,
- "omega": self.tweakers["omega"].motor,
- }
- else:
- return (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
-
- def _OLD_get_gonio_tweakers(self):
- return (
- self.tweakers["fast_x"],
- self.tweakers["fast_y"],
- self.tweakers["base_x"],
- self.tweakers["base_z"],
- self.tweakers["omega"],
- )
-
- def _OLD_get_gonio_positions(self, as_json: bool = False):
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
-
- a, b, c, d, e = (
- fx.get_position(),
- fy.get_position(),
- cx.get_position(),
- cz.get_position(),
- omega.get_position(),
- )
- if as_json:
- return {"fx": a, "fy": b, "bx": c, "bz": d, "omega": e}
- else:
- return (a, b, c, d, e)
-
- def _OLD_escape_goToTellMountPosition(self):
- self.move_gonio_to_mount_position()
- self.lock_goniometer()
-
- def _OLD_move_gonio_to_mount_position(self, offset: float = 0.0):
- fx, fy, cx, cz, omega = self.get_gonio_motors()
- bmark = "bookmark_0"
- try:
- t_fx = float(settings.value(bmark + "/mount_fx"))
- t_fy = -offset + float(settings.value(bmark + "/mount_fy"))
- t_cx = float(settings.value(bmark + "/mount_cx"))
- t_cz = float(settings.value(bmark + "/mount_cz"))
- t_omega = float(settings.value(bmark + "/mount_omega"))
- except:
- raise IncompleteConfiguration("TELL sample changer mount position is not configured!!!")
- fx.move(t_fx, wait=True, ignore_limits=True)
- fy.move(t_fy, wait=True, ignore_limits=True)
- cx.move(t_cx, wait=True, ignore_limits=True)
- cz.move(t_cz, wait=True, ignore_limits=True)
- omega.move(t_omega, wait=True, ignore_limits=True)
- app_utils.assert_motor_positions(
- [
- (fx, t_fx, 0.01),
- (fy, t_fy, 0.01),
- (cx, t_cx, 0.01),
- (cz, t_cz, 0.01),
- (omega, t_omega, 0.01),
- ]
- )
- self.cb_esc_sample_exchange()
-
- def _OLD_lock_goniometer(self):
- # tell.set_in_mount_position(True)
- res = QMessageBox.question(self, "", "Mount a sample from console and click ok once the sample is mounted.", QMessageBox.Ok, QMessageBox.Ok,)
- res = QMessageBox.question(self, "", "Is the sample is mounted?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,)
- if res in (QMessageBox.Yes, QMessageBox.No):
- # tell.set_in_mount_position(False)
- pass
-
- @pyqtSlot(int)
- def _OLD_saveBookmark(self, key: int):
- """save a bookmark for the corresponding key is the Qt.Key_* code """
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
- bmark = "bookmark_{}".format(key)
- if key == 0:
- ans = QMessageBox.question(self, "Override TELL mount position", "This will overwrite the positions used for TELL MOUNTING!!!\n\n\tContinue ?",)
- if ans != QMessageBox.Yes:
- return
-
- _log.info(
- "saving bookmark {}: {}, {}, {}, {}, {}".format(
- bmark,
- fx.get_position(),
- fy.get_position(),
- cx.get_position(),
- cz.get_position(),
- omega.get_position(),
- )
- )
- settings.setValue(bmark + "/mount_fx", fx.get_position())
- settings.setValue(bmark + "/mount_fy", fy.get_position())
- settings.setValue(bmark + "/mount_cx", cx.get_position())
- settings.setValue(bmark + "/mount_cz", cz.get_position())
- settings.setValue(bmark + "/mount_omega", omega.get_position())
-
- def _OLD_gotoBookmark(self, key: int):
- """save a bookmark for the corresponding key"""
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
- bmark = "bookmark_{}".format(key)
- try:
- t_fx = float(settings.value(bmark + "/mount_fx"))
- t_fy = float(settings.value(bmark + "/mount_fy"))
- t_cx = float(settings.value(bmark + "/mount_cx"))
- t_cz = float(settings.value(bmark + "/mount_cz"))
- t_omega = float(settings.value(bmark + "/mount_omega"))
- except:
- return
-
- fx.move(t_fx, wait=True, ignore_limits=True)
- fy.move(t_fy, wait=True, ignore_limits=True)
- cx.move(t_cx, wait=True, ignore_limits=True)
- cz.move(t_cz, wait=True, ignore_limits=True)
- omega.move(t_omega, wait=True, ignore_limits=True)
-
- def _OLD_move_cryojet_nozzle(self, pos):
- cx = self.tweakers["cryo"]
- if "in" == pos.lower():
- key = CRYOJET_NOZZLE_IN
- elif "out" == pos.lower():
- key = CRYOJET_NOZZLE_OUT
-
- to_pos = settings.value(key, 1e10, type=float)
- if to_pos > 1e9:
- raise IncompleteConfiguration(f"CRYOJET configuration is incomplete! Missing {key}")
- cx.move_abs(to_pos, assert_position=True)
-
- def _OLD_build_cryo_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(
- toolbox,
- "Cryojet",
- widget_list=[
- self.get_tweaker(f"{pfx}:MOT_CRYO", alias="cryo", label="cryo X")
- ],
- )
-
- def _OLD_build_wegde_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(toolbox,"Wedge Mover",
- widget_list=[
- self.get_tweaker(f"{pfx}:MOT_WEDGE1", alias="wedge_1", label="wedge_1"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE2", alias="wedge_2", label="wedge_2"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE3", alias="wedge_3", label="wedge_3"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE4", alias="wedge_4", label="wedge_4"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEX", alias="wedge_x", label="wedge_x"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEY", alias="wedge_y", label="wedge_y"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEA", alias="wedge_a", label="wedge_a"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEB", alias="wedge_b", label="wedge_b"),
- ],
- )
-
- def _OLD_build_slits_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(
- toolbox,
- "Slits",
- widget_list=[
- self.get_tweaker(f"{pfx}10", alias="slit_right", label="left", mtype=1, ),
- self.get_tweaker(f"{pfx}11", alias="slit_left", label="right", mtype=1,),
- self.get_tweaker(f"{pfx}12", alias="slit_bottom", label="bottom", mtype=1,),
- self.get_tweaker(f"{pfx}13",alias="slit_top",label="top",mtype=1,),
- ],
- )
-
- def _OLD_assert_post_tube_position(self, pos):
- x_up = settings.value("post_sample_tube/x_up", 1e10, type=float)
- y_up = settings.value("post_sample_tube/y_up", 1e10, type=float)
- x_down = settings.value("post_sample_tube/x_down", 1e10, type=float)
- y_down = settings.value("post_sample_tube/y_down", 1e10, type=float)
- dx = settings.value("post_sample_tube/dx", 1e10, type=float)
- dy = settings.value("post_sample_tube/dy", 1e10, type=float)
- tz_in = settings.value("post_sample_tube/z_in", 1e10, type=float)
- tz_out = settings.value("post_sample_tube/z_out", 1e10, type=float)
-
- if (x_up + y_up + x_down + y_down + dx + dy + tz_in + tz_out) > 1e9:
- raise Exception("miscofingured positions for post-sample tube")
-
- usy = self.tweakers["tube_usy"]
- dsy = self.tweakers["tube_dsy"]
- usx = self.tweakers["tube_usx"]
- dsx = self.tweakers["tube_dsx"]
- tbz = self.tweakers["tube_z"]
-
- if pos == "in":
- yu = y_up
- xu = x_up
- yd = y_down
- xd = x_down
- z = tz_in
- elif pos == "out":
- yu = y_up + dy
- xu = x_up + dx
- yd = y_down + dy
- xd = x_down + dx
- z = tz_out
-
- app_utils.assert_tweaker_positions([
- (usy, yu, 0.1),
- (dsy, yd, 0.1),
- (usx, xu, 0.1),
- (dsx, xd, 0.1),
- (tbz, z, 0.1),],timeout=2.0,
- )
-
- def _OLD_add_tweaker(self, pv, alias=None, label=None, mtype="epics_motor", layout=None):
- if layout is None:
- layout = self._tweak_container.layout()
- if mtype == "epics_motor":
- m = MotorTweak()
- else:
- m = SmaractMotorTweak()
- layout.addWidget(m)
- m.connect_motor(pv, label)
- self.tweakers[alias] = m
-
- def _OLD_done_sliding(self):
- print("done sliding at {}".format(self.slider_fast_x.value()))
-
- def _OLD_daq_grid_add_grid(self, gx=None, gy=None):
- grid_index = len(self._grids)
- if gx in (False, None):
- gx=self.tweakers["fast_x"].get_rbv()
- gy=self.tweakers["fast_y"].get_rbv()
- xstep = self._sb_grid_x_step.value()
- ystep = self._sb_grid_y_step.value()
- xoffset = self._sb_grid_x_offset.value()
- yoffset = self._sb_grid_y_offset.value()
-
- app=QApplication.instance()
- geo=app._geometry
- oc=geo._opt_ctr
- if xstep==0:
- go=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
- elif xstep==1:
- go=UsrGO.FixTargetFrame((120, -100), (200, 150), tpl='test')
- elif xstep==2:
- v=geo.pos2pix((12.5, 0))
- l=np.linalg.norm(v)
- go=UsrGO.FixTargetFrame(-oc, (l,l), tpl='12.5x12.5')
- elif xstep==3:
- v=geo.pos2pix((23, 0))
- l=np.linalg.norm(v)
- go=UsrGO.FixTargetFrame(-oc, (l,l), tpl='23.0x23.0')
- else:
- _log.error('set xstep 0..2 for tests')
- self.vb.addItem(go)
- self._goTracked['objLst'].append(go)
-
- #grid = CstROI.Grid( x_step=xstep, y_step=ystep, x_offset=xoffset, y_offset=yoffset, gonio_xy=(gx, gy), grid_index=grid_index, parent=self,)
- #self.vb.addItem(grid)
- #grid.calculate_gonio_xy()
- #grid.sigRemoveRequested.connect(lambda g=grid: self.remove_grid(g))
-
- def _OLD_daq_grid_remove_all(self):
- vb=self.vb
- for go in self._goTracked['objLst']:
- vb.removeItem(go)
- self._goTracked['objLst']=[]
-
- def _OLD_grids_pause_stage_tracking(self):
- for grid in self._grids:
- grid.disable_stage_tracking()
-
- def _OLD_grids_start_stage_tracking(self):
- for grid in self._grids:
- grid.enable_stage_tracking()
-
- def _OLD_remove_grid(self, grid):
- self.vb.removeItem(grid)
- self._grids.remove(grid)
-
-
- def _OLD_daq_grid_update(self, grid_index):
- try:
- grid = self._grids[grid_index]
- except:
- print("grid index not yet there")
- return
- points = grid.get_grid_targets()
- num_points = len(points)
- etime = float(settings.value("exposureTime"))
- doc = f"grid_{grid_index} = ["
- for n, pos in enumerate(points):
- x, y = pos
- doc += "[{:8.3f}, {:8.3f}],\n".format(x, y)
- doc += "]"
- self._grid_inspect_area.setPlainText(doc)
- m = "Number of points: {}\nEstimated Time: {:.1f} minutes".format(num_points, num_points * etime / 60.)
- self._label_grid_parameters.setText(m)
-
- def _OLD_daq_embl_collect_points(self):
- coords = self._embl_module.coords
- points = [[x, y] for x, y, bx, bz, o in coords]
- points = np.array(points)
- method = "trajectory"
- xp = (1000 * points).astype(int) # microns then round int
- params = (xp[:, 0].tolist(), xp[:, 1].tolist())
- self.daq_collect_points(points, visualizer_method=method, visualizer_params=params)
-
- def _OLD_daq_prelocated_collect_points(self):
- points = []
- data = self.prelocationModule.get_collection_targets()
- for n, cc in enumerate(data):
- is_fiducial, gx, gy, cx, cy, ox, oy = cc
- points.append([gx, gy])
- points = np.array(points)
- method = "trajectory"
- xp = (1000 * points).astype(int) # microns then round int
- params = (xp[:, 0].tolist(), xp[:, 1].tolist())
- self.daq_collect_points(points, visualizer_method=method, visualizer_params=params)
-
- def _OLD_daq_grid_findxtals(self):
- feature_size = self._sb_findxtals_feature_size.value()
- image = sample_camera.get_image()
- findObj(-image, objSize=feature_size, viz=1)
-
- def _OLD_check_jungfrau_save(self) -> bool:
- if jungfrau_detector.is_running_detector():
- saveRaw = jungfrau_detector.is_saving_data()
-
- if not saveRaw:
- box = QMessageBox()
- box.setText("Jungfrau save data disabled!")
- box.setInformativeText("Jungfrau save data is disabled!")
- box.setIcon(QMessageBox.Warning)
- box.setDetailedText("Choose to abort, enable and continue, or continue without saving raw data")
- btContinue = box.addButton("Continue", QMessageBox.YesRole)
- btAbort = box.addButton("OMG! Abort", QMessageBox.NoRole)
- btEnable = box.addButton("Enable save and continue", QMessageBox.YesRole)
- box.exec_()
- ans = box.clickedButton()
- if ans == btEnable:
- jungfrau_detector.set_save_raw(True)
- return True
- elif ans == btAbort:
- _log.info("not doing helical scan")
- return False
- return True
- return True
-
- def _OLD_daq_collect_points(self, points, visualizer_method, visualizer_params):
- app = QApplication.instance()
- cfg = app._cfg
- verbose=0xff
- fn='/tmp/shapepath'
- try:
- dt=app._deltatau
- except AttributeError:
- app._deltatau=dt=deltatau.Deltatau()
- try:
- jf=app._jungfrau
- except AttributeError:
- app._jungfrau=jf=detector.Jungfrau()
-
- sp=dt._shapepath
- sp.gen_grid_points(w=15, h=15, pitch=3, rnd=0, ofs=(0, +2000))
- #sp.gen_grid_points(w=5, h=10, pitch=1, rnd=0, ofs=(0, 0));sp.sort_points(False, 10);sp.points
- sp.sort_points(False, 15);
- sp.meta['pt2pt_time']=10
- sp.setup_gather()
- sp.setup_sync(verbose=verbose&32, timeOfs=0.05)
- sp.setup_coord_trf() # reset to shape path system
- # sp.meta['pt2pt_time']=10 #put between setup_sync and setup_motion to have more motion points than FEL syncs
- sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10)
- sp.homing() # homing if needed
- sp.run() # start motion program
- sp.wait_armed() # wait until motors are at first position
- sp.trigger(0.5) # send a start trigger (if needed) ater given time
- if not dt._comm is None:
- while True:
- p=int(sp.progress())
- if p<0: break
- #print('progress %d/%d'%(p, num_pts))
- time.sleep(.1)
- sp.gather_upload(fnRec=fn+'.npz')
- #dp=deltatau.shapepath.DebugPlot(sp)
- #dp.plot_gather(mode=11)
- #plt.show(block=False)
- #plt.show(block=True)
- return
-
-
-
- task = self.active_task()
- XDIR = -1
-
- #folders.make_if_needed()
- #if ( cfg.option(AppCfg.ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()):
- # if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau",
- # "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",):
- # _log.warning("user forgot to turn on the jungfrau")
- # return
-
- #if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- # self.escape_goToDataCollection()
-
- points *= 1000 # delta tau uses micrometers
- points[:, 0] *= XDIR # fast X axis is reversed
-
-
- # sync_mode : default=2
- # 0 : no sync at all
- # 1 : synchronize start
- # 2 : synchronize start and adapt motion speed
- # this function generates the code blocks:
- # self.sync_wait and self.sync_run
- # sync_wait can be put in the program to force a timing sync
- # sync_run are the commands to run the whole program
- # sync_flag if not using jungfrau =1 otherwise =0
- # D.O. shapepath.meta.update(sync_mode=2, sync_flag=1)
- sp.meta.update(sync_mode=0, sync_flag=0)
-
- maxacq_points = 116508
- samp_time = 0.0002 # s
- overhead_time = 0.1
- etime=10
- vscale=1.0
- #etime = settings.value("exposureTime", type=float)
- #vscale = settings.value(DELTATAU_VELOCITY_SCALE, 1.0, type=float)
- #sort_points = option(DELTATAU_SORT_POINTS)
-
- acq_per = int(np.ceil((etime * len(points) + overhead_time) / (maxacq_points * samp_time)))
- _log.info(f"gather acquisotion period = {acq_per}")
- _log.info(f"velocity scale {vscale}")
- sp.setup_gather(acq_per=acq_per)
- sp.setup_sync(verbose=True)
- sp.setup_coord_trf()
-
- assert(points.dtcfgype==np.float64)
- sp.points = points
-
- if TASK_GRID == task:
- # width, height = visualizer_params
- # _log.debug(f"grid: {width} x {height}")
- # details_1 = [width]
- # details_2 = [height]
- # sp.sort_points(xy=False, grp_sz=height)
- pass
- elif task in (TASK_PRELOCATED, TASK_EMBL):
- if sort_points:
- shapepath.sort_points()
- self.daq_method_prelocated_remove_markers()
- details_1, details_2 = visualizer_params
-
- sp.setup_motion(
- mode=3, # 1 = bad pvt 3 = pft (pvt via inverse fourier transform)
- pt2pt_time=etime * 1000.,
- #fnPrg=folders.get_prefixed_file("_program.prg"),
- scale=vscale, # velocity at target position scaling: 1=optimal speed, 0=zero speed
- dwell=10, # milli-seconds wait
- )
- sp.run()
-
- self.qprogress = QProgressDialog(self)
- self.qprogress.setRange(0, 0)
- self.qprogress.setLabelText("Acquiring GRID")
- self.qprogress.setCancelButtonText("Abort Acquisition")
- self.qprogress.canceled.connect(self.complete_daq)
- self.qprogress.setWindowModality(Qt.WindowModal)
- self.qprogress.setAutoClose(True)
- self.qprogress.show()
-
- sequencer_steps = [lambda: self.grids_pause_stage_tracking()]
-
- if jungfrau_detector.is_running_detector():
- if not self.check_jungfrau_save():
- # user aborted run from save data dialog
- return
-
- n_frames = ntrigger
- uid = settings.value(EXPERIMENT_UID, type=int)
- backend_extras = self.jungfrau.get_parameters()
- backend_extras.update(
- {
- "swissmx_trajectory_method": visualizer_method,
- "swissmx_trajectory_details_1": details_1,
- "swissmx_trajectory_details_2": details_2,
- }
- )
- jungfrau_detector.set_number_of_frames(n_frames)
- jungfrau_detector.set_data_owner_uid(uid)
- sequencer_steps.extend(
- [
- lambda: jungfrau_detector.configure(
- n_frames=n_frames,
- outfile=folders.prefix,
- outdir=folders.raw_folder,
- uid=uid,
- backend_extras=backend_extras,
- ),
- lambda: jungfrau_detector.arm(),
- ]
- )
-
- sequencer_steps.append(lambda: shapepath.wait_armed())
- if option(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.open())
-
- # if settings.value("scanning/trigger_microscope_camera", type=bool):
- # sample_camera.switch_to_trigger(True)
-
- sequencer_steps.append(lambda: shapepath.trigger(wait=0.5))
-
- def _OLD_shapepath_progress():
- while True:
- p = shapepath.progress()
- if p < 0:
- break
- time.sleep(0.1)
- self.qprogress.setLabelText(f"Acquiring GRID {p:.0f} / {ntrigger}")
- _log.warning(f"motion complete!")
- # sample_camera.stop_camera()
- # sample_camera.switch_to_trigger(False)
- # sample_camera.save_buffer_series(folders.prefix)
-
- sequencer_steps.append(shapepath_progress)
-
- if option(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.close())
-
- sequencer_steps.append(lambda: jungfrau_detector.wait_finished())
-
- sequencer_steps.append(lambda: self.grids_start_stage_tracking())
-
- self.sequencer = Sequencer(steps=sequencer_steps)
- self._thread = QThread()
- self._thread.setObjectName("acquisition_thread")
- self.sequencer.moveToThread(self._thread)
- self.sequencer.finished.connect(self.daq_collect_points_wrapup)
- self._thread.started.connect(self.sequencer.run_sequence)
- self._thread.start()
-
- def _OLD_run_steps(self, steps, title, at_end=None, cancelable=False):
- dlg = QProgressDialog(self)
- dlg.setWindowTitle(title)
- dlg.setWindowModality(Qt.WindowModal)
- dlg.setMinimumDuration(0)
- if not cancelable:
- dlg.setCancelButton(None)
- dlg.setRange(0, 0)
- dlg.setLabelText(f"{title}
")
- dlg.setAutoClose(True)
- dlg.show()
- dlg.setValue(random.randint(1, 20))
- class Runner(QObject):
- finito = pyqtSignal()
- timeoutExpired = pyqtSignal()
- errorHappened = pyqtSignal(str)
- result = pyqtSignal(str)
-
- def __init__(self, step_to_run):
- super().__init__()
- self.step = step_to_run
- self.exception = None
- self.done = False
-
- def run(self):
- try:
- self.step()
- except Exception as e:
- _log.debug(" +> step exception")
- self.exception = str(e)
- self.errorHappened.emit(str(e))
- self.finito.emit()
-
-
- for n, step in enumerate(steps):
- _log.info(f"running step {step.title}")
- dlg.setLabelText(f"{title}
{step.title}")
- dlg.setValue(n)
- thread = QThread()
- runner = Runner(step)
- runner.moveToThread(thread)
- thread.started.connect(runner.run)
- runner.finito.connect(thread.quit)
- thread.start()
- while thread.isRunning():
- dlg.setValue(random.randint(1, 20))
- time.sleep(0.01)
- if dlg.wasCanceled():
- # FIXME ensure we abort the running thread
- break
-
- if dlg.wasCanceled():
- break
- if runner.exception is not None:
- QMessageBox.critical(self, step.title, str(runner.exception))
- break
-
- if dlg.wasCanceled():
- _log.error(f"sequence {title} was cancelled by user")
- raise AcquisitionAbortedException(f"sequence {title} was cancelled by user")
-
- if at_end is not None:
- at_end()
- dlg.reset()
-
- def _OLD_daq_collect_points_wrapup(self):
- self.qprogress.reset()
- if self._thread.isRunning():
- self._thread.quit()
- shapepath.gather_upload(os.path.join(folders.res_folder, folders.prefix + ".npz"))
-
- if option(DELTATAU_SHOW_PLOTS):
- dp = DebugPlot(shapepath)
- dp.plot_gather(mode=1)
- pyplot.show()
-
- if TASK_PRELOCATED == self.active_task():
- self.daq_method_prelocated_update_markers()
-
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_sample_alignment()
-
- sequence = {"delta tau program": shapepath.prg, "points": shapepath.points.tolist(), "timestamp": tdstamp(),}
-
- sfname = folders.get_prefixed_file("_ScanInfo.json")
- try:
- with open(sfname, "w") as sf:
- _log.info("writing scan info into: {}".format(sfname))
- sf.write(json.dumps(sequence))
- except:
- _log.warning(f"failed to write scan info to {sfname}")
-
- self.re_connect_collect_button()
- jungfrau_detector.abort()
- self.increaseRunNumberRequest.emit()
-
- def _OLD_daq_collect_update_inspect(self, msg):
- te = self._inspect
- m = te.toPlainText()
- te.setPlainText(m + msg + "\n")
- te.verticalScrollBar().setValue(te.verticalScrollBar().maximum())
-
- def _OLD_daq_helical_collect(self):
- """[
- [{
- 0: (0.0, 1.238401694734829, 3.527, 0.936, 0.001),
- 120: (0.0, 1.3890393596274455, -1.957242824091597, -0.5639999999999998, 120.001),
- 240: (0.0, 1.3866130349657206, -1.1642619618562273, 3.105, 240.001)
- },
- {
- 0: (0.0, 1.238401694734829, 3.527, 0.936, 0.001),
- 120: (0.0, 1.3890393596274455, -1.957242824091597, -0.5639999999999998, 120.001),
- 240: (0.0, 1.3866130349657206, -1.1642619618562273, 3.105, 240.001)
- }]
- ]
- """
- _log.info("executing collection")
- htab = self._helical_scan_table
- num_h = htab.scanHorizontalCount()
- num_v = htab.scanVerticalCount()
-
- if ( settings.value(ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()):
- if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau",
- "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",):
- _log.warning("user forgot to turn on the jungfrau")
- return
-
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_data_collection()
-
- folders.make_if_needed()
-
- data = htab.get_data()
- _log.debug(data)
- start, end = data[0]
- FX, FY, BX, BZ, O = range(5)
- x = (
- (-1000 * start[0][BX], -1000 * start[120][BX], -1000 * start[240][BX]),
- (-1000 * end[0][BX], -1000 * end[120][BX], -1000 * end[240][BX]),
- )
- y = (1000 * start[0][FY], 1000 * end[0][FY])
- z = (
- (-1000 * start[0][BZ], -1000 * start[120][BZ], -1000 * start[240][BZ]),
- (-1000 * end[0][BZ], -1000 * end[120][BZ], -1000 * end[240][BZ]),
- )
-
- if jungfrau_detector.is_running_detector():
- if not self.check_jungfrau_save():
- return
- saveRaw = jungfrau_detector.is_saving_data()
-
- _log.debug(f"x = {x}")
- _log.debug(f"y = {y}")
- _log.debug(f"z = {z}")
-
- oscillationAngle = settings.value("oscillationAngle", type=float)
- exposureTime = 1000 * settings.value("exposureTime", type=float)
- blastRadius = settings.value("blastRadius", type=float)
- totalRange = num_v * num_h * oscillationAngle
-
- # sync_mode : default=2
- # 0 : no sync at all
- # 1 : synchronize start
- # 2 : synchronize start and adapt motion speed
- # this function generates the code blocks:
- # self.sync_wait and self.sync_run
- # sync_wait can be put in the program to force a timing sync
- # sync_run are the commands to run the whole program
- # sync_flag if not using jungfrau =1 otherwise =0
- # D.O. helical.meta.update(sync_mode=2, sync_flag=1)
- helical.meta.update(sync_mode=0, sync_flag=0)
- helical.calcParam(x=x, y=y, z=z)
- helical.setup_gather()
- helical.setup_sync()
- helical.setup_coord_trf()
- mode = 1
- hRng = (-blastRadius * num_h, blastRadius * num_h)
- w_start = 1000 * htab.startAngle()
- wRng = (w_start, w_start + (totalRange * 1000))
- _log.info(
- f"helical params mode={mode}, cnthor={num_h}, cntvert={num_v}, hrng={hRng}, wrng={wRng}"
- )
- helical.setup_motion(
- mode=mode,
- cntHor=num_h,
- cntVert=num_v,
- hRng=hRng,
- wRng=wRng,
- pt2pt_time=exposureTime,
- ) # hRng in micrometers
- helical.run()
- try:
- with open(folders.get_prefixed_file("_helical_debug.cmd"), "w") as fd:
- fd.write("calcParam(x={}, y={}, z={})".format(x, y, z))
- except:
- pass
-
- self.qprogress = QProgressDialog(self)
- self.qprogress.setRange(0, 0)
- self.qprogress.setLabelText("Acquiring HELICAL")
- self.qprogress.setCancelButtonText("Abort Acquisition")
- self.qprogress.canceled.connect(self.complete_daq)
- self.qprogress.setWindowModality(Qt.WindowModal)
- self.qprogress.setAutoClose(True)
- self.qprogress.show()
-
- sequencer_steps = [lambda: self.grids_pause_stage_tracking()]
-
- n_frames = num_h * num_v
- if jungfrau_detector.is_running_detector():
- uid = settings.value(EXPERIMENT_UID, type=int)
- backend_extras = self.jungfrau.get_parameters()
- backend_extras.update(
- {
- "swissmx_trajectory_method": "grid",
- "swissmx_trajectory_details_1": [-num_h],
- "swissmx_trajectory_details_2": [num_v],
- }
- )
-
- jungfrau_detector.set_number_of_frames(n_frames)
- jungfrau_detector.set_data_owner_uid(uid)
- sequencer_steps.extend(
- [
- lambda: jungfrau_detector.configure(
- n_frames=n_frames,
- outfile=folders.prefix,
- outdir=folders.raw_folder,
- uid=uid,
- backend_extras=backend_extras,
- ),
- lambda: jungfrau_detector.arm(),
- ]
- )
-
- sequencer_steps.append(lambda: helical.wait_armed())
- if settings.value(ACTIVATE_PULSE_PICKER):
- sequencer_steps.extend([lambda: pulsePicker.open(), lambda: pend_event(0.1)])
-
- sequencer_steps.append(lambda: helical.trigger())
-
- def _OLD_motion_progress():
- while True:
- p = helical.progress()
- if p < 0:
- break
- time.sleep(0.1)
- self.qprogress.setLabelText(f"Acquiring HELICAL {p:.0f} / {n_frames}")
- _log.warning(f"helical motion complete!")
-
- sequencer_steps.append(motion_progress)
-
- if settings.value(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.close())
-
- sequencer_steps.append(lambda: self.grids_start_stage_tracking())
-
- self.sequencer = Sequencer(steps=sequencer_steps)
- self._thread = QThread()
- self._thread.setObjectName("acquisition_thread")
- self.sequencer.moveToThread(self._thread)
- self.sequencer.finished.connect(self.daq_helical_collect_wrapup)
- self._thread.started.connect(self.sequencer.run_sequence)
- self._thread.start()
-
- def _OLD_daq_helical_collect_wrapup(self):
- try:
- self.qprogress.reset()
- except:
- pass
- if self._thread.isRunning():
- self._thread.quit()
- helical.gather_upload(os.path.join(folders.res_folder, folders.prefix + ".npz"))
-
- self.re_connect_collect_button()
- jungfrau_detector.abort()
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_sample_alignment()
- self.increaseRunNumberRequest.emit()
-
- if option(DELTATAU_SHOW_PLOTS):
- hsgui = HelicalScanGui(helical)
- hsgui.interactive_anim()
-
- def _OLD_complete_daq(self):
- _log.info("daq completed: cleaning up")
- try:
- self.qprogress.reset()
- except:
- pass
- try:
- if self._thread.isRunning():
- self._thread.quit()
- except:
- pass
- finally:
- self.abort_measurement()
- self.re_connect_collect_button()
-
- def _OLD_re_connect_collect_button(self, callback=None, **kwargs):
- _log.debug("re_connect_collect_button() {} => {}".format(callback, kwargs))
- return
- # button = self._button_collect
- # if callback is None:
- # callback = self.execute_collection
- # button.setAccessibleName("collect_button")
- # kwargs["label"] = "Collect"
- #
- # try:
- # button.disconnect()
- # finally:
- # button.clicked.connect(callback)
- #
- # if "accessibleName" in kwargs:
- # button.setAccessibleName(kwargs["accessibleName"])
- #
- # if "label" in kwargs:
- # button.setText(kwargs["label"])
- # self.load_stylesheet()
-
- def _OLD_collect_abort_grid(self):
- self._is_aborted = True
- try:
- self._eigerwaitthread._is_aborted = True
- except:
- pass
- _log.warning("aborting grid scan")
- self.abort_measurement()
- delta_tau.abort()
- jungfrau_detector.disarm()
- self.re_connect_collect_button()
-
- def _OLD_create_escape_toolbar(self):
- cont = self._wd_right
- w = QGroupBox("Escape")
- layout = QHBoxLayout()
- w.setLayout(layout)
- but = QPushButton("Exchange\nSample")
- but.setAccessibleName("escape_button_se")
- but.setObjectName("action_SampleExchange")
- but.clicked.connect(self.cb_esc_sample_exchange)
- layout.addWidget(but)
- but = QPushButton("Alignment")
- but.setAccessibleName("escape_button_sa")
- but.clicked.connect(self.cb_esc_sample_alignment)
- layout.addWidget(but)
- but = QPushButton("Collection")
- but.setAccessibleName("escape_button_dc")
- but.clicked.connect(self.cb_esc_data_collection)
- layout.addWidget(but)
- cont.layout().addWidget(w)
-
- def _OLD_daq_method_prelocated_remove_markers(self):
- try:
- for m in self._marker_rois:
- m.disconnect_signals()
- self.vb.removeItem(m)
- except Exception as e:
- _log.warning("maybe failed removing markers: {}".format(e))
- self._marker_rois = []
-
- def _OLD_pause_all_markers(self):
- for m in self._marker_rois:
- m.disconnect_signals()
-
- def _OLD_resume_all_markers(self):
- for m in self._marker_rois:
- m.reconnect_signals()
-
- def _OLD_daq_method_prelocated_update_markers(self):
- self.daq_method_prelocated_remove_markers()
- data = self.prelocationModule.get_data()
- add_xtals = self.prelocationModule._xtals_transformed
- draw_xtals = self.prelocationModule.set_draw_crystal_marks
- vb = self.vb
- self._marker_rois = []
- ppm = self.getPpm()
- for n, cc in enumerate(data):
- is_fiducial, gx, gy, cx, cy, ox, oy = cc
- if not is_fiducial:
- if not (add_xtals and draw_xtals):
- continue
- _log.debug(f"adding {'fiducial' if is_fiducial else 'xtal'} mark #{n}: {is_fiducial} {gx:.3f}, {gy:.3f}, {cx:.1f}, {cy:.1f}")
- m = CstROI.CrystalCircle(
- gonio_xy=(gx, gy),
- parent=self,
- model_row_index=n,
- is_fiducial=is_fiducial,
- ppm=ppm,
- )
- # m.sigRegionChangeFinished.connect(lambda roi=m: self.daq_method_prelocated_update_model(roi))
- self._marker_rois.append(m)
- vb.addItem(m)
- for c in self._marker_rois:
- c.reconnect_signals()
- c.follow_stage()
-
- def _OLD_daq_method_prelocated_set_fiducial(self, camx, camy, gx, gy):
- _log.debug(f"camx, camy: {camx}, {camy}, fx, fy: {gx, gy}")
- self.prelocationModule.set_fiducial_coords(camx, camy, gx, gy)
-
- def _OLD_daq_method_prelocated_append_data(self, x, y, gx, gy):
- _log.debug("appending to model: {} {}".format((x, y), (gx, gy)))
- self.prelocationModule.append_data((x, y, gx, gy))
- self.daq_method_prelocated_update_markers()
-
- def _OLD_daq_method_prelocated_update_model(self, roi):
- row = roi.get_model_row()
- pos = roi.pos()
- self.prelocationModule.set_data_camera(row, pos)
- _log.debug("updating row {} => {}".format(row, pos))
-
- def _OLD_daq_method_prelocated_add_reference(self):
- self._references.append(pg.CircleROI())
-
- def _OLD_move_fast_stage(self, x, y):
- _log.info(f"received request to move gonio to x, y = {x:.3f}, {y:.3f} mm")
- fx_motor, fy_motor, bx_motor, bz_motor, omega_motor = self.get_gonio_tweakers()
- fx_motor.move_abs(x)
- fy_motor.move_abs(y)
-
- def _OLD_toggle_maximized(self):
- if self.isMaximized():
- self.showNormal()
- else:
- self.showMaximized()
-
- def _OLD_show_window_configuration(self):
- _log.debug("maximized? {}".format(self.isMaximized()))
-
- def _OLD_update_user_and_storage(self):
- global folders
- pgroup = settings.value(EXPERIMENT_PGROUP, "not_set_yet")
- diag = GenericDialog( title="P-group for experiment", message="Enter the p-group to be used",
- inputs={EXPERIMENT_PGROUP: ("P-group", pgroup, QLineEdit(pgroup))}, use_buttons=False,)
- diag.setModal(True)
-
- run_user = getpass.getuser()
-
- pgrp_re = re.compile(r"^p(?P\d{5})$")
-
- if not self.is_recently_active():
- diag.exec()
- results = diag.results
- for k, v in results.items():
- m = pgrp_re.match(v)
- if m:
- settings.setValue(k, v)
- settings.setValue(EXPERIMENT_UID, int(m["uid"]))
- else:
- QMessageBox.critical(self, "wrong P-group format", "P-groups are in the format:\n\n\t\tp?????\n\n\twhere ? = digit",)
- self.update_user_and_storage()
- return
- settings.sync()
- folders.set_pgroup(settings.value(EXPERIMENT_PGROUP))
- try:
- folders.check_permissons()
- except:
- folder = folders.pgroup_folder
- pgroup = settings.value(EXPERIMENT_PGROUP)
- box = QMessageBox()
- box.setText("No Write Permission!")
- box.setInformativeText("User {} has no write access to p-group {} folder:\n ➜ {}\n".format(run_user, pgroup, folder))
- box.setIcon(QMessageBox.Warning)
- box.setDetailedText("The folder /sf/bernina/data/{pgroup}/res/ has to writable by the user {user}, currently running the SwissMX app.".format(pgroup=pgroup, user=run_user))
- btIgnore = box.addButton("Ignore", QMessageBox.NoRole)
- btRetry = box.addButton("Le'me try again", QMessageBox.YesRole)
- box.exec_()
- ans = box.clickedButton()
- if ans == btRetry:
- self.update_user_and_storage()
- elif ans == btIgnore:
- _log.warning("no write access to pgroup but user didn't care")
-
- self._label_pgroup.setText(settings.value(EXPERIMENT_PGROUP))
-
- def _OLD_is_recently_active(self):
- last_active = settings.value("last_active", 0, type=float)
- minutes_since_last = int((time.time() - last_active) / 60.0)
- return minutes_since_last < 60
-
- def _OLD_openPreferencesDialog(self):
- PreferencesDialog(self).exec_()
-
- def _OLD_set_app_icon(self):
- scriptDir = os.path.dirname(os.path.realpath(__file__))
- self.setWindowIcon(QtGui.QIcon(os.path.join(scriptDir + os.path.sep + "logo.png")))
-
- def _OLD_set_widget_background_color(self, color):
- """change a widget's color
- :param color:
- :return:
- """
- try:
- color = QtGui.QColor.colorNames().index(color)
- except:
- return
- p = self.palette()
- p.setColor(self.backgroundRole(), color)
- self.setPalette(p)
-
-# functions are prefixed with _OLD_
- def _OLD_build_daq_methods_grid_tab(self):
- self._grids = []
- tab = self._tab_daq_method_grid
- layout = tab.layout() # gridlayout
- self._sb_grid_x_step.setValue(30)
- self._sb_grid_y_step.setValue(30)
- self._bt_add_grid.clicked.connect(self._OLD_daq_grid_add_grid)
- self._bt_remove_all_grids.clicked.connect(self._OLD_daq_grid_remove_all)
- self._find_targets_from_microscope_image.clicked.connect(self._OLD_daq_grid_findxtals)
- self.addGridRequest.connect(self._OLD_daq_grid_add_grid)
- self.gridUpdated.connect(self._OLD_daq_grid_update)
-
- def _OLD_build_daq_methods_prelocated_tab(self):
- tab = self._tab_daq_method_prelocated
- self.prelocationModule = PrelocatedCoordinatesModel.PrelocatedCoordinates(parent=self)
- tab.layout().addWidget(self.prelocationModule)
- self.prelocationModule.prefixSelected.connect(lambda prefix: self._le_prefix.setText(prefix))
- self.prelocationModule.dataFileLoaded.connect(self._OLD_daq_method_prelocated_update_markers)
- self.prelocationModule.prelocatedDataUpdated.connect(self._OLD_daq_method_prelocated_update_markers)
- self.prelocationModule.markersDeleted.connect(self._OLD_daq_method_prelocated_remove_markers)
- self.fiducialPositionSelected.connect(self._OLD_daq_method_prelocated_set_fiducial)
- self.appendPrelocatedPosition.connect(self._OLD_daq_method_prelocated_append_data)
- self.prelocationModule.moveFastStageRequest.connect(self._OLD_move_fast_stage)
- self._preloc_inspect_area = QPlainTextEdit()
- tab.layout().addWidget(self._preloc_inspect_area)
-
- def _OLD_build_daq_methods_embl_tab(self):
- app = QApplication.instance()
- self._tab_daq_method_embl.setLayout(QVBoxLayout())
- layout = self._tab_daq_method_embl.layout()
- #motors = self.get_gonio_motors()
- self._embl_module = EmblWidget(self) #ZAC: orig. code
- #self._embl_module.configure(motors, app._camera, app._zoom)
- layout.addWidget(self._embl_module)
-
- def _OLD_create_helical_widgets(self):
- tbox = self._helical_tablebox
- htab = self._helical_scan_table = HelicalTableWidget()
- htab.gonioMoveRequest.connect(self._OLD_move_gonio_to_position)
- tbox.setLayout(QVBoxLayout())
-
- grp = QWidget()
- grp.setLayout(QFormLayout())
- le = QSpinBox()
- le.setRange(1, 100)
- le.setValue(htab.scanHorizontalCount())
- le.valueChanged.connect(lambda cnt: htab.setScanHorizontalCount(cnt))
- grp.layout().addRow("Horizontal Count", le)
-
- le = QSpinBox()
- le.setRange(1, 100)
- le.setValue(htab.scanVerticalCount())
- le.valueChanged.connect(lambda cnt: htab.setScanVerticalCount(cnt))
- grp.layout().addRow("Vertical Count", le)
-
- le = QDoubleSpinBox()
- le.setRange(-180.0, 180.0)
- le.setSingleStep(5.0)
- le.setSuffix(" degrees")
- le.valueChanged.connect(htab.setStartAngle)
- grp.layout().addRow("Start angle", le)
-
- tbox.layout().addWidget(grp)
- widgi = QWidget()
- widgi.setLayout(QHBoxLayout())
- tbox.layout().addWidget(widgi)
-
- but = QPushButton("Add Crystal")
- but.clicked.connect(htab.add_xtal)
- widgi.layout().addWidget(but)
-
- but = QPushButton("Set START")
- but.clicked.connect(lambda: htab.set_xtal_start(self.get_gonio_positions()))
- widgi.layout().addWidget(but)
-
- but = QPushButton("Set END")
- but.clicked.connect(lambda: htab.set_xtal_end(self.get_gonio_positions()))
- widgi.layout().addWidget(but)
-
- tbox.layout().addWidget(htab)
-
- def _OLD_add_beam_marker(self):
- app = QApplication.instance()
- cfg = app._cfg
- w, h = cfg.value(AppCfg.GEO_BEAM_SZ)
- self._beammark = bm = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
- tr=QtGui.QTransform() # prepare ImageItem transformation:
- tr.rotate(30)
- bm.setTransform(tr) # assign transform
- self.vb.addItem(self._beammark)
- bm=UsrGO.BeamMark([50, 120], [30, 20])
- self.vb.addItem(bm)
- vi=UsrGO.Grid((120, -100), (200, 150), (30, 20), 2)
- self.vb.addItem(vi)
-
- def _OLD_camera_pause_toggle(self):
- app=QApplication.instance()
- app._camera.pause()
-
- def _OLD_init_settings_tracker(self):
- app=QApplication.instance()
- cfg=app._cfg
- _log.info("configuring widget persistence")
- fields = {
- # 'folder': (self._label_folder, str),
- "project": (self._le_project, str),
- "prefix": (self._le_prefix, str),
- "actual_prefix": (self._label_actual_prefix, str),
- "exposureTime": (self._dsb_exposure_time, float),
- "oscillationAngle": (self._dsb_oscillation_step, float),
- "blastRadius": (self._dsb_blast_radius, float),
- }
- for key, f_config in fields.items():
- widget, conv = f_config
- value = cfg.value(key)
- try:
- wset, wget = widget.setText, widget.text
- _log.debug("tracking text field {}".format(key))
- except AttributeError:
- _log.debug("tracking {} number field {}".format(conv, key))
- wset, wget = widget.setValue, lambda fget=widget.value: conv(fget())
- except Exception as e:
- _log.error(e)
-
- try:
- wset(conv(value))
- except Exception as e:
- _log.debug(e)
- _log.warning('failed for "{}" updating field of type {} with {}'.format( key, type(widget), value))
- finally:
- # _log.debug('wget = {}; wset = {}'.format(wget, wset))
- widget.editingFinished.connect(lambda w=widget, k=key, func_get=wget: self.persist_setting(k, func_get() ) )
- #self.storage_cascade_prefix(None) #ZAC: orig. code
-
- def _OLD_init_validators(self):
- identifier_regex = QRegExp("[a-z-A-Z_0-9%]+")
- self._le_project.setValidator(QRegExpValidator(identifier_regex, self._le_project))
- self._le_prefix.setValidator(QRegExpValidator(identifier_regex, self._le_prefix))
-
- def _OLD_wire_storage(self):
- self._le_prefix.textChanged.connect(self._OLD_storage_cascade_prefix)
- self._le_prefix.textChanged.connect(lambda newtext: self.prefixChanged.emit(newtext))
- self._le_project.textChanged.connect(self._OLD_storage_cascade_prefix)
- self._le_project.textChanged.connect(lambda newtext: self.projectChanged.emit(newtext))
- self._le_prefix.editingFinished.connect(self._OLD_prepare_daq_folder)
- self._le_project.editingFinished.connect(self._OLD_prepare_daq_folder)
- self.increaseRunNumberRequest.connect(self._OLD_increase_run_number)
-
- def _OLD_storage_cascade_prefix(self, val):
- prefix = self._le_prefix.text()
- if 0 == len(prefix):
- _log.warning("empty prefix is not accepted")
- self._le_prefix.setAccessibleName("invalid_input")
- self._le_prefix.blockSignals(True)
- self._le_prefix.setText("INVALID=>" + prefix)
- QMessageBox.warning(self, "prefix is not valid", "Prefix is not valid!")
- self._le_prefix.blockSignals(False)
-
- return
- else:
- self._le_prefix.setAccessibleName("")
- project = self._le_project.text()
- folders.set_prefix(prefix)
- folders.set_project(project)
- folders.run = settings.value("run_number", type=int)
- self._label_runnumber.setText(f"{folders.run:04d}")
- self._data_folder = folders.raw_folder
- self.folderChanged.emit(folders.raw_folder)
- self._label_actual_prefix.setText(folders.prefix)
- self._label_folder.setText(folders.raw_folder)
-
- def _OLD_increase_run_number(self):
- run = settings.value("run_number", type=int)
- run += 1
- settings.setValue("run_number", run)
- folders.run = run
- self._label_runnumber.setText(f"{run:04d}")
-
- def _OLD_prepare_daq_folder(self):
- global home, folders
- prefix = folders.prefix
- folder = folders.res_folder
- if 0 == len(prefix):
- return
-
- try:
- os.makedirs(folder, 0o750, exist_ok=True)
- except:
- msg = "Failed to create folder: {}".format(folder)
- _log.warning(msg)
- QMessageBox.warning(self, "Screenshot: failed to create folder", "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!",)
- raise
-
- fname = os.path.join(folders.pgroup_folder, ".latest_raw")
- try:
- with open(fname, "w") as f:
- f.write(folders.raw_folder)
- _log.info("wrote: {}".format(fname))
- except:
- _log.warning("failed writing {}".format(fname))
-
- fname = os.path.join(folders.pgroup_folder, ".latest_res")
- try:
- with open(fname, "w") as f:
- f.write(folders.res_folder)
- _log.info("wrote: {}".format(fname))
- except:
- _log.warning("failed writing {}".format(fname))
-
- def _OLD_persist_setting(self, s, v):
- app=QApplication.instance()
- cfg=app._cfg
- _log.debug("persisting {} = {}".format(s, v))
- cfg.setValue(s, v)
-
- def _OLD_method_changed(self, index):
- method = self._tabs_daq_methods.currentWidget().accessibleName()
- _log.info("method now => {}".format(method))
-
-
-
- def _OLD_check_zescape(self):
- msg = zescape.check()
- if msg is None:
- return
- if "current" in msg:
- _log.warning(f"current state: {self._esc_state}")
- zescape.reply(self._esc_state)
- elif "goto" in msg:
- state = msg.split()[1].lower()
- _log.warning(f"TELL requests to go to {state}")
- try:
- if "sampleexchange" in state:
- _log.debug(
- f"moving to mount with offset = {self._pin_mounting_offset}"
- )
- self.move_gonio_to_mount_position(offset=self._pin_mounting_offset)
- elif "samplealignment" in state:
- self.cb_esc_sample_alignment()
- except:
- zescape.reply("Maintenance")
- zescape.reply(self._esc_state)
- else: # JSON
- data = json.loads(msg)
- if "sampleName" in data:
- _log.debug(f"TELL SAMPLE DATA => {data}")
- self.tell2storage(data)
- zescape.reply("ack")
- elif "pin_offset" in data:
- _log.debug(f"TELL pin offset => {data}")
- self._pin_mounting_offset = data["pin_offset"]
- zescape.reply("ack")
- elif "get_pin_offset" in data:
- _log.debug(f"TELL get pin offset => {data}")
- zescape.reply_json({"pin_offset": self._pin_mounting_offset})
-
- def _OLD_tell2storage(self, sample):
- _log.debug(f"2 TELL SAMPLE DATA => {type(sample)}")
- self._le_prefix.setText(sample["sampleName"])
- self._le_project.setText(sample["sampleFolder"])
- tstf = folders.get_prefixed_file("_newsample")
- self.storage_cascade_prefix(None)
- _log.warning(f"sample info: {tstf}")
-
- def _OLD_is_task(self, task):
- return task == self._active_task
-
- def _OLD_get_task_menu(self):
- pass
-
- def _OLD_toggle_shutter(self, **kwargs):
- if self._pv_shutter:
- if 0 == self._pv_shutter.get():
- self._pv_shutter.put(1)
- self._button_shutter.setText("shutter opened\n\u2622")
- else:
- self._pv_shutter.put(0)
- self._button_shutter.setText("shutter closed\n\u2622")
- elif self._has_pulse_picker:
- pulsePicker.toggle()
-
- def _OLD_update_shutter_label(self, pvname, value, char_value, **kwargs):
- if 0 == value:
- self._button_shutter.setText("shutter closed")
- else:
- self._button_shutter.setText("shutter opened")
-
- def _OLD_build_sample_selection_tab(self):
- self._sample_selection = sample_selection.SampleSelection(self)
- self._sample_selection.move_to_mount_position = (self.move_gonio_to_mount_position)
- self._tab_sample_selection.setLayout(QVBoxLayout())
- self._tab_sample_selection.layout().addWidget(self._sample_selection)
- self._tab_sample_selection.layout().addStretch(2)
-
- def _OLD_build_embl_group(self):
- grp = QGroupBox("EMBL Acquisition")
- layout = QFormLayout()
- grp.setLayout(layout)
- layout.addWidget(QLabel("Prefix"))
- self._embl_prefix = QLineEdit("img")
- layout.addWidget(self._embl_prefix)
-
- def _OLD_abort_measurement(self, ev=None):
- if settings.value(ACTIVATE_PULSE_PICKER):
- pulsePicker.close()
- jungfrau_detector.abort()
- delta_tau.abort()
- _log.debug("aborting measurement")
-
- def _OLD_trigger_detector(self, **kwargs):
- if self._pv_shutter is not None:
- self._pv_shutter.put(0)
- # self._eiger_button_collect.show()
- # self._eiger_button_abort.hide()
- # self._eiger_now_collecting_label.setText(
- # "Finished sequence id: {}\n"
- # "Data in: Data10/{}".format(
- # self._detector_sequence_id, self._eiger_now_collecting_file
- # )
- # )
-
- def _OLD_modify_camera_transform(self, t):
- if t == "remove_all":
- sample_camera.set_transformations([])
- elif t == "undo_last":
- sample_camera._transformations.pop()
- #elif type(t) ==type(camera.Transforms): #ZAC: orig. code
- # sample_camera.append_transform(t)
- try:
- label = ", ".join([t.name for t in sample_camera._transformations])
- except:
- label = ""
- self._label_transforms.setText(label)
- #settings.setValue(CAMERA_TRANSFORMATIONS, sample_camera._transformations) #ZAC: orig. code
-
- def _OLD_roi_add_line(self):
- roi = pg.LineSegmentROI(
- [200, 200],
- [300, 300],
- pen="r",
- scaleSnap=True,
- translateSnap=True,
- rotateSnap=True,
- removable=True,
- )
- # roi.sigRegionChanged.connect(self.track_roi)
- roi.sigRemoveRequested.connect(self.remove_roi)
- self.vb.addItem(roi)
- self._rois.append(roi)
-
- def _OLD_roi_add_rect(self):
- roi = pg.RectROI(
- [200, 200],
- [50, 50],
- pen="r",
- scaleSnap=True,
- translateSnap=True,
- rotateSnap=True,
- removable=True,
- )
- roi.sigRegionChanged.connect(self.track_roi)
- roi.sigRemoveRequested.connect(self.remove_roi)
- self.vb.addItem(roi)
- self._rois.append(roi)
-
- def _OLD_remove_roi(self, roi):
- self.vb.removeItem(roi)
- self._rois.remove(roi)
-
- def _OLD_prepare_microscope_page(self):
- layout = self.microscope_page.layout()
- container = QWidget()
- hlay = QHBoxLayout()
- container.setLayout(hlay)
- layout.addWidget(container)
-
- def _OLD_update_beam_marker(self, zoom_lvl):
- w, h = settings.value(BEAM_SIZE)
- try:
- bx = self.beamx_fitter(zoom_lvl)
- by = self.beamy_fitter(zoom_lvl)
- ok = True
- except:
- ok = False
- _log.warning("beam marker not defined")
- return
- _log.debug("updating beam mark to {:.1f}x{:.1f}".format(bx, by))
- self.beamCameraCoordinatesChanged.emit(bx, by)
-
- def _OLD_update_beam_marker_fitters(self):
- if len(self._beam_markers) > 2:
- _log.debug("defining beam marker")
- bx = [(n, x[0]) for n, x in self._beam_markers.items()]
- by = [(n, x[1]) for n, x in self._beam_markers.items()]
- nbx = np.asarray(bx).T
- nby = np.asarray(by).T
- bx_coefs = np.polyfit(nbx[0], nbx[1], 3)
- by_coefs = np.polyfit(nby[0], nby[1], 3)
- _log.debug(".... beam marker X coeficients {}".format(bx_coefs))
- _log.debug(".... beam marker Y coeficients {}".format(by_coefs))
- self.beamx_fitter = np.poly1d(bx_coefs)
- self.beamy_fitter = np.poly1d(by_coefs)
-
-
- def _OLD_append_to_beam_markers(self, x, y, zoom):
- self._beam_markers[zoom] = (x, y)
- _log.info("beam markers {}".format(self._beam_markers))
- settings.setValue(BEAM_MARKER_POSITIONS, self._beam_markers)
- self.update_beam_marker_fitters()
-
- def _OLD_remove_beam_markers(self):
- self._beam_markers = {}
- self.beamx_fitter = None
- self.beamy_fitter = None
-
- def _OLD_track_roi(self, roi):
- x, y = roi.pos()
- w, h = roi.size()
- # area = roi.getArrayRegion(self._im, self.img)
- # sum = np.sum(area)
- # _log.info('{} => sum {}'.format((x,y), sum))
- bx, by = x + w / 2., y + h / 2.
- _log.info("beam pos {}".format((bx, by)))
- _log.info("marker pos = {} ; size = {}".format((x, y), (w, h)))
-
- def _OLD_toggle_mouse_tracking(self):
- if self._mouse_tracking:
- self.disengage_mouse_tracking()
- else:
- self.engage_mouse_tracking()
-
- def _OLD_engage_mouse_tracking(self):
- self.glw.scene().sigMouseMoved.connect(self.cb_mouse_move)
- self.glw.scene().sigMouseMoved.emit()
- self._mouse_tracking = True
-
- def _OLD_disengage_mouse_tracking(self):
- self.glw.scene().sigMouseMoved.disconnect(self.cb_mouse_move)
- self._mouse_tracking = False
- self._lb_coords.setText("")
-
- def _OLD_get_beam_mark_on_camera_xy(self):
- app=QApplication.instance()
- z = app._zoom.get_val()
- try:
- bx = self.beamx_fitter(z)
- by = self.beamy_fitter(z)
- except:
- bx, by = 500, 500
- return (bx, by)
-
- def _OLD_move_gonio_to_position(self, fx, fy, bx, bz, omega):
- self.tweakers["fast_x"].motor.move(fx, wait=False, ignore_limits=True)
- self.tweakers["fast_y"].motor.move(fy, wait=False, ignore_limits=True)
- self.tweakers["base_x"].motor.move(bx, wait=False, ignore_limits=True)
- self.tweakers["base_z"].motor.move(bz, wait=False, ignore_limits=True)
- self.tweakers["omega"].motor.move(omega, wait=False, ignore_limits=True)
-
- def _OLD_get_gonio_motors(self, as_json=False):
- if as_json:
- return {
- "fast_x": self.tweakers["fast_x"].motor,
- "fast_y": self.tweakers["fast_y"].motor,
- "base_x": self.tweakers["base_x"].motor,
- "base_z": self.tweakers["base_z"].motor,
- "omega": self.tweakers["omega"].motor,
- }
- else:
- return (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
-
- def _OLD_get_gonio_tweakers(self):
- return (
- self.tweakers["fast_x"],
- self.tweakers["fast_y"],
- self.tweakers["base_x"],
- self.tweakers["base_z"],
- self.tweakers["omega"],
- )
-
- def _OLD_get_gonio_positions(self, as_json: bool = False):
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
-
- a, b, c, d, e = (
- fx.get_position(),
- fy.get_position(),
- cx.get_position(),
- cz.get_position(),
- omega.get_position(),
- )
- if as_json:
- return {"fx": a, "fy": b, "bx": c, "bz": d, "omega": e}
- else:
- return (a, b, c, d, e)
-
- def _OLD_escape_goToTellMountPosition(self):
- self.move_gonio_to_mount_position()
- self.lock_goniometer()
-
- def _OLD_move_gonio_to_mount_position(self, offset: float = 0.0):
- fx, fy, cx, cz, omega = self.get_gonio_motors()
- bmark = "bookmark_0"
- try:
- t_fx = float(settings.value(bmark + "/mount_fx"))
- t_fy = -offset + float(settings.value(bmark + "/mount_fy"))
- t_cx = float(settings.value(bmark + "/mount_cx"))
- t_cz = float(settings.value(bmark + "/mount_cz"))
- t_omega = float(settings.value(bmark + "/mount_omega"))
- except:
- raise IncompleteConfiguration("TELL sample changer mount position is not configured!!!")
- fx.move(t_fx, wait=True, ignore_limits=True)
- fy.move(t_fy, wait=True, ignore_limits=True)
- cx.move(t_cx, wait=True, ignore_limits=True)
- cz.move(t_cz, wait=True, ignore_limits=True)
- omega.move(t_omega, wait=True, ignore_limits=True)
- app_utils.assert_motor_positions(
- [
- (fx, t_fx, 0.01),
- (fy, t_fy, 0.01),
- (cx, t_cx, 0.01),
- (cz, t_cz, 0.01),
- (omega, t_omega, 0.01),
- ]
- )
- self.cb_esc_sample_exchange()
-
- def _OLD_lock_goniometer(self):
- # tell.set_in_mount_position(True)
- res = QMessageBox.question(self, "", "Mount a sample from console and click ok once the sample is mounted.", QMessageBox.Ok, QMessageBox.Ok,)
- res = QMessageBox.question(self, "", "Is the sample is mounted?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,)
- if res in (QMessageBox.Yes, QMessageBox.No):
- # tell.set_in_mount_position(False)
- pass
-
- @pyqtSlot(int)
- def _OLD_saveBookmark(self, key: int):
- """save a bookmark for the corresponding key is the Qt.Key_* code """
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
- bmark = "bookmark_{}".format(key)
- if key == 0:
- ans = QMessageBox.question(self, "Override TELL mount position", "This will overwrite the positions used for TELL MOUNTING!!!\n\n\tContinue ?",)
- if ans != QMessageBox.Yes:
- return
-
- _log.info(
- "saving bookmark {}: {}, {}, {}, {}, {}".format(
- bmark,
- fx.get_position(),
- fy.get_position(),
- cx.get_position(),
- cz.get_position(),
- omega.get_position(),
- )
- )
- settings.setValue(bmark + "/mount_fx", fx.get_position())
- settings.setValue(bmark + "/mount_fy", fy.get_position())
- settings.setValue(bmark + "/mount_cx", cx.get_position())
- settings.setValue(bmark + "/mount_cz", cz.get_position())
- settings.setValue(bmark + "/mount_omega", omega.get_position())
-
- def _OLD_gotoBookmark(self, key: int):
- """save a bookmark for the corresponding key"""
- fx, fy, cx, cz, omega = (
- self.tweakers["fast_x"].motor,
- self.tweakers["fast_y"].motor,
- self.tweakers["base_x"].motor,
- self.tweakers["base_z"].motor,
- self.tweakers["omega"].motor,
- )
- bmark = "bookmark_{}".format(key)
- try:
- t_fx = float(settings.value(bmark + "/mount_fx"))
- t_fy = float(settings.value(bmark + "/mount_fy"))
- t_cx = float(settings.value(bmark + "/mount_cx"))
- t_cz = float(settings.value(bmark + "/mount_cz"))
- t_omega = float(settings.value(bmark + "/mount_omega"))
- except:
- return
-
- fx.move(t_fx, wait=True, ignore_limits=True)
- fy.move(t_fy, wait=True, ignore_limits=True)
- cx.move(t_cx, wait=True, ignore_limits=True)
- cz.move(t_cz, wait=True, ignore_limits=True)
- omega.move(t_omega, wait=True, ignore_limits=True)
-
- def _OLD_move_cryojet_nozzle(self, pos):
- cx = self.tweakers["cryo"]
- if "in" == pos.lower():
- key = CRYOJET_NOZZLE_IN
- elif "out" == pos.lower():
- key = CRYOJET_NOZZLE_OUT
-
- to_pos = settings.value(key, 1e10, type=float)
- if to_pos > 1e9:
- raise IncompleteConfiguration(f"CRYOJET configuration is incomplete! Missing {key}")
- cx.move_abs(to_pos, assert_position=True)
-
- def _OLD_build_cryo_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(
- toolbox,
- "Cryojet",
- widget_list=[
- self.get_tweaker(f"{pfx}:MOT_CRYO", alias="cryo", label="cryo X")
- ],
- )
-
- def _OLD_build_wegde_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(toolbox,"Wedge Mover",
- widget_list=[
- self.get_tweaker(f"{pfx}:MOT_WEDGE1", alias="wedge_1", label="wedge_1"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE2", alias="wedge_2", label="wedge_2"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE3", alias="wedge_3", label="wedge_3"),
- self.get_tweaker(f"{pfx}:MOT_WEDGE4", alias="wedge_4", label="wedge_4"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEX", alias="wedge_x", label="wedge_x"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEY", alias="wedge_y", label="wedge_y"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEA", alias="wedge_a", label="wedge_a"),
- self.get_tweaker(f"{pfx}:MOT_WEDGEB", alias="wedge_b", label="wedge_b"),
- ],
- )
-
- def _OLD_build_slits_group(self, toolbox):
- pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
- qutilities.add_item_to_toolbox(
- toolbox,
- "Slits",
- widget_list=[
- self.get_tweaker(f"{pfx}10", alias="slit_right", label="left", mtype=1, ),
- self.get_tweaker(f"{pfx}11", alias="slit_left", label="right", mtype=1,),
- self.get_tweaker(f"{pfx}12", alias="slit_bottom", label="bottom", mtype=1,),
- self.get_tweaker(f"{pfx}13",alias="slit_top",label="top",mtype=1,),
- ],
- )
-
- def _OLD_assert_post_tube_position(self, pos):
- x_up = settings.value("post_sample_tube/x_up", 1e10, type=float)
- y_up = settings.value("post_sample_tube/y_up", 1e10, type=float)
- x_down = settings.value("post_sample_tube/x_down", 1e10, type=float)
- y_down = settings.value("post_sample_tube/y_down", 1e10, type=float)
- dx = settings.value("post_sample_tube/dx", 1e10, type=float)
- dy = settings.value("post_sample_tube/dy", 1e10, type=float)
- tz_in = settings.value("post_sample_tube/z_in", 1e10, type=float)
- tz_out = settings.value("post_sample_tube/z_out", 1e10, type=float)
-
- if (x_up + y_up + x_down + y_down + dx + dy + tz_in + tz_out) > 1e9:
- raise Exception("miscofingured positions for post-sample tube")
-
- usy = self.tweakers["tube_usy"]
- dsy = self.tweakers["tube_dsy"]
- usx = self.tweakers["tube_usx"]
- dsx = self.tweakers["tube_dsx"]
- tbz = self.tweakers["tube_z"]
-
- if pos == "in":
- yu = y_up
- xu = x_up
- yd = y_down
- xd = x_down
- z = tz_in
- elif pos == "out":
- yu = y_up + dy
- xu = x_up + dx
- yd = y_down + dy
- xd = x_down + dx
- z = tz_out
-
- app_utils.assert_tweaker_positions([
- (usy, yu, 0.1),
- (dsy, yd, 0.1),
- (usx, xu, 0.1),
- (dsx, xd, 0.1),
- (tbz, z, 0.1),],timeout=2.0,
- )
-
- def _OLD_add_tweaker(self, pv, alias=None, label=None, mtype="epics_motor", layout=None):
- if layout is None:
- layout = self._tweak_container.layout()
- if mtype == "epics_motor":
- m = MotorTweak()
- else:
- m = SmaractMotorTweak()
- layout.addWidget(m)
- m.connect_motor(pv, label)
- self.tweakers[alias] = m
-
- def _OLD_done_sliding(self):
- print("done sliding at {}".format(self.slider_fast_x.value()))
-
- def _OLD_daq_grid_add_grid(self, gx=None, gy=None):
- grid_index = len(self._grids)
- if gx in (False, None):
- gx=self.tweakers["fast_x"].get_rbv()
- gy=self.tweakers["fast_y"].get_rbv()
- xstep = self._sb_grid_x_step.value()
- ystep = self._sb_grid_y_step.value()
- xoffset = self._sb_grid_x_offset.value()
- yoffset = self._sb_grid_y_offset.value()
-
- app=QApplication.instance()
- geo=app._geometry
- oc=geo._opt_ctr
- if xstep==0:
- go=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
- elif xstep==1:
- go=UsrGO.FixTargetFrame((120, -100), (200, 150), tpl='test')
- elif xstep==2:
- v=geo.pos2pix((12.5, 0))
- l=np.linalg.norm(v)
- go=UsrGO.FixTargetFrame(-oc, (l,l), tpl='12.5x12.5')
- elif xstep==3:
- v=geo.pos2pix((23, 0))
- l=np.linalg.norm(v)
- go=UsrGO.FixTargetFrame(-oc, (l,l), tpl='23.0x23.0')
- else:
- _log.error('set xstep 0..2 for tests')
- self.vb.addItem(go)
- self._goTracked['objLst'].append(go)
-
- #grid = CstROI.Grid( x_step=xstep, y_step=ystep, x_offset=xoffset, y_offset=yoffset, gonio_xy=(gx, gy), grid_index=grid_index, parent=self,)
- #self.vb.addItem(grid)
- #grid.calculate_gonio_xy()
- #grid.sigRemoveRequested.connect(lambda g=grid: self.remove_grid(g))
-
- def _OLD_daq_grid_remove_all(self):
- vb=self.vb
- for go in self._goTracked['objLst']:
- vb.removeItem(go)
- self._goTracked['objLst']=[]
-
- def _OLD_grids_pause_stage_tracking(self):
- for grid in self._grids:
- grid.disable_stage_tracking()
-
- def _OLD_grids_start_stage_tracking(self):
- for grid in self._grids:
- grid.enable_stage_tracking()
-
- def _OLD_remove_grid(self, grid):
- self.vb.removeItem(grid)
- self._grids.remove(grid)
-
-
- def _OLD_daq_grid_update(self, grid_index):
- try:
- grid = self._grids[grid_index]
- except:
- print("grid index not yet there")
- return
- points = grid.get_grid_targets()
- num_points = len(points)
- etime = float(settings.value("exposureTime"))
- doc = f"grid_{grid_index} = ["
- for n, pos in enumerate(points):
- x, y = pos
- doc += "[{:8.3f}, {:8.3f}],\n".format(x, y)
- doc += "]"
- self._grid_inspect_area.setPlainText(doc)
- m = "Number of points: {}\nEstimated Time: {:.1f} minutes".format(num_points, num_points * etime / 60.)
- self._label_grid_parameters.setText(m)
-
- def _OLD_daq_embl_collect_points(self):
- coords = self._embl_module.coords
- points = [[x, y] for x, y, bx, bz, o in coords]
- points = np.array(points)
- method = "trajectory"
- xp = (1000 * points).astype(int) # microns then round int
- params = (xp[:, 0].tolist(), xp[:, 1].tolist())
- self.daq_collect_points(points, visualizer_method=method, visualizer_params=params)
-
- def _OLD_daq_prelocated_collect_points(self):
- points = []
- data = self.prelocationModule.get_collection_targets()
- for n, cc in enumerate(data):
- is_fiducial, gx, gy, cx, cy, ox, oy = cc
- points.append([gx, gy])
- points = np.array(points)
- method = "trajectory"
- xp = (1000 * points).astype(int) # microns then round int
- params = (xp[:, 0].tolist(), xp[:, 1].tolist())
- self.daq_collect_points(points, visualizer_method=method, visualizer_params=params)
-
- def _OLD_daq_grid_findxtals(self):
- feature_size = self._sb_findxtals_feature_size.value()
- image = sample_camera.get_image()
- findObj(-image, objSize=feature_size, viz=1)
-
- def _OLD_check_jungfrau_save(self) -> bool:
- if jungfrau_detector.is_running_detector():
- saveRaw = jungfrau_detector.is_saving_data()
-
- if not saveRaw:
- box = QMessageBox()
- box.setText("Jungfrau save data disabled!")
- box.setInformativeText("Jungfrau save data is disabled!")
- box.setIcon(QMessageBox.Warning)
- box.setDetailedText("Choose to abort, enable and continue, or continue without saving raw data")
- btContinue = box.addButton("Continue", QMessageBox.YesRole)
- btAbort = box.addButton("OMG! Abort", QMessageBox.NoRole)
- btEnable = box.addButton("Enable save and continue", QMessageBox.YesRole)
- box.exec_()
- ans = box.clickedButton()
- if ans == btEnable:
- jungfrau_detector.set_save_raw(True)
- return True
- elif ans == btAbort:
- _log.info("not doing helical scan")
- return False
- return True
- return True
-
- def _OLD_daq_collect_points(self, points, visualizer_method, visualizer_params):
- app = QApplication.instance()
- cfg = app._cfg
- verbose=0xff
- fn='/tmp/shapepath'
- try:
- dt=app._deltatau
- except AttributeError:
- app._deltatau=dt=deltatau.Deltatau()
- try:
- jf=app._jungfrau
- except AttributeError:
- app._jungfrau=jf=detector.Jungfrau()
-
- sp=dt._shapepath
- sp.gen_grid_points(w=15, h=15, pitch=3, rnd=0, ofs=(0, +2000))
- #sp.gen_grid_points(w=5, h=10, pitch=1, rnd=0, ofs=(0, 0));sp.sort_points(False, 10);sp.points
- sp.sort_points(False, 15);
- sp.meta['pt2pt_time']=10
- sp.setup_gather()
- sp.setup_sync(verbose=verbose&32, timeOfs=0.05)
- sp.setup_coord_trf() # reset to shape path system
- # sp.meta['pt2pt_time']=10 #put between setup_sync and setup_motion to have more motion points than FEL syncs
- sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10)
- sp.homing() # homing if needed
- sp.run() # start motion program
- sp.wait_armed() # wait until motors are at first position
- sp.trigger(0.5) # send a start trigger (if needed) ater given time
- if not dt._comm is None:
- while True:
- p=int(sp.progress())
- if p<0: break
- #print('progress %d/%d'%(p, num_pts))
- time.sleep(.1)
- sp.gather_upload(fnRec=fn+'.npz')
- #dp=deltatau.shapepath.DebugPlot(sp)
- #dp.plot_gather(mode=11)
- #plt.show(block=False)
- #plt.show(block=True)
- return
-
-
-
- task = self.active_task()
- XDIR = -1
-
- #folders.make_if_needed()
- #if ( cfg.option(AppCfg.ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()):
- # if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau",
- # "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",):
- # _log.warning("user forgot to turn on the jungfrau")
- # return
-
- #if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- # self.escape_goToDataCollection()
-
- points *= 1000 # delta tau uses micrometers
- points[:, 0] *= XDIR # fast X axis is reversed
-
-
- # sync_mode : default=2
- # 0 : no sync at all
- # 1 : synchronize start
- # 2 : synchronize start and adapt motion speed
- # this function generates the code blocks:
- # self.sync_wait and self.sync_run
- # sync_wait can be put in the program to force a timing sync
- # sync_run are the commands to run the whole program
- # sync_flag if not using jungfrau =1 otherwise =0
- # D.O. shapepath.meta.update(sync_mode=2, sync_flag=1)
- sp.meta.update(sync_mode=0, sync_flag=0)
-
- maxacq_points = 116508
- samp_time = 0.0002 # s
- overhead_time = 0.1
- etime=10
- vscale=1.0
- #etime = settings.value("exposureTime", type=float)
- #vscale = settings.value(DELTATAU_VELOCITY_SCALE, 1.0, type=float)
- #sort_points = option(DELTATAU_SORT_POINTS)
-
- acq_per = int(np.ceil((etime * len(points) + overhead_time) / (maxacq_points * samp_time)))
- _log.info(f"gather acquisotion period = {acq_per}")
- _log.info(f"velocity scale {vscale}")
- sp.setup_gather(acq_per=acq_per)
- sp.setup_sync(verbose=True)
- sp.setup_coord_trf()
-
- assert(points.dtcfgype==np.float64)
- sp.points = points
-
- if TASK_GRID == task:
- # width, height = visualizer_params
- # _log.debug(f"grid: {width} x {height}")
- # details_1 = [width]
- # details_2 = [height]
- # sp.sort_points(xy=False, grp_sz=height)
- pass
- elif task in (TASK_PRELOCATED, TASK_EMBL):
- if sort_points:
- shapepath.sort_points()
- self.daq_method_prelocated_remove_markers()
- details_1, details_2 = visualizer_params
-
- sp.setup_motion(
- mode=3, # 1 = bad pvt 3 = pft (pvt via inverse fourier transform)
- pt2pt_time=etime * 1000.,
- #fnPrg=folders.get_prefixed_file("_program.prg"),
- scale=vscale, # velocity at target position scaling: 1=optimal speed, 0=zero speed
- dwell=10, # milli-seconds wait
- )
- sp.run()
-
- self.qprogress = QProgressDialog(self)
- self.qprogress.setRange(0, 0)
- self.qprogress.setLabelText("Acquiring GRID")
- self.qprogress.setCancelButtonText("Abort Acquisition")
- self.qprogress.canceled.connect(self.complete_daq)
- self.qprogress.setWindowModality(Qt.WindowModal)
- self.qprogress.setAutoClose(True)
- self.qprogress.show()
-
- sequencer_steps = [lambda: self.grids_pause_stage_tracking()]
-
- if jungfrau_detector.is_running_detector():
- if not self.check_jungfrau_save():
- # user aborted run from save data dialog
- return
-
- n_frames = ntrigger
- uid = settings.value(EXPERIMENT_UID, type=int)
- backend_extras = self.jungfrau.get_parameters()
- backend_extras.update(
- {
- "swissmx_trajectory_method": visualizer_method,
- "swissmx_trajectory_details_1": details_1,
- "swissmx_trajectory_details_2": details_2,
- }
- )
- jungfrau_detector.set_number_of_frames(n_frames)
- jungfrau_detector.set_data_owner_uid(uid)
- sequencer_steps.extend(
- [
- lambda: jungfrau_detector.configure(
- n_frames=n_frames,
- outfile=folders.prefix,
- outdir=folders.raw_folder,
- uid=uid,
- backend_extras=backend_extras,
- ),
- lambda: jungfrau_detector.arm(),
- ]
- )
-
- sequencer_steps.append(lambda: shapepath.wait_armed())
- if option(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.open())
-
- # if settings.value("scanning/trigger_microscope_camera", type=bool):
- # sample_camera.switch_to_trigger(True)
-
- sequencer_steps.append(lambda: shapepath.trigger(wait=0.5))
-
- def _OLD_shapepath_progress():
- while True:
- p = shapepath.progress()
- if p < 0:
- break
- time.sleep(0.1)
- self.qprogress.setLabelText(f"Acquiring GRID {p:.0f} / {ntrigger}")
- _log.warning(f"motion complete!")
- # sample_camera.stop_camera()
- # sample_camera.switch_to_trigger(False)
- # sample_camera.save_buffer_series(folders.prefix)
-
- sequencer_steps.append(shapepath_progress)
-
- if option(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.close())
-
- sequencer_steps.append(lambda: jungfrau_detector.wait_finished())
-
- sequencer_steps.append(lambda: self.grids_start_stage_tracking())
-
- self.sequencer = Sequencer(steps=sequencer_steps)
- self._thread = QThread()
- self._thread.setObjectName("acquisition_thread")
- self.sequencer.moveToThread(self._thread)
- self.sequencer.finished.connect(self.daq_collect_points_wrapup)
- self._thread.started.connect(self.sequencer.run_sequence)
- self._thread.start()
-
- def _OLD_run_steps(self, steps, title, at_end=None, cancelable=False):
- dlg = QProgressDialog(self)
- dlg.setWindowTitle(title)
- dlg.setWindowModality(Qt.WindowModal)
- dlg.setMinimumDuration(0)
- if not cancelable:
- dlg.setCancelButton(None)
- dlg.setRange(0, 0)
- dlg.setLabelText(f"{title}
")
- dlg.setAutoClose(True)
- dlg.show()
- dlg.setValue(random.randint(1, 20))
- class Runner(QObject):
- finito = pyqtSignal()
- timeoutExpired = pyqtSignal()
- errorHappened = pyqtSignal(str)
- result = pyqtSignal(str)
-
- def __init__(self, step_to_run):
- super().__init__()
- self.step = step_to_run
- self.exception = None
- self.done = False
-
- def run(self):
- try:
- self.step()
- except Exception as e:
- _log.debug(" +> step exception")
- self.exception = str(e)
- self.errorHappened.emit(str(e))
- self.finito.emit()
-
-
- for n, step in enumerate(steps):
- _log.info(f"running step {step.title}")
- dlg.setLabelText(f"{title}
{step.title}")
- dlg.setValue(n)
- thread = QThread()
- runner = Runner(step)
- runner.moveToThread(thread)
- thread.started.connect(runner.run)
- runner.finito.connect(thread.quit)
- thread.start()
- while thread.isRunning():
- dlg.setValue(random.randint(1, 20))
- time.sleep(0.01)
- if dlg.wasCanceled():
- # FIXME ensure we abort the running thread
- break
-
- if dlg.wasCanceled():
- break
- if runner.exception is not None:
- QMessageBox.critical(self, step.title, str(runner.exception))
- break
-
- if dlg.wasCanceled():
- _log.error(f"sequence {title} was cancelled by user")
- raise AcquisitionAbortedException(f"sequence {title} was cancelled by user")
-
- if at_end is not None:
- at_end()
- dlg.reset()
-
- def _OLD_daq_collect_points_wrapup(self):
- self.qprogress.reset()
- if self._thread.isRunning():
- self._thread.quit()
- shapepath.gather_upload(os.path.join(folders.res_folder, folders.prefix + ".npz"))
-
- if option(DELTATAU_SHOW_PLOTS):
- dp = DebugPlot(shapepath)
- dp.plot_gather(mode=1)
- pyplot.show()
-
- if TASK_PRELOCATED == self.active_task():
- self.daq_method_prelocated_update_markers()
-
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_sample_alignment()
-
- sequence = {"delta tau program": shapepath.prg, "points": shapepath.points.tolist(), "timestamp": tdstamp(),}
-
- sfname = folders.get_prefixed_file("_ScanInfo.json")
- try:
- with open(sfname, "w") as sf:
- _log.info("writing scan info into: {}".format(sfname))
- sf.write(json.dumps(sequence))
- except:
- _log.warning(f"failed to write scan info to {sfname}")
-
- self.re_connect_collect_button()
- jungfrau_detector.abort()
- self.increaseRunNumberRequest.emit()
-
- def _OLD_daq_collect_update_inspect(self, msg):
- te = self._inspect
- m = te.toPlainText()
- te.setPlainText(m + msg + "\n")
- te.verticalScrollBar().setValue(te.verticalScrollBar().maximum())
-
- def _OLD_daq_helical_collect(self):
- """[
- [{
- 0: (0.0, 1.238401694734829, 3.527, 0.936, 0.001),
- 120: (0.0, 1.3890393596274455, -1.957242824091597, -0.5639999999999998, 120.001),
- 240: (0.0, 1.3866130349657206, -1.1642619618562273, 3.105, 240.001)
- },
- {
- 0: (0.0, 1.238401694734829, 3.527, 0.936, 0.001),
- 120: (0.0, 1.3890393596274455, -1.957242824091597, -0.5639999999999998, 120.001),
- 240: (0.0, 1.3866130349657206, -1.1642619618562273, 3.105, 240.001)
- }]
- ]
- """
- _log.info("executing collection")
- htab = self._helical_scan_table
- num_h = htab.scanHorizontalCount()
- num_v = htab.scanVerticalCount()
-
- if ( settings.value(ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()):
- if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau",
- "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",):
- _log.warning("user forgot to turn on the jungfrau")
- return
-
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_data_collection()
-
- folders.make_if_needed()
-
- data = htab.get_data()
- _log.debug(data)
- start, end = data[0]
- FX, FY, BX, BZ, O = range(5)
- x = (
- (-1000 * start[0][BX], -1000 * start[120][BX], -1000 * start[240][BX]),
- (-1000 * end[0][BX], -1000 * end[120][BX], -1000 * end[240][BX]),
- )
- y = (1000 * start[0][FY], 1000 * end[0][FY])
- z = (
- (-1000 * start[0][BZ], -1000 * start[120][BZ], -1000 * start[240][BZ]),
- (-1000 * end[0][BZ], -1000 * end[120][BZ], -1000 * end[240][BZ]),
- )
-
- if jungfrau_detector.is_running_detector():
- if not self.check_jungfrau_save():
- return
- saveRaw = jungfrau_detector.is_saving_data()
-
- _log.debug(f"x = {x}")
- _log.debug(f"y = {y}")
- _log.debug(f"z = {z}")
-
- oscillationAngle = settings.value("oscillationAngle", type=float)
- exposureTime = 1000 * settings.value("exposureTime", type=float)
- blastRadius = settings.value("blastRadius", type=float)
- totalRange = num_v * num_h * oscillationAngle
-
- # sync_mode : default=2
- # 0 : no sync at all
- # 1 : synchronize start
- # 2 : synchronize start and adapt motion speed
- # this function generates the code blocks:
- # self.sync_wait and self.sync_run
- # sync_wait can be put in the program to force a timing sync
- # sync_run are the commands to run the whole program
- # sync_flag if not using jungfrau =1 otherwise =0
- # D.O. helical.meta.update(sync_mode=2, sync_flag=1)
- helical.meta.update(sync_mode=0, sync_flag=0)
- helical.calcParam(x=x, y=y, z=z)
- helical.setup_gather()
- helical.setup_sync()
- helical.setup_coord_trf()
- mode = 1
- hRng = (-blastRadius * num_h, blastRadius * num_h)
- w_start = 1000 * htab.startAngle()
- wRng = (w_start, w_start + (totalRange * 1000))
- _log.info(
- f"helical params mode={mode}, cnthor={num_h}, cntvert={num_v}, hrng={hRng}, wrng={wRng}"
- )
- helical.setup_motion(
- mode=mode,
- cntHor=num_h,
- cntVert=num_v,
- hRng=hRng,
- wRng=wRng,
- pt2pt_time=exposureTime,
- ) # hRng in micrometers
- helical.run()
- try:
- with open(folders.get_prefixed_file("_helical_debug.cmd"), "w") as fd:
- fd.write("calcParam(x={}, y={}, z={})".format(x, y, z))
- except:
- pass
-
- self.qprogress = QProgressDialog(self)
- self.qprogress.setRange(0, 0)
- self.qprogress.setLabelText("Acquiring HELICAL")
- self.qprogress.setCancelButtonText("Abort Acquisition")
- self.qprogress.canceled.connect(self.complete_daq)
- self.qprogress.setWindowModality(Qt.WindowModal)
- self.qprogress.setAutoClose(True)
- self.qprogress.show()
-
- sequencer_steps = [lambda: self.grids_pause_stage_tracking()]
-
- n_frames = num_h * num_v
- if jungfrau_detector.is_running_detector():
- uid = settings.value(EXPERIMENT_UID, type=int)
- backend_extras = self.jungfrau.get_parameters()
- backend_extras.update(
- {
- "swissmx_trajectory_method": "grid",
- "swissmx_trajectory_details_1": [-num_h],
- "swissmx_trajectory_details_2": [num_v],
- }
- )
-
- jungfrau_detector.set_number_of_frames(n_frames)
- jungfrau_detector.set_data_owner_uid(uid)
- sequencer_steps.extend(
- [
- lambda: jungfrau_detector.configure(
- n_frames=n_frames,
- outfile=folders.prefix,
- outdir=folders.raw_folder,
- uid=uid,
- backend_extras=backend_extras,
- ),
- lambda: jungfrau_detector.arm(),
- ]
- )
-
- sequencer_steps.append(lambda: helical.wait_armed())
- if settings.value(ACTIVATE_PULSE_PICKER):
- sequencer_steps.extend([lambda: pulsePicker.open(), lambda: pend_event(0.1)])
-
- sequencer_steps.append(lambda: helical.trigger())
-
- def _OLD_motion_progress():
- while True:
- p = helical.progress()
- if p < 0:
- break
- time.sleep(0.1)
- self.qprogress.setLabelText(f"Acquiring HELICAL {p:.0f} / {n_frames}")
- _log.warning(f"helical motion complete!")
-
- sequencer_steps.append(motion_progress)
-
- if settings.value(ACTIVATE_PULSE_PICKER):
- sequencer_steps.append(lambda: pulsePicker.close())
-
- sequencer_steps.append(lambda: self.grids_start_stage_tracking())
-
- self.sequencer = Sequencer(steps=sequencer_steps)
- self._thread = QThread()
- self._thread.setObjectName("acquisition_thread")
- self.sequencer.moveToThread(self._thread)
- self.sequencer.finished.connect(self.daq_helical_collect_wrapup)
- self._thread.started.connect(self.sequencer.run_sequence)
- self._thread.start()
-
- def _OLD_daq_helical_collect_wrapup(self):
- try:
- self.qprogress.reset()
- except:
- pass
- if self._thread.isRunning():
- self._thread.quit()
- helical.gather_upload(os.path.join(folders.res_folder, folders.prefix + ".npz"))
-
- self.re_connect_collect_button()
- jungfrau_detector.abort()
- if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE):
- self.cb_esc_sample_alignment()
- self.increaseRunNumberRequest.emit()
-
- if option(DELTATAU_SHOW_PLOTS):
- hsgui = HelicalScanGui(helical)
- hsgui.interactive_anim()
-
- def _OLD_complete_daq(self):
- _log.info("daq completed: cleaning up")
- try:
- self.qprogress.reset()
- except:
- pass
- try:
- if self._thread.isRunning():
- self._thread.quit()
- except:
- pass
- finally:
- self.abort_measurement()
- self.re_connect_collect_button()
-
- def _OLD_re_connect_collect_button(self, callback=None, **kwargs):
- _log.debug("re_connect_collect_button() {} => {}".format(callback, kwargs))
- return
- # button = self._button_collect
- # if callback is None:
- # callback = self.execute_collection
- # button.setAccessibleName("collect_button")
- # kwargs["label"] = "Collect"
- #
- # try:
- # button.disconnect()
- # finally:
- # button.clicked.connect(callback)
- #
- # if "accessibleName" in kwargs:
- # button.setAccessibleName(kwargs["accessibleName"])
- #
- # if "label" in kwargs:
- # button.setText(kwargs["label"])
- # self.load_stylesheet()
-
- def _OLD_collect_abort_grid(self):
- self._is_aborted = True
- try:
- self._eigerwaitthread._is_aborted = True
- except:
- pass
- _log.warning("aborting grid scan")
- self.abort_measurement()
- delta_tau.abort()
- jungfrau_detector.disarm()
- self.re_connect_collect_button()
-
- def _OLD_create_escape_toolbar(self):
- cont = self._wd_right
- w = QGroupBox("Escape")
- layout = QHBoxLayout()
- w.setLayout(layout)
- but = QPushButton("Exchange\nSample")
- but.setAccessibleName("escape_button_se")
- but.setObjectName("action_SampleExchange")
- but.clicked.connect(self.cb_esc_sample_exchange)
- layout.addWidget(but)
- but = QPushButton("Alignment")
- but.setAccessibleName("escape_button_sa")
- but.clicked.connect(self.cb_esc_sample_alignment)
- layout.addWidget(but)
- but = QPushButton("Collection")
- but.setAccessibleName("escape_button_dc")
- but.clicked.connect(self.cb_esc_data_collection)
- layout.addWidget(but)
- cont.layout().addWidget(w)
-
- def _OLD_daq_method_prelocated_remove_markers(self):
- try:
- for m in self._marker_rois:
- m.disconnect_signals()
- self.vb.removeItem(m)
- except Exception as e:
- _log.warning("maybe failed removing markers: {}".format(e))
- self._marker_rois = []
-
- def _OLD_pause_all_markers(self):
- for m in self._marker_rois:
- m.disconnect_signals()
-
- def _OLD_resume_all_markers(self):
- for m in self._marker_rois:
- m.reconnect_signals()
-
- def _OLD_daq_method_prelocated_update_markers(self):
- self.daq_method_prelocated_remove_markers()
- data = self.prelocationModule.get_data()
- add_xtals = self.prelocationModule._xtals_transformed
- draw_xtals = self.prelocationModule.set_draw_crystal_marks
- vb = self.vb
- self._marker_rois = []
- ppm = self.getPpm()
- for n, cc in enumerate(data):
- is_fiducial, gx, gy, cx, cy, ox, oy = cc
- if not is_fiducial:
- if not (add_xtals and draw_xtals):
- continue
- _log.debug(f"adding {'fiducial' if is_fiducial else 'xtal'} mark #{n}: {is_fiducial} {gx:.3f}, {gy:.3f}, {cx:.1f}, {cy:.1f}")
- m = CstROI.CrystalCircle(
- gonio_xy=(gx, gy),
- parent=self,
- model_row_index=n,
- is_fiducial=is_fiducial,
- ppm=ppm,
- )
- # m.sigRegionChangeFinished.connect(lambda roi=m: self.daq_method_prelocated_update_model(roi))
- self._marker_rois.append(m)
- vb.addItem(m)
- for c in self._marker_rois:
- c.reconnect_signals()
- c.follow_stage()
-
- def _OLD_daq_method_prelocated_set_fiducial(self, camx, camy, gx, gy):
- _log.debug(f"camx, camy: {camx}, {camy}, fx, fy: {gx, gy}")
- self.prelocationModule.set_fiducial_coords(camx, camy, gx, gy)
-
- def _OLD_daq_method_prelocated_append_data(self, x, y, gx, gy):
- _log.debug("appending to model: {} {}".format((x, y), (gx, gy)))
- self.prelocationModule.append_data((x, y, gx, gy))
- self.daq_method_prelocated_update_markers()
-
- def _OLD_daq_method_prelocated_update_model(self, roi):
- row = roi.get_model_row()
- pos = roi.pos()
- self.prelocationModule.set_data_camera(row, pos)
- _log.debug("updating row {} => {}".format(row, pos))
-
- def _OLD_daq_method_prelocated_add_reference(self):
- self._references.append(pg.CircleROI())
-
- def _OLD_move_fast_stage(self, x, y):
- _log.info(f"received request to move gonio to x, y = {x:.3f}, {y:.3f} mm")
- fx_motor, fy_motor, bx_motor, bz_motor, omega_motor = self.get_gonio_tweakers()
- fx_motor.move_abs(x)
- fy_motor.move_abs(y)
-
- def _OLD_toggle_maximized(self):
- if self.isMaximized():
- self.showNormal()
- else:
- self.showMaximized()
-
- def _OLD_show_window_configuration(self):
- _log.debug("maximized? {}".format(self.isMaximized()))
-
- def _OLD_update_user_and_storage(self):
- global folders
- pgroup = settings.value(EXPERIMENT_PGROUP, "not_set_yet")
- diag = GenericDialog( title="P-group for experiment", message="Enter the p-group to be used",
- inputs={EXPERIMENT_PGROUP: ("P-group", pgroup, QLineEdit(pgroup))}, use_buttons=False,)
- diag.setModal(True)
-
- run_user = getpass.getuser()
-
- pgrp_re = re.compile(r"^p(?P\d{5})$")
-
- if not self.is_recently_active():
- diag.exec()
- results = diag.results
- for k, v in results.items():
- m = pgrp_re.match(v)
- if m:
- settings.setValue(k, v)
- settings.setValue(EXPERIMENT_UID, int(m["uid"]))
- else:
- QMessageBox.critical(self, "wrong P-group format", "P-groups are in the format:\n\n\t\tp?????\n\n\twhere ? = digit",)
- self.update_user_and_storage()
- return
- settings.sync()
- folders.set_pgroup(settings.value(EXPERIMENT_PGROUP))
- try:
- folders.check_permissons()
- except:
- folder = folders.pgroup_folder
- pgroup = settings.value(EXPERIMENT_PGROUP)
- box = QMessageBox()
- box.setText("No Write Permission!")
- box.setInformativeText("User {} has no write access to p-group {} folder:\n ➜ {}\n".format(run_user, pgroup, folder))
- box.setIcon(QMessageBox.Warning)
- box.setDetailedText("The folder /sf/bernina/data/{pgroup}/res/ has to writable by the user {user}, currently running the SwissMX app.".format(pgroup=pgroup, user=run_user))
- btIgnore = box.addButton("Ignore", QMessageBox.NoRole)
- btRetry = box.addButton("Le'me try again", QMessageBox.YesRole)
- box.exec_()
- ans = box.clickedButton()
- if ans == btRetry:
- self.update_user_and_storage()
- elif ans == btIgnore:
- _log.warning("no write access to pgroup but user didn't care")
-
- self._label_pgroup.setText(settings.value(EXPERIMENT_PGROUP))
-
- def _OLD_is_recently_active(self):
- last_active = settings.value("last_active", 0, type=float)
- minutes_since_last = int((time.time() - last_active) / 60.0)
- return minutes_since_last < 60
-
- def _OLD_openPreferencesDialog(self):
- PreferencesDialog(self).exec_()
-
- def _OLD_set_app_icon(self):
- scriptDir = os.path.dirname(os.path.realpath(__file__))
- self.setWindowIcon(QtGui.QIcon(os.path.join(scriptDir + os.path.sep + "logo.png")))
-
- def _OLD_set_widget_background_color(self, color):
- """change a widget's color
- :param color:
- :return:
- """
- try:
- color = QtGui.QColor.colorNames().index(color)
- except:
- return
- p = self.palette()
- p.setColor(self.backgroundRole(), color)
- self.setPalette(p)
diff --git a/psi_device.py b/psi_device.py
index 665d481..f15be63 100644
--- a/psi_device.py
+++ b/psi_device.py
@@ -8,17 +8,15 @@ if __name__ == "__main__":
logging.getLogger('matplotlib').setLevel(logging.INFO)
if socket.gethostname()=='ganymede':
- sys.path.insert(0, os.path.expanduser('~/Documents/prj/SwissFEL/PBTools'))
+ base=os.path.abspath(os.path.dirname(__file__))
+ sys.path.insert(0, os.path.abspath(os.path.join(base,'../PBSwissMX/python')))
+ sys.path.insert(0, os.path.abspath(os.path.join(base,'../../PBTools')))
else:
- sys.path.insert(0, '/sf/cristallina/applications/SwissMX/PBTools')
- sys.path.insert(0, '/sf/cristallina/applications/SwissMX/PBSwissMX/python')
- #_log.info(sys.path)
+ base=os.path.abspath(os.path.dirname(__file__))
+ sys.path.insert(0, os.path.join(base,'PBTools'))
+ sys.path.insert(0, os.path.join(base,'PBSwissMX/python'))
elif socket.gethostname()!='ganymede':
- #TODO: cleanup slic installation location
- sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/mx/slic'))
- #sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/slic/slic-package'))
-
-
+ sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/slic/slic-package'))
from PyQt5.QtWidgets import (QApplication,)
from app_config import AppCfg #settings, option, toggle_option
@@ -105,12 +103,6 @@ class Deltatau:
class Jungfrau:
def __init__(self,sim=False):
- #python /sf/jungfrau/applications/daq_client/daq_client.py -h
- #python /sf/jungfrau/applications/daq_client/daq_client.py -p p19739 -t no_beam_test
- # -c/sf/cristallina/config/channel_lists/channel_list_bs-e/sf/cristallina/config/channel_lists/channel_list_ca
- # -f/sf/cristallina/config/jungfrau/jf_1d5M.json
- # --start_pulseid 15382163895 --stop_pulseid 15382163905
- #rsync -vai gac-cristall@saresc-cons-03:/sf/jungfrau/applications/daq_client/daq_client.py .
# setup slic parameters
if sim:
self._sim=True
diff --git a/pyqtUsrObj.py b/pyqtUsrObj.py
index 9fe187f..3c17aa0 100644
--- a/pyqtUsrObj.py
+++ b/pyqtUsrObj.py
@@ -18,7 +18,7 @@ _log=logging.getLogger(__name__)
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-from PyQt5.QtGui import QPolygon,QPolygonF
+from PyQt5.QtGui import QPolygonF
from PyQt5.QtCore import Qt,QPointF,QLineF
from PyQt5.QtWidgets import QMenu
@@ -94,22 +94,12 @@ class Marker(UsrROI):
#widget.signal.connect(slot_function)
#self.sigRegionChangeFinished.connect(self.OnRgnChanged)
- #def OnRgnChanged(self, event):
- # print(event)
- # obj_info(self)
-
def paint(self, p, *args):
#pg.ROI.paint(self, p, *args)
r=QtCore.QRectF(0, 0, self.state['size'][0], self.state['size'][1]).normalized()
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
p.translate(r.left(), r.top())
- #p.scale(r.width(), r.height()) # -> values x,y 0 to 1
- #f=p.font();
- #f.setPixelSize(50)
- #p.setFont(f)
- # p.drawText(0, 0, '{:.0f}x{:.0f}'.format(*tuple(self.size())))
- #p.drawText(0, 0, 'Thierry')
p.scale(.01*r.width(), .01*r.height()) # -> values x,y 0 to 100
m=self._mode
@@ -129,7 +119,6 @@ class Marker(UsrROI):
ctr=tuple((self.pos()+self.size()/2)*1000)
sz=tuple(self.size()*1000)
p.drawText(ofx+5, ofy+45, '{:.1f}x{:.1f} um'.format(*sz))
- #p.drawText(5, -35, '{:.1f}'.format(ctr[0]))
p.drawText(ofx+5, ofy+55,42,30,Qt.AlignRight, '{:.1f}'.format(ctr[0]))
p.drawText(ofx+55, ofy+65, '{:.1f} um'.format(ctr[1]))
@@ -145,8 +134,6 @@ class Marker(UsrROI):
f=p.font();
f.setPixelSize(10)
p.setFont(f)
- #p.drawText(ofx+0, ofy+0, 'FFF')
- #p.drawText(ofx+100, ofy+100, 'GGG')
px=tuple(self.pos()+self.size()/2)
p.drawText(ofx+18, ofy+10, 'optical center')
p.drawText(ofx+5, ofy+80,42,30,Qt.AlignRight, '{:.1f}'.format(px[0]))
@@ -184,17 +171,11 @@ class Fiducial(UsrROI):
p.setPen(pg.mkPen(width=1, color=[255, 0, 0]))
p.drawLine(pg.Point(50,10), pg.Point(50, 90))
p.drawLine(pg.Point(10,50), pg.Point(90, 50))
- #tr=p.transform()
- #tr.setMatrix(tr.m11(), tr.m12(), tr.m13(), tr.m21(), -tr.m22(), tr.m23(), tr.m31(), tr.m32(), tr.m33())
- #p.setTransform(tr)
f=p.font()
f.setPixelSize(10)
p.setFont(f)
- #p.drawText(24, 20, 'beam marker')
ctr=tuple(self.pos()+self.size()/2)
sz=tuple(self.size())
- #print((*ctr,self._z))
- #p.drawText(5, 25, 'x{:.4g}\ny{:.4g}\nz{:.4g}'.format(*ctr,self._z))
p.drawText(52, 10,40,40,Qt.TextWordWrap, 'x{:.5g}\ny{:.5g}\nz{:.5g}'.format(*ctr,self._z))
def ctr(self):
@@ -253,11 +234,6 @@ class Grid(UsrROI):
x=i*px
p.drawEllipse(QPointF(x,y), rx, ry)
- #p.translate(r.left(), r.top())
- #p.scale(r.width(), r.height())
- #p.drawEllipse(0, 0, 1, 1)
- #p.drawRect(0, 0, 1, 1)
-
def __repr__(self):
s=f'{self.__class__.__name__}:(pos:{itr2str(self.pos())}, size:{itr2str(self.size())}, cnt:{self._cnt}, fidSize:{self._fidSz}, param:{self._param})'
return s
@@ -276,7 +252,6 @@ class Grid(UsrROI):
def get_scan_param(self):
'returns scan parameters for scanning with deltatau. the format is as used for shapepath'
scan=1 # snake motion Y fast, X slow (default)
- #pos=np.array(self.pos())
cnt=np.array(self._cnt,np.int32)
sz=np.array(self.size())
pitch=sz/cnt
@@ -292,7 +267,6 @@ class Grid(UsrROI):
for i in range(1, cnt[0], 2):
yy[i]=yy[i][::-1]
pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose()*pitch
- #pts+=pos
param={'points':pts}
param.update(self._param)
assert(param.get('code_gen',0)==0) # this provides fully x,y motor coordinates
@@ -348,8 +322,6 @@ class Path(UsrROI):
r=self._rect
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
- #p.drawEllipse(0, 0, int(sz[0]), int(sz[1]))
- #p.drawRect(0, 0, int(sz[0]), int(sz[1]))
p.drawRect(QtCore.QRectF(0, 0, sz[0], sz[1]).normalized())
#obj_info(p)
p.scale(sz[0]/r.width(), sz[1]/r.height())
@@ -470,19 +442,12 @@ class FixTargetFrame(UsrROI):
self.addScaleHandle([1, 1], [0, 0])
self.addScaleHandle([0, 0], [1, 1])
self.addScaleRotateHandle([1, 0], [0, 0])
- #self.sigHoverEvent.connect(self.hover)
-# def hover(self):
-# _log.debug(f'hover {self}')
def paint(self, p, *args):
- #pg.ROI.paint(self, p, *args)
sz=self.state['size']
- #nx, ny=self._cnt
- #px, py=sz[0]/(nx-1), sz[1]/(ny-1)
r=QtCore.QRectF(0, 0, sz[0], sz[1]).normalized()
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
- #p.drawRect(0, 0, int(sz[0]), int(sz[1]))
p.drawRect(r)
dscr=self._dscr
@@ -496,8 +461,6 @@ class FixTargetFrame(UsrROI):
ox,oy=g['pos']
px,py=g['pitch']
nx,ny=g['count']
- #x0=ox; x1=ox+(ny-1)*py
- #y0=oy; y1=oy+(nx-1)*px
x0=ox-.5*px; x1=ox+(nx-.5)*px
y0=oy-.5*py; y1=oy+(ny-.5)*py
for i in range(nx):
@@ -558,10 +521,7 @@ class FixTargetFrame(UsrROI):
scan=1 # snake motion Y fast, X slow (default)
grid=self._dscr['grid']
self._dscr['size']
- #pos=np.array(self.pos())
cnt =np.array(grid['count'],np.int32)
- #pos =np.array(grid['pos'],np.float64)
- #pitch=np.array(grid['pitch'],np.float64)
xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1]))
if scan==0: # snake motion X fast, Y slow
for i in range(1,cnt[1],2):
@@ -592,11 +552,6 @@ class FixTargetFrame(UsrROI):
param={'grid':grid, 'points':pts, 'trf':trf}
param.update(self._param)
- # trf*'gridpos' -> motor pos in mm
- # {'pos': [2080, 2080], 'pitch': [120, 120], 'count': [162, 162]}
- #np.array((0,0,1))*trf grid 0,0 (top left)
- #np.array((161,0,1))*trf # grid 161,0 (top right)
- #np.array((161,161,1))*trf # grid 161,161 (bottom right)
return param
@@ -645,9 +600,6 @@ if __name__=='__main__':
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
- # p.translate(r.left(), r.top())
- # p.scale(r.width(), r.height())
- # p.drawRect(0, 0, 1, 1)
p.drawRect(r)
tr=p.worldTransform()
obj_info(tr)
@@ -702,15 +654,9 @@ if __name__=='__main__':
def mouse_click_event(event):
- #event.pos(): return Point(self.currentItem.mapFromScene(self._scenePos))
pos=event.pos()
scn=event.scenePos() # there is a small black border, that makes the difference
print(f'mouse-> scene pos:{pt2str(scn)} currentItem pos:{pt2str(pos)}')
- #img=viImg.mapFromScene(scn)
- #roi=viUsrRoi.mapFromScene(scn)
- #print(f'mouse-> img:{pt2str(img)} roi:{pt2str(roi)}')
- #childTree(vb)
- #obj_info(viImg)
m=int(event.modifiers())
o=event.currentItem
if m&Qt.ShiftModifier:
@@ -721,9 +667,6 @@ if __name__=='__main__':
elif m&Qt.ControlModifier:
tr=o.transform()
obj_info(tr)
- #tr.setMatrix(tr.m11(),tr.m12(),tr.m13()+100,tr.m21(),tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
- #tr.setMatrix(tr.m11(),tr.m12(),tr.m13(),tr.m21(),tr.m22(),tr.m23(),tr.m31(),tr.m32()+20,tr.m33())
- #tr.setMatrix(tr.m11(),tr.m12(),tr.m13(),tr.m21(),-tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
tr.setMatrix(-tr.m11(),tr.m12(),tr.m13(),tr.m21(),-tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
obj_info(tr)
o.setTransform(tr)
@@ -774,24 +717,16 @@ if __name__=='__main__':
viImg=pg.ImageItem(arr, border='y')
vb.addItem(viImg)
- # Custom ROI for selecting an image region
- #viRoi=pg.ROI([20, -50], [60, 40])
- #viRoi=TxtROI([20, -50], [60, 40])
- #viRoi.addScaleHandle([1, 1], [0, 0])
- #viRoi.addScaleHandle([.7, .5], [0, 0])
- #vb.addItem(viRoi)
viUsrRoi=Marker([50, 120], [30, 20],mode=0)
vb.addItem(viUsrRoi)
- #obj=Marker([250, 220], [30, 20],mode=1)
- #vb.addItem(obj)
+
vi=Grid( (120,-100), (200,150), (30,20),2)
tr=QtGui.QTransform() # prepare ImageItem transformation:
tr.setMatrix(1, -.1, 0,
.2, 1, 0,
10, 10, 1)
vi.setTransform(tr) # assign transform
- #vi=Grid( (50,10), (200,150), (6,4))
vb.addItem(vi) #vi= visual item
grp=pg.ItemGroup()
@@ -811,11 +746,6 @@ if __name__=='__main__':
fiducial=np.array(((18, 7), (25, 16), (70, 20)))
path=gen_swissmx_points(ofs=(10, 5), width=200)
vi=Path((120,100),path,fiducial,fidScl)
- #tr=QtGui.QTransform() # prepare ImageItem transformation:
- #tr.setMatrix(1, 0, 0,
- # 0, 1, 0,
- # 10, 10, 1)
- #vi.setTransform(tr) # assign transform
vb.addItem(vi)
vi=FixTargetFrame((100,300),(100,100),tpl='test')
@@ -833,9 +763,6 @@ if __name__=='__main__':
viRoi=pg.ROI([-200, -200], [100, 80],movable=True, rotatable=True, resizable=True)
viRoi.addFreeHandle(pos=[.7, .5], axes=None, item=None, name=None, index=None) # rechteck , frei beweglich ??? verschwinden anch bewegung
- #viRoi.addRotateFreeHandle([.7, .5], [0, 0], axes=None, item=None, name=None, index=None) # kreis ??? verschwinden anch erstem gebrauch
- #viRoi.addRotateHandle([.7, .5], [0, 0], item=None, name=None, index=None) # kreis, nur rot
- #viRoi.addScaleHandle([.7, .5], [0, 0], axes=None, item=None, name=None, lockAspect=False, index=None) # raute scale x,y
#viRoi.addScaleRotateHandle([0, .5], [1, .5], item=None, name=None, index=None) # kreis
#viRoi.addTranslateHandle([.7, .5], axes=None, item=None, name=None, index=None) #quadrat
vb.addItem(viRoi)
@@ -846,9 +773,6 @@ if __name__=='__main__':
childTree(vb)
w.scene().sigMouseClicked.connect(mouse_click_event)
- #viImg.sigImageChanged
- #print(vb.pos())
- #vb.setPos(50,50)
if (sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
diff --git a/qutilities.py b/qutilities.py
index 55fd37b..00ae2e9 100644
--- a/qutilities.py
+++ b/qutilities.py
@@ -1,44 +1,11 @@
from PyQt5 import QtWidgets, QtGui
-from PyQt5.QtWidgets import QWidget, QSizePolicy, QVBoxLayout, QDoubleSpinBox, QMessageBox
-
-from app_config import AppCfg #option, toggle_option
-
-
-def toggle_warn(key):
- toggle_option(key)
- m = f"Option {key} => {option(key)}"
- QMessageBox.warning(None, m, m)
+from PyQt5.QtWidgets import QWidget, QSizePolicy, QVBoxLayout, QMessageBox
def horiz_spacer():
spacer = QWidget()
spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
return spacer
-
-def toggle_visibility(widget, state):
- if state:
- widget.show()
- else:
- widget.hide()
-
-
-def get_sep_line():
- line = QtWidgets.QFrame()
- line.setFixedHeight(2)
- line.setFrameShadow(QtWidgets.QFrame.Sunken)
- line.setFrameShape(QtWidgets.QFrame.HLine)
- return line
-
-
-def check_font_by_id(id):
- for family in QtGui.QFontDatabase.applicationFontFamilies(id):
- print(family)
-
-
-def toggle_groupbox(gbox, state):
- widget = gbox.layout().itemAt(0).widget()
- widget.setVisible(state)
-
def add_item_to_toolbox(toolbox, label, widget_list=[]):
block = QWidget()
block.setAccessibleName(label)
diff --git a/swissmx.py b/swissmx.py
index 558be2d..7eabb46 100755
--- a/swissmx.py
+++ b/swissmx.py
@@ -22,7 +22,7 @@ bitmask for simulation:
0x100: Deltatau motion code
"""
-import logging
+import logging,time,os,sys,socket
class col:
d='\033[0m' # default
r='\033[31m' # red
@@ -74,33 +74,22 @@ class logHandler(logging.StreamHandler):
except Exception:
self.handleError(record)
-
-# logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
logging.basicConfig(level=logging.INFO, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s',
handlers=[logHandler()])
-#logging.getLogger('PyQt5.uic').setLevel(logging.INFO)
-#logging.getLogger('requests').setLevel(logging.INFO)
-#logging.getLogger('urllib3').setLevel(logging.INFO)
-#logging.getLogger('paramiko').setLevel(logging.INFO)
-#logging.getLogger('matplotlib').setLevel(logging.INFO)
-#logging.getLogger('PIL').setLevel(logging.INFO)
-#logging.getLogger('illumination').setLevel(logging.INFO)
-#logging.getLogger('zoom').setLevel(logging.INFO)
-#logging.getLogger('pbtools.misc.pp_comm').setLevel(logging.INFO)
_log = logging.getLogger("swissmx")
if __name__=="__main__":
- import os,sys,socket
if socket.gethostname()=='ganymede':
base=os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(base,'../PBSwissMX/python')))
sys.path.insert(0, os.path.abspath(os.path.join(base,'../../PBTools')))
else:
- sys.path.insert(0, '/sf/cristallina/applications/SwissMX/PBTools')
- sys.path.insert(0, '/sf/cristallina/applications/SwissMX/PBSwissMX/python')
+ base=os.path.abspath(os.path.dirname(__file__))
+ sys.path.insert(0, os.path.join(base,'PBTools'))
+ sys.path.insert(0, os.path.join(base,'PBSwissMX/python'))
+
-import time
class timestamp():
def __init__(self):
self.t=time.time()
@@ -110,9 +99,9 @@ class timestamp():
self.t=t
ts=timestamp()
ts.log('Import part 1/8:')
-import sys, os, time
+import sys, os
import json, re
-import random, signal, subprocess
+import signal, subprocess
import matplotlib as mpl
import matplotlib.pyplot as plt
@@ -132,22 +121,18 @@ TASK_PRELOCATED = "prelocated"
TASK_HELICAL = "helical"
TASK_EMBL = "embl"
ts.log('Import part 2/8:')
-
import ModuleFixTarget
-import PrelocatedCoordinatesModel # ZAC: orig. code
-from EmblModule import EmblWidget #ZAC: orig. code
-from HelicalTable import HelicalTableWidget #ZAC: orig. code
ts.log('Import part 3/8:')
import qtawesome
import qutilities
from PyQt5 import QtCore, QtGui
-from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread, QRectF,QT_VERSION_STR
-from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator, QFont
+from PyQt5.QtCore import Qt, pyqtSlot, QSize, pyqtSignal, QObject, QRectF,QT_VERSION_STR
+from PyQt5.QtGui import QKeySequence, QPixmap
from PyQt5.QtWidgets import (
- QAction, QApplication, QDoubleSpinBox, QFileDialog, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit,
- QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox,
- QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,)
+ QAction, QApplication, QFileDialog, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
+ QMessageBox, QProgressBar, QPushButton, QShortcut, QSizePolicy,
+ QSplashScreen, QToolBox, QVBoxLayout, QWidget,)
from PyQt5.uic import loadUiType
ts.log('Import part 4/8:')
import pyqtUsrObj as UsrGO
@@ -165,7 +150,6 @@ import app_utils
from app_config import AppCfg,WndParameter #settings, option, toggle_option
import epics
-from epics.ca import pend_event
import camera,backlight,zoom,illumination,geometry
ts.log('Import part 7/8:')
import psi_device
diff --git a/zoom.py b/zoom.py
index 308e6dc..34eab37 100755
--- a/zoom.py
+++ b/zoom.py
@@ -8,30 +8,18 @@
'''
'''
-import json
import logging
_log=logging.getLogger(__name__)
import os
-from PyQt5 import QtWidgets, uic
-import PyQt5.QtWidgets as qtw
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import (
- QApplication,
- QPushButton,
- QGroupBox,
- QGridLayout,
- QLabel,
- QDoubleSpinBox,
- QSpinBox,
- QVBoxLayout,
- QHBoxLayout,
- QCheckBox,
+ QApplication, QPushButton, QGroupBox, QGridLayout, QLabel, QDoubleSpinBox, QSpinBox,
+ QVBoxLayout, QHBoxLayout, QCheckBox,
)
from PyQt5.uic import loadUiType
import backlight, illumination, camera
import epics
-from app_config import AppCfg #settings
Ui_Zoom, QWidget = loadUiType(os.path.join(os.path.dirname(__file__),"zoom.ui"))
MIN_ZOOM = 1
@@ -50,22 +38,6 @@ class Zoom(QGroupBox, Ui_Zoom):
def init_settings(self):
app=QApplication.instance()
- #cfg=app._cfg
- #keys=cfg.allKeys()
- #if cfg.ZOOM_BUTTONS in keys:
- # buttons=json.loads(cfg.value(cfg.ZOOM_BUTTONS))
- #else:
- # buttons=((1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),)
- # cfg.setValue(cfg.ZOOM_BUTTONS,json.dumps(buttons))
- #self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb)
- #self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)
- #try:
- # pv=app._zoom.getPv('POS_RB')
- #except AttributeError as e:
- # _log.debug('Simulated zoom')
- #else:
- # pv.callbacks ... = self.zoom_update_cb
- # check also: pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
buttons=((1, "1"), (200, "200"), (400, "400"), (600, "600"), (800, "800"), (1000, "1000"),)
zoom=QApplication.instance()._zoom
@@ -80,7 +52,6 @@ class Zoom(QGroupBox, Ui_Zoom):
self._zoom_spinner.setRange(MIN_ZOOM, MAX_ZOOM)
self._zoom_spinner.setValue(current_zoom_value)
self._zoom_spinner.editingFinished.connect(self.move_zoom_a)
- # self._zoom_spinner.setSingleStep(SPINNER_SINGLE_STEP)
self._zoom_spinner.setSingleStep(SPINNER_LARGE_STEP)
_box = QWidget()
_box.setLayout(QHBoxLayout())
@@ -178,14 +149,6 @@ class Zoom(QGroupBox, Ui_Zoom):
self.slid.setSuffix(" ms")
grid.addWidget(self.slid, 0, 1)
- #grid.addWidget(QLabel("Acq.Mode"), 1, 0)
- #cbox = QComboBox()
- #for mode in Camera.AcquisitionMode:
- # cbox.addItem(mode.name, mode)
- #cbox.setCurrentIndex(cam.pv_acqmode.get())
- #cbox.currentIndexChanged.connect(self.update_camera_acqmode)
- #grid.addWidget(cbox, 1, 1)
-
lbox.layout().addWidget(grp)
self.slid.editingFinished.connect(lambda: self.update_exposure(self.slid.value()))
@@ -270,21 +233,6 @@ class Zoom(QGroupBox, Ui_Zoom):
self._zoom_spinner.blockSignals(False)
self.zoomChanged.emit(float(value))
-# def get_zoom(self) -> int:
-# zoom=QApplication.instance()._zoom
-# pos = zoom.get()
-# _log.debug("get_zoom(epics) => {}".format(pos))
-# return pos
-
-# def zoom_update_cb(self, pvname, value, char_value, **kwargs):
-# self._zoom_spinner.blockSignals(True)
-# self._zoom_spinner.setValue(value)
-# self._zoom_spinner.blockSignals(False)
-
-# def zoom_status_cb(self, pvname, value, char_value, **kwargs):
-# busy = bool(value)
-# self.setDisabled(busy)
-
class QopticZoom(object):
@@ -336,7 +284,7 @@ class QopticZoom(object):
if __name__ == "__main__":
- import time, os, PIL.Image, platform, subprocess
+ import sys, os
import argparse
logging.basicConfig(level=logging.DEBUG,format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
@@ -344,18 +292,11 @@ if __name__ == "__main__":
parser.add_argument("--sim", "-s", help="simulate all devices", action='store_true')
args = parser.parse_args()
- import sys
-
_log.info('Arguments:{}'.format(args.__dict__))
os.environ['EPICS_CA_ADDR_LIST'] = '129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
app = QApplication(sys.argv)
from app_config import appsconf
- #from PyQt5 import QtGui
- #qtawesome.load_font("material","MaterialIcons-Regular.ttf","MaterialIcons-Regular.json","fonts/",)
- #QtGui.QFontDatabase.addApplicationFont("fonts/Inconsolata-Bold.ttf")
- #QtGui.QFontDatabase.addApplicationFont("fonts/Baloo-Regular.ttf")
-
if args.sim:
app._backlight = backlight.Backlight(None)
app._illumination = illumination.IlluminationControl(None)
@@ -367,8 +308,6 @@ if __name__ == "__main__":
app._zoom = QopticZoom()
app._camera = camera.epics_cam()
-
-
simulated = appsconf["microscope"]["zoom"].get("simulate", False)
obj=Zoom()