Exemplo n.º 1
0
def test_emptyish_char_waveform_monitor():
    '''a test of a char waveform of length 1 (NORD=1): value "\0"
    with using auto_monitor
    '''
    with no_simulator_updates():
        zerostr = PV(pvnames.char_arr_pv, auto_monitor=True)
        zerostr.wait_for_connection()

        zerostr.put([0], wait=True)
        time.sleep(0.2)

        assert zerostr.get(as_string=True) == ''
        numpy.testing.assert_array_equal(zerostr.get(as_string=False), [0])
        assert zerostr.get(as_string=True, as_numpy=False) == ''
        numpy.testing.assert_array_equal(
            zerostr.get(as_string=False, as_numpy=False), [0])

        zerostr.put([0, 0], wait=True)
        time.sleep(0.2)

        assert zerostr.get(as_string=True) == ''
        numpy.testing.assert_array_equal(zerostr.get(as_string=False), [0, 0])
        assert zerostr.get(as_string=True, as_numpy=False) == ''
        numpy.testing.assert_array_equal(
            zerostr.get(as_string=False, as_numpy=False), [0, 0])
        zerostr.disconnect()
Exemplo n.º 2
0
def test_with_PV_and_getPV():
    # create 2 PV objects connecting to the same PV signal, one using PV class and the other one using get_pv()
    pv1 = PV(mypv, auto_monitor=True, callback=lambda **args:...)
    pv2 = get_pv(mypv)

    pv1.wait_for_connection()
    pv2.wait_for_connection()

    # check that both PVs are connected
    assert pv1.connected is True
    assert pv2.connected is True

    # check that data is received
    assert pv1.get() is not None
    assert pv2.get() is not None

    # disconnect 1 PV
    pv1.disconnect()

    time.sleep(1)

    # check that the first PV is disconnected and doesn't receive data
    assert pv1.connected is False
    assert pv1.get() is None

    # check that the other PV is connected and still receives data
    assert pv2.connected is True
    assert pv2.get() is not None
Exemplo n.º 3
0
    def test_emptyish_char_waveform_no_monitor(self):
        '''a test of a char waveform of length 1 (NORD=1): value "\0"
        without using auto_monitor
        '''
        with no_simulator_updates():
            zerostr = PV(pvnames.char_arr_pv, auto_monitor=False)
            zerostr.wait_for_connection()

            # elem_count = 128, requested count = None, libca returns count = 1
            zerostr.put([0], wait=True)
            self.assertEquals(zerostr.get(as_string=True), '')
            numpy.testing.assert_array_equal(zerostr.get(as_string=False), [0])
            self.assertEquals(zerostr.get(as_string=True, as_numpy=False), '')
            numpy.testing.assert_array_equal(
                zerostr.get(as_string=False, as_numpy=False), [0])

            # elem_count = 128, requested count = None, libca returns count = 2
            zerostr.put([0, 0], wait=True)
            self.assertEquals(zerostr.get(as_string=True), '')
            numpy.testing.assert_array_equal(zerostr.get(as_string=False),
                                             [0, 0])
            self.assertEquals(zerostr.get(as_string=True, as_numpy=False), '')
            numpy.testing.assert_array_equal(
                zerostr.get(as_string=False, as_numpy=False), [0, 0])
            zerostr.disconnect()
Exemplo n.º 4
0
def test_force_connect():
    pv = PV(pvnames.double_arrays[0], auto_monitor=True)

    print("Connecting")
    assert pv.wait_for_connection(5.0)

    print("SUM", pv.get().sum())

    time.sleep(3)

    print("Disconnecting")
    pv.disconnect()
    print("Reconnecting")

    pv.force_connect()
    assert pv.wait_for_connection(5.0)

    called = {'called': False}

    def callback(value=None, **kwargs):
        called['called'] = True
        print("update", value.sum())

    pv.add_callback(callback)

    time.sleep(1)
    assert pv.get() is not None
    assert called['called']
Exemplo n.º 5
0
def test_memleak_disconnect():
    # try to connect multiple times to the same PV
    mem = []
    for i in range(int(2)):
        for j in range(int(1000)):
            pv = PV(mypv, auto_monitor=True, callback=lambda **args:...)
            pv.disconnect()

        process = psutil.Process(os.getpid())
        mem.append(process.memory_info().rss)

    # check used memory by the process didn't increase by more than 1%
    assert mem[1] / mem[0] < 1.01
Exemplo n.º 6
0
 def post(self, message):
     stationStr = self._BL
     msg = message
     date_formatted = datetime.datetime.strftime(datetime.datetime.now(),
                                                 "%a %d-%b-%Y %H:%M:%S")
     mscroll = PV("SF-OP:" + str(stationStr) + "-MSG:OP-MSCROLL.PROC")
     mscroll.value = 1
     msg1 = PV("SF-OP:" + str(stationStr) + "-MSG:OP-MSG1")
     msg1.value = msg.encode()
     date1 = PV("SF-OP:" + str(stationStr) + "-MSG:OP-DATE1")
     date1.value = date_formatted.encode()
     msg1.disconnect()
     date1.disconnect()
