Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Zoom 5 (or Zoom N) #312

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 77 additions & 124 deletions daq_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,131 +86,84 @@ def abortBS():
except super_state_machine.errors.TransitionError:
logger.error("caught BS")

def changeImageCenterLowMag(x,y,czoom):
zoom = int(czoom)
zoomMinXRBV = getPvDesc("lowMagZoomMinXRBV")
zoomMinYRBV = getPvDesc("lowMagZoomMinYRBV")
minXRBV = getPvDesc("lowMagMinXRBV")
minYRBV = getPvDesc("lowMagMinYRBV")

sizeXRBV = getPvDesc("lowMagZoomSizeXRBV")
sizeYRBV = getPvDesc("lowMagZoomSizeYRBV")
sizeXRBV = 640.0
sizeYRBV = 512.0
roiSizeXRBV = getPvDesc("lowMagROISizeXRBV")
roiSizeYRBV = getPvDesc("lowMagROISizeYRBV")
roiSizeZoomXRBV = getPvDesc("lowMagZoomROISizeXRBV")
roiSizeZoomYRBV = getPvDesc("lowMagZoomROISizeYRBV")
inputSizeZoomXRBV = getPvDesc("lowMagZoomMaxSizeXRBV")
inputSizeZoomYRBV = getPvDesc("lowMagZoomMaxSizeYRBV")
inputSizeXRBV = getPvDesc("lowMagMaxSizeXRBV")
inputSizeYRBV = getPvDesc("lowMagMaxSizeYRBV")
x_click = float(x)
y_click = float(y)
binningFactor = 2.0
if (zoom):
xclickFullFOV = x_click + zoomMinXRBV
yclickFullFOV = y_click + zoomMinYRBV
else:
binningFactor = 2.0
xclickFullFOV = (x_click * binningFactor) + minXRBV
yclickFullFOV = (y_click * binningFactor) + minYRBV
new_minXZoom = xclickFullFOV-(sizeXRBV/2.0)
new_minYZoom = yclickFullFOV-(sizeYRBV/2.0)
new_minX = new_minXZoom - (sizeXRBV/2.0)
new_minY = new_minYZoom - (sizeYRBV/2.0)
noZoomCenterX = sizeXRBV/2.0
noZoomCenterY = sizeYRBV/2.0
if (new_minX < 0):
new_minX = 0
noZoomCenterX = (new_minXZoom+(sizeXRBV/2.0))/binningFactor
if (new_minY < 0):
new_minY = 0
noZoomCenterY = (new_minYZoom+(sizeYRBV/2.0))/binningFactor
if (new_minX+roiSizeXRBV>inputSizeXRBV):
new_minX = inputSizeXRBV-roiSizeXRBV
noZoomCenterX = ((new_minXZoom+(sizeXRBV/2.0)) - new_minX)/binningFactor
if (new_minY+roiSizeYRBV>inputSizeYRBV):
new_minY = inputSizeYRBV-roiSizeYRBV
noZoomCenterY = ((new_minYZoom+(sizeYRBV/2.0)) - new_minY)/binningFactor
if (new_minXZoom+roiSizeZoomXRBV>inputSizeZoomXRBV):
new_minXZoom = inputSizeZoomXRBV-roiSizeZoomXRBV
if (new_minXZoom < 0):
new_minXZoom = 0
setPvDesc("lowMagZoomMinX",new_minXZoom)
if (new_minYZoom+roiSizeZoomYRBV>inputSizeZoomYRBV):
new_minYZoom = inputSizeZoomYRBV-roiSizeZoomYRBV
if (new_minYZoom < 0):
new_minYZoom = 0
setPvDesc("lowMagZoomMinY",new_minYZoom)
setPvDesc("lowMagMinX",new_minX)
setPvDesc("lowMagMinY",new_minY)
setPvDesc("lowMagCursorX",noZoomCenterX)
setPvDesc("lowMagCursorY",noZoomCenterY)

def changeImageCenter(x_clicked, y_clicked, is_zoomed, magnification="low"):
"""Updates the center and ROI of an image based on user click and zoom level."""

# Constants for image size
full_image_width = 640.0
full_image_height = 512.0

# Getting PVs for different parameters of the camera feed
roi_width = getPvDesc(f"{magnification}MagROISizeXRBV")
roi_height = getPvDesc(f"{magnification}MagROISizeYRBV")
zoom_roi_width = getPvDesc(f"{magnification}MagZoomROISizeXRBV")
zoom_roi_height = getPvDesc(f"{magnification}MagZoomROISizeYRBV")
zoom_input_width = getPvDesc(f"{magnification}MagZoomMaxSizeXRBV")
zoom_input_height = getPvDesc(f"{magnification}MagZoomMaxSizeYRBV")
input_width = getPvDesc(f"{magnification}MagMaxSizeXRBV")
input_height = getPvDesc(f"{magnification}MagMaxSizeYRBV")

# Converting click coordinates to float
x_click = float(x_clicked)
y_click = float(y_clicked)

binning_factor = 2.0

