areadetector ADURL模块应用在面探测控制的初步应用

本章中讨论了使用ADURL控制面探测器Lambda的过程:

ADURL的使用请见:

EPICS -- areaDetector URL驱动程序-CSDN博客

需要启动一个ADURL的IOC程序,并且设置相关的插件中参数的值:

# st.cm
< envPaths
< st_base.cmd

dbpf 13URL1:cam1:URL1 "/home/xspadmin/data/data_00000_raw/data_00000_raw_000000.tif"
dbpf 13URL1:image1:EnableCallbacks "1"
dbpf 13URL1:Pva1:EnableCallbacks "1"
dbpf 13URL1:image1:BlockingCallbacks "1"
dbpf 13URL1:Pva1:BlockingCallbacks "1"
dbpf 13URL1:TIFF1:EnableCallbacks "1"
dbpf 13URL1:TIFF1:BlockingCallbacks "1"
dbpf 13URL1:cam1:ImageMode "Single"

以下是这款面探测器的介绍:

areadetector ADURL模块应用在面探测控制的初步应用_第1张图片

areadetector ADURL模块应用在面探测控制的初步应用_第2张图片

Lambda探测器一个55um像素大小并且具有高帧率功能的单光子计数X射线探测器。

其官方网页:Lambda – X-Spectrum

技术信息:一个Si 250K系统的技术规格如下表所示:

模块数目 1个模块带有1个连接了4个读出芯片的传感器
传感器 Si二极管阵列
量子效率 95%@8KeV, 70%@12KeV,10%@25KeV
读出芯片 Medipix3RXv2
像素尺寸 55 X 55 um^2
传感器尺寸 28.4 X 28.4 mm^2
格式 512 X 512 pixels(262144)
动态范围 最大24位(取决于读出模式)
每个像素计数率限制

200000个/像素/s(不带计数率校准)

800000个/像素/s(如果计数率校准测量和使用)

能量范围 6keV ~ 20kev
能量分辨率 2keV
最大帧率

2000Hz@12-bit模式

4000Hz@6-bit模式

24000Hz@1-bit模式

读出时间

12-bit, 6-bit, 1-bit模式,无读出时间

24-bit模式,1ms

点扩散函数 1像素FWHM
数据格式 Hdf5(Nexus标准)
外部触发/门控 3.3V
软件接口 基于C++的硬件库,python包
冷却 气冷,水冷
尺寸 150.5mm长,85mm宽和40mm长
重量 1.2kg
过压类别 0
污染等级 II

对厂家提供探测器操作的Python代码进行封装,编写一个采集保存的py文件:

import sys
import xspcontrol as xc
import pyxsp as px

shutter_time = sys.argv[1]
numfs = sys.argv[2]



s = xc.System('/opt/xsp/config/system.yml')
d = s.open_detector('lambda')
r = s.open_receiver('lambda/1')
d.operation_mode = px.OperationMode(px.BitDepth.DEPTH_24, px.ChargeSumming.OFF, px.CounterMode.SINGLE, px.Pitch.PITCH_55)
d.number_of_frames = int(numfs)
d.shutter_time = float(shutter_time)
d.bit_depth = px.BitDepth.DEPTH_24
w = xc.Writer()
w.save_to_file = True
w.save_mode =  xc.SaveMode.OVERWRITE
w.save_directory = '/home/xspadmin/data'
w.save_file_prefix = 'data'
s.set_writer('lambda/1', w)
s.frame_timeout_ms = d.shutter_time+10000


while not r.ready:
    time.sleep(1)

s.start_acquisition()

while not s.acquisition_finished:
    time.sleep(0.5)



del r
del d
del w
del s

由于探测器的数据文件格式为nexus,而ADURL模块不能读取这个格式的文件,需要进行格式类型的转换,厂家也提供了将nexus格式转为tif格式的python程序ConvertNxsToTIFF.py,转换后的文件格式是ADURL模块可以读取的;编写一个bash脚本execute.sh,将采集和转换放在一个脚本中,并且触发ADURL模块程序进行数据读取:

#!/bin/bash

#echo "$1"
#echo "$2"

if [ "$#" != 2 ]; then
        shutter_time=1.0
        num_frames=1
else
        shutter_time=$1
        num_frames=$2
fi