Exemplo n.º 7
0
def test_reconnect():
    # connect and disconnect
    pv = PV(mypv, auto_monitor=True, callback=lambda **args:...)
    pv.wait_for_connection()
    pv.disconnect()

    # try to reconnect to the same PV
    connected = pv.reconnect()

    # check that PV is connected
    assert connected is True

    # check that data is received
    value = pv.get()
    assert value is not None
Exemplo n.º 8
0
    def release(self):
        if (self.app == None):
            return False

        release_pv = PV('{}:THR_LOADED'.format(self.app.get_pv_name()))

        if (self.verbose):
            sys.stdout.write('Releasing IOC (setting {})...'.format(
                release_pv.pvname))

        # do release
        if (release_pv.host == None):
            print('ERROR: Failed to read release PV {}'.format(
                release_pv.pvname))
            return False

        try:
            release_pv.put(1)
        except epics.ca.CASeverityException:
            print('ERROR: Tried to write to a read-only PV ({}=1)'.\
                    format(release_pv.pvname))
            return False

        release_pv.disconnect()

        enable_pv = PV('{}:MPS_EN'.format(self.app.get_pv_name()))

        if (self.verbose):
            sys.stdout.write('Releasing IOC (setting {})...'.format(
                enable_pv.pvname))

        # do release
        if (enable_pv.host == None):
            print('ERROR: Failed to read release PV {}'.format(
                enable_pv.pvname))
            return False

        try:
            enable_pv.put(1)
        except epics.ca.CASeverityException:
            print('ERROR: Tried to write to a read-only PV ({}=1)'.\
                    format(enable_pv.pvname))
            return False

        enable_pv.disconnect()

        if (self.verbose):
            print(' done.')
Exemplo n.º 9
0
def test_with_caget_nomonitor():
    pv = PV(mypv, auto_monitor=True, callback=lambda **args:...)
    pv.wait_for_connection()

    # check that the PV is connected and  data is received
    assert pv.connected is True
    assert pv.get() is not None

    # use caget to get data from the same PV
    assert caget(mypv, use_monitor=False) is not None

    # disconnect PV object
    pv.disconnect()

    # check that the PV is disconnected and doesn't receive data
    assert pv.connected is False
    assert pv.get() is None

    # check that you can still use caget to get data from the same PV
    assert caget(mypv, use_monitor=False) is not None
Exemplo n.º 10
0
def test_connect_disconnect():
    pv = PV(mypv, auto_monitor=True, callback=lambda **args:...)

    pv.wait_for_connection()

    # check that PV is connected
    assert pv.connected is True

    # check that data is received
    value = pv.get()
    assert value is not None

    pv.disconnect()

    # check that PV is disconnected
    assert pv.connected is False

    # check that no data is received after disconnect
    value = pv.get()
    assert value is None
Exemplo n.º 11
0
def test_with_camonitor():
    pv = PV(mypv, auto_monitor=True, callback=lambda **args:...)
    pv.wait_for_connection()

    # check that the PV is connected and  data is received
    assert pv.connected is True
    assert pv.get() is not None

    # use camonitor
    received = {'flag': False}

    def callback(**args):
        received['flag'] = True

    camonitor(mypv, callback=callback)
    time.sleep(1)

    # check that the monitor receives data
    assert received['flag'] is True

    # disconnect PV object
    pv.disconnect()
    time.sleep(1)

    # check that the PV is disconnected and doesn't receive data
    assert pv.connected is False
    assert pv.get() is None

    # reset the flag to check that new data is received by camonitor
    received['flag'] = False
    time.sleep(1)
    assert received['flag'] is True

    # clear the monitor
    camonitor_clear(mypv)
    time.sleep(1)

    # reset the flag to check that no new data is received by camonitor
    received['flag'] = False
    time.sleep(1)
    assert received['flag'] is False
