5. 正在扫描

本节讨论扫描,这是在GDA中收集数据的主要方法。

5.1. 扫描的定义

在GDA中,有两种类型的扫描可用:基于步骤的扫描和连续扫描。连续或快速扫描是指探测器在其他硬件(如马达)运行期间一直在收集数据。这样的扫描可以非常方便,因为扫描可以花费更少的时间。然而,连续扫描给用户提供的灵活性较低,因为需要在扫描中涉及的特定电机和探测器电子设备之间布线。

步骤扫描不需要这样的特定布线。它们在硬件的移动和随后的探测器采集和读出之间有明显的分离。这样的扫描有两个对象列表:探测器和扫描仪。在步进扫描中的每个节点,操作扫描对象(这些操作按每个扫描对象具有的级别属性分组。因此,从最低级别到最高级别,特定级别的所有扫描仪都是同时操作的,一旦它们完成了它们的移动,就会操作下一个级别,依此类推。)一旦扫描仪已经运行,则同时从所有探测器收集数据,并且一旦它们全部完成,则来自该轮采集的数据加上所有扫描仪的新位置被记录到文件中。

可扫描对象是一种通用类型的对象,表示任何不是检测器的对象,它需要在每一轮数据采集之间操作。它们可以像马达一样简单,但也可以是基于几个马达位置的计算,或者Scanable甚至可以表示在扫描中的每个点都运行的脚本。

扫描对象可以定义为表示一个数字或数字数组。它们的操作类似于马达,即它们有方法来“移动”它们,一种方法来请求它们的状态以查看它们是否在移动,还有一种方法来获得它们的当前位置。它们是用户将在GDA中与之交互的主要对象类型

5.1.1. 步进式扫描仪结构

为了详细说明扫描的工作原理,下面列出了步进式扫描的结构。有关扫描各部分的说明,请参阅本节的睡觉。对于那些编写自己的Scanable类并需要详细了解扫描的人来说,这种结构应该很有帮助。

准备扫描:

  1. 对属于扫描一部分的所有可扫描对象调用atScanStart方法

  2. 如果已将标志设置为在扫描后将所有扫描件返回其原始位置,则记录所有扫描件的当前位置

  3. 创建新的数据文件

在每个级别迭代扫描的所有维度:

  1. 对所有扫描对象调用atScanLineStart方法

  2. 将该维度的可扫描对象移动到其下一步

  3. 如果位于最内侧的维度,则循环通过该扫描中的所有点。在每个点上:

    1. 在扫描中的每个可扫描对象上调用atPointStart

    2. 移动该尺寸的扫描仪以及扫描中不是单独尺寸的所有其他扫描仪(如果命令行中的参数显示应操作扫描仪)。此时要操作的所有扫描对象都按其级别属性定义的组进行操作。一旦某一级别中的所有扫描对象都完成了移动(这可以通过轮询其isBusy方法得知),则操作下一级别中的扫描对象

    3. 从扫描过程中的所有检测器收集数据

    4. 在数据文件中记录数据和扫描位置。需要时,数据还会广播到GDA客户端进行可视化。这是循环中调用Scanables的getPosition方法的唯一点

    5. 在扫描中的每个可扫描对象上调用atPointEnd

  4. 对扫描中的每个可扫描对象调用atScanLineEnd方法

完成扫描:

  1. 对扫描中的每个可扫描对象调用atScanEnd方法

  2. 关闭数据文件

  3. 如果已将标志设置为在扫描后将所有扫描对象返回其原始位置,则将所有扫描对象移回开始位置

5.2. 扫描命令

扫描命令的格式为::

scan <scannable> <start> <stop> <step> [<scannable> [<start>] [<stop>] [<step>]] ...
     ... [<detector1>] [<detector2>]

只需要第一个扫描对象及其起始值、停止值和步长值。其他扫描仪是可选的,可以在扫描过程中操作,或者只在扫描的每一步记录它们的位置。如果后续可扫描对象的名称后有三个参数,则这将被视为扫描的额外维度。扫描中可以包含的维度数量没有限制。

检测器在命令中也是可选的:在GDA Jython环境中,有一个默认扫描对象和检测器列表,它们将包含在每次扫描中,而不必将对象包括在扫描命令中。

为了解释此格式提供的各种可能选项,下面是一些更明确的解释,后面跟着示例:

5.2.1. 其他类型的步进扫描

还有以类似方式工作但采用替代输入参数的其他步骤扫描可用。这些扫描及其命令是:

重新宣布!

5.3. 扫描选项

扫描命令由要移动或观察的扫描列表和要触发的检测器列表组成。在扫描的每个点,在可扫描器和检测器完成其任务之后,读取并记录可扫描器的位置和来自检测器的数据。默认情况下,除非给予扫描件不同的优先级,否则它们将同时移动(请参阅下面关于优先级的一节)。有许多不同类型的扫描,每种扫描都使用不同的语法调用:

  • 单参数扫描 ::

    >>> scan scannable start stop step [detector [exposure time]]
    

    可扫描对象以步长步长从起始值扫描到停止值。如果指定,则在每个点都会触发检测器。可以为检测器提供可选的曝光时间。

  • 并发移动的参数扫描 ::

    >>> scan scannable start stop step scannable2 start step (detector)
    

    第二个扫描仪与第一个扫描仪同时变化。第二个设备不需要停止值,因为访问的点数由第一个设备的值确定。

  • 多维扫描 ::

    >>> scan scannable start stop step scannable2 start stop step (detector)
    

    该示例是二维扫描,其中在第一个可扫描对象的每次移动之后执行对scannable2的整个扫描。

  • Move-to-keep-still scan ::

    >>> scan scannable start stop step scannable2 start (detector)
    

    在该示例中,scannable2被移动到开始位置,然后在扫描scannable2时保持该位置。下面的一个示例说明了这可能有用的原因。

    在扫描中的每个点上,与来自探测器的数据一起,数据文件中会存储一行记录命令中列出的每个可扫描对象的值。这意味着扫描件可以像探测器一样使用来记录值。例如。

  • 监视可扫描设备 ::

    >>> scan scannable start stop step scannable2 scannable3 (detector)
    

    对于扫描中的每个点,记录第二个和第三个扫描对象(当然还有第一个扫描对象)的值。

任何扫描中可以包含的扫描仪或检测器的数量没有限制。可以混合使用这些命令的语法来构建复杂的扫描。

5.4. 示例扫描命令

以下是在钻石的光束线上使用的一些有用的示例扫描。

能量扫描。扫描命令可用于扫描照亮样本的光子的能量或波长。例如:

>>> scan pgmenergy 500 2000 0.1 uv 2

这以0.1 eV的步长扫描500 eV到2000 eV的X射线能量。在每个扫描点,都会从一台名为UV的相机上拍摄一张图像。相机曝光时间设置为2秒。此命令与以下命令相同::

>>> scan pgmenergy 500 2000 0.1 ca43s 0.5

除了在每个点上之外,通过从标量卡通道CA43S读取来测量漏电流。定标卡计数时间设置为0.5秒。(这些命令来自I06,需要在光束线上定义pgmenergy、uv和ca43s。)

时间扫描。SCAN命令可用于执行关于时间::的扫描

>>> scan x 1 100 1 ct4 1 detector

这将扫描一个虚拟的Scanable x,它只充当一个计数器。对于x的每一步,定时器可扫描CT4等待一秒,然后触发检测器。这是一个有用的扫描,用于跟踪测量的稳定性或查看如果移动另一个设备会发生什么情况。(这是来自16号州际公路的。要使用此命令,必须在光束线中定义x和CT4的可扫描。)

移动到保持静止扫描。扫描命令可以扫描某些自由度,同时保持第二个常数,即使第二个自由度受到第一个自由度的影响。例如::

>>> scan en 7.0 7.1 0.001 hkl 100 detector

这扫描控制由单色仪选择的能量或波长的可扫描EN。随着波长的变化,感兴趣的散射射线离开样品的角度也会变化。为了检测这种射线,样品必须随着波长的变化而旋转,以保持射线指向固定的探测器。可扫描HK1100对样本进行定向,从而检测由米勒指数(1,0,0)描述的特定射线。由于该取向是波长的函数,因此可扫描的hkl将使样本在扫描波长时适当地旋转。

5.5. 默认设备和检测器

您可能需要在每次扫描中操作一些扫描仪或检测器。为避免每次扫描时都必须键入对象的名称,每次扫描中都会包含一个“默认值”列表:

list_defaults

返回在每次扫描中操作的默认对象列表

add_default <object name>

将给定对象添加到默认值列表

remove_default <object name>

将给定对象从默认列表中删除。

您可能会发现,启动GDA时,某些检测器会自动添加到默认列表中。

5.6. 配置可扫描移动优先级(级别)

通常情况下,扫描对象在点之间同时移动;也就是说,它们都同时开始移动,一旦(一个接一个)完成移动,数据就会被读取和记录。但是,也可以明确定义扫描件的数字优先级。设备按顺序移动到下一个扫描点,优先级最高(编号最低)的设备最先移动。从最高优先级开始,同时移动具有该优先级的所有设备。一旦这些设备完成移动,就会移动下一个最高优先级的所有设备,依此类推。一旦该序列完成并且所有设备都已到达最终位置,则对所有检测器的值和所有设备的位置进行采样和记录。

扫描仪的默认级别为5。可以使用LEVEL命令读取或修改该值。

要返回可扫描的级别(较高优先级=较低数字),请执行以下操作:

>>> level <Scannable>

要将可扫描对象的级别设置为给定值,请执行以下操作:

>>> level <Scannable> <integer>

例如,要移动x和y,其中y的实际位置取决于x的位置,则x的优先级应设置为高于y的优先级。在x完成其移动之前,y现在不会移动;如果y读取x的值以用于计算,则它将使用新值x。

作为另一个例子,如果要求移动到n,等待设备可以简单地等待n秒。要在所有设备都已移动之后使用这一点来增加建立延迟,请将其指定为低优先级。一旦设备的睡觉已经移动,在读取所有设备的位置并触发检测器之前,等待设备将‘移动’n秒。