#echo "shutter_time:", $shutter_time, "num_frames:", $num_frames
rm -rf /home/xspadmin/data/data_00000_raw
python /home/xspadmin/command/collect.py $shutter_time $num_frames
python /home/xspadmin/NxsToTiff_Scripts/ConvertNxsToTIFF.py --r /home/xspadmin/data/data_00000.nxs


filename=$(date  "+%Y-%m-%d-%H_%M_%S")
mv  /home/xspadmin/data/data_00000.nxs /home/xspadmin/data/data_$filename.nxs

caput 13URL1:cam1:Acquire 1

编写一个IOC程序来执行以上的bash脚本,在这个IOC程序中使用了一个sub记录,此记录执行时可以调用系统命令来执行这个程序脚本。

以下是这个C程序:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int mySubDebug = 0;
static char cmdstr[100];

static long mySubInit(struct subRecord *precord)
{
        if (mySubDebug)
        {
                printf("Record %s called mySubInit(%p)\n", precord->name, (void *)precord);
        }
        printf("subInit was called\n");
        return 0;
}

static long mySubProcess(struct subRecord * precord)
{
        if(mySubDebug)
        {
                printf("Record %s called mySubProcess(%p)\n", precord->name,(void *)precord);
        }
        precord->val++;

        sprintf(cmdstr, "%s %.2f %d", precord->desc, precord->a,  (int )precord->b);
        printf("execute command: %s\n", cmdstr);
        system(cmdstr);

        return 0;
}

epicsExportAddress(int, mySubDebug);
epicsRegisterFunction(mySubInit);
epicsRegisterFunction(mySubProcess);

对应的db文件如下:

record(bi, "$(P)$(R)ExecuteLambda")
{
    field(ONAM, "Start")
    field(ZNAM, "Stop")
    field(FLNK, "$(P)$(R)ExecuteLambdaCheck")
}

record(calcout, "$(P)$(R)ExecuteLambdaCheck")
{
    field(INPA, "$(P)$(R)ExecuteLambda")
    field(CALC, "A==1")
    field(OOPT, "When Non-zero")
    field(OUT, "$(P)$(R)ExecuteOK PP CA")
}

record(bo, "$(P)$(R)ExecuteOK")
{
    field(FLNK, "$(P)$(R)ExecuteLambdaStart")
}

record(bi, "$(P)$(R)ExecuteIndicate")
{
    field(ONAM, "Running")
    field(ZNAM, "Idle")
}

record(sub, "$(P)$(R)ExecuteLambdaStart")
{
    field(SCAN, "Passive")
    field(INPA, "$(P)$(R)TimeLambda")
    field(INPB, "$(P)$(R)FramesLambda")

    field(SNAM,"mySubProcess")
    field(DESC, "execute.sh")
    field(FLNK, "$(P)$(R)ExecuteLambdaFinsh.PROC")
}


record(ai, "$(P)$(R)TimeLambda")
{
    field(VAL, "1.0")
}

对应的启动文件为:

#!../../bin/linux-x86_64/lambda

#- You may have to change lambda to something else
#- everywhere it appears in this file

< envPaths

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/lambda.dbd"
lambda_registerRecordDeviceDriver pdbbase

## Load record instances
dbLoadRecords("db/lambda.db","P=13URL1:,R=cam1:")

cd "${TOP}/iocBoot/${IOC}"
iocInit

编译以上程序,并且启动以上IOC:

epics> dbl
13URL1:cam1:ExecuteLambda

执行通道访问命令运行一次sub记录:

 xspadmin@xspserver:/usr/local/EPICS/lambda/iocBoot/ioclambda$ caput 13URL1:cam1:ExecuteLambda.PROC 1

或者用CSS做成图像界面:

areadetector ADURL模块应用在面探测控制的初步应用_第3张图片 具有设置探测器快门时间以及每次采集中需要采集的帧数的功能,点击Collect开始采集。

如果设置了ImageJ插件中数据的访问通道:

areadetector ADURL模块应用在面探测控制的初步应用_第4张图片

在ADURL读取了数据后,将实时显示这个数据:

areadetector ADURL模块应用在面探测控制的初步应用_第5张图片

你可能感兴趣的:(EPICS教程,Linux,C,EPICS,C语言,linux)