Exemplo n.º 12
0
class PCO2000(StandardDevice):
    TYPE_TIFF = "TIFF"
    TYPE_HDF = "HDF"

    #CALLBACK FUNCTION FOR THE CCD ACQUIRE STATUS PV
    def onAcquireChange(self, value, **kw):
        self._doneRecord = (value == 0)

    def onAcquireRBVChange(self, value, **kw):
        self._doneReadOut = (value == 0)

    def onDataChange(self, value, **kw):
        if(self.initCamera):
            self.initCamera = False
            return
        self.imageBufferQueue.put(value)
        self.NData = self.NData + 1

    def onNELMChange(self, value, **kw):
        if(self.initNELM):
            self.initNELM = False
            return
        self.NCount = self.NCount + 1

    #CONSTRUCTOR OF CCD CLASS
    def __init__(self, pvName, mnemonic, imageBufferQueue=None, processName=""):
        StandardDevice.__init__(self, mnemonic)
        self.processName = processName
        self.initCamera = True
        self.initNELM = True
        self.NCount = 0
        self.NData = 0
        self.imageBufferQueue = imageBufferQueue

        self.pvData = PV(pvName+":Data", auto_monitor=True)
        self.pvData.add_callback(self.onDataChange)

        self.pvAcquire = PV(pvName+":Acquire", callback=self.onAcquireChange, auto_monitor=True)
        self.pvAcquireRBV = PV(pvName+":Acquire_RBV", callback=self.onAcquireRBVChange, auto_monitor=True)
        self.pvNELM = PV(pvName+":Data.NELM", callback=self.onNELMChange)

        self._done = self.isDone()

        self.pvPixelSize = PV(pvName + ":PixelSize")
        self.pvCheckImage = PV(pvName + ":CheckImage")
        self.pvMinX = PV(pvName + ":MinX")
        self.pvMinY = PV(pvName + ":MinY")
        self.pvSizeX = PV(pvName + ":SizeX")
        self.pvSizeY = PV(pvName + ":SizeY")
        self.pvAcquireTime = PV(pvName+":AcquireTime")
        self.pvAcquireTimeBase = PV(pvName+":AcquireTimeBase")
        self.pvDelayTime = PV(pvName + ":DelayTime")
        self.pvDelayTimeBase = PV(pvName + ":DelayTimeBase")

        self.pvFileFormat = PV(pvName + ":FileFormat")
        self.pvFileName = PV(pvName + ":FileName")
        self.pvFileNumber = PV(pvName + ":FileNumber")
        self.pvFilePath = PV(pvName + ":FilePath")

#         #### PVS Bellow are used only for information display, no need to be here in the Python Class
#         #### If needed just uncomment and create the proper methods for GET and SET values.
#         self.pvADC = PV(pvName+":ADC")
#         self.pvAutoIncrement = PV(pvName+":AutoIncrement")
#         self.pvBinHorz = PV(pvName + ":BinHorz")
#         self.pvBinVert = PV(pvName + ":BinVert")
#         self.pvBoolTest = PV(pvName + ":BoolTest")
#         self.pvCamTemp = PV(pvName + ":CamTemp")
#         self.pvCCDTemp = PV(pvName + ":CCDTemp")
#         self.pvDoubleImage = PV(pvName + ":DoubleImage")
#         self.pvHotPixelCorrection = PV(pvName + ":HotPixelCorrection")
#         self.pvHotPixelX = PV(pvName + ":HotPixelX")
#         self.pvHotPixelY = PV(pvName + ":HotPixelY")
#         self.pvNoiseFiltering = PV(pvName + ":NoiseFiltering")
#         self.pvPixelRate = PV(pvName + ":PixelRate")
#         self.pvPixelSize = PV(pvName + ":PixelSize")
#         self.pvPowTemp = PV(pvName + ":PowTemp")
#         self.pvTimestamp = PV(pvName + ":Timestamp")
#         self.pvStatus = PV(pvName + ":Status")

    def getPixelSize(self):
        return self.pvPixelSize.get()

    def getCheckImage(self):
        return self.pvCheckImage.get()

    def setCheckImage(self, v):
        self.pvCheckImage.put(v)

    def getMinX(self):
        return self.pvMinX.get()
        
    def setMinX(self, v):
        self.pvMinX.put(v)

    def getMinY(self):
        return self.pvMinY.get()

    def setMinY(self, v):
        self.pvMinY.put(v)

    def getSizeX(self):
        return self.pvSizeX.get()

    def setSizeX(self, v):
        self.pvSizeX.put(v)

    def getSizeY(self):
        return self.pvSizeY.get() 

    def setSizeY(self, v):
        self.pvSizeY.put(v)

    def getAcquireTime(self):
        return self.pvAcquireTime.get()
    
    def setAcquireTime(self, v):
        self.pvAcquireTime.put(v)
    
    
    def getAcquireTimeBase(self):
        return self.pvAcquireTimeBase.get()
    
    def setAcquireTimeBase(self, v):
        self.pvAcquireTimeBase.put(v)
    
    def getDelayTime(self):
        return self.pvDelayTime.get()
    
    def setDelayTime(self, v):
        self.pvDelayTime.put(v)
        
    def getDelayTimeBase(self):
        return self.pvDelayTimeBase.get()
    
    def setDelaytimeBase(self, v):
        self.pvDelayTimeBase.put(v)
    
    
    def getFileFormat(self):
        return self.pvFileFormat.get()
    
    def setFileFormat(self, v):
        if(v in [self.TYPE_HDF, self.TYPE_TIFF]):
            self.pvFileFormat.put(v)
        else:
            msg = 'File format "' + v + '" not supported. Only supported are: '
            raise Exception('Error: ',msg)
        
    def getFileName(self):
        return self.pvFileName.get()
    
    def setFileName(self, v):
        self.pvFileName.put(v)
        
    def getFileNumber(self):
        return self.pvFileNumber.get()
    
    def setFuleNumber(self, v):
        self.pvFileNumber.put(v)
        
    def getFilePath(self):
        return self.pvFilePath.get()
    
    def setFilePath(self, v):
        self.pvFilePath.put(v)
    

    def getCompleteFilePath(self):
        if(self.getFileFormat() == self.TYPE_TIFF):
            ext = ".tif"
        elif(self.getFileFormat() == self.TYPE_HDF):
            ext = ".h5"
        else:
            ext = "" 
        
        return self.getFilePath()+"/"+self.getFileName()+ext
    
    def getNELMChangeCount(self):
        return self.NCount

    def getData(self):
        self._newData = False
        return self.pvData.get()

    def isDone(self):
        return (self.pvAcquireRBV.get() == 0)

    def isRecordDone(self):
        return (self.pvAcquire.get() == 0)

    def isReadOutDone(self):
        return (self.pvAcquireRBV.get() == 0)
    
    def getIntensity(self):
        return self.scaler.getIntensity()

    def acquire(self, waitRecord=False, waitReadOut=False):
        #self.scaler.setCountTime(self.time)
        #self.scaler.setCountStart()
        self.pvAcquire.put(1)

        self._doneRecord = False
        self._doneReadOut = False
        self._newData = False

        if(waitRecord):
            self.waitRecord()

        if(waitReadOut):
            self.waitReadOut()

        #self.scaler.setCountStop()

    def waitConfig(self):
        self._doneConfig = False
        while(not self._doneConfig):
            sleep(0.001)

    def waitRecord(self):
        while(not self._doneRecord):
            sleep(0.001)

    def waitReadOut(self):
        while(not self._doneReadOut):
            sleep(0.001)

    def destroy(self):
        self.pvData.disconnect()
        self.pvAcquire.disconnect()
        self.pvAcquireRBV.disconnect()
        self.pvNELM.disconnect()
        self.imageBufferQueue = None
Exemplo n.º 13
0
class Feed(object):
    """
    This class reads frames in a real time using pyepics, and delivers to consuming process.
    """
    def __init__(self, config, app):
        """
        Constructor
        """
        self.app = app
        self.eventq = tqueue.Queue()
        self.detector = config['detector']
        with open(config['pvs']) as file:
            self.pvs = json.loads(file.read())
        self.sizex = 0
        self.sizey = 0
        self.index = 0
        self.current_counter = None

    def event(self, event_str):
        # we will find out later how to handle the events
        pass

    def deliver_data(self, data):
        # process data in the same thread as the callback
        self.app.process_data(data)

    def handle_event(self):
        """
        This function receives data, processes it, and delivers to consuming process.

        This function is invoked at the beginning of the feed as a distinct thread. It reads data from a thread_dataq
        inside a loop that delivers current counter value on change.
        If the counter is not a consecutive number to the previous reading a 'missing' string is enqueued into
        process_dataq in place of the data to mark the missing frames.
        For every received frame data, it reads a data type from PV, and the two elements are delivered to a consuming
        process via process_dataq as Data instance. If a sequence is defined, then the data type for this frame
        determined from sequence is compared with the data type read from PV. If they are different, a warning log is
        recorded.
        On the loop exit an 'all_data' string is enqueud into the inter-process queue, and 'exit' string is enqueued
        into the inter-thread queue, to notify the main thread of the exit event.

        Parameters
        ----------
        data_pv : str
            a PV string for the area detector data

        frame_type_pv : str
            a PV string for the area detector data type

        logger : Logger
            a Logger instance, typically synchronized with the consuming process logger

        Returns
        -------
        None
        """
        self.done = False
        while not self.done:
            try:
                callback_item = self.eventq.get(timeout=1)
                if callback_item == 'finish':
                    print('done')
                    self.done = True
                else:
                    current_ctr = callback_item
                    if current_ctr > self.current_counter + 1:
                        self.event('missing frames')
                    self.current_counter = current_ctr + 1

                    try:
                        print('current cntr', self.current_counter)
                        pv_pairs = {}
                        slice = np.array(caget(self.get_data_pv_name()))
                        print('pvname', self.get_data_pv_name())
                        # read other pvs
                        for pv in self.pvs:
                            pv_pairs[pv] = (self.pvs[pv], caget(self.pvs[pv]))
                        print('pv pairs', pv_pairs)
                        if slice is None:
                            self.done = True
                            self.event(
                                'reading image times out, possibly the detector exposure time is too small'
                            )
                        else:
                            slice.resize(self.sizex, self.sizey)
                            data = ut.Data(slice, pv_pairs)
                            # deliver data to monitor
                            self.deliver_data(data)
                    except:
                        self.done = True
                        self.event(
                            'reading image raises exception, possibly the detector exposure time is too small'
                        )
            except tqueue.Empty:
                continue

        self.finish()

    def acq_done(self, pvname=None, **kws):
        """
        A callback method that activates when pv acquire switches to off.

        If the value is 0, the function enqueues key word 'finish' into event queue that will be dequeued by the
        'handle_event' function.

        Parameters
        ----------
        pvname : str
            a PV string for acquire

        Returns
        -------
        None
        """
        if kws['value'] == 0:
            self.eventq.put('finish')

    def on_change(self, pvname=None, **kws):
        """
        A callback method that activates when a frame counter of area detector changes.

        This method reads the counter value and enqueues it into event queue that will be dequeued by the
        'handle_event' function.
        If it is a first read, the function adjusts counter data in the self object.

        Parameters
        ----------
        pvname : str
            a PV string for the area detector frame counter

        Returns
        -------
        None
        """

        current_ctr = kws['value']
        # init on first read
        if self.current_counter is None:
            self.current_counter = current_ctr - 1  # the self.current_counter holds previous
        self.eventq.put(current_ctr)

    def start_processes(self):
        """
        This function starts processes and callbacks.

        This is a main thread that starts thread reacting to the callback, starts the consuming process, and sets a
        callback on the frame counter PV change. The function then awaits for the data in the exit queue that indicates
        that all frames have been processed. The functin cancells the callback on exit.

        Parameters
        ----------
        none

        Returns
        -------
        nothing
        """
        data_thread = CAThread(target=self.handle_event, args=())
        data_thread.start()

        self.counter_pv = PV(self.get_counter_pv_name())
        self.counter_pv.add_callback(self.on_change, index=1)

        self.acq_pv = PV(self.get_acquire_pv_name())
        self.acq_pv.add_callback(self.acq_done, index=2)

    def get_acquire_pv_name(self):
        return self.detector + ':cam1:Acquire'

    def get_counter_pv_name(self):
        return self.detector + ':cam1:ArrayCounter_RBV'

    def get_data_pv_name(self):
        return self.detector + ':image1:ArrayData'

    def feed_data(self):
        """
        This function is called by a client to start the process.

        After all initial settings are completed, the method awaits for the area detector to start acquireing by polling
        the PV. When the area detective is active it starts processing.

        Parameters
        ----------
        none

        Returns
        -------
        nothing
        """
        test = True

        sizex_pv = self.detector + ':image1:ArraySize0_RBV'
        sizey_pv = self.detector + ':image1:ArraySize1_RBV'
        acquire_pv_name = self.get_acquire_pv_name()
        while test:
            self.sizex = caget(sizex_pv)
            self.sizey = caget(sizey_pv)
            ack = caget(acquire_pv_name)
            if ack == 1:
                test = False
                self.start_processes()
            else:
                time.sleep(.005)

        # # start the infinit loop so the feed does not stop after this init
        # if True:
        #     time.sleep(10)
        #
        return caget(acquire_pv_name)

    def finish(self):
        try:
            self.counter_pv.disconnect()
        except:
            pass
        try:
            self.acq_pv.disconnect()
        except:
            pass