# Calculate the full Field Of View (FOV) click position, depending on the zoom level
if is_zoomed:
x_click_full_fov = x_click + getPvDesc(f"{magnification}MagZoomMinXRBV")
y_click_full_fov = y_click + getPvDesc(f"{magnification}MagZoomMinYRBV")
else:
x_click_full_fov = (x_click * binning_factor) + getPvDesc(f"{magnification}MagMinXRBV")
y_click_full_fov = (y_click * binning_factor) + getPvDesc(f"{magnification}MagMinYRBV")

# Calculate half size of image
half_width = center_x = full_image_width / 2.0
half_height = center_y = full_image_height / 2.0

# Calculate new position of the zoomed ROI and full ROI
zoom_min_x = x_click_full_fov - half_width
zoom_min_y = y_click_full_fov - half_height
full_roi_min_x = zoom_min_x - half_width
full_roi_min_y = zoom_min_y - half_height

# Make sure ROIs are within valid boundaries and recalculate the center positions
if full_roi_min_x < 0:
full_roi_min_x = 0
center_x = (zoom_min_x + half_width) / binning_factor

if full_roi_min_y < 0:
full_roi_min_y = 0
center_y = (zoom_min_y + half_height) / binning_factor

if full_roi_min_x + roi_width > input_width:
full_roi_min_x = input_width - roi_width
center_x = ((zoom_min_x + half_width) - full_roi_min_x) / binning_factor

if full_roi_min_y + roi_height > input_height:
full_roi_min_y = input_height - roi_height
center_y = ((zoom_min_y + half_height) - full_roi_min_y) / binning_factor

if zoom_min_x + zoom_roi_width > zoom_input_width:
zoom_min_x = zoom_input_width - zoom_roi_width

if zoom_min_x < 0:
zoom_min_x = 0

if zoom_min_y + zoom_roi_height > zoom_input_height:
zoom_min_y = zoom_input_height - zoom_roi_height

if zoom_min_y < 0:
zoom_min_y = 0

# Update the EPICS PVs with the newly calculated ROI positions and center positions
setPvDesc(f"{magnification}MagZoomMinX", zoom_min_x)
setPvDesc(f"{magnification}MagZoomMinY", zoom_min_y)
setPvDesc(f"{magnification}MagMinX", full_roi_min_x)
setPvDesc(f"{magnification}MagMinY", full_roi_min_y)
setPvDesc(f"{magnification}MagCursorX", center_x)
setPvDesc(f"{magnification}MagCursorY", center_y)

def changeImageCenterHighMag(x,y,czoom):
zoom = int(czoom)
zoomMinXRBV = getPvDesc("highMagZoomMinXRBV")
zoomMinYRBV = getPvDesc("highMagZoomMinYRBV")
minXRBV = getPvDesc("highMagMinXRBV")
minYRBV = getPvDesc("highMagMinYRBV")

sizeXRBV = getPvDesc("highMagZoomSizeXRBV")
sizeYRBV = getPvDesc("highMagZoomSizeYRBV")
sizeXRBV = 640.0
sizeYRBV = 512.0
roiSizeXRBV = getPvDesc("highMagROISizeXRBV")
roiSizeYRBV = getPvDesc("highMagROISizeYRBV")
roiSizeZoomXRBV = getPvDesc("highMagZoomROISizeXRBV")
roiSizeZoomYRBV = getPvDesc("highMagZoomROISizeYRBV")
inputSizeZoomXRBV = getPvDesc("highMagZoomMaxSizeXRBV")
inputSizeZoomYRBV = getPvDesc("highMagZoomMaxSizeYRBV")
inputSizeXRBV = getPvDesc("highMagMaxSizeXRBV")
inputSizeYRBV = getPvDesc("highMagMaxSizeYRBV")
x_click = float(x)
y_click = float(y)
binningFactor = 2.0
if (zoom):
xclickFullFOV = x_click + zoomMinXRBV
yclickFullFOV = y_click + zoomMinYRBV
else:
binningFactor = 2.0
xclickFullFOV = (x_click * binningFactor) + minXRBV
yclickFullFOV = (y_click * binningFactor) + minYRBV
new_minXZoom = xclickFullFOV-(sizeXRBV/2.0)
new_minYZoom = yclickFullFOV-(sizeYRBV/2.0)
new_minX = new_minXZoom - (sizeXRBV/2.0)
new_minY = new_minYZoom - (sizeYRBV/2.0)
noZoomCenterX = sizeXRBV/2.0
noZoomCenterY = sizeYRBV/2.0
if (new_minX < 0):
new_minX = 0
noZoomCenterX = (new_minXZoom+(sizeXRBV/2.0))/binningFactor
if (new_minY < 0):
new_minY = 0
noZoomCenterY = (new_minYZoom+(sizeYRBV/2.0))/binningFactor
if (new_minX+roiSizeXRBV>inputSizeXRBV):
new_minX = inputSizeXRBV-roiSizeXRBV
noZoomCenterX = ((new_minXZoom+(sizeXRBV/2.0)) - new_minX)/binningFactor
if (new_minY+roiSizeYRBV>inputSizeYRBV):
new_minY = inputSizeYRBV-roiSizeYRBV
noZoomCenterY = ((new_minYZoom+(sizeYRBV/2.0)) - new_minY)/binningFactor

