Esempio n. 1
0
    def _execute_monitor(self, request):
        # Connect to the channel
        path = ".".join(request.path[1:])
        channel = pvaccess.Channel(request.path[0])
        self._monitors[request.generate_key()] = channel

        # Store the connection within the monitor set
        def callback(value=None):
            # TODO: ordering is not maintained here...
            # TODO: should we strip_tuples here?
            d = value.toDict(True)
            if d.get("typeid", "") == Error.typeid:
                response = Error(request.id, d["message"])
                self._monitors.pop(request.generate_key())
                channel.unsubscribe("")
            else:
                # TODO: support Deltas properly
                if request.delta:
                    response = Delta(request.id, [[[], d]])
                else:
                    response = Update(request.id, d)
            request.callback(response)

        # Perform a subscribe, but it returns nothing
        channel.subscribe("sub", callback)
        channel.startMonitor(path)
        a = None
        return a
Esempio n. 2
0
    def __enter__(self):
        self.pv_channel = pvaccess.Channel(self.pv_image)
        x, y = self.pv_channel.get('field()')['dimension']
        self.dims = (y['size'], x['size'])
        labels = [
            item["name"]
            for item in self.pv_channel.get('field()')["attribute"]
        ]
        self.theta_key = labels.index("SampleRotary")
        self.scan_delta_key = labels.index("ScanDelta")
        self.start_position_key = labels.index("StartPos")
        self.last_save_dest = labels.index("SaveDest")
        self.imageId = labels.index("ArrayCounter")
        self.flat_count = 0
        self.dark_count = 0
        self.flat_counter = 0
        self.dark_counter = 0
        self.sequence = 0
        print(self.dims)
        if self.num_sinograms > 0:
            if (self.beg_sinogram < 0) or (
                    self.beg_sinogram + self.num_sinograms > self.dims[0]):
                raise Exception(
                    "Exceeds the sinogram boundary: {} vs. {}".format(
                        self.beg_sinogram + self.num_sinograms, self.dims[0]))
            self.beg_index = self.beg_sinogram * self.dims[1]
            self.end_index = self.beg_sinogram * self.dims[
                1] + self.num_sinograms * self.dims[1]
        self.pv_channel.subscribe('push_image_data', self.push_image_data)

        return self
Esempio n. 3
0
    def __init__(self,stype):

        [ntheta,nz,n] = [1024,1024,1024]
        rate = 5*1024**3#GB/s
        buffer_size = 100000
        # queue
        self.data_queue = queue.Queue(maxsize=buffer_size)
        
        self.epics_pvs = {}
         # pva type channel that contains projection and metadata
        image_pv_name = "2bmbSP2:Pva1:"
        self.epics_pvs['PvaPImage']          = pva.Channel(image_pv_name + 'Image')
        self.epics_pvs['PvaPDataType_RBV']   = pva.Channel(image_pv_name + 'DataType_RBV')
        self.pva_plugin_image = self.epics_pvs['PvaPImage']
        # create pva type pv for reconstrucion by copying metadata from the data pv, but replacing the sizes
        # This way the ADViewer (NDViewer) plugin can be also used for visualizing reconstructions.
        pva_image_data = self.pva_plugin_image.get('')
        pva_image_dict = pva_image_data.getStructureDict()        
        self.pv_rec = pva.PvObject(pva_image_dict)
      
        # run server for reconstruction pv
        recon_pva_name = "2bmb:Rec"
        if(stype=='server'):
            self.server_rec = pva.PvaServer(recon_pva_name, self.pv_rec)

        pva_image_data = self.pva_plugin_image.get('')
        width = pva_image_data['dimension'][0]['size']
        height = pva_image_data['dimension'][1]['size']
        self.pv_rec['dimension'] = [{'size': width, 'fullSize': width, 'binning': 1},
                                    {'size': height, 'fullSize': height, 'binning': 1}]

        self.epics_pvs['PvaPImage']          = pva.Channel(recon_pva_name)
        self.pva_rec_image = self.epics_pvs['PvaPImage'] 
        #self.pv_rec['value'] = ({'floatValue': rec.flatten()},)     
        # self.theta = self.epics_pvs['ThetaArray'].get()[:self.epics_pvs['NumAngles'].get()]                
        # start monitoring projection data        
        datatype_list = self.epics_pvs['PvaPDataType_RBV'].get()['value']   
        self.datatype = datatype_list['choices'][datatype_list['index']].lower()                



        self.datatype='uint16'
        self.buffer_size=buffer_size
        self.height=height
        self.width=width
        self.cur_id=0
        self.tmp=np.zeros([height*width],dtype='uint16')
Esempio n. 4
0
 def execute_put(self, request):
     # Connect to the channel
     c = pvaccess.Channel(request["endpoint"][0])
     # Create the path request from the endpoints (not including the block name endpoint)
     path = ".".join(request["endpoint"][1:])
     self.log_debug("path: %s", path)
     # Perform a put, but there is no response available
     c.put(request["value"], path)
     # Now create the Return object and populate it with the response
     return_object = Return(id_=request["id"], value="No return value from put")
     return return_object
Esempio n. 5
0
def main():
    global app, img, x, y, MAX_FRAMES
    global args

    parser = argparse.ArgumentParser(description='AreaDetector video example')

    parser.add_argument(
        "ImagePV", help="EPICS PVA image PV name, such as 13PG2:Pva1:Image")
    parser.add_argument('--benchmark',
                        action='store_true',
                        help='measure framerate')
    parser.add_argument('--noAGC',
                        action='store_true',
                        help='disable auto gain')
    parser.add_argument('--frames',
                        action='store_true',
                        help='maximum number of frames (-1: unlimited)')

    args = parser.parse_args()

    app = QtGui.QApplication([])
    win = QtWidgets.QWidget()
    win.setWindowTitle('daqScope')
    layout = QtGui.QGridLayout()
    layout.setMargin(0)
    win.setLayout(layout)
    img = RawImageWidget(win)
    layout.addWidget(img, 0, 0, 0, 0)
    win.show()
    chan = pvaccess.Channel(args.ImagePV)

    x, y = chan.get('field()')['dimension']
    x = x['size']
    y = y['size']
    win.resize(x, y)

    chan.subscribe('update', update)
    chan.startMonitor()

    if args.benchmark:
        start = time.time()

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
        chan.stopMonitor()
        chan.unsubscribe('update')

    if args.benchmark:
        stop = time.time()
        print('Frames displayed: %d' % framesDisplayed)
        print('Elapsed time:     %.3f sec' % (stop - start))
        print('Frames per second: %.3f FPS' % (framesDisplayed /
                                               (stop - start)))
Esempio n. 6
0
  def __enter__(self):
    self.pv_channel = pvaccess.Channel(self.pv_image)
    y, x = self.pv_channel.get('field()')['dimension']
    self.dims=(y['size'], x['size'])
    if self.num_sinograms>0:
      if (self.beg_sinogram<0) or (self.beg_sinogram+self.num_sinograms>self.dims[0]): 
        raise Exception("Exceeds the sinogram boundary: {} vs. {}".format(
                            self.beg_sinogram+self.num_sinograms, self.dims[0]))
      self.beg_index = self.beg_sinogram*self.dims[1]
      self.end_index = self.beg_sinogram*self.dims[1] + self.num_sinograms*self.dims[1]
    self.pv_channel.subscribe('push_image_data', self.push_image_data)

    return self
Esempio n. 7
0
def takeflat(chdata):
    """ take 1 flat field, probably Multiple is needed """

    chTriggerMode = pva.Channel('2bmbSP1:cam1:TriggerMode', pva.CA)
    chImageMode = pva.Channel('2bmbSP1:cam1:ImageMode', pva.CA)
    chAcquire = pva.Channel('2bmbSP1:cam1:Acquire', pva.CA)
    #chNumImages= pva.Channel('2bmbSP1:cam1:NumImages', pva.CA)

    chSamXrbv = pva.Channel('2bma:m49.RBV', pva.CA)
    chSamX = pva.Channel('2bma:m49', pva.CA)

    # remember the current position samx
    cur = chSamXrbv.get('')['value']

    # move sample out
    chSamX.put(-10)
    time.sleep(10)

    # change to single mode
    chTriggerMode.put('Off')
    time.sleep(0.1)
    chImageMode.put('Single')
    time.sleep(0.1)

    # chNumImages.put(10)
    # time.sleep(0.1)

    # Acquire, and take array from pv
    chAcquire.put(1)
    flat = chdata.get('')['value'][0]['ubyteValue']
    time.sleep(1)

    # move sample in
    chSamX.put(cur)
    time.sleep(10)

    return flat
Esempio n. 8
0
 def execute_monitor(self, request):
     # Connect to the channel
     c = pvaccess.Channel(request["endpoint"][0])
     # Store the connection within the monitor set
     mon = MonitorHandler(request["id"], c, self)
     self._monitors[request["id"]] = mon
     # Create the path request from the endpoints (not including the block name endpoint)
     path = ".".join(request["endpoint"][1:])
     self.log_debug("Monitor path: %s", path)
     # Perform a put, but there is no response available
     c.subscribe(path, mon.monitor_update)
     self.log_debug("Created subscription")
     c.startMonitor(path)
     self.log_debug("Started monitor")
     return None
Esempio n. 9
0
    def feed_data(self):
        self.chan = pvaccess.Channel(self.pva_name)

        x, y = self.chan.get('field()')['dimension']
        self.dims = (y['size'], x['size'])
        print(self.dims)

        labels = [
            item['name'] for item in self.chan.get('field()')['attribute']
        ]
        self.ack_time = labels.index("AckTime")

        self.chan.subscribe('update', self.on_change)
        self.chan.startMonitor("value,attribute,uniqueId")

        # start the infinit loop so the feed does not stop after this init
        if True:
            time.sleep(10)
Esempio n. 10
0
    def subscribe(self, client):
        """ Subscribes WebSocket client to receive this PV's updates. """
        if client not in self._clients:
            self._clients.append(client)
            #log.info("Subscribed client: {0}".format(client.getClientId()))

        if self._ch is None:
            self._ch = pvaccess.Channel(self._pvname, self._protocol)
            self._ch.subscribe("webepics", self.updateCb)
            self._ch.startMonitor("field()")

        if self._cached:
            # Monitor is already active and it won't send full PV structure once it connects,
            # but the protocol requires client receives full update on connect so do it here
            try:
                self.sendToClients(self._cached, [client])
            except tornado.websocket.WebSocketClosedError:
                pass
Esempio n. 11
0
    def feed_data(self):
        self.chan = pvaccess.Channel(self.pva_name)

        x, y = self.chan.get('field()')['dimension']
        self.dims = (y['size'], x['size'])
        print(self.dims)
        #send the dimensions to client
        data = containers.Data(const.DATA_STATUS_DIM)
        data.dim_x = x
        data.dim_y = y
        self.cons.send_to_zmq(data)

        labels = [item['name'] for item in self.chan.get('field()')['attribute']]
        self.theta_key = labels.index("SampleRotary")
        self.scan_delta_key = labels.index("ScanDelta")
        self.start_position_key = labels.index("StartPos")

        self.chan.subscribe('update', self.on_change)
        self.chan.startMonitor("value,attribute,uniqueId")
Esempio n. 12
0
 def execute_get(self, request):
     # Connect to the channel
     c = pvaccess.Channel(request["endpoint"][0])
     # Create the path request from the endpoints (not including the block name endpoint)
     path = ".".join(request["endpoint"][1:])
     self.log_debug("path: %s", path)
     # Perform a get and record the response
     response = c.get(path)
     self.log_debug("Response: %s", response)
     # Now create the Return object and populate it with the response
     value = response.toDict(True)
     if 'typeid' in value:
         if value['typeid'] == 'malcolm:core/Error:1.0':
             return_object = Error(id_=request["id"], message=value['message'])
         else:
             return_object = Return(id_=request["id"], value=value)
     else:
         return_object = Error(id_=request["id"], message="No valid return typeid")
     return return_object
Esempio n. 13
0
 def _execute_put(self, request):
     path = ".".join(request.path[1:])
     channel = pvaccess.Channel(request.path[0])
     channel.put(request.value, path)
     response = Return(request.id)
     return response
Esempio n. 14
0
 def _execute_get(self, request):
     path = ".".join(request.path[1:])
     channel = pvaccess.Channel(request.path[0])
     d = channel.get(path).toDict()
     response = self._response_from_dict(request, d)
     return response
Esempio n. 15
0
def start_fly():
    """ init and run fly scan """

    chfly = pva.Channel('2bma:PSOFly2:fly', pva.CA)
    chtaxi = pva.Channel('2bma:PSOFly2:taxi', pva.CA)
    chTriggerMode = pva.Channel('2bmbSP1:cam1:TriggerMode', pva.CA)
    chTriggerSource = pva.Channel('2bmbSP1:cam1:TriggerSource', pva.CA)
    chTriggerOverlap = pva.Channel('2bmbSP1:cam1:TriggerOverlap', pva.CA)
    chExposureMode = pva.Channel('2bmbSP1:cam1:ExposureMode', pva.CA)
    chImageMode = pva.Channel('2bmbSP1:cam1:ImageMode', pva.CA)
    chArrayCallbacks = pva.Channel('2bmbSP1:cam1:ArrayCallbacks', pva.CA)
    chFrameRateEnable = pva.Channel('2bmbSP1:cam1:FrameRateEnable', pva.CA)
    chTriggerMode = pva.Channel('2bmbSP1:cam1:TriggerMode', pva.CA)
    chAcquire = pva.Channel('2bmbSP1:cam1:Acquire', pva.CA)

    chtaxi.put(1)
    chTriggerMode.put('Off')
    time.sleep(0.1)
    chTriggerSource.put('Line2')
    chTriggerOverlap.put('ReadOut')
    chExposureMode.put('Timed')
    chImageMode.put('Continuous')
    chArrayCallbacks.put('Enable')
    chFrameRateEnable.put(0)
    time.sleep(0.1)
    chTriggerMode.put('On')
    time.sleep(0.1)
    chAcquire.put(1)

    chfly.put(1)
Esempio n. 16
0
#!/usr/bin/env python
import pvaccess as pva

s = pva.PvaServer('foo', pva.PvObject({'value': pva.INT}))
c = pva.Channel('foo')
c.get()
s.removeRecord('foo')
Esempio n. 17
0
def pvput(name, value, use_ca=True):
    pvaccess.Channel(name, pvaccess.CA if use_ca else pvaccess.PVA).put(value)
Esempio n. 18
0
 def _create_pv(self, pv_name):
     return pvaccess.Channel(pv_name, pvaccess.PVA if self.usepva else pvaccess.CA)
Esempio n. 19
0
# Read PV from EPICSV4Sandbox/neutronsDemoServer
# (start_neutrondemo)
import pvaccess
c = pvaccess.Channel('neutrons')

# By default, the Channel will request "field(value"),
# which is not valid for this custom structure and
# would result in "PvaClientGet::connect invalid pvRequest".
# Fetch all elements:
custom = c.get("field()")
# Could also configure the channel to fetch selected
# elements of the structure:
# custom = c.get("field(proton_charge, pixel)")

print("Custom data structure:")
print(custom)

# Acts as a python dictionary
p_charge = custom['proton_charge']['value']
pixels = custom['pixel']['value']