Exemplo n.º 14
0
class PCO2000(StandardDevice):
    TYPE_TIFF = "TIFF"
    TYPE_HDF = "HDF"

    #CALLBACK FUNCTION FOR THE CCD ACQUIRE STATUS PV
    def onAcquireChange(self, value, **kw):
        self._doneRecord = (value == 0)

    def onAcquireRBVChange(self, value, **kw):
        self._doneReadOut = (value == 0)

    def onDataChange(self, value, **kw):
        if (self.initCamera):
            self.initCamera = False
            return
        self.imageBufferQueue.put(value)
        self.NData = self.NData + 1

    def onNELMChange(self, value, **kw):
        if (self.initNELM):
            self.initNELM = False
            return
        self.NCount = self.NCount + 1

    #CONSTRUCTOR OF CCD CLASS
    def __init__(self,
                 pvName,
                 mnemonic,
                 imageBufferQueue=None,
                 processName=""):
        StandardDevice.__init__(self, mnemonic)
        self.processName = processName
        self.initCamera = True
        self.initNELM = True
        self.NCount = 0
        self.NData = 0
        self.imageBufferQueue = imageBufferQueue

        self.pvData = PV(pvName + ":Data", auto_monitor=True)
        self.pvData.add_callback(self.onDataChange)

        self.pvAcquire = PV(pvName + ":Acquire",
                            callback=self.onAcquireChange,
                            auto_monitor=True)
        self.pvAcquireRBV = PV(pvName + ":Acquire_RBV",
                               callback=self.onAcquireRBVChange,
                               auto_monitor=True)
        self.pvNELM = PV(pvName + ":Data.NELM", callback=self.onNELMChange)

        self._done = self.isDone()

        self.pvPixelSize = PV(pvName + ":PixelSize")
        self.pvCheckImage = PV(pvName + ":CheckImage")
        self.pvMinX = PV(pvName + ":MinX")
        self.pvMinY = PV(pvName + ":MinY")
        self.pvSizeX = PV(pvName + ":SizeX")
        self.pvSizeY = PV(pvName + ":SizeY")
        self.pvAcquireTime = PV(pvName + ":AcquireTime")
        self.pvAcquireTimeBase = PV(pvName + ":AcquireTimeBase")
        self.pvDelayTime = PV(pvName + ":DelayTime")
        self.pvDelayTimeBase = PV(pvName + ":DelayTimeBase")

        self.pvFileFormat = PV(pvName + ":FileFormat")
        self.pvFileName = PV(pvName + ":FileName")
        self.pvFileNumber = PV(pvName + ":FileNumber")
        self.pvFilePath = PV(pvName + ":FilePath")

