stub计划
这些是用于合成上述的"成分",制作以上预组装计划的片段。对这些组件的介绍见本教程编写自定义计划。
用于与硬件交互的计划:
bluesky.plan_stubs.abs_set
# 设置一个值。可选的,在继续前等待它结束。
bluesky.plan_stubs.abs_set(obj, *args, group=None, wait=False, **kwargs)
"""
参数:
1、obj:Device
2、group:string (或者任何可哈希的对象), 可选,由'wait'使用的标识符
3、wait:boolean, 可选。如果True,在处理更多消息前,等待。默认,False。
4、args:被传递给obj.set()
5、kwargs:被传递给obj.set()
生成:msg:Msg
"""
bluesky.plan_stubs.rel_set
# 相对当前值设置一个值。可选的,在继续前等待它结束。
bluesky.plan_stubs.rel_set(obj, *args, group=None, wait=False, **kwargs)
"""
参数:
1、obj:Device
2、group:string (或者任何可哈希的对象), 可选,由'wait'使用的标识符
3、wait:boolean, 可选。如果True,在处理更多消息前,等待。默认,False。
4、args:被传递给obj.set()
5、kwargs:被传递给obj.set()
生成:msg:Msg
"""
bluesky.plan_stubs.mv
# 一个一个或多个Devices到一个设置点。等待它们都结束。如果制定了多个设备,移动是并行执行的。
bluesky.plan_stubs.mv(*args, group=None, **kwargs)
"""
参数:
1、args:device1, value1, device2,value2, ...
2、group:string,可选的。用于标记被等待的这些作为一个单位
3、kargs:传递给obj.set()
生成:msg:Msg
"""
bluesky.plan_stubs.mvr
# 移动一个或多个Devices到一个相对设置点。等待它们都结束。如果指定了多个设备,移动是并行执行的。
bluesky.plan_stubs.mvr(*args, group=None, **kwargs)
"""
参数:
1、args:device1, value1, device2,value2, ...
2、group:string,可选的。用于标记被等待的这些作为一个单位
3、kargs:传递给obj.set()
生成:msg:Msg
"""
bluesky.plan_stubs.trigger
# 触发和采集。可选地,等待它结束。
bluesky.plan_stubs.trigger(obj, *, group=None, wait=False)
"""
Trigger and acquisition. Optionally, wait for it to complete.
参数:
1、obj:Device
2、group:string (或者任何可哈希对象), 可选地。由'wait'使用地标识符。默认None
3、wait:boolean, 可选地。如果True,在再处理任何消息前,等待结束。默认False。
生成:msg:Msg
"""
bluesky.plan_stubs.read
# 获取读数并且添加它到当前一组读数中
bluesky.plan_stubs.read(obj)
"""
参数:
1、obj:Device或signal
产生:msg:Msg Msg('read', obj)
"""
bluesky.plan_stubs.rd
# 读取一个单值非触发的对象。
bluesky.plan_stubs.rd(obj, *, default_value=0)
"""
这是一个helper计划,获取一个Device(诸如EpicsMotor或单个EpicsSignal)的scaler值。
对于实现了Locatable协议的设备,位置是典型的,并且被返回,步解析这个读取键。
对于有多个读取键的设备,使用以下规则:
如果确实1个字段被提示,使用那个值。
如果没有字段被提示,并且在读取中确实1个值,使用那个值。
如果多个字段被提示,产生一个异常。
如果没有字段被提示,并且再读取中有多个键,产生一个异常。
设备不被触发,并且这个计划不创建任何事件。
参数:
1、obj:Device,要被读取的设备。
2、default_value:Any,当没在一个'活的'RunEngine中运行时,要返回的值。当
ret = yield Msg('read', obj)
assert ret is None
时,这出现。
这个计划被传递给list或者某个其它迭代器,它重复发送None到这个计划来推进这个生成器。
返回:
val:Any 活 None 设备的"单"值。
"""
bluesky.plan_stubs.stage
# ‘Stage’一个设备(即是:准备使用它,’arm‘它)
bluesky.plan_stubs.stage(obj, *, group=None, wait=None)
"""
参数:
1、obj:Device
2、group:string (或任何可哈希对象or any hashable object),可选的。
'wait'使用的标识符;默认None
3、wait:boolean, 可选,如果True,在处理任何消息前,等待结束,默认False。
生成:msg:Msg
"""
bluesky.plan_stubs.unstage
# 'unstage'一个设备(即:让它待机,'disarm'它)
bluesky.plan_stubs.unstage(obj, *, group=None, wait=None)
"""
参数:
1、obj:Device
2、group:string (或任何可哈希对象or any hashable object),可选的。
'wait'使用的标识符;默认None
3、wait:boolean, 可选,如果True,在处理任何消息前,等待结束,默认False。
生成:msg:Msg
"""
bluesky.plan_stubs.configure
# 更改设备配置并且发出一个被更新的Event描述符文档。
bluesky.plan_stubs.configure(obj, *args, **kwargs)
"""
参数:
1、obj:Device
2、args:被传递给obj.configure()
3、kwargs:被传递给obj.configure()
生成:msg:Msg Msg('configure', obj, *args, **kwargs)
"""
bluesky.plan_stubs.stop
# 停止一个设备
bluesky.plan_stubs.stop(obj)
"""
参数:
obj:Device
产生:msg:Msg
"""
用于异步采集的计划:
bluesky.plan_stubs.monitor
# 对新值的异步监视并且发出Event文档。
bluesky.plan_stubs.monitor(obj, *, name=None, **kwargs)
"""
参数:
1、obj:Signal
2、args:传递给obj.subscribe()
3、name:string, 可选,事件流的名称,默认None
4、kargs:传递给obj.subscribe()
生成:msg:Msg Msg('monitor', obj, *args, **kwargs)
"""
bluesky.plan_stubs.unmonitor
# 停止监控
bluesky.plan_stubs.unmonitor(obj)
"""
参数:
obj:Signal
生成:msg:Msg Msg(‘unmonitor’, obj)
"""
bluesky.plan_stubs.kickoff
# 启动一个飞行扫描设备。
bluesky.plan_stubs.kickoff(obj, *, group=None, wait=False, **kwargs)
"""
参数:
1、obj:fly-able,带有'kickoff', 'complete'和'collect'方法的设备。
2、group:string (或任何可哈希对象), 可选的,由'wait'使用的标识符
3、wait:boolean, 可选,如果True,在再处理任何消息前,等待结束。默认False。
4、kwargs:传递给obj.kickoff()。
生成:msg:Msg Msg(‘kickoff’, obj)
"""
bluesky.plan_stubs.complete
# 告诉一个flyer,'一旦你准备好了,停止采集'
bluesky.plan_stubs.complete(obj, *, group=None, wait=False, **kwargs)
"""
这个flyer返回一个状态status对象.一些flyers通过立即停止采集并且返回一个结束的status对象,
响应这个命令. 其他flyers结束它们给定的course并且在它们结束时结束,无论是否发送这个命令.
参数:
1 obj: fly-able 带有‘kickoff’, ‘complete’, 和 ‘collect’ 方法的设备.
2 group: string (或者任何可哈希的对象), 可选的. 由'wait'使用的标识符
3 wait: boolean,可选的,如果True, 在处理任何消息前,等待结束. 默认False
4 kwargs: 传给obj.complete()
生成: msg:Msg 一个'complete'Msg,并且可能是'wait'消息
"""
bluesky.plan_stubs.collect
# 采集由一个飞行扫描设备缓存的数据并且发出文档。
bluesky.plan_stubs.collect(obj, *, stream=False, return_payload=True, name=None)
"""
参数:
1、obj:fly-able,带有'kickoff', 'complete'和'collect'方法的设备
2、stream:boolean, 可选的,如果False(默认),用一个批量存储发出Event文档。如果True,一次一个发送事件。
3、return_payload: boolean, 可选的,如果True,返回收集的事件。如果False,返回None。一起使用stream=True和return_payload=False,避免在内存中积累文档:在采集它们时,它们被发出,并且它们不被累积。
4、name: str,可选的,将采集指定名称的字符串,否则将对所有流执行采集。
生成:msg:Msg Msg(‘collect’, obj)
"""
控制RunEngine的计划
bluesky.plan_stubs.open_run
# 标记一个新"run"开始. 发出一个RunStart文档.
bluesky.plan_stubs.open_run(md=None)
"""
参数:
:
md:dict, 可选, 元数据
生成:msg:Msg Msg('open_run', **md)
"""
bluesky.plan_stubs.close_run
# 标记当前的'run'结束.发出一个RunStop文档.
bluesky.plan_stubs.close_run(exit_status=None, reason=None)[source]¶
"""
参数:
1 exit_status: {None, ‘success’, ‘abort’, ‘fail’}
在Stop文档中报告的退出状态.
2 reason: str, 可选,运行为什么结束的长格式描述
生成: msg:Msg Msg(‘close_run’)
"""
bluesky.plan_stubs.create
# 捆绑未来的读取到一个新的Event文档.
bluesky.plan_stubs.create(name='primary')
"""
参数:
name:string, 可选,传给事件流的名称,用于方便的识别默认是'primary'
生成: msg:Msg Msg(‘create’, name=name)
"""
bluesky.plan_stubs.save
# 关闭一堆读数,并且发出一个完成的Event文档
bluesky.plan_stubs.save()
"""
生成: msg:Msg Msg(‘save’)
"""
bluesky.plan_stubs.drop
# 丢弃一堆数据,而不发出一个完成的Event文档.
bluesky.plan_stubs.drop()
"""
生成:msg:Msg Msg('drop')
"""
bluesky.plan_stubs.pause
# 暂停并且等待用户继续
bluesky.plan_stubs.pause()
"""
生成:msg:Msg Msg(‘pause’)
"""
bluesky.plan_stubs.deferred_pause
# 在下个检查点暂停
bluesky.plan_stubs.deferred_pause()
"""
生成:msgMsg Msg(‘pause’, defer=True)
"""
bluesky.plan_stubs.checkpoint
# 如果中断,再回到这个点
bluesky.plan_stubs.checkpoint()
"""
生成:msg:Msg Msg(‘checkpoint’)
"""
bluesky.plan_stubs.clear_checkpoint
# 指定继续是不安全的.如果中断或暂停,取消.
bluesky.plan_stubs.clear_checkpoint()
"""
生成:msg:Msg Msg(‘clear_checkpoint’)
"""
bluesky.plan_stubs.sleep
# 在异步进行其他运行时,告诉RunEngine睡眠.
bluesky.plan_stubs.sleep(time)
"""
与import time time.sleep()不相同, 因为它允许其他操作,像中断,
在睡眠时,要被运行.
参数:
time:float, 秒
生成:msg:Msg Msg(‘sleep’, None, time)
"""
bluesky.plan_stubs.input_plan
# 提示用户文本输入.
bluesky.plan_stubs.input_plan(prompt='')
"""
参数:
prompt: str 提示字符串,例如"enter user name"或"enter next position"
prompt string, e.g., ‘enter user name’ or ‘enter next position’
生成:
msg:Msg Msg(‘input’, prompt=prompt)
"""
bluesky.plan_stubs.subscribe
# 订阅发出文档的流
bluesky.plan_stubs.subscribe(name, func)
"""
参数:
参数:
1 name:{‘all’, ‘start’, ‘descriptor’, ‘event’, ‘stop’}
2 func: 可调用, 预计签名:f(name, doc),此处name时以上{‘all’, ‘start’, ‘descriptor’, ‘event’, ‘stop’}字符串之一,而odc是一个dict
生成: msgMsg Msg(‘subscribe’, None, func, name)
"""
bluesky.plan_stubs.install_suspender
# 在一个计划过程中,安装一个supender
bluesky.plan_stubs.install_suspender(suspender)
"""
参数:
suspender: bluesky.suspenders.SuspenderBase 要安装的suspender
生成: msg:Msg Msg(‘install_suspender’, None, suspender)
"""
bluesky.plan_stubs.wait
# 等待一个组中所有状态报告结束了
bluesky.plan_stubs.wait(group=None, *, timeout=None)
"""
1 group:string (任何可哈希对象), 可选的,传递给abs_set, rel_set, trigger的标识符
默认None
生成: msg:Msg Msg(‘wait’, None, group=group)
"""
bluesky.plan_stubs.wait_for
# 底层:等待要设置(完成)的asyncio.Future对象列表
bluesky.plan_stubs.wait_for(futures, **kwargs)[source]¶
"""
参数:
1 futures: collection, asyncio.Future对象集合
2 kwargs: 传递给asyncio.wait()
生成: msgMsg Msg('wait_for', None, futures, **kwargs)
"""
bluesky.plan_stubs.null
# 生成一个非操作消息(主要用于调试和测试)
bluesky.plan_stubs.null()
"""
生成: msg:Msg Msg('null')
"""
以上的组合经常更方便
bluesky.plan_stubs.trigger_and_read
# 触发和读取一个探测器列表并且捆绑读数到一个Event
bluesky.plan_stubs.trigger_and_read(devices, name='primary')
"""
参数:
1 devices:iterable, 要触发(如果它们有一个trigger方法)并且接着读取的设备
2 name:string, 可选的, 事件流名称, 一个方便的人性化标识符,默认名称是'primary'
生成: msg:Msg 传给‘trigger’, ‘wait’ 和 ‘read’的消息.
"""
bluesky.plan_stubs.one_1d_step
# 一个1D步进扫描的内层循环, 这是在1D计划中用于per_step的默认函数.
bluesky.plan_stubs.one_1d_step(detectors, motor, step, take_reading=None)
"""
参数:
1 detectors:iterable, 要读取的设备
2 motor: 可设置,要移动的电机
3 step: 任何, 移动此电机到的地方
4 take_reading: plan, option, 进行实际采集的函数
def take_reading(dets, name='primary'):
yield from ...
Callable[List[OphydObj], Optional[str]] -> Generator[Msg], optional
默认为trigger_and_read
"""
bluesky.plan_stubs.one_nd_step
# N维步进扫描的内存循环。
# 这是在ND计划中per_step参数的默认函数。
bluesky.plan_stubs.one_nd_step(detectors, step, pos_cache, take_reading=None)[source]¶
"""
参数:
1、detectors:iterable,要读取的设备
2、step:dict 在这步中映射电机到位置。
3、pos_cache:dict,映射电机到它们最后设置的位置
4、taking_reading:计划,可选的,进行实际采集的函数。
def take_reading(dets, name='primary'):
yield from ...
Callable[List[OphydObj], Optional[str]] -> Generator[Msg], optional
默认为trigger_and_read
"""
bluesky.plan_stubs.one_shot
# 一个计数的内存循环
# 这是在count计划中用于per_shot的默认函数。
bluesky.plan_stubs.one_shot(detectors, take_reading=None)[source]¶
"""
参数:
1、detectors: Iterable[OphydObj] 要读取的设备
2、take_reading:计划,可选的,进行使劲采集的函数。
def take_reading(dets, name='primary'):
yield from ...
Callable[List[OphydObj], Optional[str]] -> Generator[Msg], optional
默认为trigger_and_read.
"""
bluesky.plan_stubs.move_per_step
# 一个不带任何读取的N维步进扫描的内层循环。
# 这可以用作自定义per_step stubs的构建块
bluesky.plan_stubs.move_per_step(step, pos_cache)
"""
1、step:dict,在此步进中映射电机到位置。
2、pos_cache:dict,映射电机到它们最终设置的位置。
"""
特殊工具
bluesky.plan_stubs.repeat
# 在重复之间用延时和检查点重复一个计划数目。
# 这不同于repeater和caching_repeater,在此,它添加了检查点并且如果提供了延时,可选地睡眠消息。
# 这是提供给需要count结构体但不想要重新实现这个控制流的用户。
bluesky.plan_stubs.repeat(plan, num=1, delay=None)
"""
1、plan:callable 返回一个Msg对象地可迭代的可调用的
2、num:integer, 可选的,要读取的次数,默认是1,如果None,在取消前,捕获数据
3、delay:iterable 或 scalar, 可选的,连续读取之间的延时,默认是0
注意:如果delay是一个iterable,它必须至少有num-1条目,否则,它将在迭代中产生一个ValueError。
"""
bluesky.plan_stubs.repeater
# 产生来自gen_func的消息的n个链接副本
bluesky.plan_stubs.repeater(n, gen_func, *args, **kwargs)
"""
参数:
1、n:int或None, 重复总数,如果None,无限
2、gen_func:callable, 返回生成器实例
3、"*args": gen_func的args
4、"**kwargs":gen_func的kwargs
产生:msg:Msg
"""
bluesky.plan_stubs.caching_repeater
# 在一个计划中产生消息的n个链接副本
# 这不同于以上的repeater,因为它出现在生成器或迭代器中,而不是返回一个的函数最当红
bluesky.plan_stubs.caching_repeater(n, plan)
Generate n chained copies of the messages in a plan.
"""
参数:
n:int 或 None 重复总数,如果None,无限
plan:iterable
产生:msg:Msg
"""
bluesky.plan_stubs.broadcast_msg
# 产生一条消息的很多副本,把它应用到一个设备列表中
bluesky.plan_stubs.broadcast_msg(command, objs, *args, **kwargs)
"""
1、command:string
2、devices:可迭代,
3、"args":对应消息的args
4、"**kwargs":对应消息的kwargs
"""
计划预处理程序
Supplemental数据
计划预处理程序即刻修改一个计划内容。预处理程序的一个常见用法是在每个run的起始和结束时或者一个组设备的"baseline"读数。将其应用到通过一个RunEngine使用SupplementdalData执行的所有计划是方便的。
classbluesky.preprocessors.SupplementalData(*, baseline=None, monitors=None, flyers=None)
"""
1、baseline:list 在每次run开始和结束时,要读取的设备。
2、monitors:list 在每次run过程中,要被监视的信号(非多信号设备),异步产生读数。
3、flyers:list 在每次run前要开始的"可飞行"设备,并在每次run结束时,被采集。
"""
用于补充测量的配置预处理程序。这是一个计划预处理程序。它插入消息到计划来:
1、在每次run的起始和结束时对在其baseline属性中列出的设备,采集"baseline"读数。
2、在每次run的过程中,为异步更新,监视在其monitor属性中的信号。
3、在每次运行开始时,开始在其flyers属性中列出的"可飞行"设备,并且在结束时,采集它们的数据。
内部,它使用计划预处理程序:
- baseline_wrapper()
- monitor_during_wrapper()
- fly_during_wrapper
示例:
创建一个SupplementalData实例,并且对一个RunEngine应用它:
from bluesky import RunEngine
from bluesky.callbacks.best_effort import BestEffortCallback
from ophyd.sim import det1, det2, motor, motor1,motor2
from bluesky.preprocessors import SupplementalData
bec = BestEffortCallback()
RE = RunEngine({})
RE.subscribe(bec)
sd = SupplementalData(baseline=[motor, motor1, motor2, det1])
RE.preprocessors.append(sd)
现在有RE执行的所有计划将被修改,添加(在每次运行前和后)的baseline读数,(在每次run过程中)监视,以及(在每次run前开始,并且在之后被采集)。
每个属性(baseline, monitors, flyers)是一个常规的Python list,支持所有标准的list方法,诸如:
传递给SupplementalData的参数是可选的。默认所有lists将是空的。如上所示,它们可以被交互地填充。
sd = SupplementalData()
RE = RunEngine({})
RE.preprocessors.append(sd)
sd.baseline.append(det1)
sd.baseline
我们在RunEngine上安装了一个"预处理程序"。一个预处理程序修改计划,用某种方式补充或更改它们的指令。从现在开始,每次我们输入RE(some_plan()),RunEngine将悄悄更改some_plan()为sd(some_plan()),在此处,sd可能插入某些额外指令。想象这些指令从some_plan流到了sd,并且到了RE。sd预处理程序在运行过程中在指令由RunEngine运行前有机会检查这些指令,并且在其认为合适时,修改它们。
预处理程序Wrappers和Decorators
预处理程序可以对一个计划做任何修改,并且变得非常灵活。例如,relative_set_wrapper()重写相对于初始位置的所有位置。
from bluesky.plans import scan
def myrel_scan(detectors, motor, start, stop, num):
absolute = scan(detectors, motor, start, stop, num)
relative = relative_set_wrapper(absolute, [motor])
yield from relative
这是微妙但非常强大的特性。
像relative_set_wrapper()的包装器对一个生成器实例进行操作,如scan(...)。有相应的装饰器函数,如relative_set_decorator,对一个生成器函数自身进行操作,如scan(...)。
# 使用一个装饰器来修改一个生成器函数
def myrel_scan(detectors, motor, start, stop, num):
@relative_set_decorator([motor])
def inner_relative_scan():
yield from scan(detectors, motor, start, stop, num)
yield from inner_relative_scan()
顺便提一句,名称inner_relative_scan只是一个内部变量,因此,我们为什么选择这样一个冗余的名称?为什么不只取名为f?当然这会运行,但使用一个描述性的名称可以使调试更加容易。当艰难地导航时,深度嵌套地tracebacks,如果内部变量有清晰名称时,它有用。
注意:
装饰器用法,@是一个传递一个函数给另一个函数地简洁方式。
这是:
@g
def f(...):
pass
f(...)
# 相当于
g(f)(...)