if (new_minXZoom+roiSizeZoomXRBV>inputSizeZoomXRBV):
new_minXZoom = inputSizeZoomXRBV-roiSizeZoomXRBV
if (new_minXZoom < 0):
new_minXZoom = 0
if (new_minYZoom+roiSizeZoomYRBV>inputSizeZoomYRBV):
new_minYZoom = inputSizeZoomYRBV-roiSizeZoomYRBV
if (new_minYZoom < 0):
new_minYZoom = 0
setPvDesc("highMagZoomMinX",new_minXZoom)
setPvDesc("highMagZoomMinY",new_minYZoom)
setPvDesc("highMagMinX",new_minX)
setPvDesc("highMagMinY",new_minY)
setPvDesc("highMagCursorX",noZoomCenterX)
setPvDesc("highMagCursorY",noZoomCenterY)


def autoRasterLoop(currentRequest):
Expand Down
3 changes: 2 additions & 1 deletion daq_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def setBlConfig(param, value, beamline=beamline):

def init_environment():
global beamline,detector_id,mono_mot_code,has_beamline,has_xtalview,xtal_url,xtal_url_small,unitScaling,sampleCameraCount,xtalview_user,xtalview_pass,det_type,has_dna,beamstop_x_pvname,beamstop_y_pvname,camera_offset,det_radius,lowMagFOVx,lowMagFOVy,highMagFOVx,highMagFOVy,lowMagPixX,lowMagPixY,highMagPixX,highMagPixY,screenPixX,screenPixY,screenPixCenterX,screenPixCenterY,screenProtocol,screenPhist,screenPhiend,screenWidth,screenDist,screenExptime,screenWave,screenReso,gonioPvPrefix,searchParams,screenEnergy,detectorOffline,imgsrv_host,imgsrv_port,beamlineComm,primaryDewarName,lowMagCamURL,highMagZoomCamURL,lowMagZoomCamURL,highMagCamURL,owner,dewarPlateMap,mag1ViewAngle,mag2ViewAngle,mag3ViewAngle,mag4ViewAngle

global sampleCameraConfig

owner = getpass.getuser()
primaryDewarName = getBlConfig("primaryDewarName")
Expand All @@ -72,6 +72,7 @@ def init_environment():
highMagPixY = float(getBlConfig("highMagPixY"))
screenPixX = float(getBlConfig("screenPixX"))
screenPixY = float(getBlConfig("screenPixY"))
sampleCameraConfig = getBlConfig("sampleCameraConfig")

try:
unitScaling = float(getBlConfig("unitScaling"))
Expand Down
59 changes: 59 additions & 0 deletions gui/camera/scene.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from qtpy.QtGui import QCursor
from qtpy.QtWidgets import QGraphicsView
from qtpy.QtCore import Signal, Qt
import daq_utils
import typing

if typing.TYPE_CHECKING:
from gui.control_main import ControlMain


class CustomView(QGraphicsView):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created CustomView mainly to handle events that happen when the sample cam is in focus. It handles the following events:

  • Using the mouse wheel (connects to handle_wheel method in gui.camera.zoom_widget.ZoomSlider
  • Detects whether Ctrl key is pressed and the mouse is clicked on the sample cam
  • Triggers center_on_click when all conditions above are met

y_value = Signal(float)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.parent: ControlMain = kwargs['parent']
self.control_pressed = False

def wheelEvent(self, event) -> None:
"""Wheel event to manage zoom in/out of sample cam"""
self.y_value.emit(event.angleDelta().y())
return super().wheelEvent(event)

def enterEvent(self, event):
self.setFocus() # set focus on mouse enter
super().enterEvent(event)

def keyPressEvent(self, event):
if event.key() == Qt.Key_Control:
self.control_pressed = True
self.setCursor(QCursor(Qt.CrossCursor))


def keyReleaseEvent(self, event):
if event.key() == Qt.Key_Control:
self.control_pressed = False
self.setCursor(QCursor(Qt.ArrowCursor))

def mousePressEvent(self, event) -> None:
if self.control_pressed and event.button() == Qt.LeftButton:
self.center_on_click(event)
return super().mousePressEvent(event)


def center_on_click(self, event):
# If C2C is not clicked and user is in control, then C2C
if self.parent.vidActionC2CRadio.isChecked():
return
correctedC2C_x = daq_utils.screenPixCenterX + (
event.pos().x() - (self.parent.centerMarker.x() + self.parent.centerMarkerCharOffsetX)
)
correctedC2C_y = daq_utils.screenPixCenterY + (
event.pos().y() - (self.parent.centerMarker.y() + self.parent.centerMarkerCharOffsetY)
)
fov = self.parent.getCurrentFOV()
current_viewangle = self.parent.zoomSlider.get_current_viewangle()
comm_s = f'center_on_click({correctedC2C_x},{correctedC2C_y},{fov["x"]},{fov["y"]},source="screen",maglevel=0,viewangle={current_viewangle})'
if self.parent.govStateMessagePV.get(as_string=True) == "state SA":
self.parent.aux_send_to_server(comm_s)
Loading