#         #### PVS Bellow are used only for information display, no need to be here in the Python Class
#         #### If needed just uncomment and create the proper methods for GET and SET values.
#         self.pvADC = PV(pvName+":ADC")
#         self.pvAutoIncrement = PV(pvName+":AutoIncrement")
#         self.pvBinHorz = PV(pvName + ":BinHorz")
#         self.pvBinVert = PV(pvName + ":BinVert")
#         self.pvBoolTest = PV(pvName + ":BoolTest")
#         self.pvCamTemp = PV(pvName + ":CamTemp")
#         self.pvCCDTemp = PV(pvName + ":CCDTemp")
#         self.pvDoubleImage = PV(pvName + ":DoubleImage")
#         self.pvHotPixelCorrection = PV(pvName + ":HotPixelCorrection")
#         self.pvHotPixelX = PV(pvName + ":HotPixelX")
#         self.pvHotPixelY = PV(pvName + ":HotPixelY")
#         self.pvNoiseFiltering = PV(pvName + ":NoiseFiltering")
#         self.pvPixelRate = PV(pvName + ":PixelRate")
#         self.pvPixelSize = PV(pvName + ":PixelSize")
#         self.pvPowTemp = PV(pvName + ":PowTemp")
#         self.pvTimestamp = PV(pvName + ":Timestamp")
#         self.pvStatus = PV(pvName + ":Status")

    def getPixelSize(self):
        return self.pvPixelSize.get()

    def getCheckImage(self):
        return self.pvCheckImage.get()

    def setCheckImage(self, v):
        self.pvCheckImage.put(v)

    def getMinX(self):
        return self.pvMinX.get()

    def setMinX(self, v):
        self.pvMinX.put(v)

    def getMinY(self):
        return self.pvMinY.get()

    def setMinY(self, v):
        self.pvMinY.put(v)

    def getSizeX(self):
        return self.pvSizeX.get()

    def setSizeX(self, v):
        self.pvSizeX.put(v)

    def getSizeY(self):
        return self.pvSizeY.get()

    def setSizeY(self, v):
        self.pvSizeY.put(v)

    def getAcquireTime(self):
        return self.pvAcquireTime.get()

    def setAcquireTime(self, v):
        self.pvAcquireTime.put(v)

    def getAcquireTimeBase(self):
        return self.pvAcquireTimeBase.get()

    def setAcquireTimeBase(self, v):
        self.pvAcquireTimeBase.put(v)

    def getDelayTime(self):
        return self.pvDelayTime.get()

    def setDelayTime(self, v):
        self.pvDelayTime.put(v)

    def getDelayTimeBase(self):
        return self.pvDelayTimeBase.get()

    def setDelaytimeBase(self, v):
        self.pvDelayTimeBase.put(v)

    def getFileFormat(self):
        return self.pvFileFormat.get()

    def setFileFormat(self, v):
        if (v in [self.TYPE_HDF, self.TYPE_TIFF]):
            self.pvFileFormat.put(v)
        else:
            msg = 'File format "' + v + '" not supported. Only supported are: '
            raise Exception('Error: ', msg)

    def getFileName(self):
        return self.pvFileName.get()

    def setFileName(self, v):
        self.pvFileName.put(v)

    def getFileNumber(self):
        return self.pvFileNumber.get()

    def setFuleNumber(self, v):
        self.pvFileNumber.put(v)

    def getFilePath(self):
        return self.pvFilePath.get()

    def setFilePath(self, v):
        self.pvFilePath.put(v)

    def getCompleteFilePath(self):
        if (self.getFileFormat() == self.TYPE_TIFF):
            ext = ".tif"
        elif (self.getFileFormat() == self.TYPE_HDF):
            ext = ".h5"
        else:
            ext = ""

        return self.getFilePath() + "/" + self.getFileName() + ext

    def getNELMChangeCount(self):
        return self.NCount

    def getData(self):
        self._newData = False
        return self.pvData.get()

    def isDone(self):
        return (self.pvAcquireRBV.get() == 0)

    def isRecordDone(self):
        return (self.pvAcquire.get() == 0)

    def isReadOutDone(self):
        return (self.pvAcquireRBV.get() == 0)

    def getIntensity(self):
        return self.scaler.getIntensity()

    def acquire(self, waitRecord=False, waitReadOut=False):
        #self.scaler.setCountTime(self.time)
        #self.scaler.setCountStart()
        self.pvAcquire.put(1)

        self._doneRecord = False
        self._doneReadOut = False
        self._newData = False

        if (waitRecord):
            self.waitRecord()

        if (waitReadOut):
            self.waitReadOut()

        #self.scaler.setCountStop()

    def waitConfig(self):
        self._doneConfig = False
        while (not self._doneConfig):
            sleep(0.001)

    def waitRecord(self):
        while (not self._doneRecord):
            sleep(0.001)

    def waitReadOut(self):
        while (not self._doneReadOut):
            sleep(0.001)

    def destroy(self):
        self.pvData.disconnect()
        self.pvAcquire.disconnect()
        self.pvAcquireRBV.disconnect()
        self.pvNELM.disconnect()
        self.imageBufferQueue = None
