本章中讨论了使用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"
以下是这款面探测器的介绍:
技术信息:Lambda是一个55um像素大小并且具有高帧率功能的单光子计数X射线探测器。一个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 xspcontrol as xc
import pyxsp as px
s = xc.System('/opt/xsp/config/system.yml')
d = s.open_detector('lambda')
r = s.open_receiver('lambda/1')
d.number_of_frames = 1
d.shutter_time = 1000.0
d.bit_depth = px.BitDepth.DEPTH_12
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)
while not r.ready:
time.sleep(1)
s.start_acquisition()
del r
del d
del w
del s
由于探测器的数据文件格式为nexus,而ADURL模块不能读取这个格式的文件,需要进行格式类型的转换,厂家也提供了将nexus格式转为tif格式的python程序ConvertNxsToTIFF.py,转换后的文件格式是ADURL模块可以读取的;编写一个bash脚本execute.sh,将采集和转换放在一个脚本中,并且触发ADURL模块程序进行数据读取:
#!/bin/bash
# 删除指定路径下所有文件,此路径提供给探测器保存数据使用
rm -rf /home/xspadmin/data/*
# 触发探测器采集,并且保存数据到指定路径
python /home/xspadmin/command/collect.py
# 把nxs文件转成tif文件,ADURL模块才能读取
python /home/xspadmin/NxsToTiff_Scripts/ConvertNxsToTIFF.py --r /home/xspadmin/data/data_00000.nxs
# 触发ADURL模块读取数据
caput 13URL1:cam1:Acquire 1
编写一个IOC程序来执行以上的bash脚本,在这个IOC程序中使用了一个sub记录,此记录执行时可以调用系统命令来执行这个程序脚本。
以下是这个C程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dbDefs.h>
#include <registryFunction.h>
#include <subRecord.h>
#include <epicsExport.h>
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", precord->desc);
printf("execute command: %s\n", cmdstr);
system(cmdstr);
return 0;
}
epicsExportAddress(int, mySubDebug);
epicsRegisterFunction(mySubInit);
epicsRegisterFunction(mySubProcess);
对应的db文件如下:
record(sub, "$(P)$(R)ExecuteLambda")
{
field(SNAM,"mySubProcess")
field(DESC, "execute.sh")
}
对应的启动文件为:
#!../../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
如果设置了ImageJ插件中数据的访问通道:
在ADURL读取了数据后,将实时显示这个数据: