class CameraProfileBrick(BlissWidget): def __init__(self, *args): BlissWidget.__init__(self, *args) self.__view = None self.__drawing = None self.__line = None self.__pointSelected = None self.__graphs = None self.__refreshTimer = qt.QTimer(self) qt.QObject.connect(self.__refreshTimer, qt.SIGNAL("timeout()"), self.__refreshGraph) # Properties ####### SIGNAL ####### self.defineSignal("getView", ()) self.defineSignal("getImage", ()) self.setFixedSize(0, 0) def run(self): key = {} self.emit(qt.PYSIGNAL("getView"), (key, )) try: self.__view = key["view"] self.__drawing = key["drawing"] except KeyError: logging.getLogger().error( "%s : You have to connect this brick to the CameraBrick", self.name()) return self.__toggleButton = QubToggleAction( label="Show profile", name="histogram", place="toolbar", group="Camera", autoConnect=True, ) qt.QObject.connect(self.__toggleButton, qt.PYSIGNAL("StateChanged"), self.__showCBK) self.__view.addAction([self.__toggleButton]) self.__line, _, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine) self.__line.setEndDrawCallBack(self.__clickedPoint) graphV = _graphPoint(self.__drawing.canvas()) graphV.setPen(qt.QPen(qt.Qt.red, 2)) graphH = _graphPoint(self.__drawing.canvas()) graphH.setPen(qt.QPen(qt.Qt.green, 2)) graphH.setZ(5) self.__graphs = (graphH, graphV) def __showCBK(self, state): if state: self.__line.startDrawing() self.__refreshTimer.start(1000) else: self.__refreshTimer.stop() self.__line.hide() self.__line.stopDrawing() def __clickedPoint(self, drawingMgr): self.__pointSelected = drawingMgr.point() for graph in self.__graphs: graph.show() self.__refreshGraph() def __refreshGraph(self): key = {} try: self.emit(qt.PYSIGNAL("getImage"), (key, )) qimage = key["image"] except KeyError: return matrix = self.__drawing.matrix() try: x, y = self.__pointSelected except TypeError: return (graphH, graphV) = self.__graphs array = numpy.fromstring( qimage.bits().asstring(qimage.width() * qimage.height() * 4), dtype=numpy.uint8, ) array.shape = qimage.height(), qimage.width(), -1 yColor = array[y] yData = yColor[:, 0] * 0.114 + yColor[:, 1] * 0.587 + yColor[:, 2] * 0.299 maxData = yData.max() maxHeight = qimage.height() / 3 z = float(maxHeight) / maxData yData = yData * z yData = (qimage.height()) - yData # yData[len(yData)/2]= 220 xData = numpy.arange(qimage.width()) allPoint = numpy.array(zip(xData, yData)) allPoint.shape = -1 aP = qt.QPointArray(len(xData)) aP.putPoints(0, allPoint.tolist()) aP = matrix.map(aP) graphH._myXProfile = aP graphH.setPoints(aP) xColor = array[:, x] xData = xColor[:, 0] * 0.114 + xColor[:, 1] * 0.587 + xColor[:, 2] * 0.299 maxData = xData.max() maxHeight = qimage.width() / 3 z = float(maxHeight) / maxData xData = xData * z xData = qimage.width() - xData yData = numpy.arange(qimage.height()) allPoint = numpy.array(zip(xData, yData)) allPoint.shape = -1 aP = qt.QPointArray(len(xData)) aP.putPoints(0, allPoint.tolist()) aP = matrix.map(aP) graphV._myYProfile = aP graphV.setPoints(aP)
class SoleilHutchMenuBrick(BlissWidget): SNAPSHOT_FORMATS = ('png', 'jpeg') def __init__(self, *args): BlissWidget.__init__(self, *args) self.minidiff = None self.beamInfo = None self.sampleChanger = None self.collectObj = None self.queue_hwobj = None self.beam_position = [30, 30] self.beam_size = [0.04, 0.02] self.beam_shape = "Rectangular" self.pixels_per_mm = [0, 0] self.slitbox = None self.sampleChanger = None self.queue_hwobj = None self._bx, self._by = (0, 0) #self.allowMoveToBeamCentring = False # Define properties self.addProperty('minidiff', 'string', '') self.addProperty('beamInfo', 'string', '') self.addProperty('dataCollect', 'string', '') self.addProperty('beamInfo', 'string', '') # self.addProperty('slitbox','string','') self.addProperty('samplechanger', 'string', '') self.addProperty('extraCommands', 'string', '') self.addProperty('extraCommandsIcons', 'string', '') self.addProperty('icons', 'string', '') self.addProperty('label', 'string', 'Sample centring') #self.addProperty('displaySlitbox', 'boolean', True) self.addProperty('displayBeam', 'boolean', True) self.addProperty('queue', 'string', '/queue') self.addProperty('useMDPhases', 'boolean', True) # Define signals and slots self.defineSignal('enableMinidiff', ()) self.defineSignal('centringStarted', ()) self.defineSignal('centringAccepted', ()) self.defineSignal('getView', ()) self.defineSignal('beamPositionChanged', ()) self.defineSignal('calibrationChanged', ()) self.defineSignal('newCentredPos', ()) #self.defineSignal('setMoveToBeamState', ()) self.defineSlot('setDirectory', ()) self.defineSlot('setPrefix', ()) #self.defineSlot('movedToBeam', ()) self.defineSlot('startCentring', ()) self.defineSlot('rejectCentring', ()) self.defineSlot('setSample', ()) #self.defineSlot('enableAutoStartLoopCentring', ()) self.defineSlot('getSnapshot', ()) self.sampleCentreBox = QVBox(self) # self.sampleCentreBox.setInsideMargin(11) # self.sampleCentreBox.setInsideSpacing(0) # self.modeBox=QVButtonGroup(self.sampleCentreBox) # self.modeBox.setFrameShape(self.modeBox.NoFrame) # self.modeBox.setInsideMargin(0) # self.modeBox.setInsideSpacing(0) # QObject.connect(self.modeBox,SIGNAL('clicked(int)'),self.centringModeChanged) #self.userConfirmsButton=QCheckBox("User confirms", self.sampleCentreBox) # self.userConfirmsButton.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) # self.userConfirmsButton.setChecked(True) self.buttonsBox = QVBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.buttonCentre = MenuButton(self.buttonsBox, "Centre") self.buttonCentre.setMinimumSize(QSize(75, 50)) self.connect( self.buttonCentre, PYSIGNAL('executeCommand'), self.centreSampleClicked) self.connect( self.buttonCentre, PYSIGNAL('cancelCommand'), self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(75, 50)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept, SIGNAL('clicked()'), self.acceptClicked) self.standardColor = None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(75, 50)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject, SIGNAL('clicked()'), self.rejectClicked) # HorizontalSpacer4(self.sampleCentreBox) self.extraCommands = CommandMenuBrick.CommandMenuBrick(self.sampleCentreBox) self.extraCommands['showBorder'] = False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(75, 50)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot, SIGNAL('clicked()'), self.saveSnapshot) #self.buttonToogleMDPhase = QToolButton(self.sampleCentreBox) # self.buttonToogleMDPhase.setUsesTextLabel(True) #self.buttonToogleMDPhase.setTextLabel("MD phase") # self.buttonToogleMDPhase.setMinimumSize(QSize(75,50)) #self.buttonToogleMDPhase.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # QObject.connect(self.buttonToogleMDPhase,SIGNAL('clicked()'),self.toogleMDPhase) # self.buttonToogleMDPhase.hide() # HorizontalSpacer3(self.sampleCentreBox) self.centringButtons = [] self.defaultBackgroundColor = None self.insideDataCollection = False self.currentCentring = None self.isMoving = False self.isShooting = False self.directory = "/tmp" self.prefix = "snapshot" self.fileIndex = 1 self.formatType = "png" self.clickedPoints = [] self.selectedSamples = None # Layout self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) QHBoxLayout(self) self.layout().addWidget(self.sampleCentreBox) self.instanceSynchronize("") self.resetMethods = {MiniDiff.MiniDiff.MANUAL3CLICK_MODE: self.manualCentreReset, MiniDiff.MiniDiff.C3D_MODE: self.automaticCentreReset} # MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamReset} self.successfulMethods = {MiniDiff.MiniDiff.MANUAL3CLICK_MODE: None, MiniDiff.MiniDiff.C3D_MODE: self.automaticCentreSuccessful} # MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamSuccessful} self.sampleCentreBox.hide() self.sampleCentreBox = QHBox(self) self.buttonsBox = QHBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.sampleCentreBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonsBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.layout().addWidget(self.sampleCentreBox) self.buttonCentre = MenuButton(self.buttonsBox, "Centre") self.buttonCentre.setMinimumSize(QSize(50, 40)) self.connect( self.buttonCentre, PYSIGNAL('executeCommand'), self.centreSampleClicked) self.connect( self.buttonCentre, PYSIGNAL('cancelCommand'), self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(50, 40)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept, SIGNAL('clicked()'), self.acceptClicked) self.standardColor = None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(50, 40)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject, SIGNAL('clicked()'), self.rejectClicked) self.extraCommands = CommandMenuBrick.CommandMenuBrick(self.sampleCentreBox) self.extraCommands['showBorder'] = False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(50, 40)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot, SIGNAL('clicked()'), self.saveSnapshot) self.buttonBeamPosition = QToolButton(self.sampleCentreBox) self.buttonBeamPosition.setUsesTextLabel(True) self.buttonBeamPosition.setTextLabel("BeamPosition") self.buttonBeamPosition.setMinimumSize(QSize(50, 40)) self.buttonBeamPosition.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonBeamPosition.setPixmap(Icons.load("green_led")) QObject.connect( self.buttonBeamPosition, SIGNAL('clicked()'), self.beamPositionCheck) self.buttonApertureAlign = QToolButton(self.sampleCentreBox) self.buttonApertureAlign.setUsesTextLabel(True) self.buttonApertureAlign.setTextLabel("ApertureAlign") self.buttonApertureAlign.setMinimumSize(QSize(50, 40)) self.buttonApertureAlign.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonApertureAlign.setPixmap(Icons.load("Align")) QObject.connect( self.buttonApertureAlign, SIGNAL('clicked()'), self.apertureAlign) def beamPositionCheck(self): self.minidiff.beamPositionCheck() def apertureAlign(self): self.minidiff.apertureAlign() def enableAutoStartLoopCentring(self, enable): if self.minidiff is not None: self.minidiff.enableAutoStartLoopCentring(enable) def propertyChanged(self, propertyName, oldValue, newValue): #print "HutchMenuBrick.propertyChanged",property,newValue if propertyName == 'minidiff': if self.minidiff is not None: self.disconnect( self.minidiff, PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.disconnect( self.minidiff, PYSIGNAL('minidiffReady'), self.miniDiffReady) self.disconnect( self.minidiff, PYSIGNAL('minidiffNotReady'), self.miniDiffNotReady) self.disconnect( self.minidiff, PYSIGNAL('minidiffStateChanged'), self.miniDiffStateChanged) self.disconnect( self.minidiff, PYSIGNAL('centringStarted'), self.centringStarted) self.disconnect( self.minidiff, PYSIGNAL('centringSuccessful'), self.centringSuccessful) self.disconnect( self.minidiff, PYSIGNAL('centringFailed'), self.centringFailed) self.disconnect( self.minidiff, PYSIGNAL('centringMoving'), self.centringMoving) self.disconnect( self.minidiff, PYSIGNAL('centringInvalid'), self.centringInvalid) self.disconnect( self.minidiff, PYSIGNAL('centringSnapshots'), self.centringSnapshots) self.disconnect( self.minidiff, PYSIGNAL('progressMessage'), self.miniDiffMessage) self.disconnect( self.minidiff, PYSIGNAL('newAutomaticCentringPoint'), self.drawAutoCentringPoint) self.disconnect( self.minidiff, PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.disconnect( self.minidiff, PYSIGNAL('centringAccepted'), self.centringAccepted) self.minidiff = self.getHardwareObject(newValue) if self.minidiff is not None: self.connect( self.minidiff, PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.connect( self.minidiff, PYSIGNAL('minidiffReady'), self.miniDiffReady) self.connect( self.minidiff, PYSIGNAL('minidiffNotReady'), self.miniDiffNotReady) self.connect( self.minidiff, PYSIGNAL('minidiffStateChanged'), self.miniDiffStateChanged) self.connect( self.minidiff, PYSIGNAL('centringStarted'), self.centringStarted) self.connect( self.minidiff, PYSIGNAL('centringSuccessful'), self.centringSuccessful) self.connect( self.minidiff, PYSIGNAL('centringFailed'), self.centringFailed) self.connect( self.minidiff, PYSIGNAL('centringMoving'), self.centringMoving) self.connect( self.minidiff, PYSIGNAL('centringInvalid'), self.centringInvalid) self.connect( self.minidiff, PYSIGNAL('centringSnapshots'), self.centringSnapshots) self.connect( self.minidiff, PYSIGNAL('progressMessage'), self.miniDiffMessage) self.connect( self.minidiff, "newAutomaticCentringPoint", self.drawAutoCentringPoint) self.connect( self.minidiff, PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.connect( self.minidiff, PYSIGNAL('centringAccepted'), self.centringAccepted) if self.minidiff.isReady(): self.miniDiffReady() else: self.miniDiffNotReady() else: self.miniDiffNotReady() # elif propertyName=='slitbox': # if self.slitbox is not None: # for role in ('s1v', 's2v', 's1h', 's2h'): # m = self.slitbox.getDeviceByRole(role) # m.disconnect('stateChanged', self.slitsPositionChanged) # self.slitbox=self.getHardwareObject(newValue) # if self.slitbox is not None: # for role in ('s1v', 's2v', 's1h', 's2h'): # m = self.slitbox.getDeviceByRole(role) # m.connect("stateChanged", self.slitsPositionChanged) # #self.slitsPositionChanged() elif propertyName == "beamInfo": if self.beamInfo is not None: self.disconnect( self.beamInfo, PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.disconnect( self.beamInfo, PYSIGNAL('beamPosChanged'), self.beamPosChanged) self.beamInfo = self.getHardwareObject(newValue) if self.beamInfo is not None: self.connect( self.beamInfo, PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.connect( self.beamInfo, PYSIGNAL('beamPosChanged'), self.beamPosChanged) elif propertyName == "samplechanger": self.sampleChanger = self.getHardwareObject(newValue) elif propertyName == "dataCollect": self.collectObj = self.getHardwareObject(newValue) elif propertyName == 'icons': self.setIcons(newValue) elif propertyName == 'label': pass # self.sampleCentreBox.setTitle(newValue) elif propertyName == 'extraCommands': self.extraCommands['mnemonic'] = newValue elif propertyName == 'extraCommandsIcons': self.extraCommands['icons'] = newValue elif propertyName == 'queue': self.queue_hwobj = self.getHardwareObject(newValue) else: BlissWidget.propertyChanged(self, propertyName, oldValue, newValue) def setIcons(self, icons): icons_list = icons.split() try: self.buttonCentre.setIcons(icons_list[0], icons_list[1]) except IndexError: pass try: self.buttonAccept.setPixmap(Icons.load(icons_list[2])) except IndexError: pass try: self.buttonSnapshot.setPixmap(Icons.load(icons_list[3])) except IndexError: pass try: self.buttonReject.setPixmap(Icons.load(icons_list[4])) except IndexError: pass def setDirectory(self, directory): self.directory = str(directory) self.fileIndex = 1 def setPrefix(self, prefix): self.prefix = str(prefix) self.fileIndex = 1 def setSample(self, samples_list): self.selectedSamples = samples_list try: blsampleid = int(self.selectedSamples[0][0]) except BaseException: blsampleid = None try: self.minidiff.setSampleInfo({"blsampleid": blsampleid}) except BaseException: pass def emitWidgetSynchronize(self): # mode=self.modeBox.selectedId() points = self.clickedPoints #self.emit(PYSIGNAL("widgetSynchronize"),( (mode,points), )) self.emit(PYSIGNAL("widgetSynchronize"), ((points), )) def widgetSynchronize(self, state): # centring_method=state[0] # clicked_points=state[1] clicked_points = state[0] # self.modeBox.setButton(centring_method) if len(clicked_points): point = clicked_points[-1] self.__point.startDrawing() self.__point.show() self.__point.setPoint(point[0], point[1]) self.__point.stopDrawing() else: self.__point.hide() def startCentring(self): # this is called from another brick, not by user self.insideDataCollection = True self.centreSampleClicked() def rejectCentring(self): self.cancelCentringClicked(reject=True) def acceptCentring(self): self.acceptClicked() def centreSampleClicked(self): self.minidiff.startCentringMethod(self.minidiff.MANUAL3CLICK_MODE) def saveSnapshot(self): formats = "" for format in SoleilHutchMenuBrick.SNAPSHOT_FORMATS: formats += "*.%s " % format formats = formats.strip() current_filename = os.path.join(self.directory, self.prefix) current_filename = current_filename + \ '_%d%s%s' % (self.fileIndex, os.path.extsep, self.formatType) filename = str(QFileDialog.getSaveFileName(current_filename, "Images (%s)" % formats, self, None, "Choose a filename to save under", None, False)) if len(filename): image_type = os.path.splitext(filename)[1].strip('.').upper() try: matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() logging.getLogger().info("Saving snapshot : %s", filename) QubImageSave.save( filename, img, self.__drawing.canvas(), zoom, image_type) except BaseException: logging.getLogger().exception("HutchMenuBrick: error saving snapshot!") logging.getLogger().error("HutchMenuBrick: error saving snapshot!") else: self.formatType = image_type.lower() self.fileIndex += 1 def centredPositionSnapshot(self): matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() fd, name = tempfile.mkstemp() os.close(fd) QubImageSave.save(name, img, self.__drawing.canvas(), zoom, "JPEG") f = open(name, "r") imgcopy = f.read() f.close() os.unlink(name) return imgcopy def getSnapshot(self, img): logging.getLogger().debug("Taking snapshot for centred position") img['data'] = self.centredPositionSnapshot() def cancelCentringClicked(self, reject=False): #print "CANCELCENTRINGCLICKED",reject self.minidiff.cancelCentringMethod(reject=reject) def acceptClicked(self): if self.standardColor is not None: self.buttonAccept.setPaletteBackgroundColor(self.standardColor) #logging.info("disabling accept because accept was clicked") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) self.minidiff.acceptCentring() def rejectClicked(self): if self.standardColor is not None: self.buttonReject.setPaletteBackgroundColor(self.standardColor) #logging.info("disabling accept because reject was clicked") self.buttonReject.setEnabled(False) self.buttonAccept.setEnabled(False) self.minidiff.rejectCentring() self.insideDataCollection = False def centringMoving(self): self.isMoving = True logging.info("disabling accept because centring is moving ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringInvalid(self): if self.collectObj is not None: self.collectObj.setCentringStatus(None) logging.info("disabling accept because centring is invalid ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringAccepted(self, state, centring_status): logging.info("Centring has been accepted") if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) logging.info("disabling accept because centring has been accepted ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if self.insideDataCollection: self.insideDataCollection = False self.emit(PYSIGNAL("centringAccepted"), (state, centring_status)) if self.beamInfo is not None: beam_info = self.beamInfo.get_beam_info() if beam_info is not None: beam_info['size_x'] = beam_info['size_x'] * self.pixels_per_mm[0] beam_info['size_y'] = beam_info['size_y'] * self.pixels_per_mm[1] self.emit(PYSIGNAL("newCentredPos"), (state, centring_status, beam_info)) #self.emit(PYSIGNAL("newCentredPos"), (state, centring_status)) if self.queue_hwobj.is_executing(): self.setEnabled(False) def centringSnapshots(self, state): if state is None: self.isShooting = True self.sampleCentreBox.setEnabled(False) else: self.isShooting = False self.sampleCentreBox.setEnabled(True) def centringStarted(self, method, flexible): self.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (False,)) if self.insideDataCollection: self.emit(PYSIGNAL("centringStarted"), ()) self.isCentring = True self.isMoving = False self.isShooting = False """ for but in self.centringButtons: if str(but.text())==method: if self.defaultBackgroundColor is None: self.defaultBackgroundColor=but.paletteBackgroundColor() but.setPaletteBackgroundColor(QWidget.yellow) self.currentCentring=but break """ self.currentCentring = CentringMethod(method) self.buttonCentre.commandStarted() logging.info("disabling accept because centring has been started ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if method == MiniDiff.MiniDiff.MANUAL3CLICK_MODE: self.__point.startDrawing() self.__helpLine.startDrawing() self.__pointer.startDrawing() def drawAutoCentringPoint(self, x, y): if -1 in (x, y): self.__autoCentringPoint.hide() return self.__autoCentringPoint.startDrawing() self.__autoCentringPoint.setPoint(x, y) self.__autoCentringPoint.stopDrawing() self.__autoCentringPoint.show() def centringSuccessful(self, method, centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() #logging.info("HutchMenuBrick: centringSuccesful received") self.clickedPoints = [] self.emitWidgetSynchronize() self.buttonCentre.commandDone() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring = None self.buttonAccept.setEnabled(True) self.buttonReject.setEnabled(True) if self.insideDataCollection: if self.standardColor is None: self.standardColor = self.buttonAccept.paletteBackgroundColor() self.buttonAccept.setPaletteBackgroundColor(widget_colors.LIGHT_GREEN) self.buttonReject.setPaletteBackgroundColor(widget_colors.LIGHT_RED) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.isMoving = False self.sampleCentreBox.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: successful_method = self.successfulMethods[method] except KeyError as diag: pass else: try: successful_method() except BaseException: pass def centringFailed(self, method, centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints = [] self.emitWidgetSynchronize() self.buttonCentre.commandFailed() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring = None logging.info("disabling accept because centing failed") self.buttonAccept.setEnabled(False) if self.insideDataCollection: if self.standardColor is None: self.standardColor = self.buttonAccept.paletteBackgroundColor() self.buttonReject.setEnabled(True) self.buttonReject.setPaletteBackgroundColor(QWidget.red) else: self.buttonReject.setEnabled(False) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: reset_method = self.resetMethods[method] except KeyError as diag: pass else: try: reset_method() except BaseException: pass # def movedToBeam(self,x,y): # pass def manualCentreReset(self): self.resetPoints() def automaticCentreReset(self): if not self.userConfirmsButton.isChecked(): self.rejectCentring() def automaticCentreSuccessful(self): if not self.userConfirmsButton.isChecked(): self.acceptCentring() # def moveToBeamSuccessful(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass # def moveToBeamReset(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass def __endDrawingPoint(self, drawingManager): x, y = drawingManager.point() self.imageClicked(x, y, x, y) # Handler for clicking the video when doing the 3-click centring def imageClicked(self, x, y, xi, yi): #print "HutchMenuBrick.imageClicked",self.minidiff,self.manualCentering if self.currentCentring is not None and str(self.currentCentring.text( )) == MiniDiff.MiniDiff.MANUAL3CLICK_MODE and self.minidiff.isReady(): try: points = self.minidiff.imageClicked(x, y, xi, yi) except StopIteration: pass else: self.addPoint(x, y, xi, yi) # Signals a new point in the 3-click centering def addPoint(self, x, y, xi, yi): self.clickedPoints.append((x, y, xi, yi)) self.emitWidgetSynchronize() # Resets the points in the 3-click centering def resetPoints(self): self.clickedPoints = [] self.emitWidgetSynchronize() # Displays a message def showMessageToUser(self, message=None): #print "showMessage",message try: self.__drawing.setInfo(message) except BaseException: pass def connectNotify(self, signalName): print "..... HutchMenuBrick:connectNotify ", signalName if signalName == 'beamPositionChanged': if self.minidiff and self.minidiff.isReady() and self.beamInfo is not None: self.beam_position = self.beamInfo.get_beam_position() self.pixels_per_mm = self.minidiff.get_pixels_per_mm() self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1])) # if self.minidiff and self.minidiff.isReady(): # beam_xc = self.minidiff.getBeamPosX() # beam_yc = self.minidiff.getBeamPosY() # pxmmy=self.minidiff.pixelsPerMmY # pxmmz=self.minidiff.pixelsPerMmZ # # self.emit(PYSIGNAL("beamPositionChanged"), (beam_xc, beam_yc, # self._bx, self._by)) elif signalName == 'calibrationChanged': if self.minidiff and self.minidiff.isReady(): try: #self.emit(PYSIGNAL("calibrationChanged"), (1e3/self.minidiff.pixelsPerMmY, 1e3/self.minidiff.pixelsPerMmZ)) self.emit( PYSIGNAL("calibrationChanged"), (1e3 / self.pixels_per_mm[0], 1e3 / self.pixels_per_mm[1])) except BaseException: pass # Event when the minidiff is in ready state def miniDiffReady(self): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() if self.beamInfo is not None: self.beam_position = self.beamInfo.get_beam_position() except BaseException: import traceback logging.getLogger().error("error on minidiff ready %s", traceback.format_exc()) self.pixels_per_mm = [None, None] # pxmmy=None # pxmmz=None # if pxmmy is not None and pxmmz is not None: if self.beamInfo is not None: if self.pixels_per_mm[0] is not None and self.pixels_per_mm[1] is not None: self.sampleCentreBox.setEnabled(True) self.updateBeam() #self.emit(PYSIGNAL("beamPositionChanged"), (beam_xc, beam_yc, self._bx, self._by)) self.emit( PYSIGNAL("beamPositionChanged"), (self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1])) else: self.miniDiffNotReady() # Event when the minidiff is in notready state def miniDiffNotReady(self): #import pdb; pdb.set_trace() try: self.__beam.hide() except AttributeError: pass if not self.buttonCentre.executing: self.sampleCentreBox.setEnabled(False) def miniDiffStateChanged(self, state): if self.buttonCentre.executing or self.isMoving or self.isShooting: return try: self.sampleCentreBox.setEnabled(state == self.minidiff.phiMotor.READY) except BaseException: pass # Displays a message (signaled from the minidiff hardware object) def miniDiffMessage(self, msg=None): #print "MINIDIFF MESSAGE!!!",msg self.showMessageToUser(msg) # Update both zoom and slits when started def run(self): logging.getLogger().info("HucthMenuBrick runs") if self.minidiff is not None: zoom = self.minidiff.zoomMotor if zoom is not None: if zoom.isReady(): self.zoomPositionChanged(zoom.getCurrentPositionName(), 0) keys = {} self.emit(PYSIGNAL('getView'), (keys,)) self.__drawing = keys.get('drawing', None) self.__view = keys.get('view', None) if self.minidiff is not None: self.minidiff._drawing = self.__drawing try: self.__point, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__point.setEndDrawCallBack(self.__endDrawingPoint) self.__point.setColor(Qt.yellow) self.__autoCentringPoint, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__autoCentringPoint.setColor(Qt.green) self.__helpLine, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasVLine) self.__helpLine.setAutoDisconnectEvent(True) self.__helpLine.setExclusive(False) self.__helpLine.setColor(Qt.yellow) logging.getLogger().info("HutchMenuBrick help line OK") self.__rectangularBeam, _ = QubAddDrawing( self.__drawing, QubContainerDrawingMgr, QubCanvasSlitbox) self.__rectangularBeam.set_xMid_yMid( self.beam_position[0], self.beam_position[1]) self.__rectangularBeam.show() self.__rectangularBeam.setSlitboxSize(0, 0) self.__rectangularBeam.setColor(Qt.red) self.__rectangularBeam.setSlitboxPen(QPen(Qt.blue)) #self.beam_position = self.beamInfo.get_beam_position() logging.getLogger().info("HutchMenuBrick rectangular beam OK") self.__beam, _ = QubAddDrawing( self.__drawing, QubContainerDrawingMgr, QubCanvasBeam) self.__beam.setPen(QPen(Qt.blue)) self.__beam.hide() logging.getLogger().info("HutchMenuBrick beam setPen successful") self.__pointer, _, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine) self.__pointer.setDrawingEvent(QubMoveNPressed1Point) self.__pointer.setExclusive(False) self.__pointer.setColor(Qt.yellow) logging.getLogger().info("HutchMenuBrick runs. pointer successful") self.__scale, scale = QubAddDrawing( self.__drawing, QubContainerDrawingMgr, QubCanvasScale) self.sx = self.__scale.setXPixelSize self.sy = self.__scale.setYPixelSize self.__scale.show() logging.getLogger().info("HutchMenuBrick runs. Scale just changed") try: self.__scale.setXPixelSize(self.__scaleX) self.__scale.setYPixelSize(self.__scaleY) except AttributeError: pass else: self.emit(PYSIGNAL("calibrationChanged"), (self.__scaleX, self.__scaleY)) # self.slitsPositionChanged() logging.getLogger().info("HutchMenuBrick runs. It will now update the beam drawing") self.__rectangularBeam.set_xMid_yMid( self.beam_position[0], self.beam_position[1]) logging.getLogger().info( "HutchMenuBrick setting rectangular beam xMid, yMid to %s, %s" % (self.beam_position[0], self.beam_position[1])) self.updateBeam(force=True) except BaseException: import traceback logging.getLogger().debug("HutchMenuBrick: problem starting up display") logging.getLogger().exception(traceback.format_exc()) else: logging.getLogger().info("HucthMenuBrick runs cool") def _drawBeam(self): try: self.__rectangularBeam.show() # if None in (self._by, self._bx): if None in self.beam_size: return #bx = self._bx #by = self._by # pxmmy=self.minidiff.pixelsPerMmY # pxmmz=self.minidiff.pixelsPerMmZ # if self._bshape == "rectangular": # self.__rectangularBeam.setSlitboxSize(bx*pxmmy, by*pxmmz) if self.beam_shape == "rectangular": self.__rectangularBeam.setSlitboxSize(self.beam_size[0] * self.pixels_per_mm[0], self.beam_size[1] * self.pixels_per_mm[1]) self.__beam.hide() else: self.__rectangularBeam.setSlitboxSize(0, 0) self.__beam.setSize(self.beam_size[0] * self.pixels_per_mm[0], self.beam_size[1] * self.pixels_per_mm[1]) logging.getLogger().info("beam drawn with size %s " % str(self.beam_size)) #self.__beam.setSize(bx*pxmmy, by*pxmmz) self.__beam.show() except BaseException: pass def _updateBeam(self, ret): logging.info("UPDATE BEAM %s", ret) self._bx = float(ret["size_x"]) self._bshape = ret["shape"] self._by = float(ret["size_y"]) self._drawBeam() def updateBeam(self, force=False): logging.getLogger().info("updating beam ") if self.minidiff is None: return if self["displayBeam"]: if not self.minidiff.isReady(): time.sleep(0.2) #beam_x = self.minidiff.getBeamPosX() #beam_y = self.minidiff.getBeamPosY() try: logging.getLogger().info("self %s" % str(self)) self.__rectangularBeam.set_xMid_yMid( self.beam_position[0], self.beam_position[1]) logging.getLogger().info("rectangle drawn at position %s " % str(self.beam_position)) # self.__rectangularBeam.set_xMid_yMid(beam_x,beam_y) except AttributeError: import traceback logging.getLogger().info("update beam failed 1" + traceback.format_exc()) pass try: self.__beam.move(self.beam_position[0], self.beam_position[1]) self._drawBeam() except AttributeError: logging.getLogger().info("update beam failed 2") import traceback logging.getLogger().info("update beam failed 2" + traceback.format_exc()) def beamPosChanged(self, position): logging.getLogger().info( "hutch menu brick. Beam position chagned. It is %s" % str(position)) self.beam_position = position self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1])) self.updateBeam(True) def beamInfoChanged(self, beam_info): logging.getLogger().info( "hutch menu brick. Beam info chagned. It is %s" % str(beam_info)) self.beam_size = (beam_info["size_x"], beam_info["size_y"]) self.beam_shape = beam_info["shape"] self.updateBeam(True) # Zoom changed: update pixels per mm def zoomPositionChanged(self, position, offset): pxmmy, pxmmz, pxsize_y, pxsize_z = None, None, None, None print "** HutchMenuBrick: zoomPositionChanged", position, offset if offset is None: # unknown zoom pos. try: self.__scale.hide() self.__rectangularBeam.hide() self.__beam.hide() except AttributeError: print "&&& zoomPositionChanged AttributeError" self.__scaleX = None self.__scaleY = None else: if self.minidiff is not None: # pxmmy=self.minidiff.pixelsPerMmY # pxmmz=self.minidiff.pixelsPerMmZ self.pixels_per_mm = self.minidiff.get_pixels_per_mm() if self.pixels_per_mm[0] is not None and self.pixels_per_mm[1] is not None: pxsize_y = 1e-3 / self.pixels_per_mm[0] pxsize_z = 1e-3 / self.pixels_per_mm[1] try: self.sx(pxsize_y) self.sy(pxsize_z) except AttributeError: self.__scaleX = pxsize_y self.__scaleY = pxsize_z else: self.emit(PYSIGNAL("calibrationChanged"), (pxsize_y, pxsize_z)) self.updateBeam(True) # self._drawBeam() self.__scale.show() # Slits changed: update beam size def slitsPositionChanged(self, *args): if self.minidiff is None or self.slitbox is None or self.minidiff.pixelsPerMmY is None or self.minidiff.pixelsPerMmZ is None: pass else: self.updateBeam(force=True)
class CameraProfileBrick(BlissWidget): def __init__(self, *args): BlissWidget.__init__(self, *args) self.__view = None self.__drawing = None self.__line = None self.__pointSelected = None self.__graphs = None self.__refreshTimer = qt.QTimer(self) qt.QObject.connect( self.__refreshTimer, qt.SIGNAL("timeout()"), self.__refreshGraph ) # Properties ####### SIGNAL ####### self.defineSignal("getView", ()) self.defineSignal("getImage", ()) self.setFixedSize(0, 0) def run(self): key = {} self.emit(qt.PYSIGNAL("getView"), (key,)) try: self.__view = key["view"] self.__drawing = key["drawing"] except KeyError: logging.getLogger().error( "%s : You have to connect this brick to the CameraBrick", self.name() ) return self.__toggleButton = QubToggleAction( label="Show profile", name="histogram", place="toolbar", group="Camera", autoConnect=True, ) qt.QObject.connect( self.__toggleButton, qt.PYSIGNAL("StateChanged"), self.__showCBK ) self.__view.addAction([self.__toggleButton]) self.__line, _, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine ) self.__line.setEndDrawCallBack(self.__clickedPoint) graphV = _graphPoint(self.__drawing.canvas()) graphV.setPen(qt.QPen(qt.Qt.red, 2)) graphH = _graphPoint(self.__drawing.canvas()) graphH.setPen(qt.QPen(qt.Qt.green, 2)) graphH.setZ(5) self.__graphs = (graphH, graphV) def __showCBK(self, state): if state: self.__line.startDrawing() self.__refreshTimer.start(1000) else: self.__refreshTimer.stop() self.__line.hide() self.__line.stopDrawing() def __clickedPoint(self, drawingMgr): self.__pointSelected = drawingMgr.point() for graph in self.__graphs: graph.show() self.__refreshGraph() def __refreshGraph(self): key = {} try: self.emit(qt.PYSIGNAL("getImage"), (key,)) qimage = key["image"] except KeyError: return matrix = self.__drawing.matrix() try: x, y = self.__pointSelected except TypeError: return (graphH, graphV) = self.__graphs array = numpy.fromstring( qimage.bits().asstring(qimage.width() * qimage.height() * 4), dtype=numpy.uint8, ) array.shape = qimage.height(), qimage.width(), -1 yColor = array[y] yData = yColor[:, 0] * 0.114 + yColor[:, 1] * 0.587 + yColor[:, 2] * 0.299 maxData = yData.max() maxHeight = qimage.height() / 3 z = float(maxHeight) / maxData yData = yData * z yData = (qimage.height()) - yData # yData[len(yData)/2]= 220 xData = numpy.arange(qimage.width()) allPoint = numpy.array(zip(xData, yData)) allPoint.shape = -1 aP = qt.QPointArray(len(xData)) aP.putPoints(0, allPoint.tolist()) aP = matrix.map(aP) graphH._myXProfile = aP graphH.setPoints(aP) xColor = array[:, x] xData = xColor[:, 0] * 0.114 + xColor[:, 1] * 0.587 + xColor[:, 2] * 0.299 maxData = xData.max() maxHeight = qimage.width() / 3 z = float(maxHeight) / maxData xData = xData * z xData = qimage.width() - xData yData = numpy.arange(qimage.height()) allPoint = numpy.array(zip(xData, yData)) allPoint.shape = -1 aP = qt.QPointArray(len(xData)) aP.putPoints(0, allPoint.tolist()) aP = matrix.map(aP) graphV._myYProfile = aP graphV.setPoints(aP)
class HutchMenuBrick(BlissWidget): SNAPSHOT_FORMATS = ("png", "jpeg") def __init__(self, *args): BlissWidget.__init__(self, *args) self.minidiff = None self.beamInfo = None self.sampleChanger = None self.collectObj = None self.queue_hwobj = None self.beam_position = None self.beam_size = None self.beam_shape = None self.pixels_per_mm = None # self.allowMoveToBeamCentring = False # Define properties self.addProperty("beamInfo", "string", "") self.addProperty("minidiff", "string", "") self.addProperty("dataCollect", "string", "") self.addProperty("samplechanger", "string", "") self.addProperty("extraCommands", "string", "") self.addProperty("extraCommandsIcons", "string", "") self.addProperty("icons", "string", "") self.addProperty("label", "string", "Sample centring") self.addProperty("displayBeam", "boolean", True) self.addProperty("queue", "string", "/queue") self.addProperty("useMDPhases", "boolean", False) # Define signals and slots self.defineSignal("enableMinidiff", ()) self.defineSignal("centringStarted", ()) self.defineSignal("centringAccepted", ()) self.defineSignal("getView", ()) self.defineSignal("beamPositionChanged", ()) self.defineSignal("calibrationChanged", ()) self.defineSignal("newCentredPos", ()) # self.defineSignal('setMoveToBeamState', ()) self.defineSlot("setDirectory", ()) self.defineSlot("setPrefix", ()) # self.defineSlot('movedToBeam', ()) self.defineSlot("startCentring", ()) self.defineSlot("rejectCentring", ()) self.defineSlot("setSample", ()) # self.defineSlot('enableAutoStartLoopCentring', ()) self.defineSlot("getSnapshot", ()) self.sampleCentreBox = QVBox(self) self.buttonsBox = QVBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.buttonCentre = MenuButton(self.buttonsBox, "Centre") self.buttonCentre.setMinimumSize(QSize(75, 50)) self.connect(self.buttonCentre, PYSIGNAL("executeCommand"), self.centreSampleClicked) self.connect(self.buttonCentre, PYSIGNAL("cancelCommand"), self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(75, 50)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept, SIGNAL("clicked()"), self.acceptClicked) self.standardColor = None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(75, 50)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject, SIGNAL("clicked()"), self.rejectClicked) # HorizontalSpacer4(self.sampleCentreBox) self.extraCommands = CommandMenuBrick.CommandMenuBrick( self.sampleCentreBox) self.extraCommands["showBorder"] = False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(75, 50)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot, SIGNAL("clicked()"), self.saveSnapshot) self.buttonToogleMDPhase = QToolButton(self.sampleCentreBox) self.buttonToogleMDPhase.setUsesTextLabel(True) self.buttonToogleMDPhase.setTextLabel("MD phase") self.buttonToogleMDPhase.setMinimumSize(QSize(75, 50)) self.buttonToogleMDPhase.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonToogleMDPhase, SIGNAL("clicked()"), self.toggleMDPhase) self.buttonToogleMDPhase.hide() # HorizontalSpacer3(self.sampleCentreBox) self.centringButtons = [] self.defaultBackgroundColor = None self.insideDataCollection = False self.currentCentring = None self.isMoving = False self.isShooting = False self.directory = "/tmp" self.prefix = "snapshot" self.fileIndex = 1 self.formatType = "png" self.clickedPoints = [] self.selectedSamples = None # Layout self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) QHBoxLayout(self) self.layout().addWidget(self.sampleCentreBox) self.instanceSynchronize("") self.resetMethods = None self.successfulMethods = None def enableAutoStartLoopCentring(self, enable): if self.minidiff is not None: self.minidiff.enableAutoStartLoopCentring(enable) def propertyChanged(self, propertyName, oldValue, newValue): if propertyName == "beamInfo": if self.beamInfo is not None: self.disconnect(self.beamInfo, PYSIGNAL("beamInfoChanged"), self.beamInfoChanged) self.disconnect(self.beamInfo, PYSIGNAL("beamPosChanged"), self.beamPosChanged) self.beamInfo = self.getHardwareObject(newValue) if self.beamInfo is not None: self.connect(self.beamInfo, PYSIGNAL("beamInfoChanged"), self.beamInfoChanged) self.connect(self.beamInfo, PYSIGNAL("beamPosChanged"), self.beamPosChanged) elif propertyName == "minidiff": if self.minidiff is not None: self.disconnect(self.minidiff, PYSIGNAL("minidiffReady"), self.miniDiffReady) self.disconnect(self.minidiff, PYSIGNAL("minidiffNotReady"), self.miniDiffNotReady) self.disconnect( self.minidiff, PYSIGNAL("minidiffStateChanged"), self.miniDiffStateChanged, ) self.disconnect(self.minidiff, PYSIGNAL("centringStarted"), self.centringStarted) self.disconnect( self.minidiff, PYSIGNAL("centringSuccessful"), self.centringSuccessful, ) self.disconnect(self.minidiff, PYSIGNAL("centringAccepted"), self.centringAccepted) self.disconnect(self.minidiff, PYSIGNAL("centringFailed"), self.centringFailed) self.disconnect(self.minidiff, PYSIGNAL("centringMoving"), self.centringMoving) self.disconnect(self.minidiff, PYSIGNAL("centringInvalid"), self.centringInvalid) self.disconnect(self.minidiff, PYSIGNAL("centringSnapshots"), self.centringSnapshots) self.disconnect(self.minidiff, PYSIGNAL("progressMessage"), self.miniDiffMessage) self.disconnect( self.minidiff, PYSIGNAL("newAutomaticCentringPoint"), self.drawAutoCentringPoint, ) self.disconnect( self.minidiff, PYSIGNAL("zoomMotorPredefinedPositionChanged"), self.zoomPositionChanged, ) self.minidiff = self.getHardwareObject(newValue) if self.minidiff is not None: self.connect(self.minidiff, PYSIGNAL("minidiffReady"), self.miniDiffReady) self.connect(self.minidiff, PYSIGNAL("minidiffNotReady"), self.miniDiffNotReady) self.connect( self.minidiff, PYSIGNAL("minidiffStateChanged"), self.miniDiffStateChanged, ) self.connect(self.minidiff, PYSIGNAL("centringStarted"), self.centringStarted) self.connect( self.minidiff, PYSIGNAL("centringSuccessful"), self.centringSuccessful, ) self.connect(self.minidiff, PYSIGNAL("centringAccepted"), self.centringAccepted) self.connect(self.minidiff, PYSIGNAL("centringFailed"), self.centringFailed) self.connect(self.minidiff, PYSIGNAL("centringMoving"), self.centringMoving) self.connect(self.minidiff, PYSIGNAL("centringInvalid"), self.centringInvalid) self.connect(self.minidiff, PYSIGNAL("centringSnapshots"), self.centringSnapshots) self.connect(self.minidiff, PYSIGNAL("progressMessage"), self.miniDiffMessage) self.connect( self.minidiff, PYSIGNAL("newAutomaticCentringPoint"), self.drawAutoCentringPoint, ) self.connect( self.minidiff, PYSIGNAL("zoomMotorPredefinedPositionChanged"), self.zoomPositionChanged, ) if self.minidiff.isReady(): self.miniDiffReady() else: self.miniDiffNotReady() self.resetMethods = { self.minidiff.MANUAL3CLICK_MODE: self.manualCentreReset, self.minidiff.C3D_MODE: self.automaticCentreReset, } # MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamReset} self.successfulMethods = { self.minidiff.MANUAL3CLICK_MODE: None, self.minidiff.C3D_MODE: self.automaticCentreSuccessful, } # MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamSuccessful} else: self.miniDiffNotReady() elif propertyName == "samplechanger": self.sampleChanger = self.getHardwareObject(newValue) elif propertyName == "dataCollect": self.collectObj = self.getHardwareObject(newValue) elif propertyName == "icons": self.setIcons(newValue) elif propertyName == "label": pass # self.sampleCentreBox.setTitle(newValue) elif propertyName == "extraCommands": self.extraCommands["mnemonic"] = newValue elif propertyName == "extraCommandsIcons": self.extraCommands["icons"] = newValue elif propertyName == "queue": self.queue_hwobj = self.getHardwareObject(newValue) self.queue_hwobj.connect("queue_execution_finished", self.enable) self.queue_hwobj.connect("queue_stopped", self.enable) elif propertyName == "useMDPhases": if newValue: self.buttonToogleMDPhase.show() else: self.buttonToogleMDPhase.hide() else: BlissWidget.propertyChanged(self, propertyName, oldValue, newValue) def enable(self, *args): self.setEnabled(True) def disable(self, *args): self.setEnabled(False) def setIcons(self, icons): icons_list = icons.split() try: self.buttonCentre.setIcons(icons_list[0], icons_list[1]) except IndexError: pass try: self.buttonAccept.setPixmap(Icons.load(icons_list[2])) except IndexError: pass try: self.buttonSnapshot.setPixmap(Icons.load(icons_list[3])) except IndexError: pass try: self.buttonReject.setPixmap(Icons.load(icons_list[4])) except IndexError: pass try: self.buttonToogleMDPhase.setPixmap(Icons.load(icons_list[5])) except IndexError: pass def setDirectory(self, directory): self.directory = str(directory) self.fileIndex = 1 def setPrefix(self, prefix): self.prefix = str(prefix) self.fileIndex = 1 def setSample(self, samples_list): self.selectedSamples = samples_list try: blsampleid = int(self.selectedSamples[0][0]) except BaseException: blsampleid = None try: self.minidiff.setSampleInfo({"blsampleid": blsampleid}) except BaseException: pass def emitWidgetSynchronize(self): # mode=self.modeBox.selectedId() points = self.clickedPoints # self.emit(PYSIGNAL("widgetSynchronize"),( (mode,points), )) self.emit(PYSIGNAL("widgetSynchronize"), ((points), )) def widgetSynchronize(self, state): # centring_method=state[0] # clicked_points=state[1] clicked_points = state[0] # self.modeBox.setButton(centring_method) if len(clicked_points): point = clicked_points[-1] self.__point.startDrawing() self.__point.show() self.__point.setPoint(point[0], point[1]) self.__point.stopDrawing() else: self.__point.hide() def startCentring(self): # this is called from another brick, not by user self.insideDataCollection = True self.centreSampleClicked() def rejectCentring(self): self.cancelCentringClicked(reject=True) def acceptCentring(self): self.acceptClicked() def centreSampleClicked(self): self.minidiff.startCentringMethod(self.minidiff.MANUAL3CLICK_MODE) def saveSnapshot(self): formats = "" for format in HutchMenuBrick.SNAPSHOT_FORMATS: formats += "*.%s " % format formats = formats.strip() current_filename = os.path.join(self.directory, self.prefix) current_filename = current_filename + "_%d%s%s" % ( self.fileIndex, os.path.extsep, self.formatType, ) filename = str( QFileDialog.getSaveFileName( current_filename, "Images (%s)" % formats, self, None, "Choose a filename to save under", None, False, )) if len(filename): image_type = os.path.splitext(filename)[1].strip(".").upper() try: matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() logging.getLogger().info("Saving snapshot : %s", filename) QubImageSave.save(filename, img, self.__drawing.canvas(), zoom, image_type) except BaseException: logging.getLogger().exception( "HutchMenuBrick: error saving snapshot!") logging.getLogger().error( "HutchMenuBrick: error saving snapshot!") else: self.formatType = image_type.lower() self.fileIndex += 1 def centredPositionSnapshot(self): matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() fd, name = tempfile.mkstemp() os.close(fd) QubImageSave.save(name, img, self.__drawing.canvas(), zoom, "JPEG") f = open(name, "r") imgcopy = f.read() f.close() os.unlink(name) return imgcopy def getSnapshot(self, img): logging.getLogger().debug("Taking snapshot for centred position") img["data"] = self.centredPositionSnapshot() def cancelCentringClicked(self, reject=False): # print "CANCELCENTRINGCLICKED",reject self.minidiff.cancelCentringMethod(reject=reject) def acceptClicked(self): if self.standardColor is not None: self.buttonAccept.setPaletteBackgroundColor(self.standardColor) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) self.minidiff.acceptCentring() def rejectClicked(self): if self.standardColor is not None: self.buttonReject.setPaletteBackgroundColor(self.standardColor) self.buttonReject.setEnabled(False) self.buttonAccept.setEnabled(False) self.minidiff.rejectCentring() self.insideDataCollection = False def centringMoving(self): self.isMoving = True self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringInvalid(self): if self.collectObj is not None: self.collectObj.setCentringStatus(None) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringAccepted(self, state, centring_status): if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if self.insideDataCollection: self.insideDataCollection = False self.emit(PYSIGNAL("centringAccepted"), (state, centring_status)) beam_info = self.beamInfo.get_beam_info() if beam_info is not None: beam_info["size_x"] = beam_info["size_x"] * self.pixels_per_mm[0] beam_info["size_y"] = beam_info["size_y"] * self.pixels_per_mm[1] self.emit(PYSIGNAL("newCentredPos"), (state, centring_status, beam_info)) if self.queue_hwobj.is_executing(): self.disable() def centringSnapshots(self, state): if state is None: self.isShooting = True self.sampleCentreBox.setEnabled(False) else: self.isShooting = False self.sampleCentreBox.setEnabled(True) def centringStarted(self, method, flexible): self.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (False, )) if self.insideDataCollection: self.emit(PYSIGNAL("centringStarted"), ()) self.isCentring = True self.isMoving = False self.isShooting = False """ for but in self.centringButtons: if str(but.text())==method: if self.defaultBackgroundColor is None: self.defaultBackgroundColor=but.paletteBackgroundColor() but.setPaletteBackgroundColor(QWidget.yellow) self.currentCentring=but break """ self.currentCentring = CentringMethod(method) self.buttonCentre.commandStarted() self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if method == self.minidiff.MANUAL3CLICK_MODE: self.__point.startDrawing() self.__helpLine.startDrawing() self.__pointer.startDrawing() def drawAutoCentringPoint(self, x, y): if -1 in (x, y): self.__autoCentringPoint.hide() return self.__autoCentringPoint.startDrawing() self.__autoCentringPoint.setPoint(x, y) self.__autoCentringPoint.stopDrawing() self.__autoCentringPoint.show() def centringSuccessful(self, method, centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints = [] self.emitWidgetSynchronize() self.buttonCentre.commandDone() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring = None self.buttonAccept.setEnabled(True) self.buttonReject.setEnabled(True) if self.insideDataCollection: if self.standardColor is None: self.standardColor = self.buttonAccept.paletteBackgroundColor() self.buttonAccept.setPaletteBackgroundColor( widget_colors.LIGHT_GREEN) self.buttonReject.setPaletteBackgroundColor( widget_colors.LIGHT_RED) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.isMoving = False self.sampleCentreBox.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (True, )) try: successful_method = self.successfulMethods[method] except KeyError as diag: pass else: try: successful_method() except BaseException: pass def centringFailed(self, method, centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints = [] self.emitWidgetSynchronize() self.buttonCentre.commandFailed() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring = None self.buttonAccept.setEnabled(False) if self.insideDataCollection: if self.standardColor is None: self.standardColor = self.buttonAccept.paletteBackgroundColor() self.buttonReject.setEnabled(True) self.buttonReject.setPaletteBackgroundColor(QWidget.red) else: self.buttonReject.setEnabled(False) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.emit(PYSIGNAL("enableMinidiff"), (True, )) try: reset_method = self.resetMethods[method] except KeyError as diag: pass else: try: reset_method() except BaseException: pass # def movedToBeam(self,x,y): # pass def manualCentreReset(self): self.resetPoints() def automaticCentreReset(self): if not self.userConfirmsButton.isChecked(): self.rejectCentring() def automaticCentreSuccessful(self): if not self.userConfirmsButton.isChecked(): self.acceptCentring() # def moveToBeamSuccessful(self): # self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass # def moveToBeamReset(self): # self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass def __endDrawingPoint(self, drawingManager): x, y = drawingManager.point() self.imageClicked(x, y, x, y) # Handler for clicking the video when doing the 3-click centring def imageClicked(self, x, y, xi, yi): if (self.currentCentring is not None and str( self.currentCentring.text()) == self.minidiff.MANUAL3CLICK_MODE and self.minidiff.isReady()): try: points = self.minidiff.imageClicked(x, y, xi, yi) except StopIteration: pass else: self.addPoint(x, y, xi, yi) # Signals a new point in the 3-click centering def addPoint(self, x, y, xi, yi): self.clickedPoints.append((x, y, xi, yi)) self.emitWidgetSynchronize() # Resets the points in the 3-click centering def resetPoints(self): self.clickedPoints = [] self.emitWidgetSynchronize() # Displays a message def showMessageToUser(self, message=None): try: self.__drawing.setInfo(message) except BaseException: pass def connectNotify(self, signalName): if signalName == "beamPositionChanged": if self.minidiff and self.beamInfo: if self.minidiff.isReady(): self.beam_position = self.beamInfo.get_beam_position() self.emit( PYSIGNAL("beamPositionChanged"), ( self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1], ), ) elif signalName == "calibrationChanged": if self.minidiff and self.minidiff.isReady(): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() self.emit( PYSIGNAL("calibrationChanged"), (1e3 / self.pixels_per_mm[0], 1e3 / self.pixels_per_mm[1]), ) except BaseException: pass # Event when the minidiff is in ready state def miniDiffReady(self): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() except BaseException: self.pixels_per_mm = [None, None] if self.pixels_per_mm[0] is not None and self.pixels_per_mm[ 1] is not None: self.beam_position = self.beamInfo.get_beam_position() self.beam_size = self.beamInfo.get_beam_size() self.sampleCentreBox.setEnabled(True) self.updateBeam() self.emit( PYSIGNAL("beamPositionChanged"), ( self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1], ), ) else: self.miniDiffNotReady() # Event when the minidiff is in notready state def miniDiffNotReady(self): try: self.__beam.hide() except AttributeError: pass if not self.buttonCentre.executing: self.sampleCentreBox.setEnabled(False) def miniDiffStateChanged(self, state): if self.buttonCentre.executing or self.isMoving or self.isShooting: return try: self.sampleCentreBox.setEnabled( state == self.minidiff.phiMotor.READY) except BaseException: pass # Displays a message (signaled from the minidiff hardware object) def miniDiffMessage(self, msg=None): self.showMessageToUser(msg) # Update both zoom and slits when started def run(self): if self.minidiff is not None: zoom = self.minidiff.zoomMotor if zoom is not None: if zoom.isReady(): self.zoomPositionChanged(zoom.getCurrentPositionName(), 0) keys = {} self.emit(PYSIGNAL("getView"), (keys, )) self.__drawing = keys.get("drawing", None) self.__view = keys.get("view", None) if self.minidiff is not None: self.minidiff._drawing = self.__drawing try: self.__point, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__point.setEndDrawCallBack(self.__endDrawingPoint) self.__point.setColor(Qt.yellow) self.__autoCentringPoint, _ = QubAddDrawing( self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__autoCentringPoint.setColor(Qt.green) self.__helpLine, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasVLine) self.__helpLine.setAutoDisconnectEvent(True) self.__helpLine.setExclusive(False) self.__helpLine.setColor(Qt.yellow) self.__rectangularBeam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasSlitbox) self.__rectangularBeam.show() self.__rectangularBeam.setSlitboxSize(0, 0) self.__rectangularBeam.setColor(Qt.red) self.__rectangularBeam.setSlitboxPen(QPen(Qt.blue)) self.__beam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasBeam) self.__beam.setPen(QPen(Qt.blue)) self.__beam.hide() self.__pointer, _, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine) self.__pointer.setDrawingEvent(QubMoveNPressed1Point) self.__pointer.setExclusive(False) self.__pointer.setColor(Qt.yellow) self.__scale, scale = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasScale) self.sx = self.__scale.setXPixelSize self.sy = self.__scale.setYPixelSize self.__scale.show() try: self.__scale.setXPixelSize(self.__scaleX) self.__scale.setYPixelSize(self.__scaleY) except AttributeError: pass else: self.emit(PYSIGNAL("calibrationChanged"), (self.__scaleX, self.__scaleY)) self.updateBeam(force=True) except BaseException: logging.getLogger().exception( "HutchMenuBrick: problem starting up display") def _drawBeam(self): if None in (self.beam_size, self.beam_shape): self.beam_position = self.beamInfo.get_beam_position() self.beam_size = self.beamInfo.get_beam_size() if True: self.__rectangularBeam.show() if None in self.beam_size: return if self.beam_shape == "rectangular": self.__rectangularBeam.setSlitboxSize( self.beam_size[0] * self.pixels_per_mm[0], self.beam_size[1] * self.pixels_per_mm[1], ) self.__beam.hide() else: self.__rectangularBeam.setSlitboxSize(0, 0) self.__beam.setSize( self.beam_size[0] * self.pixels_per_mm[0], self.beam_size[1] * self.pixels_per_mm[1], ) self.__beam.show() def updateBeam(self, force=False): if self["displayBeam"]: # if self.minidiff: # if not self.minidiff.isReady(): time.sleep(0.2) try: self.__rectangularBeam.set_xMid_yMid(self.beam_position[0], self.beam_position[1]) except AttributeError: pass try: self.__beam.move(self.beam_position[0], self.beam_position[1]) self._drawBeam() # try: # self._updateBeam(self.beamInfo.get_beam_info()) # except: # logging.getLogger().exception("Could not get beam size: cannot display beam") # self.__beam.hide() except AttributeError: pass def beamPosChanged(self, position): self.beam_position = position self.emit( PYSIGNAL("beamPositionChanged"), ( self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1], ), ) self.updateBeam(True) def beamInfoChanged(self, beam_info): try: self.beam_position = self.beamInfo.get_beam_position() except BaseException: pass self.beam_size = (beam_info["size_x"], beam_info["size_y"]) self.beam_shape = beam_info["shape"] self.emit( PYSIGNAL("beamPositionChanged"), ( self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1], ), ) self.updateBeam(True) # Zoom changed: update pixels per mm def zoomPositionChanged(self, position, offset): pxmmy, pxmmz, pxsize_y, pxsize_z = None, None, None, None if offset is None: # unknown zoom pos. try: self.__scale.hide() self.__rectangularBeam.hide() self.__beam.hide() except AttributeError: self.__scaleX = None self.__scaleY = None else: if self.minidiff is not None: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() if (self.pixels_per_mm[0] is not None and self.pixels_per_mm[1] is not None): pxsize_y = 1e-3 / self.pixels_per_mm[0] pxsize_z = 1e-3 / self.pixels_per_mm[1] try: self.sx(pxsize_y) self.sy(pxsize_z) except AttributeError: self.__scaleX = pxsize_y self.__scaleY = pxsize_z else: self.emit(PYSIGNAL("calibrationChanged"), (pxsize_y, pxsize_z)) self.updateBeam(True) self.__scale.show() def toggleMDPhase(self): if self.minidiff is not None: self.minidiff.togglePhase()
class HutchMenuBrick(BlissWidget): SNAPSHOT_FORMATS = ('png', 'jpeg') def __init__(self, *args): BlissWidget.__init__(self, *args) self.minidiff = None self.beamInfo = None self.sampleChanger=None self.collectObj = None self.queue_hwobj = None self.beam_position = None self.beam_size = None self.beam_shape = None self.pixels_per_mm = None #self.allowMoveToBeamCentring = False # Define properties self.addProperty('beamInfo', 'string', '') self.addProperty('minidiff','string','') self.addProperty('dataCollect','string','') self.addProperty('samplechanger','string','') self.addProperty('extraCommands','string','') self.addProperty('extraCommandsIcons','string','') self.addProperty('icons','string','') self.addProperty('label','string','Sample centring') self.addProperty('displayBeam', 'boolean', True) self.addProperty('queue', 'string', '/queue') self.addProperty('useMDPhases', 'boolean', False) # Define signals and slots self.defineSignal('enableMinidiff',()) self.defineSignal('centringStarted',()) self.defineSignal('centringAccepted',()) self.defineSignal('getView',()) self.defineSignal('beamPositionChanged', ()) self.defineSignal('calibrationChanged', ()) self.defineSignal('newCentredPos', ()) #self.defineSignal('setMoveToBeamState', ()) self.defineSlot('setDirectory',()) self.defineSlot('setPrefix',()) #self.defineSlot('movedToBeam', ()) self.defineSlot('startCentring', ()) self.defineSlot('rejectCentring', ()) self.defineSlot('setSample',()) #self.defineSlot('enableAutoStartLoopCentring', ()) self.defineSlot('getSnapshot',()) self.sampleCentreBox=QVBox(self) self.buttonsBox=QVBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.buttonCentre=MenuButton(self.buttonsBox,"Centre") self.buttonCentre.setMinimumSize(QSize(75,50)) self.connect(self.buttonCentre,PYSIGNAL('executeCommand'),self.centreSampleClicked) self.connect(self.buttonCentre,PYSIGNAL('cancelCommand'),self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(75,50)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept,SIGNAL('clicked()'),self.acceptClicked) self.standardColor=None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(75,50)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject,SIGNAL('clicked()'),self.rejectClicked) #HorizontalSpacer4(self.sampleCentreBox) self.extraCommands=CommandMenuBrick.CommandMenuBrick(self.sampleCentreBox) self.extraCommands['showBorder']=False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(75,50)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot,SIGNAL('clicked()'),self.saveSnapshot) self.buttonToogleMDPhase = QToolButton(self.sampleCentreBox) self.buttonToogleMDPhase.setUsesTextLabel(True) self.buttonToogleMDPhase.setTextLabel("MD phase") self.buttonToogleMDPhase.setMinimumSize(QSize(75,50)) self.buttonToogleMDPhase.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonToogleMDPhase,SIGNAL('clicked()'),self.toggleMDPhase) self.buttonToogleMDPhase.hide() #HorizontalSpacer3(self.sampleCentreBox) self.centringButtons=[] self.defaultBackgroundColor=None self.insideDataCollection=False self.currentCentring = None self.isMoving=False self.isShooting=False self.directory="/tmp" self.prefix="snapshot" self.fileIndex=1 self.formatType="png" self.clickedPoints=[] self.selectedSamples=None # Layout self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) QHBoxLayout(self) self.layout().addWidget(self.sampleCentreBox) self.instanceSynchronize("") self.resetMethods = None self.successfulMethods = None def enableAutoStartLoopCentring(self, enable): if self.minidiff is not None: self.minidiff.enableAutoStartLoopCentring(enable) def propertyChanged(self,propertyName,oldValue,newValue): if propertyName=="beamInfo": if self.beamInfo is not None: self.disconnect(self.beamInfo,PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.disconnect(self.beamInfo,PYSIGNAL('beamPosChanged'), self.beamPosChanged) self.beamInfo=self.getHardwareObject(newValue) if self.beamInfo is not None: self.connect(self.beamInfo,PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.connect(self.beamInfo,PYSIGNAL('beamPosChanged'), self.beamPosChanged) elif propertyName=='minidiff': if self.minidiff is not None: self.disconnect(self.minidiff,PYSIGNAL('minidiffReady'),self.miniDiffReady) self.disconnect(self.minidiff,PYSIGNAL('minidiffNotReady'),self.miniDiffNotReady) self.disconnect(self.minidiff,PYSIGNAL('minidiffStateChanged'),self.miniDiffStateChanged) self.disconnect(self.minidiff,PYSIGNAL('centringStarted'),self.centringStarted) self.disconnect(self.minidiff,PYSIGNAL('centringSuccessful'),self.centringSuccessful) self.disconnect(self.minidiff,PYSIGNAL('centringAccepted'),self.centringAccepted) self.disconnect(self.minidiff,PYSIGNAL('centringFailed'),self.centringFailed) self.disconnect(self.minidiff,PYSIGNAL('centringMoving'),self.centringMoving) self.disconnect(self.minidiff,PYSIGNAL('centringInvalid'),self.centringInvalid) self.disconnect(self.minidiff,PYSIGNAL('centringSnapshots'),self.centringSnapshots) self.disconnect(self.minidiff,PYSIGNAL('progressMessage'),self.miniDiffMessage) self.disconnect(self.minidiff,PYSIGNAL('newAutomaticCentringPoint'),self.drawAutoCentringPoint) self.disconnect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.minidiff=self.getHardwareObject(newValue) if self.minidiff is not None: self.connect(self.minidiff,PYSIGNAL('minidiffReady'),self.miniDiffReady) self.connect(self.minidiff,PYSIGNAL('minidiffNotReady'),self.miniDiffNotReady) self.connect(self.minidiff,PYSIGNAL('minidiffStateChanged'),self.miniDiffStateChanged) self.connect(self.minidiff,PYSIGNAL('centringStarted'),self.centringStarted) self.connect(self.minidiff,PYSIGNAL('centringSuccessful'),self.centringSuccessful) self.connect(self.minidiff,PYSIGNAL('centringAccepted'),self.centringAccepted) self.connect(self.minidiff,PYSIGNAL('centringFailed'),self.centringFailed) self.connect(self.minidiff,PYSIGNAL('centringMoving'),self.centringMoving) self.connect(self.minidiff,PYSIGNAL('centringInvalid'),self.centringInvalid) self.connect(self.minidiff,PYSIGNAL('centringSnapshots'),self.centringSnapshots) self.connect(self.minidiff,PYSIGNAL('progressMessage'),self.miniDiffMessage) self.connect(self.minidiff,PYSIGNAL('newAutomaticCentringPoint'),self.drawAutoCentringPoint) self.connect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'),self.zoomPositionChanged) if self.minidiff.isReady(): self.miniDiffReady() else: self.miniDiffNotReady() self.resetMethods={self.minidiff.MANUAL3CLICK_MODE:self.manualCentreReset, self.minidiff.C3D_MODE:self.automaticCentreReset} #MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamReset} self.successfulMethods={self.minidiff.MANUAL3CLICK_MODE:None, self.minidiff.C3D_MODE:self.automaticCentreSuccessful} #MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamSuccessful} else: self.miniDiffNotReady() elif propertyName=="samplechanger": self.sampleChanger=self.getHardwareObject(newValue) elif propertyName=="dataCollect": self.collectObj=self.getHardwareObject(newValue) elif propertyName == 'icons': self.setIcons(newValue) elif propertyName=='label': pass #self.sampleCentreBox.setTitle(newValue) elif propertyName=='extraCommands': self.extraCommands['mnemonic']=newValue elif propertyName=='extraCommandsIcons': self.extraCommands['icons']=newValue elif propertyName=='queue': self.queue_hwobj = self.getHardwareObject(newValue) self.queue_hwobj.connect("queue_execution_finished", self.enable) self.queue_hwobj.connect("queue_stopped", self.enable) elif propertyName=='useMDPhases': if newValue: self.buttonToogleMDPhase.show() else: self.buttonToogleMDPhase.hide() else: BlissWidget.propertyChanged(self,propertyName,oldValue,newValue) def enable(self, *args): self.setEnabled(True) def disable(self, *args): self.setEnabled(False) def setIcons(self,icons): icons_list=icons.split() try: self.buttonCentre.setIcons(icons_list[0],icons_list[1]) except IndexError: pass try: self.buttonAccept.setPixmap(Icons.load(icons_list[2])) except IndexError: pass try: self.buttonSnapshot.setPixmap(Icons.load(icons_list[3])) except IndexError: pass try: self.buttonReject.setPixmap(Icons.load(icons_list[4])) except IndexError: pass try: self.buttonToogleMDPhase.setPixmap(Icons.load(icons_list[5])) except IndexError: pass def setDirectory(self,directory): self.directory=str(directory) self.fileIndex=1 def setPrefix(self,prefix): self.prefix=str(prefix) self.fileIndex=1 def setSample(self,samples_list): self.selectedSamples = samples_list try: blsampleid=int(self.selectedSamples[0][0]) except: blsampleid=None try: self.minidiff.setSampleInfo({"blsampleid":blsampleid}) except: pass def emitWidgetSynchronize(self): #mode=self.modeBox.selectedId() points=self.clickedPoints #self.emit(PYSIGNAL("widgetSynchronize"),( (mode,points), )) self.emit(PYSIGNAL("widgetSynchronize"),( (points), )) def widgetSynchronize(self,state): #centring_method=state[0] #clicked_points=state[1] clicked_points=state[0] #self.modeBox.setButton(centring_method) if len(clicked_points): point=clicked_points[-1] self.__point.startDrawing() self.__point.show() self.__point.setPoint(point[0],point[1]) self.__point.stopDrawing() else: self.__point.hide() def startCentring(self): # this is called from another brick, not by user self.insideDataCollection=True self.centreSampleClicked() def rejectCentring(self): self.cancelCentringClicked(reject=True) def acceptCentring(self): self.acceptClicked() def centreSampleClicked(self): self.minidiff.startCentringMethod(self.minidiff.MANUAL3CLICK_MODE) def saveSnapshot(self): formats="" for format in HutchMenuBrick.SNAPSHOT_FORMATS: formats+="*.%s " % format formats=formats.strip() current_filename=os.path.join(self.directory, self.prefix) current_filename=current_filename + '_%d%s%s' % (self.fileIndex, os.path.extsep, self.formatType) filename=str(QFileDialog.getSaveFileName(current_filename,"Images (%s)" % formats,\ self,None,"Choose a filename to save under",None,False)) if len(filename): image_type=os.path.splitext(filename)[1].strip('.').upper() try: matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() logging.getLogger().info("Saving snapshot : %s", filename) QubImageSave.save(filename, img, self.__drawing.canvas(), zoom, image_type) except: logging.getLogger().exception("HutchMenuBrick: error saving snapshot!") logging.getLogger().error("HutchMenuBrick: error saving snapshot!") else: self.formatType=image_type.lower() self.fileIndex+=1 def centredPositionSnapshot(self): matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() fd, name = tempfile.mkstemp() os.close(fd) QubImageSave.save(name, img, self.__drawing.canvas(), zoom, "JPEG") f = open(name, "r") imgcopy = f.read() f.close() os.unlink(name) return imgcopy def getSnapshot(self, img): logging.getLogger().debug("Taking snapshot for centred position") img['data'] = self.centredPositionSnapshot() def cancelCentringClicked(self,reject=False): #print "CANCELCENTRINGCLICKED",reject self.minidiff.cancelCentringMethod(reject=reject) def acceptClicked(self): if self.standardColor is not None: self.buttonAccept.setPaletteBackgroundColor(self.standardColor) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) self.minidiff.acceptCentring() def rejectClicked(self): if self.standardColor is not None: self.buttonReject.setPaletteBackgroundColor(self.standardColor) self.buttonReject.setEnabled(False) self.buttonAccept.setEnabled(False) self.minidiff.rejectCentring() self.insideDataCollection=False def centringMoving(self): self.isMoving=True self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringInvalid(self): if self.collectObj is not None: self.collectObj.setCentringStatus(None) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringAccepted(self,state,centring_status): if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if self.insideDataCollection: self.insideDataCollection = False self.emit(PYSIGNAL("centringAccepted"), (state,centring_status)) beam_info = self.beamInfo.get_beam_info() if beam_info is not None: beam_info['size_x'] = beam_info['size_x'] * self.pixels_per_mm[0] beam_info['size_y'] = beam_info['size_y'] * self.pixels_per_mm[1] self.emit(PYSIGNAL("newCentredPos"), (state, centring_status, beam_info)) if self.queue_hwobj.is_executing(): self.disable() def centringSnapshots(self,state): if state is None: self.isShooting=True self.sampleCentreBox.setEnabled(False) else: self.isShooting=False self.sampleCentreBox.setEnabled(True) def centringStarted(self,method,flexible): self.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (False,)) if self.insideDataCollection: self.emit(PYSIGNAL("centringStarted"), ()) self.isCentring=True self.isMoving=False self.isShooting=False """ for but in self.centringButtons: if str(but.text())==method: if self.defaultBackgroundColor is None: self.defaultBackgroundColor=but.paletteBackgroundColor() but.setPaletteBackgroundColor(QWidget.yellow) self.currentCentring=but break """ self.currentCentring = CentringMethod(method) self.buttonCentre.commandStarted() self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if method == self.minidiff.MANUAL3CLICK_MODE: self.__point.startDrawing() self.__helpLine.startDrawing() self.__pointer.startDrawing() def drawAutoCentringPoint(self, x,y): if -1 in (x,y): self.__autoCentringPoint.hide() return self.__autoCentringPoint.startDrawing() self.__autoCentringPoint.setPoint(x,y) self.__autoCentringPoint.stopDrawing() self.__autoCentringPoint.show() def centringSuccessful(self,method,centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints=[] self.emitWidgetSynchronize() self.buttonCentre.commandDone() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring=None self.buttonAccept.setEnabled(True) self.buttonReject.setEnabled(True) if self.insideDataCollection: if self.standardColor is None: self.standardColor=self.buttonAccept.paletteBackgroundColor() self.buttonAccept.setPaletteBackgroundColor(widget_colors.LIGHT_GREEN) self.buttonReject.setPaletteBackgroundColor(widget_colors.LIGHT_RED) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.isMoving=False self.sampleCentreBox.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: successful_method=self.successfulMethods[method] except KeyError as diag: pass else: try: successful_method() except: pass def centringFailed(self,method,centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints=[] self.emitWidgetSynchronize() self.buttonCentre.commandFailed() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring=None self.buttonAccept.setEnabled(False) if self.insideDataCollection: if self.standardColor is None: self.standardColor=self.buttonAccept.paletteBackgroundColor() self.buttonReject.setEnabled(True) self.buttonReject.setPaletteBackgroundColor(QWidget.red) else: self.buttonReject.setEnabled(False) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: reset_method=self.resetMethods[method] except KeyError as diag: pass else: try: reset_method() except: pass #def movedToBeam(self,x,y): # pass def manualCentreReset(self): self.resetPoints() def automaticCentreReset(self): if not self.userConfirmsButton.isChecked(): self.rejectCentring() def automaticCentreSuccessful(self): if not self.userConfirmsButton.isChecked(): self.acceptCentring() #def moveToBeamSuccessful(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass #def moveToBeamReset(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass def __endDrawingPoint(self,drawingManager) : x,y = drawingManager.point() self.imageClicked(x,y,x,y) # Handler for clicking the video when doing the 3-click centring def imageClicked(self,x,y,xi,yi): if self.currentCentring is not None\ and str(self.currentCentring.text()) == self.minidiff.MANUAL3CLICK_MODE\ and self.minidiff.isReady(): try: points=self.minidiff.imageClicked(x,y,xi,yi) except StopIteration: pass else: self.addPoint(x,y,xi,yi) # Signals a new point in the 3-click centering def addPoint(self,x,y,xi,yi): self.clickedPoints.append((x,y,xi,yi)) self.emitWidgetSynchronize() # Resets the points in the 3-click centering def resetPoints(self): self.clickedPoints=[] self.emitWidgetSynchronize() # Displays a message def showMessageToUser(self,message=None): try: self.__drawing.setInfo(message) except: pass def connectNotify(self, signalName): if signalName=='beamPositionChanged': if self.minidiff and self.beamInfo: if self.minidiff.isReady(): self.beam_position = self.beamInfo.get_beam_position() self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) elif signalName=='calibrationChanged': if self.minidiff and self.minidiff.isReady(): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() self.emit(PYSIGNAL("calibrationChanged"), (1e3 / self.pixels_per_mm[0],\ 1e3 / self.pixels_per_mm[1])) except: pass # Event when the minidiff is in ready state def miniDiffReady(self): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() except: self.pixels_per_mm = [None, None] if self.pixels_per_mm[0] is not None\ and self.pixels_per_mm[1] is not None: self.beam_position = self.beamInfo.get_beam_position() self.beam_size = self.beamInfo.get_beam_size() self.sampleCentreBox.setEnabled(True) self.updateBeam() self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) else: self.miniDiffNotReady() # Event when the minidiff is in notready state def miniDiffNotReady(self): try: self.__beam.hide() except AttributeError: pass if not self.buttonCentre.executing: self.sampleCentreBox.setEnabled(False) def miniDiffStateChanged(self,state): if self.buttonCentre.executing or self.isMoving or self.isShooting: return try: self.sampleCentreBox.setEnabled(state == self.minidiff.phiMotor.READY) except: pass # Displays a message (signaled from the minidiff hardware object) def miniDiffMessage(self,msg=None): self.showMessageToUser(msg) # Update both zoom and slits when started def run(self): if self.minidiff is not None: zoom=self.minidiff.zoomMotor if zoom is not None: if zoom.isReady(): self.zoomPositionChanged(zoom.getCurrentPositionName(),0) keys = {} self.emit(PYSIGNAL('getView'),(keys,)) self.__drawing = keys.get('drawing',None) self.__view = keys.get('view',None) if self.minidiff is not None: self.minidiff._drawing = self.__drawing try: self.__point, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__point.setEndDrawCallBack(self.__endDrawingPoint) self.__point.setColor(Qt.yellow) self.__autoCentringPoint, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__autoCentringPoint.setColor(Qt.green) self.__helpLine, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasVLine) self.__helpLine.setAutoDisconnectEvent(True) self.__helpLine.setExclusive(False) self.__helpLine.setColor(Qt.yellow) self.__rectangularBeam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasSlitbox) self.__rectangularBeam.show() self.__rectangularBeam.setSlitboxSize(0,0) self.__rectangularBeam.setColor(Qt.red) self.__rectangularBeam.setSlitboxPen(QPen(Qt.blue)) self.__beam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasBeam) self.__beam.setPen(QPen(Qt.blue)) self.__beam.hide() self.__pointer, _, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine) self.__pointer.setDrawingEvent(QubMoveNPressed1Point) self.__pointer.setExclusive(False) self.__pointer.setColor(Qt.yellow) self.__scale, scale = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasScale) self.sx = self.__scale.setXPixelSize self.sy = self.__scale.setYPixelSize self.__scale.show() try: self.__scale.setXPixelSize(self.__scaleX) self.__scale.setYPixelSize(self.__scaleY) except AttributeError: pass else: self.emit(PYSIGNAL("calibrationChanged"), (self.__scaleX, self.__scaleY)) self.updateBeam(force=True) except: logging.getLogger().exception("HutchMenuBrick: problem starting up display") def _drawBeam(self): if None in (self.beam_size, self.beam_shape): self.beam_position = self.beamInfo.get_beam_position() self.beam_size = self.beamInfo.get_beam_size() if True: self.__rectangularBeam.show() if None in self.beam_size: return if self.beam_shape == "rectangular": self.__rectangularBeam.setSlitboxSize(self.beam_size[0] * self.pixels_per_mm[0],\ self.beam_size[1] * self.pixels_per_mm[1]) self.__beam.hide() else: self.__rectangularBeam.setSlitboxSize(0,0) self.__beam.setSize(self.beam_size[0] * self.pixels_per_mm[0],\ self.beam_size[1] * self.pixels_per_mm[1]) self.__beam.show() def updateBeam(self,force=False): if self["displayBeam"]: #if self.minidiff: # if not self.minidiff.isReady(): time.sleep(0.2) try: self.__rectangularBeam.set_xMid_yMid(self.beam_position[0], self.beam_position[1]) except AttributeError: pass try: self.__beam.move(self.beam_position[0], self.beam_position[1]) self._drawBeam() #try: # self._updateBeam(self.beamInfo.get_beam_info()) #except: # logging.getLogger().exception("Could not get beam size: cannot display beam") # self.__beam.hide() except AttributeError: pass def beamPosChanged(self, position): self.beam_position = position self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) self.updateBeam(True) def beamInfoChanged(self, beam_info): try: self.beam_position = self.beamInfo.get_beam_position() except: pass self.beam_size = (beam_info["size_x"], beam_info["size_y"]) self.beam_shape = beam_info["shape"] self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) self.updateBeam(True)
class SoleilHutchMenuBrick(BlissWidget): SNAPSHOT_FORMATS = ('png', 'jpeg') def __init__(self, *args): BlissWidget.__init__(self, *args) self.minidiff = None self.beamInfo = None self.sampleChanger=None self.collectObj = None self.queue_hwobj = None self.beam_position = [30, 30] self.beam_size = [0.04, 0.02] self.beam_shape = "Rectangular" self.pixels_per_mm = [0, 0] self.slitbox = None self.sampleChanger=None self.queue_hwobj = None self._bx, self._by = (0, 0) #self.allowMoveToBeamCentring = False # Define properties self.addProperty('minidiff','string','') self.addProperty('beamInfo', 'string', '') self.addProperty('dataCollect','string','') self.addProperty('beamInfo','string','') #self.addProperty('slitbox','string','') self.addProperty('samplechanger','string','') self.addProperty('extraCommands','string','') self.addProperty('extraCommandsIcons','string','') self.addProperty('icons','string','') self.addProperty('label','string','Sample centring') #self.addProperty('displaySlitbox', 'boolean', True) self.addProperty('displayBeam', 'boolean', True) self.addProperty('queue', 'string', '/queue') self.addProperty('useMDPhases', 'boolean', True) # Define signals and slots self.defineSignal('enableMinidiff',()) self.defineSignal('centringStarted',()) self.defineSignal('centringAccepted',()) self.defineSignal('getView',()) self.defineSignal('beamPositionChanged', ()) self.defineSignal('calibrationChanged', ()) self.defineSignal('newCentredPos', ()) #self.defineSignal('setMoveToBeamState', ()) self.defineSlot('setDirectory',()) self.defineSlot('setPrefix',()) #self.defineSlot('movedToBeam', ()) self.defineSlot('startCentring', ()) self.defineSlot('rejectCentring', ()) self.defineSlot('setSample',()) #self.defineSlot('enableAutoStartLoopCentring', ()) self.defineSlot('getSnapshot',()) self.sampleCentreBox=QVBox(self) #self.sampleCentreBox.setInsideMargin(11) #self.sampleCentreBox.setInsideSpacing(0) #self.modeBox=QVButtonGroup(self.sampleCentreBox) #self.modeBox.setFrameShape(self.modeBox.NoFrame) #self.modeBox.setInsideMargin(0) #self.modeBox.setInsideSpacing(0) #QObject.connect(self.modeBox,SIGNAL('clicked(int)'),self.centringModeChanged) #self.userConfirmsButton=QCheckBox("User confirms", self.sampleCentreBox) #self.userConfirmsButton.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) #self.userConfirmsButton.setChecked(True) self.buttonsBox=QVBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.buttonCentre=MenuButton(self.buttonsBox,"Centre") self.buttonCentre.setMinimumSize(QSize(75,50)) self.connect(self.buttonCentre,PYSIGNAL('executeCommand'),self.centreSampleClicked) self.connect(self.buttonCentre,PYSIGNAL('cancelCommand'),self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(75,50)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept,SIGNAL('clicked()'),self.acceptClicked) self.standardColor=None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(75,50)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject,SIGNAL('clicked()'),self.rejectClicked) #HorizontalSpacer4(self.sampleCentreBox) self.extraCommands=CommandMenuBrick.CommandMenuBrick(self.sampleCentreBox) self.extraCommands['showBorder']=False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(75,50)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot,SIGNAL('clicked()'),self.saveSnapshot) #self.buttonToogleMDPhase = QToolButton(self.sampleCentreBox) #self.buttonToogleMDPhase.setUsesTextLabel(True) #self.buttonToogleMDPhase.setTextLabel("MD phase") #self.buttonToogleMDPhase.setMinimumSize(QSize(75,50)) #self.buttonToogleMDPhase.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) #QObject.connect(self.buttonToogleMDPhase,SIGNAL('clicked()'),self.toogleMDPhase) #self.buttonToogleMDPhase.hide() #HorizontalSpacer3(self.sampleCentreBox) self.centringButtons=[] self.defaultBackgroundColor=None self.insideDataCollection=False self.currentCentring = None self.isMoving=False self.isShooting=False self.directory="/tmp" self.prefix="snapshot" self.fileIndex=1 self.formatType="png" self.clickedPoints=[] self.selectedSamples=None # Layout self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) QHBoxLayout(self) self.layout().addWidget(self.sampleCentreBox) self.instanceSynchronize("") self.resetMethods={MiniDiff.MiniDiff.MANUAL3CLICK_MODE:self.manualCentreReset, MiniDiff.MiniDiff.C3D_MODE:self.automaticCentreReset} #MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamReset} self.successfulMethods={MiniDiff.MiniDiff.MANUAL3CLICK_MODE:None, MiniDiff.MiniDiff.C3D_MODE:self.automaticCentreSuccessful} #MiniDiff.MiniDiff.MOVE_TO_BEAM_MODE:self.moveToBeamSuccessful} self.sampleCentreBox.hide() self.sampleCentreBox = QHBox(self) self.buttonsBox=QHBox(self.sampleCentreBox) self.buttonsBox.setSpacing(0) self.sampleCentreBox.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) self.buttonsBox.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) self.layout().addWidget(self.sampleCentreBox) self.buttonCentre=MenuButton(self.buttonsBox,"Centre") self.buttonCentre.setMinimumSize(QSize(50,40)) self.connect(self.buttonCentre,PYSIGNAL('executeCommand'),self.centreSampleClicked) self.connect(self.buttonCentre,PYSIGNAL('cancelCommand'),self.cancelCentringClicked) self.buttonAccept = QToolButton(self.buttonsBox) self.buttonAccept.setUsesTextLabel(True) self.buttonAccept.setTextLabel("Save") self.buttonAccept.setMinimumSize(QSize(50,40)) self.buttonAccept.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonAccept.setEnabled(False) QObject.connect(self.buttonAccept,SIGNAL('clicked()'),self.acceptClicked) self.standardColor=None self.buttonReject = QToolButton(self.buttonsBox) self.buttonReject.setUsesTextLabel(True) self.buttonReject.setTextLabel("Reject") self.buttonReject.setMinimumSize(QSize(50,40)) self.buttonReject.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonReject.setEnabled(False) self.buttonReject.hide() QObject.connect(self.buttonReject,SIGNAL('clicked()'),self.rejectClicked) self.extraCommands=CommandMenuBrick.CommandMenuBrick(self.sampleCentreBox) self.extraCommands['showBorder']=False self.buttonSnapshot = QToolButton(self.sampleCentreBox) self.buttonSnapshot.setUsesTextLabel(True) self.buttonSnapshot.setTextLabel("Snapshot") self.buttonSnapshot.setMinimumSize(QSize(50,40)) self.buttonSnapshot.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) QObject.connect(self.buttonSnapshot,SIGNAL('clicked()'),self.saveSnapshot) self.buttonBeamPosition = QToolButton(self.sampleCentreBox) self.buttonBeamPosition.setUsesTextLabel(True) self.buttonBeamPosition.setTextLabel("BeamPosition") self.buttonBeamPosition.setMinimumSize(QSize(50,40)) self.buttonBeamPosition.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonBeamPosition.setPixmap(Icons.load("green_led")) QObject.connect(self.buttonBeamPosition, SIGNAL('clicked()'), self.beamPositionCheck) self.buttonApertureAlign = QToolButton(self.sampleCentreBox) self.buttonApertureAlign.setUsesTextLabel(True) self.buttonApertureAlign.setTextLabel("ApertureAlign") self.buttonApertureAlign.setMinimumSize(QSize(50,40)) self.buttonApertureAlign.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.buttonApertureAlign.setPixmap(Icons.load("Align")) QObject.connect(self.buttonApertureAlign, SIGNAL('clicked()'), self.apertureAlign) def beamPositionCheck(self): self.minidiff.beamPositionCheck() def apertureAlign(self): self.minidiff.apertureAlign() def enableAutoStartLoopCentring(self, enable): if self.minidiff is not None: self.minidiff.enableAutoStartLoopCentring(enable) def propertyChanged(self,propertyName,oldValue,newValue): #print "HutchMenuBrick.propertyChanged",property,newValue if propertyName=='minidiff': if self.minidiff is not None: self.disconnect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.disconnect(self.minidiff,PYSIGNAL('minidiffReady'),self.miniDiffReady) self.disconnect(self.minidiff,PYSIGNAL('minidiffNotReady'),self.miniDiffNotReady) self.disconnect(self.minidiff,PYSIGNAL('minidiffStateChanged'),self.miniDiffStateChanged) self.disconnect(self.minidiff,PYSIGNAL('centringStarted'),self.centringStarted) self.disconnect(self.minidiff,PYSIGNAL('centringSuccessful'),self.centringSuccessful) self.disconnect(self.minidiff,PYSIGNAL('centringFailed'),self.centringFailed) self.disconnect(self.minidiff,PYSIGNAL('centringMoving'),self.centringMoving) self.disconnect(self.minidiff,PYSIGNAL('centringInvalid'),self.centringInvalid) self.disconnect(self.minidiff,PYSIGNAL('centringSnapshots'),self.centringSnapshots) self.disconnect(self.minidiff,PYSIGNAL('progressMessage'),self.miniDiffMessage) self.disconnect(self.minidiff,PYSIGNAL('newAutomaticCentringPoint'),self.drawAutoCentringPoint) self.disconnect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'), self.zoomPositionChanged) self.disconnect(self.minidiff,PYSIGNAL('centringAccepted'),self.centringAccepted) self.minidiff=self.getHardwareObject(newValue) if self.minidiff is not None: self.connect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'),self.zoomPositionChanged) self.connect(self.minidiff,PYSIGNAL('minidiffReady'),self.miniDiffReady) self.connect(self.minidiff,PYSIGNAL('minidiffNotReady'),self.miniDiffNotReady) self.connect(self.minidiff,PYSIGNAL('minidiffStateChanged'),self.miniDiffStateChanged) self.connect(self.minidiff,PYSIGNAL('centringStarted'),self.centringStarted) self.connect(self.minidiff,PYSIGNAL('centringSuccessful'),self.centringSuccessful) self.connect(self.minidiff,PYSIGNAL('centringFailed'),self.centringFailed) self.connect(self.minidiff,PYSIGNAL('centringMoving'),self.centringMoving) self.connect(self.minidiff,PYSIGNAL('centringInvalid'),self.centringInvalid) self.connect(self.minidiff,PYSIGNAL('centringSnapshots'),self.centringSnapshots) self.connect(self.minidiff,PYSIGNAL('progressMessage'),self.miniDiffMessage) self.connect(self.minidiff, "newAutomaticCentringPoint", self.drawAutoCentringPoint) self.connect(self.minidiff,PYSIGNAL('zoomMotorPredefinedPositionChanged'),self.zoomPositionChanged) self.connect(self.minidiff,PYSIGNAL('centringAccepted'),self.centringAccepted) if self.minidiff.isReady(): self.miniDiffReady() else: self.miniDiffNotReady() else: self.miniDiffNotReady() #elif propertyName=='slitbox': # if self.slitbox is not None: # for role in ('s1v', 's2v', 's1h', 's2h'): # m = self.slitbox.getDeviceByRole(role) # m.disconnect('stateChanged', self.slitsPositionChanged) # self.slitbox=self.getHardwareObject(newValue) # if self.slitbox is not None: # for role in ('s1v', 's2v', 's1h', 's2h'): # m = self.slitbox.getDeviceByRole(role) # m.connect("stateChanged", self.slitsPositionChanged) # #self.slitsPositionChanged() elif propertyName=="beamInfo": if self.beamInfo is not None: self.disconnect(self.beamInfo,PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.disconnect(self.beamInfo,PYSIGNAL('beamPosChanged'), self.beamPosChanged) self.beamInfo=self.getHardwareObject(newValue) if self.beamInfo is not None: self.connect(self.beamInfo,PYSIGNAL('beamInfoChanged'), self.beamInfoChanged) self.connect(self.beamInfo,PYSIGNAL('beamPosChanged'), self.beamPosChanged) elif propertyName=="samplechanger": self.sampleChanger=self.getHardwareObject(newValue) elif propertyName=="dataCollect": self.collectObj=self.getHardwareObject(newValue) elif propertyName == 'icons': self.setIcons(newValue) elif propertyName=='label': pass #self.sampleCentreBox.setTitle(newValue) elif propertyName=='extraCommands': self.extraCommands['mnemonic']=newValue elif propertyName=='extraCommandsIcons': self.extraCommands['icons']=newValue elif propertyName=='queue': self.queue_hwobj = self.getHardwareObject(newValue) else: BlissWidget.propertyChanged(self,propertyName,oldValue,newValue) def setIcons(self,icons): icons_list=icons.split() try: self.buttonCentre.setIcons(icons_list[0],icons_list[1]) except IndexError: pass try: self.buttonAccept.setPixmap(Icons.load(icons_list[2])) except IndexError: pass try: self.buttonSnapshot.setPixmap(Icons.load(icons_list[3])) except IndexError: pass try: self.buttonReject.setPixmap(Icons.load(icons_list[4])) except IndexError: pass def setDirectory(self,directory): self.directory=str(directory) self.fileIndex=1 def setPrefix(self,prefix): self.prefix=str(prefix) self.fileIndex=1 def setSample(self,samples_list): self.selectedSamples = samples_list try: blsampleid=int(self.selectedSamples[0][0]) except: blsampleid=None try: self.minidiff.setSampleInfo({"blsampleid":blsampleid}) except: pass def emitWidgetSynchronize(self): #mode=self.modeBox.selectedId() points=self.clickedPoints #self.emit(PYSIGNAL("widgetSynchronize"),( (mode,points), )) self.emit(PYSIGNAL("widgetSynchronize"),( (points), )) def widgetSynchronize(self,state): #centring_method=state[0] #clicked_points=state[1] clicked_points=state[0] #self.modeBox.setButton(centring_method) if len(clicked_points): point=clicked_points[-1] self.__point.startDrawing() self.__point.show() self.__point.setPoint(point[0],point[1]) self.__point.stopDrawing() else: self.__point.hide() def startCentring(self): # this is called from another brick, not by user self.insideDataCollection=True self.centreSampleClicked() def rejectCentring(self): self.cancelCentringClicked(reject=True) def acceptCentring(self): self.acceptClicked() def centreSampleClicked(self): self.minidiff.startCentringMethod(self.minidiff.MANUAL3CLICK_MODE) def saveSnapshot(self): formats="" for format in SoleilHutchMenuBrick.SNAPSHOT_FORMATS: formats+="*.%s " % format formats=formats.strip() current_filename=os.path.join(self.directory, self.prefix) current_filename=current_filename + '_%d%s%s' % (self.fileIndex, os.path.extsep, self.formatType) filename=str(QFileDialog.getSaveFileName(current_filename,"Images (%s)" % formats,\ self,None,"Choose a filename to save under",None,False)) if len(filename): image_type=os.path.splitext(filename)[1].strip('.').upper() try: matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() logging.getLogger().info("Saving snapshot : %s", filename) QubImageSave.save(filename, img, self.__drawing.canvas(), zoom, image_type) except: logging.getLogger().exception("HutchMenuBrick: error saving snapshot!") logging.getLogger().error("HutchMenuBrick: error saving snapshot!") else: self.formatType=image_type.lower() self.fileIndex+=1 def centredPositionSnapshot(self): matrix = self.__drawing.matrix() zoom = 1 if matrix is not None: zoom = matrix.m11() img = self.__drawing.getPPP() fd, name = tempfile.mkstemp() os.close(fd) QubImageSave.save(name, img, self.__drawing.canvas(), zoom, "JPEG") f = open(name, "r") imgcopy = f.read() f.close() os.unlink(name) return imgcopy def getSnapshot(self, img): logging.getLogger().debug("Taking snapshot for centred position") img['data'] = self.centredPositionSnapshot() def cancelCentringClicked(self,reject=False): #print "CANCELCENTRINGCLICKED",reject self.minidiff.cancelCentringMethod(reject=reject) def acceptClicked(self): if self.standardColor is not None: self.buttonAccept.setPaletteBackgroundColor(self.standardColor) #logging.info("disabling accept because accept was clicked") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) self.minidiff.acceptCentring() def rejectClicked(self): if self.standardColor is not None: self.buttonReject.setPaletteBackgroundColor(self.standardColor) #logging.info("disabling accept because reject was clicked") self.buttonReject.setEnabled(False) self.buttonAccept.setEnabled(False) self.minidiff.rejectCentring() self.insideDataCollection=False def centringMoving(self): self.isMoving=True logging.info("disabling accept because centring is moving ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringInvalid(self): if self.collectObj is not None: self.collectObj.setCentringStatus(None) logging.info("disabling accept because centring is invalid ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) def centringAccepted(self,state,centring_status): logging.info("Centring has been accepted") if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) logging.info("disabling accept because centring has been accepted ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if self.insideDataCollection: self.insideDataCollection = False self.emit(PYSIGNAL("centringAccepted"), (state,centring_status)) if self.beamInfo is not None: beam_info = self.beamInfo.get_beam_info() if beam_info is not None: beam_info['size_x'] = beam_info['size_x'] * self.pixels_per_mm[0] beam_info['size_y'] = beam_info['size_y'] * self.pixels_per_mm[1] self.emit(PYSIGNAL("newCentredPos"), (state, centring_status, beam_info)) #self.emit(PYSIGNAL("newCentredPos"), (state, centring_status)) if self.queue_hwobj.is_executing(): self.setEnabled(False) def centringSnapshots(self,state): if state is None: self.isShooting=True self.sampleCentreBox.setEnabled(False) else: self.isShooting=False self.sampleCentreBox.setEnabled(True) def centringStarted(self,method,flexible): self.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (False,)) if self.insideDataCollection: self.emit(PYSIGNAL("centringStarted"), ()) self.isCentring=True self.isMoving=False self.isShooting=False """ for but in self.centringButtons: if str(but.text())==method: if self.defaultBackgroundColor is None: self.defaultBackgroundColor=but.paletteBackgroundColor() but.setPaletteBackgroundColor(QWidget.yellow) self.currentCentring=but break """ self.currentCentring = CentringMethod(method) self.buttonCentre.commandStarted() logging.info("disabling accept because centring has been started ") self.buttonAccept.setEnabled(False) self.buttonReject.setEnabled(False) if method==MiniDiff.MiniDiff.MANUAL3CLICK_MODE: self.__point.startDrawing() self.__helpLine.startDrawing() self.__pointer.startDrawing() def drawAutoCentringPoint(self, x,y): if -1 in (x,y): self.__autoCentringPoint.hide() return self.__autoCentringPoint.startDrawing() self.__autoCentringPoint.setPoint(x,y) self.__autoCentringPoint.stopDrawing() self.__autoCentringPoint.show() def centringSuccessful(self,method,centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() #logging.info("HutchMenuBrick: centringSuccesful received") self.clickedPoints=[] self.emitWidgetSynchronize() self.buttonCentre.commandDone() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring=None self.buttonAccept.setEnabled(True) self.buttonReject.setEnabled(True) if self.insideDataCollection: if self.standardColor is None: self.standardColor=self.buttonAccept.paletteBackgroundColor() self.buttonAccept.setPaletteBackgroundColor(widget_colors.LIGHT_GREEN) self.buttonReject.setPaletteBackgroundColor(widget_colors.LIGHT_RED) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.isMoving=False self.sampleCentreBox.setEnabled(True) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: successful_method=self.successfulMethods[method] except KeyError as diag: pass else: try: successful_method() except: pass def centringFailed(self,method,centring_status): self.__point.stopDrawing() self.__point.hide() self.__helpLine.hide() self.__helpLine.stopDrawing() self.__pointer.stopDrawing() self.__pointer.hide() self.clickedPoints=[] self.emitWidgetSynchronize() self.buttonCentre.commandFailed() if self.currentCentring is not None: # self.currentCentring.setPaletteBackgroundColor(self.defaultBackgroundColor) self.currentCentring=None logging.info("disabling accept because centing failed") self.buttonAccept.setEnabled(False) if self.insideDataCollection: if self.standardColor is None: self.standardColor=self.buttonAccept.paletteBackgroundColor() self.buttonReject.setEnabled(True) self.buttonReject.setPaletteBackgroundColor(QWidget.red) else: self.buttonReject.setEnabled(False) if self.collectObj is not None: self.collectObj.setCentringStatus(centring_status) self.emit(PYSIGNAL("enableMinidiff"), (True,)) try: reset_method=self.resetMethods[method] except KeyError as diag: pass else: try: reset_method() except: pass #def movedToBeam(self,x,y): # pass def manualCentreReset(self): self.resetPoints() def automaticCentreReset(self): if not self.userConfirmsButton.isChecked(): self.rejectCentring() def automaticCentreSuccessful(self): if not self.userConfirmsButton.isChecked(): self.acceptCentring() #def moveToBeamSuccessful(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass #def moveToBeamReset(self): #self.emit(PYSIGNAL("setMoveToBeamState"), (False,)) # pass def __endDrawingPoint(self,drawingManager) : x,y = drawingManager.point() self.imageClicked(x,y,x,y) # Handler for clicking the video when doing the 3-click centring def imageClicked(self,x,y,xi,yi): #print "HutchMenuBrick.imageClicked",self.minidiff,self.manualCentering if self.currentCentring is not None and str(self.currentCentring.text())==MiniDiff.MiniDiff.MANUAL3CLICK_MODE and self.minidiff.isReady(): try: points=self.minidiff.imageClicked(x,y,xi,yi) except StopIteration: pass else: self.addPoint(x,y,xi,yi) # Signals a new point in the 3-click centering def addPoint(self,x,y,xi,yi): self.clickedPoints.append((x,y,xi,yi)) self.emitWidgetSynchronize() # Resets the points in the 3-click centering def resetPoints(self): self.clickedPoints=[] self.emitWidgetSynchronize() # Displays a message def showMessageToUser(self,message=None): #print "showMessage",message try: self.__drawing.setInfo(message) except: pass def connectNotify(self, signalName): print("..... HutchMenuBrick:connectNotify ", signalName) if signalName=='beamPositionChanged': if self.minidiff and self.minidiff.isReady() and self.beamInfo is not None: self.beam_position = self.beamInfo.get_beam_position() self.pixels_per_mm = self.minidiff.get_pixels_per_mm() self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) #if self.minidiff and self.minidiff.isReady(): # beam_xc = self.minidiff.getBeamPosX() # beam_yc = self.minidiff.getBeamPosY() # pxmmy=self.minidiff.pixelsPerMmY # pxmmz=self.minidiff.pixelsPerMmZ # # self.emit(PYSIGNAL("beamPositionChanged"), (beam_xc, beam_yc, # self._bx, self._by)) elif signalName=='calibrationChanged': if self.minidiff and self.minidiff.isReady(): try: #self.emit(PYSIGNAL("calibrationChanged"), (1e3/self.minidiff.pixelsPerMmY, 1e3/self.minidiff.pixelsPerMmZ)) self.emit(PYSIGNAL("calibrationChanged"), (1e3/self.pixels_per_mm[0], 1e3/self.pixels_per_mm[1])) except: pass # Event when the minidiff is in ready state def miniDiffReady(self): try: self.pixels_per_mm = self.minidiff.get_pixels_per_mm() if self.beamInfo is not None: self.beam_position = self.beamInfo.get_beam_position() except: import traceback logging.getLogger().error("error on minidiff ready %s", traceback.format_exc()) self.pixels_per_mm = [None, None] #pxmmy=None #pxmmz=None #if pxmmy is not None and pxmmz is not None: if self.beamInfo is not None: if self.pixels_per_mm[0] is not None and self.pixels_per_mm[1] is not None: self.sampleCentreBox.setEnabled(True) self.updateBeam() #self.emit(PYSIGNAL("beamPositionChanged"), (beam_xc, beam_yc, self._bx, self._by)) self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0], self.beam_position[1], self.beam_size[0], self.beam_size[1])) else: self.miniDiffNotReady() # Event when the minidiff is in notready state def miniDiffNotReady(self): #import pdb; pdb.set_trace() try: self.__beam.hide() except AttributeError: pass if not self.buttonCentre.executing: self.sampleCentreBox.setEnabled(False) def miniDiffStateChanged(self,state): if self.buttonCentre.executing or self.isMoving or self.isShooting: return try: self.sampleCentreBox.setEnabled(state==self.minidiff.phiMotor.READY) except: pass # Displays a message (signaled from the minidiff hardware object) def miniDiffMessage(self,msg=None): #print "MINIDIFF MESSAGE!!!",msg self.showMessageToUser(msg) # Update both zoom and slits when started def run(self): logging.getLogger().info("HucthMenuBrick runs") if self.minidiff is not None: zoom=self.minidiff.zoomMotor if zoom is not None: if zoom.isReady(): self.zoomPositionChanged(zoom.getCurrentPositionName(),0) keys = {} self.emit(PYSIGNAL('getView'),(keys,)) self.__drawing = keys.get('drawing',None) self.__view = keys.get('view',None) if self.minidiff is not None: self.minidiff._drawing = self.__drawing try: self.__point, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__point.setEndDrawCallBack(self.__endDrawingPoint) self.__point.setColor(Qt.yellow) self.__autoCentringPoint, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasTarget) self.__autoCentringPoint.setColor(Qt.green) self.__helpLine, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasVLine) self.__helpLine.setAutoDisconnectEvent(True) self.__helpLine.setExclusive(False) self.__helpLine.setColor(Qt.yellow) logging.getLogger().info("HutchMenuBrick help line OK") self.__rectangularBeam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasSlitbox) self.__rectangularBeam.set_xMid_yMid(self.beam_position[0], self.beam_position[1]) self.__rectangularBeam.show() self.__rectangularBeam.setSlitboxSize(0,0) self.__rectangularBeam.setColor(Qt.red) self.__rectangularBeam.setSlitboxPen(QPen(Qt.blue)) #self.beam_position = self.beamInfo.get_beam_position() logging.getLogger().info("HutchMenuBrick rectangular beam OK") self.__beam, _ = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasBeam) self.__beam.setPen(QPen(Qt.blue)) self.__beam.hide() logging.getLogger().info("HutchMenuBrick beam setPen successful") self.__pointer, _, _ = QubAddDrawing(self.__drawing, QubPointDrawingMgr, QubCanvasHLine, QubCanvasVLine) self.__pointer.setDrawingEvent(QubMoveNPressed1Point) self.__pointer.setExclusive(False) self.__pointer.setColor(Qt.yellow) logging.getLogger().info("HutchMenuBrick runs. pointer successful") self.__scale, scale = QubAddDrawing(self.__drawing, QubContainerDrawingMgr, QubCanvasScale) self.sx = self.__scale.setXPixelSize self.sy = self.__scale.setYPixelSize self.__scale.show() logging.getLogger().info("HutchMenuBrick runs. Scale just changed") try: self.__scale.setXPixelSize(self.__scaleX) self.__scale.setYPixelSize(self.__scaleY) except AttributeError: pass else: self.emit(PYSIGNAL("calibrationChanged"), (self.__scaleX, self.__scaleY)) #self.slitsPositionChanged() logging.getLogger().info("HutchMenuBrick runs. It will now update the beam drawing") self.__rectangularBeam.set_xMid_yMid(self.beam_position[0], self.beam_position[1]) logging.getLogger().info("HutchMenuBrick setting rectangular beam xMid, yMid to %s, %s" % (self.beam_position[0], self.beam_position[1])) self.updateBeam(force=True) except: import traceback logging.getLogger().debug("HutchMenuBrick: problem starting up display") logging.getLogger().exception( traceback.format_exc()) else: logging.getLogger().info("HucthMenuBrick runs cool") def _drawBeam(self): try: self.__rectangularBeam.show() #if None in (self._by, self._bx): if None in self.beam_size: return #bx = self._bx #by = self._by #pxmmy=self.minidiff.pixelsPerMmY #pxmmz=self.minidiff.pixelsPerMmZ #if self._bshape == "rectangular": # self.__rectangularBeam.setSlitboxSize(bx*pxmmy, by*pxmmz) if self.beam_shape == "rectangular": self.__rectangularBeam.setSlitboxSize(self.beam_size[0] * self.pixels_per_mm[0],\ self.beam_size[1] * self.pixels_per_mm[1]) self.__beam.hide() else: self.__rectangularBeam.setSlitboxSize(0,0) self.__beam.setSize(self.beam_size[0] * self.pixels_per_mm[0],\ self.beam_size[1] * self.pixels_per_mm[1]) logging.getLogger().info("beam drawn with size %s " % str(self.beam_size)) #self.__beam.setSize(bx*pxmmy, by*pxmmz) self.__beam.show() except: pass def _updateBeam(self, ret): logging.info("UPDATE BEAM %s", ret) self._bx = float(ret["size_x"]) self._bshape = ret["shape"] self._by = float(ret["size_y"]) self._drawBeam() def updateBeam(self,force=False): logging.getLogger().info("updating beam " ) if self.minidiff is None: return if self["displayBeam"]: if not self.minidiff.isReady(): time.sleep(0.2) #beam_x = self.minidiff.getBeamPosX() #beam_y = self.minidiff.getBeamPosY() try: logging.getLogger().info("self %s" % str(self)) self.__rectangularBeam.set_xMid_yMid(self.beam_position[0], self.beam_position[1]) logging.getLogger().info("rectangle drawn at position %s " % str(self.beam_position)) #self.__rectangularBeam.set_xMid_yMid(beam_x,beam_y) except AttributeError: import traceback logging.getLogger().info("update beam failed 1" + traceback.format_exc()) pass try: self.__beam.move(self.beam_position[0], self.beam_position[1]) self._drawBeam() except AttributeError: logging.getLogger().info("update beam failed 2") import traceback logging.getLogger().info("update beam failed 2" + traceback.format_exc()) def beamPosChanged(self, position): logging.getLogger().info("hutch menu brick. Beam position chagned. It is %s" % str(position)) self.beam_position = position self.emit(PYSIGNAL("beamPositionChanged"), (self.beam_position[0],\ self.beam_position[1], self.beam_size[0],\ self.beam_size[1])) self.updateBeam(True) def beamInfoChanged(self, beam_info): logging.getLogger().info("hutch menu brick. Beam info chagned. It is %s" % str(beam_info)) self.beam_size = (beam_info["size_x"], beam_info["size_y"]) self.beam_shape = beam_info["shape"] self.updateBeam(True) # Zoom changed: update pixels per mm def zoomPositionChanged(self,position,offset): pxmmy, pxmmz, pxsize_y, pxsize_z = None,None,None,None print("** HutchMenuBrick: zoomPositionChanged", position,offset) if offset is None: # unknown zoom pos. try: self.__scale.hide() self.__rectangularBeam.hide() self.__beam.hide() except AttributeError: print("&&& zoomPositionChanged AttributeError") self.__scaleX = None self.__scaleY = None else: if self.minidiff is not None: #pxmmy=self.minidiff.pixelsPerMmY #pxmmz=self.minidiff.pixelsPerMmZ self.pixels_per_mm = self.minidiff.get_pixels_per_mm() if self.pixels_per_mm[0] is not None and self.pixels_per_mm[1] is not None: pxsize_y = 1e-3 / self.pixels_per_mm[0] pxsize_z = 1e-3 / self.pixels_per_mm[1] try: self.sx(pxsize_y) self.sy(pxsize_z) except AttributeError: self.__scaleX = pxsize_y self.__scaleY = pxsize_z else: self.emit(PYSIGNAL("calibrationChanged"), (pxsize_y, pxsize_z)) self.updateBeam(True) #self._drawBeam() self.__scale.show() # Slits changed: update beam size def slitsPositionChanged(self, *args): if self.minidiff is None or self.slitbox is None or self.minidiff.pixelsPerMmY is None or self.minidiff.pixelsPerMmZ is None: pass else: self.updateBeam(force=True)