Exemplo n.º 15
0
class XAFSviewerFrame(wx.Frame):
    def __init__(self, parent=None, *args, **kwds):

        kwds["style"] = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER | wx.TAB_TRAVERSAL

        wx.Frame.__init__(self, parent, wx.NewId(), '', wx.DefaultPosition, wx.Size(-1, -1), **kwds)
        self.SetTitle(" WXMPlot Plotting Demo")

        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False))
        menu = wx.Menu()
        ID_EXIT = wx.NewId()
        ID_TIMER = wx.NewId()

        menu.Append(ID_EXIT, "E&xit", "Terminate the program")

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&File")
        self.SetMenuBar(menuBar)

        wx.EVT_MENU(self, ID_EXIT, self.OnExit)

        self.Bind(wx.EVT_CLOSE, self.OnExit)
        
        self.plotframe = None

        framesizer = wx.BoxSizer(wx.VERTICAL)

        panel = wx.Panel(self, -1, size=(-1, -1))
        panelsizer = wx.BoxSizer(wx.VERTICAL)

        panelsizer.Add(wx.StaticText(panel, -1, 'XAFS Spectra viewer '),
                       0, wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT | wx.EXPAND, 10)

        b40 = wx.Button(panel, -1, 'Start Timed Plot',    size=(-1, -1))
        #b40.Bind(wx.EVT_BUTTON,self.onStartTimer)
        panelsizer.Add(b40, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.LEFT, 5)

        panel.SetSizer(panelsizer)
        panelsizer.Fit(panel)

        framesizer.Add(panel, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER | wx.EXPAND, 2)
        self.SetSizer(framesizer)
        framesizer.Fit(self)

        #----------- added by LWW -----------------------------
        self.ShowPlotFrame(do_raise=False, clear=False)
        self.plotYdata = []
        self.plotXdata = []

        # ----------epics PVs-----------------------
        self.i0 = PV('BL10C:scaler1_calc2.VAL')
        self.it = PV('BL10C:scaler1_calc3.VAL')
        self.iF = PV('BL10C:scaler1_calc4.VAL')
        self.trans = PV('BL10C:scaler1_calc8.VAL')
        self.motorPos = PV('mobiis:m2.RBV')
        
        self.scanStart = PV('BL10C:scan2.EXSC.VAL', callback=self.scanStartCALLBACK)
        
        while self.motorPos.get() is None:
            print self.motorPos.get()
        
        self.countDonePV = PV('BL10C:scaler1.CNT', callback=self.countDoneCALLBACK)
        
        self.time0 = time.time()
        self.datrange = None
        #----------- end of add by LWW -----------------------
        
        #wx.EVT_TIMER(self, ID_TIMER, self.onTimer)
        #self.timer = wx.Timer(self, ID_TIMER)
        self.Refresh()

    # --------------epics callback method---------------------
    def scanStartCALLBACK(self, **kwargs):
        if kwargs['value'] is 1:  # 0:Done, 1: scanning
            self.ShowPlotFrame(do_raise=True, clear=True)
            
            print 'New Scan Started!!!'
        
        else:
            print 'scan stopped!!!'
        
        return
    
    def countDoneCALLBACK(self, **kwargs):
        if kwargs['value'] is 1:  # 0:Done, 1:Counting
            return

        ## self._flag = True
        self.plotYdata.append(self.trans.get())
        self.plotXdata.append(self.motorPos.get())
        ## self._flag = False
        
        print 'X:%s,  Y:%s' % (len(self.plotXdata), len(self.plotYdata))
        
        # Todo: we need new scan start sequence.
        #       new list, graph clear, data save...,
        # print 'timer ', self.count, time.time()
        ## self.count += 1
        #self.ShowPlotFrame(do_raise=False, clear=False)
        ## n = self.count
        if len(self.plotXdata) < 2:
            return
        # Todo: implementation of scan finish sequence.
        '''
        if n >= self.npts:
            self.timer.Stop()
            self.timer_results()
        elif n <= 3:
        '''
        if len(self.plotXdata) <= 3:
            self.plotframe.plot(self.plotXdata, self.plotYdata,
                                linewidth=0.5, marker='o',
                                markersize=6, xlabel='energy[eV]',
                                ylabel='[count]')
                                # , grid=False)

        else:
            xx = np.array(self.plotXdata)
            yy = np.array(self.plotYdata)
            
            self.plotframe.update_line(0, xx, yy, update_limits=len(xx) < 10, draw=True)
            
            etime = time.time() - self.time0
            s = " %i / %i points in %8.4f s" % (len(self.plotXdata), len(self.plotYdata), etime)
            self.plotframe.write_message(s)

        if self.datrange is None:
            self.datrange = [min(self.plotXdata), max(self.plotXdata), min(self.plotYdata), max(self.plotYdata)]

        dr = [min(self.plotXdata), max(self.plotXdata),
              min(self.plotYdata), max(self.plotYdata)]
        
        lims = self.plotframe.panel.get_viewlimits()
        if dr[0] < lims[0] or dr[1] > lims[1] or dr[2] < lims[2] or dr[3] > lims[3]:
            self.datrange = dr
            ## if len(self.plotXdata) < len(self.x):
            ##     nmax = min(int(n*1.6), len(self.x)-1)
            ##     self.datrange[1] = self.x[nmax]
            self.plotframe.panel.set_xylims(self.datrange)
            
    def ShowPlotFrame(self, do_raise=True, clear=True):
        """make sure plot frame is enabled, and visible"""
        if self.plotframe is None:
            self.plotframe = PlotFrame(self, axissize=[0.08, 0.06, 0.91, 0.92])
            # self.has_plot = False
        try:
            self.plotframe.Show()
        except wx.PyDeadObjectError:
            self.plotframe = PlotFrame(self, axissize=[0.08, 0.06, 0.91, 0.92])
            self.plotframe.Show()

        if do_raise:
            self.plotframe.Raise()
        if clear:
            self.plotframe.panel.clear()
            self.plotframe.reset_config()
            
            self.plotYdata = []
            self.plotXdata = []
            
    '''    
    def onStartTimer(self,event=None):
        self.count    = 0
        self.up_count = 0
        self.n_update = 1
        self.datrange = None
        self.time0    = time.time()
        ### LWW self.start_mem= self.report_memory()
        self.timer.Start(10)
        # self.timer.Start(500)
    
    def timer_results(self):
        if (self.count < 2): return
        etime = time.time() - self.time0
        tpp   = etime/max(1,self.count)
        s = "drew %i points in %8.3f s: time/point= %8.4f s" % (self.count,etime,tpp)
        self.plotframe.write_message(s)
        self.time0 = 0
        self.count = 0
        self.datrange = None
    '''
    '''
    def onTimer(self, event):
        # print 'timer ', self.count, time.time()
        self.count += 1
        self.ShowPlotFrame(do_raise=False, clear=False)
        n = self.count
        if n < 2:
            return
        if n >= self.npts:
            self.timer.Stop()
            self.timer_results()
        elif n <= 3:
            self.plotframe.plot(self.x[:n], self.y1[:n])# , grid=False)

        else:
            self.plotframe.update_line(0, self.x[:n], self.y1[:n], update_limits=n<10, draw=True)

            etime = time.time() - self.time0
            s = " %i / %i points in %8.4f s" % (n,self.npts,etime)
            self.plotframe.write_message(s)

        if self.datrange is None:
            self.datrange = [min(self.x[:n]), max(self.x[:n]),
                             min(self.y1[:n]),max(self.y1[:n])]

        dr = [min(self.x[:n]),  max(self.x[:n]),
              min(self.y1[:n]), max(self.y1[:n])]
        
        lims = self.plotframe.panel.get_viewlimits()
        if dr[0] < lims[0] or dr[1] > lims[1] or dr[2] < lims[2] or dr[3] > lims[3]:
            self.datrange = dr
            if n < len(self.x):
                nmax = min(int(n*1.6), len(self.x)-1)
                self.datrange[1] = self.x[nmax]
            self.plotframe.panel.set_xylims(self.datrange)
    '''
    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "This program shows MCA Spectra\n"
                                     "message dialog.",
                                     "About MPlot test", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnExit(self, event):
        # 1st. disconnect PV(s)
        self.countDonePV.clear_callbacks()
        self.i0.disconnect()
        self.it.disconnect()
        self.iF.disconnect()
        self.trans.disconnect()
        self.motorPos.disconnect()
        
        try:
            if self.plotframe is not None:
                self.plotframe.onExit()
        except:
            pass
        self.Destroy()