print("Last pulse had a charge of %g Coulomb" % p_charge)
print("The detector was hit at these pixels IDs:")
print(str(pixels))
Esempio n. 20
0
def streaming():
    """
	Main computational function, take data from pvdata ('2bmbSP1:Pva1:Image'),
	reconstruct orthogonal slices and write the result to pvrec ('AdImage')
	"""

    ##### init pvs ######
    # init pvs for the streaming GUI

    # orthoslices
    chStreamX = pva.Channel('2bmS1:StreamX', pva.CA)
    chStreamY = pva.Channel('2bmS1:StreamY', pva.CA)
    chStreamZ = pva.Channel('2bmS1:StreamZ', pva.CA)

    # frame type
    chStreamFrameType = pva.Channel('2bma:TomoScan:FrameType', pva.CA)
    # theta array
    chStreamThetaArray = pva.Channel('2bma:PSOFly2:motorPos.AVAL', pva.CA)
    # total number of fly scan angles
    chStreamNumAngles = pva.Channel('2bma:TomoScan:NumAngles', pva.CA)
    # total number of dark fields
    chStreamNumDarkFields = pva.Channel('2bma:TomoScan:NumDarkFields', pva.CA)
    # total number of flat fields
    chStreamNumFlatFields = pva.Channel('2bma:TomoScan:NumFlatFields', pva.CA)
    # dark field mode
    chStreamDarkFieldMode = pva.Channel('2bma:TomoScan:DarkFieldMode', pva.CA)
    # flat field mode
    chStreamFlatFieldMode = pva.Channel('2bma:TomoScan:FlatFieldMode', pva.CA)

    # NEW: buffer size for for projections
    #chStreamBS = pva.Channel('2bmS1:StreamBS', pva.CA)
    # NEW: rotation center
    #chStreamRC = pva.Channel('2bmS1:StreamRC', pva.CA)

    ## init pva streaming pv for the detector
    # NEW: PV channel that contains projection and metadata (angle, flag: regular, flat or dark)
    chdata = pva.Channel('2bmbSP1:Pva1:Image')
    pvdata = chdata.get('')
    # init pva streaming pv for reconstrucion with coping dictionary from pvdata
    pvdict = pvdata.getStructureDict()
    pvrec = pva.PvObject(pvdict)

    # take dimensions
    n = pvdata['dimension'][0]['size']
    nz = pvdata['dimension'][1]['size']
    # set dimensions for reconstruction
    pvrec['dimension'] = [{
        'size': 3 * n,
        'fullSize': 3 * n,
        'binning': 1
    }, {
        'size': n,
        'fullSize': n,
        'binning': 1
    }]

    ##### run server for reconstruction pv #####
    # NEW: replace AdImage by a new name for Reconstruction PV, e.g. 2bmS1:StreamREC
    s = pva.PvaServer('AdImage', pvrec)

    ##### procedures before running fly #######

    # 0) form circular buffer, whenever the angle goes higher than 180
    # than corresponding projection is replacing the first one
    ntheta = 180  #chStreamBS.get('')['value']
    nflatinit = chStreamNumFlatFields.get('')['value']
    ndarkinit = chStreamNumDarkFields.get('')['value']

    databuffer = np.zeros([ntheta, nz * n], dtype='uint8')
    flatbuffer = np.zeros([nflatinit, nz * n], dtype='uint8')
    darkbuffer = np.zeros([ndarkinit, nz * n], dtype='uint8')
    thetabuffer = np.zeros(ntheta, dtype='float32')

    # Load angles
    theta = chStreamThetaArray.get(
        '')['value'][:chStreamNumAngles.get('')['value']]

    # find first id of the projection data, skipping ids for dadrk and flat fields
    flatmodeall = chStreamFlatFieldMode.get('')['value']
    flatmode = flatmodeall['choices'][flatmodeall['index']]
    darkmodeall = chStreamDarkFieldMode.get('')['value']
    darkmode = darkmodeall['choices'][darkmodeall['index']]

    ## the following is not needed, since the id is set to zero before acquiring pojections
    # firstid = chdata.get('')['uniqueId']
    # if(flatmode == 'Start' or flatmode=='Both'):
    # 	firstid += chStreamNumFlatFields.get('')['value']
    # if(darkmode == 'Start' or darkmode=='Both'):
    # 	firstid += chStreamNumDarkFields.get('')['value']
    # print('first projection id', firstid)

    nflat = 0
    ndark = 0
    nproj = 0

    # number of streamed images of each type
    def addData(pv):
        """ read data from the detector, 3 types: flat, dark, projection"""
        nonlocal nflat
        nonlocal ndark
        nonlocal nproj

        #with mrwlock.w_locked():
        curid = pv['uniqueId']
        ftypeall = chStreamFrameType.get('')['value']
        ftype = ftypeall['choices'][ftypeall['index']]
        if (ftype == 'FlatField'):
            flatbuffer[nflat] = pv['value'][0]['ubyteValue']
            nflat += 1
        if (ftype == 'DarkField'):
            darkbuffer[ndark] = pv['value'][0]['ubyteValue']
            ndark += 1
        if (ftype == 'Projection'):
            databuffer[np.mod(nproj, ntheta)] = pv['value'][0]['ubyteValue']
            thetabuffer[np.mod(nproj, ntheta)] = theta[curid - 1]
            nproj += 1
        print('add:', ftype, 'id:', curid)

    # start monitoring projection data
    chdata.monitor(addData, '')

    # create solver class on GPU
    slv = OrthoRec(ntheta, n, nz)
    # allocate memory for result slices
    recall = np.zeros([n, 3 * n], dtype='float32')

    # wait until dark and flats are acquired
    while (nproj == 0):
        1

    # init data as flat
    databuffer[:] = flatbuffer[0]
    print(databuffer.shape)
    # copy dark and flat to GPU
    print('copy dark and flat to GPU')
    slv.set_flat(np.mean(flatbuffer[:nflat], axis=0))
    slv.set_dark(np.mean(darkbuffer[:ndark], axis=0))

    ##### streaming reconstruction ######
    while (True):
        #with mrwlock.r_locked():  # lock buffer before reading
        datap = databuffer.copy()
        thetap = thetabuffer.copy()

        # take 3 ortho slices ids
        idx = chStreamX.get('')['value']
        idy = chStreamY.get('')['value']
        idz = chStreamZ.get('')['value']

        # NEW: center
        center = 1224  #chStreamC.get('')['value']
        # print(thetap)
        # reconstruct on GPU
        #tic()
        recx, recy, recz = slv.rec_ortho(datap, thetap * np.pi / 180, center,
                                         idx, idy, idz)
        #print('rec time:',toc(),'norm',np.linalg.norm(recx))

        # concatenate (supposing nz<n)
        recall[:nz, :n] = recx
        recall[:nz, n:2 * n] = recy
        recall[:, 2 * n:] = recz
        # write to pv
        pvrec['value'] = ({'floatValue': recall.flatten()}, )
        # reconstruction rate limit
        time.sleep(0.1)
