Exemplo n.º 1
0
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 CameraOffLineImageManagerBrick(BlissWidget):
    def __init__(self,parent,name,**keys) :
        BlissWidget.__init__(self,parent,name)
        self.__hMotor = None
        self.__vMotor = None
        self.__motor_pos_save = []
        self.__master_motor = None
        self.__masterPosition2Item = weakref.WeakValueDictionary()
        self.__currentCalib = None
        self.__currentBeamPos = None
        self.__camDecompNPlug = None
        self.mosaicView = None
        self.drawing = None
        self.__saveImageTreeDirName = '.'
        self.__imageMosaicPosition = None
                       ####### Property #######
        self.addProperty('horizontal','string','')
        self.addProperty('vertical','string','')
        self.addProperty('save_motors','string','')
        self.addProperty('master_motor','string','')
        self.addProperty('focus_motor','string','')
        self.addProperty('live_camera','string','')
        self.addProperty("formatString", "formatString", "###.##")
                        ####### SIGNAL #######
        self.defineSignal("getImage",())
        self.defineSignal('getView',())
        self.defineSignal('getMosaicView',())
                         ####### SLOT #######
        self.defineSlot("ChangePixelCalibration", ())
        self.defineSlot("ChangeBeamPosition", ())
        self.defineSlot('setMosaicImageSelected',())
        
        self.__widgetTree = self.loadUIFile('CameraOffLineImageManager.ui')
        self.__frame = self.__widgetTree.child('__frame')
        self.__frame.reparent(self,qt.QPoint(0,0))
        layout = qt.QHBoxLayout(self)
        layout.addWidget(self.__frame)
        
        snapButton = self.child('__snapShoot')
        iconSet = qt.QIconSet(loadIcon("snapshot.png"))
        snapButton.setIconSet(iconSet)
        qt.QObject.connect(snapButton,qt.SIGNAL('clicked()'),self.__snapCBK)

        liveCheckBox = self.child('__liveCheckBox')
        liveCheckBox.hide()
        qt.QObject.connect(liveCheckBox,qt.SIGNAL('toggled(bool)'),self.__liveOnOff)
        

        self.__imageList = self.child('__imageList')
        self.__imageList.setSelectionMode(qt.QListView.Extended)
        self.__imageList.setSortColumn(-1)
        self.__popUpMenu = qt.QPopupMenu(self)
        self.__popUpMenu.insertItem('layer up',self.__layerUp)
        self.__popUpMenu.insertItem('layer down',self.__layerDown)
        self.__popUpMenu.insertItem('remove',self.__removeImage)

        self.__popUpMenu.insertSeparator()
        self.__popUpMenu.insertItem('load',self.__loadImageTree)
        self.__popUpMenu.insertItem('save',self.__saveImageTree)

        qt.QObject.connect(self.__imageList,qt.SIGNAL('rightButtonPressed(QListViewItem*,const QPoint &,int)'),
                           self.__popUpDisplay)

    def propertyChanged(self,propertyName,oldValue,newValue) :
        if propertyName == 'horizontal' :
            if self.__hMotor:
                self.disconnect(self.__hMotor, qt.PYSIGNAL("positionChanged"), self.__hMotorPositionChanged)
            self.__hMotor = self.getHardwareObject(newValue)
            self.connect(self.__hMotor, qt.PYSIGNAL("positionChanged"), self.__hMotorPositionChanged)
            self.connect(self.__hMotor,qt.PYSIGNAL("limitsChanged"),self.__hMotorLimitsChanged)
        elif propertyName == 'vertical' :
            if self.__vMotor:
                self.disconnect(self.__vMotor, qt.PYSIGNAL("positionChanged"), self.__vMotorPositionChanged)
            self.__vMotor = self.getHardwareObject(newValue)
            self.connect(self.__vMotor, qt.PYSIGNAL("positionChanged"), self.__vMotorPositionChanged)
            self.connect(self.__vMotor,qt.PYSIGNAL("limitsChanged"),self.__vMotorLimitsChanged)

        elif propertyName == 'save_motors' :
            equipment = self.getHardwareObject(newValue)
            self.__motor_pos_save = []
            if equipment :
                try:
                    ho = equipment['motors']
                except KeyError:
                    print(equipment.userName(), 'is not an Equipment : no <motors> section.')
                    return
                for motor in ho.getDevices() :
                    self.__motor_pos_save.append(motor)

                #Refresh Tree column
                nbColumn = self.__imageList.columns()
                for columnId in range(1,self.__imageList.columns()) :
                    self.__imageList.removeColumn(columnId)
                for motor in self.__motor_pos_save:
                    self.__imageList.addColumn(motor.userName())
        elif propertyName == 'master_motor':
            if self.__master_motor is not None:
                self.__imageList.takeItem(self.__masterControler)
            self.__master_motor = self.getHardwareObject(newValue)
            if self.__master_motor is not None:
                self.__masterControler = qt.QCheckListItem(self.__imageList,self.__master_motor.userName())
                self.__masterControler.setSelectable(False)
                self.__masterControler.setOpen(True)
        elif propertyName == 'focus_motor':
            self.__focus_motor = self.getHardwareObject(newValue)
            moveFocusCheckBox = self.child('__moveFocusCheckBox')
            if self.__focus_motor is not None:
                moveFocusCheckBox.show()
            else:
                moveFocusCheckBox.hide()
        elif propertyName == 'live_camera' :
            if self.__camDecompNPlug :
                camera,decomp,_ = self.__camDecompNPlug
                self.disconnect(camera,qt.PYSIGNAL('imageReceived'),decomp.putData)
                self.__camDecompNPlug = None
                
            camera = self.getHardwareObject(newValue)
            liveCheckBox = self.child('__liveCheckBox')
            if camera is not None:
                decomp = QubStdData2Image()
                plug = _LiveImagePlug(self)
                decomp.plug(plug)

                imageInfo = camera.imageType()
                if imageInfo and imageInfo.type() == 'bayer': imType = decomp.BAYER_RG
                elif imageInfo and imageInfo.type() == 'raw': imType = decomp.RAW
                else: imType = decomp.STANDARD # JPEG
                decomp.setImageType(imType)

                self.__camDecompNPlug = camera,decomp,plug

                liveCheckBox.show()
            else:
                liveCheckBox.hide()
        elif propertyName == 'formatString':
            self._formatString = self['formatString']
            
    def ChangePixelCalibration(self,sizeX,sizeY) :
        if sizeX is not None and sizeY is not None:
            motorXUnit = self.__hMotor.getProperty('unit')
            if motorXUnit is None : motorXUnit = 1e-3

            motorYUnit = self.__vMotor.getProperty('unit')
            if motorYUnit is None : motorYUnit = 1e-3

            self.__currentCalib = sizeX / motorXUnit,sizeY / motorYUnit

            if self.__camDecompNPlug :
                camera,decomp,plug = self.__camDecompNPlug
                plug.setPixelCalibration(*self.__currentCalib)
        else:
            self.__currentCalib = None
            
    def ChangeBeamPosition(self,x,y) :
        self.__currentBeamPos = x,y
        if self.__camDecompNPlug :
            camera,decomp,plug = self.__camDecompNPlug
            plug.setBeamPosition(*self.__currentBeamPos)

    def setMosaicImageSelected(self,imageSelectedID) :
        moveFocusCheckBox = self.child('__moveFocusCheckBox')
        if moveFocusCheckBox.isChecked() :
            position = self.__focus_motor.getPosition()
            def _recursfind(item,lookinId) :
                while item:
                    if id(item) == lookinId:
                        return item
                    else:
                        returnItem = _recursfind(item.firstChild(),lookinId)
                        if returnItem: return returnItem
                        item = item.nextSibling()
            item = _recursfind(self.__imageList.firstChild(),imageSelectedID)
            try:
                if item and item.focusMotorPosition != position:
                    self.__focus_motor.move(item.focusMotorPosition)
            except AttributeError:
                pass
    def __displayMotorsPositionUnderMouse(self,drawingManager) :
        point = drawingManager.mosaicPoints()
        try:
            point = point[0]
            beamY,beamZ = point.refPoint
            YSize,ZSize = point.calibration
            horMotorPos,verMotorPos = point.absPoint
            y,z = point.point
            imageId = point.imageId
        except TypeError: return
        movetoy = horMotorPos - (beamY - y) * YSize
        movetoz = verMotorPos - (beamZ - z) * ZSize

        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(QubRulerAction.HORIZONTAL,1,
                                                         movetoy)
            self.__imageMosaicPosition.setCursorPosition(QubRulerAction.VERTICAL,1,
                                                         movetoz)
            self.__mouseMotorPosition.setXValue(movetoy)
            self.__mouseMotorPosition.setYValue(movetoz)
            
    def __hMotorPositionChanged(self,position) :
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(QubRulerAction.HORIZONTAL, 0,
                                                         position)
            self.__currentMotorPosition.setXValue(position)
            
        if self.__camDecompNPlug :
            camera,decomp,plug = self.__camDecompNPlug
            plug.setHMotorPosition(position)
            
    def __hMotorLimitsChanged(self,limit) :
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,0,
                                                 *limit)
            self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,1,
                                                 *limit)
        
    def __vMotorPositionChanged(self,position) :
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(QubRulerAction.VERTICAL, 0,
                                                         position)
            self.__currentMotorPosition.setYValue(position)
        if self.__camDecompNPlug :
            camera,decomp,plug = self.__camDecompNPlug
            plug.setVMotorPosition(position)

    def __vMotorLimitsChanged(self,limit) :
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,0,
                                                 *limit)
            self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,1,
                                                 *limit)
        
    def __getMasterItem(self,position = None) :
        if self.__master_motor is not None:
            if position is None:
                position = self.__master_motor.getPosition()
            try:
                master_item = self.__masterPosition2Item[position]
            except KeyError:
                positionString = self._formatString % position
                master_item = _MasterCheckItem(self.__masterControler,'p_%d (%s)' % (len(self.__masterPosition2Item),positionString))
                self.__masterPosition2Item[position] = master_item
        else:
            master_item = self.__imageList
            position = None
        return master_item,position
        
    def __snapCBK(self) :
        key = {}
        self.emit(qt.PYSIGNAL('getImage'),(key,))
        image = key.get('image',None)
        if image:
            master_item,position = self.__getMasterItem()
            if self.__focus_motor is not None:
                focusPosition = self.__focus_motor.getPosition()
            else:
                focusPosition = None
            try:
                item = _CheckItem(master_item,'image',self,image,
                                  self.__currentBeamPos,self.__currentCalib,
                                  self.__hMotor,self.__vMotor,self.__motor_pos_save,position,focusPosition)
            except:
                logging.getLogger().error('CameraOffLineImageManager : Spec not connected')

        else:
            logging.getLogger().error('CameraOffLineImageManager : getImage is not connected to CameraOffLineImageManager!!!')

    def __liveOnOff(self,state) :
        camera,decomp,plug = self.__camDecompNPlug
        if state:
            self.connect(camera,qt.PYSIGNAL('imageReceived'),decomp.putData)
            plug.show()
        else:
            self.disconnect(camera,qt.PYSIGNAL('imageReceived'),decomp.putData)
            plug.hide()

    def __saveImageTree(self,i) :
        pickleObjects = []
        self.__saveImageRecurse(self.__imageList.firstChild(),pickleObjects)
        if pickleObjects:
            fullpathname = qt.QFileDialog.getSaveFileName(self.__saveImageTreeDirName,'Camera mosaic (*.mosaic)',self,
                                                          'Save mosaic images',
                                                          "Choose a filename to save under")
            if fullpathname:
                fullpathname = fullpathname.latin1()
                self.__saveImageTreeDirName,fname = os.path.split(fullpathname)
                filename,ext = os.path.splitext(fname)
                fullpathname = os.path.join(self.__saveImageTreeDirName,'%s.mosaic' % filename)
                pickle.dump(pickleObjects,file(fullpathname,'w'))
        else:
            errorMess = qt.QErrorMessage(self)
            errorMess.message('Nothing to Save!!!')

    def __loadImageTree(self,i) :
        fullpathname = qt.QFileDialog.getOpenFileName(self.__saveImageTreeDirName,'Camera mosaic (*.mosaic)',self,
                                                      'Load mosaic images',
                                                      "Load a image tree")
        if fullpathname:
            fullpathname = fullpathname.latin1()
            self.__imageList.selectAll(True)
            self.__removeImage(0)
            for saveItem in pickle.load(file(fullpathname)):
              master_item,position = self.__getMasterItem(saveItem.masterPosition)
              _CheckItem(master_item,saveItem,self)
            
    def __saveImageRecurse(self,item,pickleObjects) :
        while item:
            NextItem = item.nextSibling()
            try: pickleObjects.append(item.getSavePickleObject())
            except AttributeError: pass
            self.__saveImageRecurse(item.firstChild(),pickleObjects)
            item = NextItem

    @_foreachSelectedItems
    def __removeImage(self,item,i)  :
        try:
            item.parent().takeItem(item)
        except AttributeError:
            self.__imageList.takeItem(item)
        return True
    @_foreachSelectedItems
    def __layerUp(self,item,i) :
        item.layerUp()

    @_foreachSelectedItems
    def __layerDown(self,item,i) :
        item.layerDown()

    def __popUpDisplay(self,item,point,columnid) :
        self.__popUpMenu.exec_loop(point)

    def run(self) :
        key = {}
        self.emit(qt.PYSIGNAL('getView'),(key,))
        try:
            view = key['view']
            drawing = key['drawing']

            self.__snapAction = QubToolButtonAction(name='MosaicSnap',iconName='snapshot',toolButtonStyle = True,
                                                    place='toolbar',
                                                    group='image',autoConnect = True)
            qt.QObject.connect(self.__snapAction,qt.PYSIGNAL('ButtonPressed'),self.__snapCBK)
            view.addAction([self.__snapAction])
        except KeyError:
            logging.getLogger().error('getView is not connected to CameraOffLineImageManager!!!')
            


        mosaicKey = {}
        self.emit(qt.PYSIGNAL('getMosaicView'),(mosaicKey,))
        try:
            self.mosaicView = mosaicKey['view']
            self.drawing = mosaicKey['drawing']
            class _openDialog(QubOpenDialogAction) :
                def __init__(self,*args,**keys) :
                    QubOpenDialogAction.__init__(self,*args,**keys)
                def setCanvas(self,canvas) :
                    self.__canvas = canvas
                    
                def _showDialog(self) :
                    if self._dialog.exec_loop() == qt.QDialog.Accepted :
                        file_path = self._dialog.selectedFile().ascii()
                        dirName,file_name = os.path.split(file_path)
                        base,ext = os.path.splitext(file_name)
                        QubImageSave.save(os.path.join(dirName,'%s.svg' % base),None,self.__canvas,1,'svg',True)
                        
            self.__saveMosaicAction = _openDialog(parent=self,label='Save image',name="save", iconName='save',group="admin")
            saveMosaicDialogue = qt.QFileDialog('.','Mosaic Images (*.svg)',self,'Save mosaic Images',True)
            saveMosaicDialogue.setMode(saveMosaicDialogue.AnyFile)
            self.__saveMosaicAction.setDialog(saveMosaicDialogue)
            self.__saveMosaicAction.setCanvas(self.drawing.canvas())

            self.__imageMosaicPosition = QubRulerAction(name='Motor Position',
                                                        place='toolbar',
                                                        group='Tools')

            self.__mouseMotorPosition = _MouseOrMotorPosition(name='mouse motor position',
                                                              place='statusbar',
                                                              group='info',
                                                              mouseFlag = True)
            
            self.__currentMotorPosition = _MouseOrMotorPosition(name='current motor position',
                                                                place='statusbar',
                                                                group='info')
            
            self.mosaicView.addAction([self.__imageMosaicPosition,self.__saveMosaicAction,
                                       self.__currentMotorPosition,self.__mouseMotorPosition])
            
            if self.__vMotor is not None:
                self.__imageMosaicPosition.setLabel(QubRulerAction.VERTICAL,0,self.__vMotor.getMotorMnemonic())
                self.__imageMosaicPosition.setCursorPosition(QubRulerAction.VERTICAL, 0,
                                                             self.__vMotor.getPosition())
                limits = self.__vMotor.getLimits()
                self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,0,
                                                     *limits)
                self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,1,
                                                     *limits)

                self.__imageMosaicPosition.setLabel(QubRulerAction.VERTICAL,1, '')
                for label in [self.__mouseMotorPosition,self.__currentMotorPosition] :
                    label.setMotyName(self.__vMotor.getMotorMnemonic())
                    label.setYValue(self.__vMotor.getPosition())
                                        
            if self.__hMotor is not None:
                self.__imageMosaicPosition.setLabel(QubRulerAction.HORIZONTAL,0,self.__hMotor.getMotorMnemonic())
                limits = self.__hMotor.getLimits()
                self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,0,
                                                     *limits)
                self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,1,
                                                     *limits)
                
                self.__imageMosaicPosition.setCursorPosition(QubRulerAction.HORIZONTAL, 0,
                                                             self.__hMotor.getPosition())
                self.__imageMosaicPosition.setLabel(QubRulerAction.HORIZONTAL,1,'')

                for label in [self.__mouseMotorPosition,self.__currentMotorPosition] :
                    label.setMotxName(self.__hMotor.getMotorMnemonic())
                    label.setXValue(self.__hMotor.getPosition())
                    
            for ruler in self.__imageMosaicPosition._QubRulerAction__ruler:
                ruler.setZ(99)          # upper layer

            #Add a follow mulot
            class _MouseFollow(_DrawingEventNDrawingMgr) :
                def __init__(self,aDrawingMgr,oneShot,**keys) :
                    _DrawingEventNDrawingMgr.__init__(self,aDrawingMgr,False)
                    
                def mouseMove(self,x,y) :
                    d = self._drawingMgr()
                    if d:
                        d.move(x,y)
                        d.endDraw()
            self.__followPointMouse,_ = QubAddDrawing(self.drawing,QubMosaicPointDrawingMgr,QubCanvasTarget)
            self.__followPointMouse.setDrawingEvent(_MouseFollow)
            self.__followPointMouse.setExclusive(False)
            self.__followPointMouse.startDrawing()
            self.__followPointMouse.setEndDrawCallBack(self.__displayMotorsPositionUnderMouse)
        except KeyError: pass

        if self.__camDecompNPlug:
            camera,decomp,plug = self.__camDecompNPlug
            try:
                plug.addImage()
                try:
                    plug.move(self.__hMotor.getPosition(),self.__vMotor.getPosition())
                except: pass
                else:
                    try:
                        plug.setCalibration(*self.__currentCalib)
                        plug.setBeamPosition(*self.__currentBeamPos)
                    except (AttributeError,TypeError) :
                        pass
            except AttributeError:
                liveCheckBox = self.child('__liveCheckBox')
                liveCheckBox.hide()
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
class CameraOffLineImageManagerBrick(BlissWidget):
    def __init__(self, parent, name, **keys):
        BlissWidget.__init__(self, parent, name)
        self.__hMotor = None
        self.__vMotor = None
        self.__motor_pos_save = []
        self.__master_motor = None
        self.__masterPosition2Item = weakref.WeakValueDictionary()
        self.__currentCalib = None
        self.__currentBeamPos = None
        self.__camDecompNPlug = None
        self.mosaicView = None
        self.drawing = None
        self.__saveImageTreeDirName = '.'
        self.__imageMosaicPosition = None
        ####### Property #######
        self.addProperty('horizontal', 'string', '')
        self.addProperty('vertical', 'string', '')
        self.addProperty('save_motors', 'string', '')
        self.addProperty('master_motor', 'string', '')
        self.addProperty('focus_motor', 'string', '')
        self.addProperty('live_camera', 'string', '')
        self.addProperty("formatString", "formatString", "###.##")
        ####### SIGNAL #######
        self.defineSignal("getImage", ())
        self.defineSignal('getView', ())
        self.defineSignal('getMosaicView', ())
        ####### SLOT #######
        self.defineSlot("ChangePixelCalibration", ())
        self.defineSlot("ChangeBeamPosition", ())
        self.defineSlot('setMosaicImageSelected', ())

        self.__widgetTree = self.loadUIFile('CameraOffLineImageManager.ui')
        self.__frame = self.__widgetTree.child('__frame')
        self.__frame.reparent(self, qt.QPoint(0, 0))
        layout = qt.QHBoxLayout(self)
        layout.addWidget(self.__frame)

        snapButton = self.child('__snapShoot')
        iconSet = qt.QIconSet(loadIcon("snapshot.png"))
        snapButton.setIconSet(iconSet)
        qt.QObject.connect(snapButton, qt.SIGNAL('clicked()'), self.__snapCBK)

        liveCheckBox = self.child('__liveCheckBox')
        liveCheckBox.hide()
        qt.QObject.connect(liveCheckBox, qt.SIGNAL('toggled(bool)'),
                           self.__liveOnOff)

        self.__imageList = self.child('__imageList')
        self.__imageList.setSelectionMode(qt.QListView.Extended)
        self.__imageList.setSortColumn(-1)
        self.__popUpMenu = qt.QPopupMenu(self)
        self.__popUpMenu.insertItem('layer up', self.__layerUp)
        self.__popUpMenu.insertItem('layer down', self.__layerDown)
        self.__popUpMenu.insertItem('remove', self.__removeImage)

        self.__popUpMenu.insertSeparator()
        self.__popUpMenu.insertItem('load', self.__loadImageTree)
        self.__popUpMenu.insertItem('save', self.__saveImageTree)

        qt.QObject.connect(
            self.__imageList,
            qt.SIGNAL('rightButtonPressed(QListViewItem*,const QPoint &,int)'),
            self.__popUpDisplay)

    def propertyChanged(self, propertyName, oldValue, newValue):
        if propertyName == 'horizontal':
            if self.__hMotor:
                self.disconnect(self.__hMotor, qt.PYSIGNAL("positionChanged"),
                                self.__hMotorPositionChanged)
            self.__hMotor = self.getHardwareObject(newValue)
            self.connect(self.__hMotor, qt.PYSIGNAL("positionChanged"),
                         self.__hMotorPositionChanged)
            self.connect(self.__hMotor, qt.PYSIGNAL("limitsChanged"),
                         self.__hMotorLimitsChanged)
        elif propertyName == 'vertical':
            if self.__vMotor:
                self.disconnect(self.__vMotor, qt.PYSIGNAL("positionChanged"),
                                self.__vMotorPositionChanged)
            self.__vMotor = self.getHardwareObject(newValue)
            self.connect(self.__vMotor, qt.PYSIGNAL("positionChanged"),
                         self.__vMotorPositionChanged)
            self.connect(self.__vMotor, qt.PYSIGNAL("limitsChanged"),
                         self.__vMotorLimitsChanged)

        elif propertyName == 'save_motors':
            equipment = self.getHardwareObject(newValue)
            self.__motor_pos_save = []
            if equipment:
                try:
                    ho = equipment['motors']
                except KeyError:
                    print equipment.userName(
                    ), 'is not an Equipment : no <motors> section.'
                    return
                for motor in ho.getDevices():
                    self.__motor_pos_save.append(motor)

                #Refresh Tree column
                nbColumn = self.__imageList.columns()
                for columnId in range(1, self.__imageList.columns()):
                    self.__imageList.removeColumn(columnId)
                for motor in self.__motor_pos_save:
                    self.__imageList.addColumn(motor.userName())
        elif propertyName == 'master_motor':
            if self.__master_motor is not None:
                self.__imageList.takeItem(self.__masterControler)
            self.__master_motor = self.getHardwareObject(newValue)
            if self.__master_motor is not None:
                self.__masterControler = qt.QCheckListItem(
                    self.__imageList, self.__master_motor.userName())
                self.__masterControler.setSelectable(False)
                self.__masterControler.setOpen(True)
        elif propertyName == 'focus_motor':
            self.__focus_motor = self.getHardwareObject(newValue)
            moveFocusCheckBox = self.child('__moveFocusCheckBox')
            if self.__focus_motor is not None:
                moveFocusCheckBox.show()
            else:
                moveFocusCheckBox.hide()
        elif propertyName == 'live_camera':
            if self.__camDecompNPlug:
                camera, decomp, _ = self.__camDecompNPlug
                self.disconnect(camera, qt.PYSIGNAL('imageReceived'),
                                decomp.putData)
                self.__camDecompNPlug = None

            camera = self.getHardwareObject(newValue)
            liveCheckBox = self.child('__liveCheckBox')
            if camera is not None:
                decomp = QubStdData2Image()
                plug = _LiveImagePlug(self)
                decomp.plug(plug)

                imageInfo = camera.imageType()
                if imageInfo and imageInfo.type() == 'bayer':
                    imType = decomp.BAYER_RG
                elif imageInfo and imageInfo.type() == 'raw':
                    imType = decomp.RAW
                else:
                    imType = decomp.STANDARD  # JPEG
                decomp.setImageType(imType)

                self.__camDecompNPlug = camera, decomp, plug

                liveCheckBox.show()
            else:
                liveCheckBox.hide()
        elif propertyName == 'formatString':
            self._formatString = self['formatString']

    def ChangePixelCalibration(self, sizeX, sizeY):
        if sizeX is not None and sizeY is not None:
            motorXUnit = self.__hMotor.getProperty('unit')
            if motorXUnit is None: motorXUnit = 1e-3

            motorYUnit = self.__vMotor.getProperty('unit')
            if motorYUnit is None: motorYUnit = 1e-3

            self.__currentCalib = sizeX / motorXUnit, sizeY / motorYUnit

            if self.__camDecompNPlug:
                camera, decomp, plug = self.__camDecompNPlug
                plug.setPixelCalibration(*self.__currentCalib)
        else:
            self.__currentCalib = None

    def ChangeBeamPosition(self, x, y):
        self.__currentBeamPos = x, y
        if self.__camDecompNPlug:
            camera, decomp, plug = self.__camDecompNPlug
            plug.setBeamPosition(*self.__currentBeamPos)

    def setMosaicImageSelected(self, imageSelectedID):
        moveFocusCheckBox = self.child('__moveFocusCheckBox')
        if moveFocusCheckBox.isChecked():
            position = self.__focus_motor.getPosition()

            def _recursfind(item, lookinId):
                while item:
                    if id(item) == lookinId:
                        return item
                    else:
                        returnItem = _recursfind(item.firstChild(), lookinId)
                        if returnItem: return returnItem
                        item = item.nextSibling()

            item = _recursfind(self.__imageList.firstChild(), imageSelectedID)
            try:
                if item and item.focusMotorPosition != position:
                    self.__focus_motor.move(item.focusMotorPosition)
            except AttributeError:
                pass

    def __displayMotorsPositionUnderMouse(self, drawingManager):
        point = drawingManager.mosaicPoints()
        try:
            point = point[0]
            beamY, beamZ = point.refPoint
            YSize, ZSize = point.calibration
            horMotorPos, verMotorPos = point.absPoint
            y, z = point.point
            imageId = point.imageId
        except TypeError:
            return
        movetoy = horMotorPos - (beamY - y) * YSize
        movetoz = verMotorPos - (beamZ - z) * ZSize

        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(
                QubRulerAction.HORIZONTAL, 1, movetoy)
            self.__imageMosaicPosition.setCursorPosition(
                QubRulerAction.VERTICAL, 1, movetoz)
            self.__mouseMotorPosition.setXValue(movetoy)
            self.__mouseMotorPosition.setYValue(movetoz)

    def __hMotorPositionChanged(self, position):
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(
                QubRulerAction.HORIZONTAL, 0, position)
            self.__currentMotorPosition.setXValue(position)

        if self.__camDecompNPlug:
            camera, decomp, plug = self.__camDecompNPlug
            plug.setHMotorPosition(position)

    def __hMotorLimitsChanged(self, limit):
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL, 0,
                                                 *limit)
            self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL, 1,
                                                 *limit)

    def __vMotorPositionChanged(self, position):
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setCursorPosition(
                QubRulerAction.VERTICAL, 0, position)
            self.__currentMotorPosition.setYValue(position)
        if self.__camDecompNPlug:
            camera, decomp, plug = self.__camDecompNPlug
            plug.setVMotorPosition(position)

    def __vMotorLimitsChanged(self, limit):
        if self.__imageMosaicPosition:
            self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL, 0,
                                                 *limit)
            self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL, 1,
                                                 *limit)

    def __getMasterItem(self, position=None):
        if self.__master_motor is not None:
            if position is None:
                position = self.__master_motor.getPosition()
            try:
                master_item = self.__masterPosition2Item[position]
            except KeyError:
                positionString = self._formatString % position
                master_item = _MasterCheckItem(
                    self.__masterControler, 'p_%d (%s)' %
                    (len(self.__masterPosition2Item), positionString))
                self.__masterPosition2Item[position] = master_item
        else:
            master_item = self.__imageList
            position = None
        return master_item, position

    def __snapCBK(self):
        key = {}
        self.emit(qt.PYSIGNAL('getImage'), (key, ))
        image = key.get('image', None)
        if image:
            master_item, position = self.__getMasterItem()
            if self.__focus_motor is not None:
                focusPosition = self.__focus_motor.getPosition()
            else:
                focusPosition = None
            try:
                item = _CheckItem(master_item, 'image', self, image,
                                  self.__currentBeamPos, self.__currentCalib,
                                  self.__hMotor, self.__vMotor,
                                  self.__motor_pos_save, position,
                                  focusPosition)
            except:
                logging.getLogger().error(
                    'CameraOffLineImageManager : Spec not connected')

        else:
            logging.getLogger().error(
                'CameraOffLineImageManager : getImage is not connected to CameraOffLineImageManager!!!'
            )

    def __liveOnOff(self, state):
        camera, decomp, plug = self.__camDecompNPlug
        if state:
            self.connect(camera, qt.PYSIGNAL('imageReceived'), decomp.putData)
            plug.show()
        else:
            self.disconnect(camera, qt.PYSIGNAL('imageReceived'),
                            decomp.putData)
            plug.hide()

    def __saveImageTree(self, i):
        pickleObjects = []
        self.__saveImageRecurse(self.__imageList.firstChild(), pickleObjects)
        if pickleObjects:
            fullpathname = qt.QFileDialog.getSaveFileName(
                self.__saveImageTreeDirName, 'Camera mosaic (*.mosaic)', self,
                'Save mosaic images', "Choose a filename to save under")
            if fullpathname:
                fullpathname = fullpathname.latin1()
                self.__saveImageTreeDirName, fname = os.path.split(
                    fullpathname)
                filename, ext = os.path.splitext(fname)
                fullpathname = os.path.join(self.__saveImageTreeDirName,
                                            '%s.mosaic' % filename)
                pickle.dump(pickleObjects, file(fullpathname, 'w'))
        else:
            errorMess = qt.QErrorMessage(self)
            errorMess.message('Nothing to Save!!!')

    def __loadImageTree(self, i):
        fullpathname = qt.QFileDialog.getOpenFileName(
            self.__saveImageTreeDirName, 'Camera mosaic (*.mosaic)', self,
            'Load mosaic images', "Load a image tree")
        if fullpathname:
            fullpathname = fullpathname.latin1()
            self.__imageList.selectAll(True)
            self.__removeImage(0)
            for saveItem in pickle.load(file(fullpathname)):
                master_item, position = self.__getMasterItem(
                    saveItem.masterPosition)
                _CheckItem(master_item, saveItem, self)

    def __saveImageRecurse(self, item, pickleObjects):
        while item:
            NextItem = item.nextSibling()
            try:
                pickleObjects.append(item.getSavePickleObject())
            except AttributeError:
                pass
            self.__saveImageRecurse(item.firstChild(), pickleObjects)
            item = NextItem

    @_foreachSelectedItems
    def __removeImage(self, item, i):
        try:
            item.parent().takeItem(item)
        except AttributeError:
            self.__imageList.takeItem(item)
        return True

    @_foreachSelectedItems
    def __layerUp(self, item, i):
        item.layerUp()

    @_foreachSelectedItems
    def __layerDown(self, item, i):
        item.layerDown()

    def __popUpDisplay(self, item, point, columnid):
        self.__popUpMenu.exec_loop(point)

    def run(self):
        key = {}
        self.emit(qt.PYSIGNAL('getView'), (key, ))
        try:
            view = key['view']
            drawing = key['drawing']

            self.__snapAction = QubToolButtonAction(name='MosaicSnap',
                                                    iconName='snapshot',
                                                    toolButtonStyle=True,
                                                    place='toolbar',
                                                    group='image',
                                                    autoConnect=True)
            qt.QObject.connect(self.__snapAction, qt.PYSIGNAL('ButtonPressed'),
                               self.__snapCBK)
            view.addAction([self.__snapAction])
        except KeyError:
            logging.getLogger().error(
                'getView is not connected to CameraOffLineImageManager!!!')

        mosaicKey = {}
        self.emit(qt.PYSIGNAL('getMosaicView'), (mosaicKey, ))
        try:
            self.mosaicView = mosaicKey['view']
            self.drawing = mosaicKey['drawing']

            class _openDialog(QubOpenDialogAction):
                def __init__(self, *args, **keys):
                    QubOpenDialogAction.__init__(self, *args, **keys)

                def setCanvas(self, canvas):
                    self.__canvas = canvas

                def _showDialog(self):
                    if self._dialog.exec_loop() == qt.QDialog.Accepted:
                        file_path = self._dialog.selectedFile().ascii()
                        dirName, file_name = os.path.split(file_path)
                        base, ext = os.path.splitext(file_name)
                        QubImageSave.save(
                            os.path.join(dirName, '%s.svg' % base), None,
                            self.__canvas, 1, 'svg', True)

            self.__saveMosaicAction = _openDialog(parent=self,
                                                  label='Save image',
                                                  name="save",
                                                  iconName='save',
                                                  group="admin")
            saveMosaicDialogue = qt.QFileDialog('.', 'Mosaic Images (*.svg)',
                                                self, 'Save mosaic Images',
                                                True)
            saveMosaicDialogue.setMode(saveMosaicDialogue.AnyFile)
            self.__saveMosaicAction.setDialog(saveMosaicDialogue)
            self.__saveMosaicAction.setCanvas(self.drawing.canvas())

            self.__imageMosaicPosition = QubRulerAction(name='Motor Position',
                                                        place='toolbar',
                                                        group='Tools')

            self.__mouseMotorPosition = _MouseOrMotorPosition(
                name='mouse motor position',
                place='statusbar',
                group='info',
                mouseFlag=True)

            self.__currentMotorPosition = _MouseOrMotorPosition(
                name='current motor position', place='statusbar', group='info')

            self.mosaicView.addAction([
                self.__imageMosaicPosition, self.__saveMosaicAction,
                self.__currentMotorPosition, self.__mouseMotorPosition
            ])

            if self.__vMotor is not None:
                self.__imageMosaicPosition.setLabel(
                    QubRulerAction.VERTICAL, 0,
                    self.__vMotor.getMotorMnemonic())
                self.__imageMosaicPosition.setCursorPosition(
                    QubRulerAction.VERTICAL, 0, self.__vMotor.getPosition())
                limits = self.__vMotor.getLimits()
                self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,
                                                     0, *limits)
                self.__imageMosaicPosition.setLimits(QubRulerAction.VERTICAL,
                                                     1, *limits)

                self.__imageMosaicPosition.setLabel(QubRulerAction.VERTICAL, 1,
                                                    '')
                for label in [
                        self.__mouseMotorPosition, self.__currentMotorPosition
                ]:
                    label.setMotyName(self.__vMotor.getMotorMnemonic())
                    label.setYValue(self.__vMotor.getPosition())

            if self.__hMotor is not None:
                self.__imageMosaicPosition.setLabel(
                    QubRulerAction.HORIZONTAL, 0,
                    self.__hMotor.getMotorMnemonic())
                limits = self.__hMotor.getLimits()
                self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,
                                                     0, *limits)
                self.__imageMosaicPosition.setLimits(QubRulerAction.HORIZONTAL,
                                                     1, *limits)

                self.__imageMosaicPosition.setCursorPosition(
                    QubRulerAction.HORIZONTAL, 0, self.__hMotor.getPosition())
                self.__imageMosaicPosition.setLabel(QubRulerAction.HORIZONTAL,
                                                    1, '')

                for label in [
                        self.__mouseMotorPosition, self.__currentMotorPosition
                ]:
                    label.setMotxName(self.__hMotor.getMotorMnemonic())
                    label.setXValue(self.__hMotor.getPosition())

            for ruler in self.__imageMosaicPosition._QubRulerAction__ruler:
                ruler.setZ(99)  # upper layer

            #Add a follow mulot
            class _MouseFollow(_DrawingEventNDrawingMgr):
                def __init__(self, aDrawingMgr, oneShot, **keys):
                    _DrawingEventNDrawingMgr.__init__(self, aDrawingMgr, False)

                def mouseMove(self, x, y):
                    d = self._drawingMgr()
                    if d:
                        d.move(x, y)
                        d.endDraw()

            self.__followPointMouse, _ = QubAddDrawing(
                self.drawing, QubMosaicPointDrawingMgr, QubCanvasTarget)
            self.__followPointMouse.setDrawingEvent(_MouseFollow)
            self.__followPointMouse.setExclusive(False)
            self.__followPointMouse.startDrawing()
            self.__followPointMouse.setEndDrawCallBack(
                self.__displayMotorsPositionUnderMouse)
        except KeyError:
            pass

        if self.__camDecompNPlug:
            camera, decomp, plug = self.__camDecompNPlug
            try:
                plug.addImage()
                try:
                    plug.move(self.__hMotor.getPosition(),
                              self.__vMotor.getPosition())
                except:
                    pass
                else:
                    try:
                        plug.setCalibration(*self.__currentCalib)
                        plug.setBeamPosition(*self.__currentBeamPos)
                    except (AttributeError, TypeError):
                        pass
            except AttributeError:
                liveCheckBox = self.child('__liveCheckBox')
                liveCheckBox.hide()