Esempio n. 21
0
def streaming():
    """
	Main computational function, take data from pvdata ('2bmbSP1:Pva1:Image'),
	reconstruct orthogonal slices and write the result to pvrec ('AdImage')
	"""

    ##### init pvs ######
    # init ca pvs
    chscanDelta = pva.Channel('2bma:PSOFly2:scanDelta', pva.CA)
    chrotangle = pva.Channel('2bma:m82', pva.CA)
    chrotangleset = pva.Channel('2bma:m82.SET', pva.CA)
    chrotanglestop = pva.Channel('2bma:m82.STOP', pva.CA)
    chStreamX = pva.Channel('2bmS1:StreamX', pva.CA)
    chStreamY = pva.Channel('2bmS1:StreamY', pva.CA)
    chStreamZ = pva.Channel('2bmS1:StreamZ', pva.CA)
    # init pva streaming pv for the detector
    chdata = pva.Channel('2bmbSP1:Pva1:Image')
    pvdata = chdata.get('')
    # init pva streaming pv for reconstrucion with coping dictionary from pvdata
    pvdict = pvdata.getStructureDict()
    pvrec = pva.PvObject(pvdict)
    # take dimensions
    n = pvdata['dimension'][0]['size']
    nz = pvdata['dimension'][1]['size']
    # set dimensions for reconstruction
    pvrec['dimension'] = [{
        'size': 3 * n,
        'fullSize': 3 * n,
        'binning': 1
    }, {
        'size': n,
        'fullSize': n,
        'binning': 1
    }]

    ##### run server for reconstruction pv #####
    s = pva.PvaServer('AdImage', pvrec)

    ##### procedures before running fly #######

    # 0) form circular buffer, whenever the angle goes higher than 180
    # than corresponding projection is replacing the first one
    scanDelta = chscanDelta.get('')['value']
    ntheta = np.int(180 / scanDelta + 0.5)
    databuffer = np.zeros([ntheta, nz * n], dtype='uint8')
    thetabuffer = np.zeros(ntheta, dtype='float32')
    # 1) stop rotation, replace rotation stage angle to a value in [0,360)
    chrotanglestop.put(1)
    time.sleep(3)
    rotangle = chrotangle.get('')['value']
    chrotangleset.put(1)
    chrotangle.put(rotangle - rotangle // 360 * 360)
    chrotangleset.put(0)
    # 2) take flat field
    flat = takeflat(chdata)
    firstid = chdata.get('')['uniqueId']
    # 3) create solver class on GPU, and copy flat field to gpu
    slv = OrthoRec(ntheta, n, nz)
    slv.set_flat(flat)
    # 4) allocate memory for result slices
    recall = np.zeros([n, 3 * n], dtype='float32')

    # 5) start monitoring the detector pv for data collection

    def addProjection(pv):
        with mrwlock.w_locked():
            curid = pv['uniqueId']
            databuffer[np.mod(curid, ntheta)] = pv['value'][0]['ubyteValue']
            thetabuffer[np.mod(curid, ntheta)] = (curid - firstid) * scanDelta
            #print(firstid, curid)

    chdata.monitor(addProjection, '')

    ##### start acquisition #######
    start_fly()

    ##### streaming reconstruction ######
    while (True):  # infinite loop over angular partitions
        with mrwlock.r_locked():  # lock buffer before reading
            datap = databuffer.copy()
            thetap = thetabuffer.copy()

        # take 3 ortho slices ids
        idx = chStreamX.get('')['value']
        idy = chStreamY.get('')['value']
        idz = chStreamZ.get('')['value']
        # reconstruct on GPU
        tic()
        recx, recy, recz = slv.rec_ortho(datap, thetap * np.pi / 180, n // 2,
                                         idx, idy, idz)
        print('rec time:', toc())

        # concatenate (supposing nz<n)
        recall[:nz, :n] = recx
        recall[:nz, n:2 * n] = recy
        recall[:, 2 * n:] = recz
        # write to pv
        pvrec['value'] = ({'floatValue': recall.flatten()}, )
        # reconstruction rate limit
        time.sleep(0.1)
Esempio n. 22
0
    def put(self, value):
        """ Request a put command with a new value. """

        ch = pvaccess.Channel(self._pvname, self._protocol)
        ch.put(value)
Esempio n. 23
0
# takes Pva from AD and extracts the NTNDArray structure then
# creates a new pv that uses the same structure and hosts a random image.
# these new pv is them served as 'AdImage'.
# run it with:
#
# python -i test_03.py
#
# then from a terminal you can get the image with:
# pvget AdImage | more

import pvaccess as pva
import numpy as np
import time

c = pva.Channel('2bmbSP1:Pva1:Image')
pv1 = c.get('')
pv1d = pv1.getStructureDict()
print(pv1d)

exit()
# copy dictionaries for value and dimension fields
pv2 = pva.PvObject(pv1d)
image = (np.random.random([512, 256]) * 256).astype('float32')
pv2['value'] = ({'floatValue': image}, )
# set dimensions for data
pv2['dimension'] = [{'size':image.shape[0], 'fullSize':image.shape[0], 'binning':1},\
     {'size':image.shape[1], 'fullSize':image.shape[0], 'binning':1}]
s = pva.PvaServer('AdImage', pv2)
while (True):
    image = (np.random.random([512, 256])).astype('float32').flatten()
    pv2['value'] = ({'floatValue': image}, )
Esempio n. 24
0
def main():
    global app, img, x, y, MAX_FRAMES
    global args

    parser = argparse.ArgumentParser(description='AreaDetector video example')

    parser.add_argument(
        "ImagePV", help="EPICS PVA image PV name, such as 13PG2:Pva1:Image")
    parser.add_argument('--benchmark',
                        action='store_true',
                        help='measure framerate')
    parser.add_argument('--noAGC',
                        action='store_true',
                        help='disable auto gain')
    parser.add_argument('--frames',
                        help='maximum number of frames (-1: unlimited)')

    parser.add_argument('--bindip',
                        default=None,
                        help='ip address to bind tmq)')
    parser.add_argument('--port',
                        type=int,
                        default=5560,
                        help='Port address to bind tmq')
    parser.add_argument('--beg_sinogram',
                        type=int,
                        help='Starting sinogram for reconstruction')
    parser.add_argument('--num_sinograms',
                        type=int,
                        help='Number of sinograms to reconstruct')
    parser.add_argument('--mock_data',
                        action='store_true',
                        default=False,
                        help='Mock data acquisition from file')
    parser.add_argument('--mock_file',
                        help='File name for mock data acquisition')

    args = parser.parse_args()

    global start_sino, num_sinos, mock_data
    start_sino = args.beg_sinogram
    num_sinos = args.num_sinograms
    mock_data = args.mock_data

    if mock_data:
        print("Mock data is set")
        setup_mock_data(args.mock_file)

    app = QtGui.QApplication([])
    win = QtWidgets.QWidget()
    win.setWindowTitle('daqScope')
    layout = QtGui.QGridLayout()
    layout.setMargin(0)
    win.setLayout(layout)
    img = RawImageWidget(win)
    layout.addWidget(img, 0, 0, 0, 0)
    win.show()
    chan = pvaccess.Channel(args.ImagePV)

    global x, y
    x, y = chan.get('field()')['dimension']
    x = x['size']
    y = y['size']
    win.resize(x, y)

    #### Setup TMQ #####
    tmq.init_tmq()
    # Handshake w. remote processes
    # For set TMQ for 2 sinograms
    print(type(x))
    print(type(num_sinos))
    if mock_data:
        print("Mock data handshake: input data shape={}".format(idata.shape))
        tmq.handshake(args.bindip, args.port, int(num_sinos), idata.shape[2])
    else:
        print("Streaming data handshake: input data shape={},{}".format(
            int(num_sinos), int(x)))
        tmq.handshake(args.bindip, args.port, int(num_sinos), int(x))
    ####################

    chan.subscribe('update', update)
    chan.startMonitor()

    if args.benchmark:
        start = time.time()

    # Finalize streaming ?
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
        chan.stopMonitor()
        chan.unsubscribe('update')
        print("Remove")
        # Finalize TMQ
        tmq.done_image()
        tmq.finalize_tmq()

    if args.benchmark:
        stop = time.time()
        print('Frames displayed: %d' % framesDisplayed)
        print('Elapsed time:     %.3f sec' % (stop - start))
        print('Frames per second: %.3f FPS' % (framesDisplayed /
                                               (stop - start)))
Esempio n. 25
0
def pvget(name, as_string=False, use_ca=True):
    channel = pvaccess.Channel(name, pvaccess.CA if use_ca else pvaccess.PVA)
    return _pvget(channel, as_string=as_string)
Esempio n. 26
0
    def __init__(self, pv_files, macros):

        log.setup_custom_logger("./tomostream.log")

        # init pvs
        self.config_pvs = {}
        self.control_pvs = {}
        self.pv_prefixes = {}

        if not isinstance(pv_files, list):
            pv_files = [pv_files]
        for pv_file in pv_files:
            self.read_pv_file(pv_file, macros)
        self.show_pvs()
        self.epics_pvs = {**self.config_pvs, **self.control_pvs}
        
        
        prefix = self.pv_prefixes['TomoScan']
        # tomoscan pvs
        self.epics_pvs['FrameType']          = PV(prefix + 'FrameType')
        self.epics_pvs['NumAngles']          = PV(prefix + 'NumAngles')
    
        self.epics_pvs['RotationStep']       = PV(prefix + 'RotationStep')
        
        # Replace PSOPVPrefix to link to check a TomoScanStream PV so it returns if scan IOC is down
        # self.epics_pvs['PSOPVPrefix']        = PV(prefix + 'PSOPVPrefix')
        # if self.epics_pvs['PSOPVPrefix'].get(as_string=True) == None:
        #     log.error("TomoScan is down")
        #     log.error("Type exit() here and start TomoScan first")
        #     return
  
        # pva type channel for flat and dark fields pv broadcasted from the detector machine
        self.epics_pvs['PvaDark']        = pva.Channel(self.epics_pvs['DarkPVAName'].get())
        self.pva_dark = self.epics_pvs['PvaDark']
        self.epics_pvs['PvaFlat']        = pva.Channel(self.epics_pvs['FlatPVAName'].get())
        self.pva_flat = self.epics_pvs['PvaFlat']   
        self.epics_pvs['PvaTheta']        = pva.Channel(self.epics_pvs['ThetaPVAName'].get())
        self.pva_theta = self.epics_pvs['PvaTheta']   
        
        # pva type channel that contains projection and metadata
        image_pv_name = PV(self.epics_pvs['ImagePVAPName'].get()).get()
        self.epics_pvs['PvaPImage']          = pva.Channel(image_pv_name + 'Image')
        self.epics_pvs['PvaPDataType_RBV']   = pva.Channel(image_pv_name + 'DataType_RBV')
        self.pva_plugin_image = self.epics_pvs['PvaPImage']
        
        # create pva type pv for reconstrucion by copying metadata from the data pv, but replacing the sizes
        # This way the ADViewer (NDViewer) plugin can be also used for visualizing reconstructions.
        pva_image_data = self.pva_plugin_image.get('')
        pva_image_dict = pva_image_data.getStructureDict()        
        self.pv_rec = pva.PvObject(pva_image_dict)
    
        # run server for reconstruction pv
        recon_pva_name = self.epics_pvs['ReconPVAName'].get()
        self.server_rec = pva.PvaServer(recon_pva_name, self.pv_rec)

        self.epics_pvs['StartRecon'].put('Done')
        self.epics_pvs['AbortRecon'].put('Yes')
        
        self.epics_pvs['StartRecon'].add_callback(self.pv_callback)
        self.epics_pvs['AbortRecon'].add_callback(self.pv_callback)
        
         # Set ^C, ^Z interrupt to abort the stream reconstruction
        signal.signal(signal.SIGINT, self.signal_handler)
        signal.signal(signal.SIGTSTP, self.signal_handler)


        # Start the watchdog timer thread
        thread = threading.Thread(target=self.reset_watchdog, args=(), daemon=True)
        thread.start()
Esempio n. 27
0
#!/usr/bin/env python

from __future__ import print_function

import time
import pvaccess

def monitor(pvObject):
    ntTable = pvaccess.NtTable(pvObject)
    print("Full NT Table")
    print(ntTable)
    print("Column 0:")
    print(ntTable.getColumn(0))

c = pvaccess.Channel('testTable')
c.subscribe('m1', monitor)
c.startMonitor('field()')
time.sleep(10)
c.unsubscribe('m1')

Esempio n. 28
0
# Read PV from examples/iocBoot/iocExample
import pvaccess
c = pvaccess.Channel('training:calc1')
print(c.get())

Esempio n. 29
0
def streaming(theta, nthetap):
    """
    Main computational function, take data from pvdata ('2bmbSP1:Pva1:Image'),
    reconstruct orthogonal slices and write the result to pvrec ('AdImage')
    """

    # init streaming pv for the detector
    c = pva.Channel('2bmbSP1:Pva1:Image')
    pvdata = c.get('')
    # take dimensions
    n = pvdata['dimension'][0]['size']
    nz = pvdata['dimension'][1]['size']

    # init streaming pv for reconstrucion with copuing dictionary from pvdata
    pvdatad = pvdata.getStructureDict()
    pvrec = pva.PvObject(pvdatad)
    # set dimensions for data
    pvrec['dimension'] = [{
        'size': 3 * n,
        'fullSize': 3 * n,
        'binning': 1
    }, {
        'size': n,
        'fullSize': n,
        'binning': 1
    }]
    s = pva.PvaServer('AdImage', pvrec)

    # init with slices through the middle
    ix = n // 2
    iy = n // 2
    iz = nz // 2

    # I suggest using buffers that has only certain number of angles,
    # e.g. nhetap=50, this buffer is continuously update with monitoring
    # the detector pv (function addProjection), called inside pv monitor
    databuffer = np.zeros([nthetap, nz, n], dtype='float32')
    thetabuffer = np.zeros(nthetap, dtype='float32')

    def addProjection(pv):
        curid = pv['uniqueId']
        databuffer[np.mod(curid,
                          nthetap)] = pv['value'][0]['ubyteValue'].reshape(
                              nz, n).astype('float32')
        thetabuffer[np.mod(curid, nthetap)] = theta[np.mod(
            curid, ntheta)]  # take some theta with respect to id

    c.monitor(addProjection, '')

    # solver class on gpu
    with OrthoRec(nthetap, n, nz) as slv:
        # memory for result slices
        recall = np.zeros([n, 3 * n], dtype='float32')
        while (True):  # infinite loop over angular partitions
            # new = take ix,iy,iz from gui
            new = None
            flgx, flgy, flgz = 0, 0, 0  # recompute slice or not
            if (new != None):
                [newx, newy, newz] = new
                if (newx != ix):
                    ix = newx  # change slice id
                    flgx = 1  # recompute flg
                if (newy != iy):
                    iy = newy
                    flgy = 1
                if (newz != iz):
                    iz = newz
                    flgz = 1

            # take interlaced projections and corresponding angles
            # I guess there should be read/write locks here.
            datap = databuffer.copy()
            thetap = thetabuffer.copy()

            print('data partition norm:', np.linalg.norm(datap))
            print('partition angles:', thetap)

            # recover 3 ortho slices
            recx, recy, recz = slv.rec_ortho(datap, thetap, n // 2, ix, iy, iz,
                                             flgx, flgy, flgz)

            # concatenate (supposing nz<n)
            recall[:nz, :n] = recx
            recall[:nz, n:2 * n] = recy
            recall[:, 2 * n:] = recz

            # 1s reconstruction rate
            time.sleep(1)

            # write to pv
            pvrec['value'] = ({'floatValue': recall.flatten()}, )
 def __init__(self):
     #Define all channels with CA
     self.EvgPrescaleSP1 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:Mxc2-Prescaler-SP", pvaccess.ProviderType.CA)
     self.EvgPrescaleSP2 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:Mxc3-Prescaler-SP", pvaccess.ProviderType.CA)
     self.EvgPrescaleSP3 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:Mxc4-Prescaler-SP", pvaccess.ProviderType.CA)
     self.EvgPrescaleSP4 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:Mxc5-Prescaler-SP", pvaccess.ProviderType.CA)
     self.EvgEvtCode1 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:TrigEvt2-EvtCode-SP",
         pvaccess.ProviderType.CA)
     self.EvgEvtCode2 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:TrigEvt3-EvtCode-SP",
         pvaccess.ProviderType.CA)
     self.EvgEvtCode3 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:TrigEvt4-EvtCode-SP",
         pvaccess.ProviderType.CA)
     self.EvgEvtCode4 = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:TrigEvt5-EvtCode-SP",
         pvaccess.ProviderType.CA)
     self.EvrOutEvtTrig = pvaccess.Channel(
         "MDTST{evr:1-DlyGen:3}Evt:Trig0-SP", pvaccess.ProviderType.CA)
     self.EvrInEvt = pvaccess.Channel("MDTST{evr:1-In:0}Code:Ext-SP",
                                      pvaccess.ProviderType.CA)
     self.EvrCptEvtSP1 = pvaccess.Channel("MDTST{evr:1-tsflu:1}CptEvt-SP",
                                          pvaccess.ProviderType.CA)
     self.EvrCptEvtSP2 = pvaccess.Channel("MDTST{evr:1-tsflu:2}CptEvt-SP",
                                          pvaccess.ProviderType.CA)
     self.EvrCptEvtSP3 = pvaccess.Channel("MDTST{evr:1-tsflu:3}CptEvt-SP",
                                          pvaccess.ProviderType.CA)
     self.EvrCptEvtSP4 = pvaccess.Channel("MDTST{evr:1-tsflu:4}CptEvt-SP",
                                          pvaccess.ProviderType.CA)
     self.EvrCptEvtPrevSP1 = pvaccess.Channel(
         "MDTST{evr:1-tsprev:1}CptEvt-SP", pvaccess.ProviderType.CA)
     self.EvrFlshEvtSP1 = pvaccess.Channel("MDTST{evr:1-tsflu:1}FlshEvt-SP",
                                           pvaccess.ProviderType.CA)
     self.EvrFlshEvtSP2 = pvaccess.Channel("MDTST{evr:1-tsflu:2}FlshEvt-SP",
                                           pvaccess.ProviderType.CA)
     self.EvrFlshEvtSP3 = pvaccess.Channel("MDTST{evr:1-tsflu:3}FlshEvt-SP",
                                           pvaccess.ProviderType.CA)
     self.EvrFlshEvtSP4 = pvaccess.Channel("MDTST{evr:1-tsflu:4}FlshEvt-SP",
                                           pvaccess.ProviderType.CA)
     self.EvrFlshEvtPrevSP1 = pvaccess.Channel(
         "MDTST{evr:1-tsprev:1}FlshEvt-SP", pvaccess.ProviderType.CA)
     self.EvrTSI1 = pvaccess.Channel("MDTST{evr:1-tsflu:1}TS-I",
                                     pvaccess.ProviderType.CA)
     self.EvrTSI2 = pvaccess.Channel("MDTST{evr:1-tsflu:2}TS-I",
                                     pvaccess.ProviderType.CA)
     self.EvrTSI3 = pvaccess.Channel("MDTST{evr:1-tsflu:3}TS-I",
                                     pvaccess.ProviderType.CA)
     self.EvrTSI4 = pvaccess.Channel("MDTST{evr:1-tsflu:4}TS-I",
                                     pvaccess.ProviderType.CA)
     self.EvrTSIPrev1 = pvaccess.Channel("MDTST{evr:1-tsprev:1}TS-I",
                                         pvaccess.ProviderType.CA)
     self.EvrCptEvtFirSP1 = pvaccess.Channel(
         "MDTST{evr:1-tsfir:1}CptEvt-SP", pvaccess.ProviderType.CA)
     self.EvrFlshEvtFirSP1 = pvaccess.Channel(
         "MDTST{evr:1-tsfir:1}FlshEvt-SP", pvaccess.ProviderType.CA)
     self.EvrCptEvtFirSP2 = pvaccess.Channel(
         "MDTST{evr:1-tsfir:2}CptEvt-SP", pvaccess.ProviderType.CA)
     self.EvrFlshEvtFirSP2 = pvaccess.Channel(
         "MDTST{evr:1-tsfir:2}FlshEvt-SP", pvaccess.ProviderType.CA)
     self.EvrTSIFir1 = pvaccess.Channel("MDTST{evr:1-tsfir:1}TS-I",
                                        pvaccess.ProviderType.CA)
     self.EvrTSIFir2 = pvaccess.Channel("MDTST{evr:1-tsfir:2}TS-I",
                                        pvaccess.ProviderType.CA)
     self.EvrManFlshFir2 = pvaccess.Channel("MDTST{evr:1-tsfir:2}Flsh-SP",
                                            pvaccess.ProviderType.CA)
     self.EvrDropI1 = pvaccess.Channel("MDTST{evr:1-tsflu:1}Drop-I",
                                       pvaccess.ProviderType.CA)
     self.EvrDropI2 = pvaccess.Channel("MDTST{evr:1-tsflu:2}Drop-I",
                                       pvaccess.ProviderType.CA)
     self.EvgSeq2Unit = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:SoftSeq2-TsResolution-Sel",
         pvaccess.ProviderType.CA)
     self.EvgSeq2Evts = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:SoftSeq2-EvtCode-SP",
         pvaccess.ProviderType.CA)
     self.EvgSeq2TS = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:SoftSeq2-Timestamp-SP",
         pvaccess.ProviderType.CA)
     self.EvgSeq2Commit = pvaccess.Channel(
         "Utgard:MDS:TS-EVG-01:SoftSeq2-Commit-Cmd",
         pvaccess.ProviderType.CA)
     self.EvrRBCptEvtSP1 = pvaccess.Channel("MDTST{evr:1-ts:1}CptEvt-SP",
                                            pvaccess.ProviderType.CA)
     self.EvrRBCptEvtRB1 = pvaccess.Channel("MDTST{evr:1-ts:1}CptEvt-RB",
                                            pvaccess.ProviderType.CA)
     self.EvrTSI1Alrm = pvaccess.Channel("MDTST{evr:1-tsflu:1}TS-I")