Coder Social home page Coder Social logo

bluesky / bluesky-darkframes Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 5.0 156 KB

Tools for "dark frame" acquisition and subtraction

Home Page: https://blueskyproject.io/bluesky-darkframes

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%

bluesky-darkframes's Introduction

CI Coverage PyPI License

Bluesky โ€” An Experiment Specification & Orchestration Engine

Source https://github.com/bluesky/bluesky
PyPI pip install bluesky
Documentation https://bluesky.github.io/bluesky
Releases https://github.com/bluesky/bluesky/releases

Bluesky is a library for experiment control and collection of scientific data and metadata. It emphasizes the following virtues:

  • Live, Streaming Data: Available for inline visualization and processing.
  • Rich Metadata: Captured and organized to facilitate reproducibility and searchability.
  • Experiment Generality: Seamlessly reuse a procedure on completely different hardware.
  • Interruption Recovery: Experiments are "rewindable," recovering cleanly from interruptions.
  • Automated Suspend/Resume: Experiments can be run unattended, automatically suspending and resuming if needed.
  • Pluggable I/O: Export data (live) into any desired format or database.
  • Customizability: Integrate custom experimental procedures and commands, and get the I/O and interruption features for free.
  • Integration with Scientific Python: Interface naturally with numpy and Python scientific stack.

Bluesky Documentation.

The Bluesky Project enables experimental science at the lab-bench or facility scale. It is a collection of Python libraries that are co-developed but independently useful and may be adopted a la carte.

Bluesky Project Documentation.

See https://bluesky.github.io/bluesky for more detailed documentation.

bluesky-darkframes's People

Contributors

danielballan avatar gwbischof avatar jklynch avatar mikehart85 avatar mrakitin avatar tacaswell avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bluesky-darkframes's Issues

Behavior when using `bps.trigger_and_read([det1, det2])`

Hi, I am a user of the this package. I have a question of the behavior of this dark preprocessor. If I use the dark plan shown in the documents and create two dark preprocessor for det1 and det2 separately and use the dark preprocessor on the generator returned by the function below.

def take_two_images_at_the_same_time():
    return bpp.pchain(
        bps.mv(shutter, "open"),
        bps.stage(det1),
        bps.stage(det2),
        bps.trigger_and_read([det1, det2]),
        bps.unstage(det2),
        bps.unstage(det1),
        bps.mv(shutter, "closed")
    )

I think it causes the shutter to close at the time right after the det1 is triggered to collect the light frame. I wonder if this will make det1 collect frames when there is no x-ray on the detector?

Here, I print out the messages yield from the preporcessed generator. It shows that the shutter is closed after the det 1 is triggered. The shutter is turned to closed because it is preparing for collecting dark for det2.

set        | shutter    | open                 | group: 3c22dfcd-a081-44e3-b6f9-fa7c1e34983e
wait       |            |                      | group: 3c22dfcd-a081-44e3-b6f9-fa7c1e34983e
stage      | det1       |                      |                     
stage      | det2       |                      |                     
set        | shutter    | closed               | group: 776fbf20-cad4-4b61-8837-ef3805fd26b6
wait       |            |                      | group: 776fbf20-cad4-4b61-8837-ef3805fd26b6
unstage    | det1       |                      |                     
stage      | det1       |                      |                     
trigger    | det1       |                      | group: bluesky-darkframes-trigger
wait       |            |                      | group: bluesky-darkframes-trigger
unstage    | det1       |                      |                     
stage      | det1       |                      |                     
set        | shutter    | open                 | group: 97da8bae-a3e5-433a-b2b3-7429fe6aee91
wait       |            |                      | group: 97da8bae-a3e5-433a-b2b3-7429fe6aee91
stage      | det1       |                      |                     
trigger    | det1       |                      | group: bluesky-darkframes-trigger-e6679b
wait       |            |                      | group: bluesky-darkframes-trigger-e6679b
create     |            |                      |                     
read       | det1       |                      |                     
save       |            |                      |                     
unstage    | det1       |                      |                     
trigger    | det1       |                      | group: trigger-e083e1
set        | shutter    | closed               | group: 687a0d5e-9ece-4a98-bbc9-271d9564b13a
wait       |            |                      | group: 687a0d5e-9ece-4a98-bbc9-271d9564b13a
unstage    | det2       |                      |                     
stage      | det2       |                      |                     
trigger    | det2       |                      | group: bluesky-darkframes-trigger
wait       |            |                      | group: bluesky-darkframes-trigger
unstage    | det2       |                      |                     
stage      | det2       |                      |                     
set        | shutter    | open                 | group: 18ca7f05-4c65-4d6a-90a0-fff3a7f7462a
wait       |            |                      | group: 18ca7f05-4c65-4d6a-90a0-fff3a7f7462a
stage      | det2       |                      |                     
trigger    | det2       |                      | group: bluesky-darkframes-trigger-34a31e
wait       |            |                      | group: bluesky-darkframes-trigger-34a31e
create     |            |                      |                     
read       | det2       |                      |                     
save       |            |                      |                     
unstage    | det2       |                      |                     
trigger    | det2       |                      | group: trigger-e083e1
wait       |            |                      | group: trigger-e083e1
create     |            |                      |                     
read       | det1       |                      |                     
read       | det2       |                      |                     
save       |            |                      |                     
unstage    | det2       |                      |                     
unstage    | det1       |                      |                     
set        | shutter    | closed               | group: 176938b5-d1d5-43bd-80ea-e8cfe4d97718
wait       |            |                      | group: 176938b5-d1d5-43bd-80ea-e8cfe4d97718

BUG: error reported in pytest when taking dark frame

I defined a function "create_dark_frame_preprocessor" to create the dark frame preprocessor.

"""Dark frame plans."""
import typing

import bluesky.plan_stubs as bps
from bluesky_darkframes import DarkFramePreprocessor, SnapshotDevice
from ophyd import Device


def basic_dark_plan(
    detector: typing.Any,
    shutter: typing.Any,
    open_state: typing.Hashable,
    close_state: typing.Hashable
) -> SnapshotDevice:
    """A basic dark frame plan."""
    # Restage to ensure that dark frames goes into a separate file.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    print("INFO: close the shutter ...")
    yield from bps.mv(shutter, close_state)
    # The `group` parameter passed to trigger MUST start with
    # bluesky-darkframes-trigger.
    print("INFO: take a dark frame ...")
    yield from bps.trigger(detector, group='bluesky-darkframes-trigger')
    yield from bps.wait('bluesky-darkframes-trigger')
    snapshot = SnapshotDevice(detector)
    print("INFO: open the shutter ...")
    yield from bps.mv(shutter, open_state)
    # Restage.
    yield from bps.unstage(detector)
    yield from bps.stage(detector)
    return snapshot


def create_dark_frame_preprocessor(
    area_det: typing.Any,
    shutter: typing.Any,
    close_state: typing.Any,
    open_state: typing.Any,
    max_age: float,
    locked_signals: list = None,
    limit=None
) -> DarkFramePreprocessor:
    def dark_plan(detector: Device) -> SnapshotDevice:
        snapshot_device = yield from basic_dark_plan(
            detector,
            shutter=shutter,
            close_state=close_state,
            open_state=open_state
        )
        return snapshot_device

    return DarkFramePreprocessor(
        dark_plan=dark_plan,
        detector=area_det,
        max_age=max_age,
        locked_signals=locked_signals,
        limit=limit
    )

And then I test it in the pytest for two detectors and different configuration.

import bluesky.plans as bp
import pytest
from bluesky import RunEngine
from bluesky_darkframes.sim import DiffractionDetector
from xpdsim import xpd_pe1c

from xpdacq.plans.dark_plan import create_dark_frame_preprocessor
from xpdacq.xpdacq import XPD_shutter, XPD_SHUTTER_CONF


@pytest.mark.parametrize(
    "area_det, locked_signals",
    [
        (xpd_pe1c, None),
        (xpd_pe1c, [xpd_pe1c.images_per_set]),
        (xpd_pe1c, [xpd_pe1c.cam.acquire_time]),
        (xpd_pe1c, [xpd_pe1c.images_per_set, xpd_pe1c.cam.acquire_time]),
        (DiffractionDetector, None),
        (DiffractionDetector, [DiffractionDetector.exposure_time])
    ]
)
def test_dark_frame_preprocessor(fresh_xrun, area_det, locked_signals):
    RE = RunEngine()
    dfp = create_dark_frame_preprocessor(
        area_det=area_det,
        shutter=XPD_shutter,
        open_state=XPD_SHUTTER_CONF["open"],
        close_state=XPD_SHUTTER_CONF["close"],
        locked_signals=locked_signals,
        max_age=60
    )
    RE.preprocessors.append(dfp)
    RE(bp.count([area_det]))

All of them report a bug like below.

xpdacq/tests/plans/test_dark_plan.py:10 (test_dark_frame_preprocessor[area_det0-None])
self = <DarkFramePreprocessor 0 snapshots cached>, state = {}

    def get_snapshot(self, state):
        """
        Access a darkframe.
    
        Parameters
        ----------
        state: dict
            Mapping each of the names of the locked_signals (if any) to its
            value.
        """
        self._evict_old_entries()
        key = frozendict(state)
        try:
>           creation_time, snapshot = self._cache[key]
E           KeyError: <frozendict {}>

key        = <frozendict {}>
self       = <DarkFramePreprocessor 0 snapshots cached>
state      = {}

/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky_darkframes/__init__.py:280: KeyError

The above exception was the direct cause of the following exception:

force_read = True
msg = Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0.,......, 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None)

    def insert_dark_frame(force_read, msg=None):
        # Acquire a fresh Snapshot if we need one, or retrieve a cached one.
        state = {}
        for signal in self.locked_signals:
            reading = yield from bluesky.plan_stubs.read(signal)
            # Restructure
            # {'data_key': {'value': <value>, 'timestamp': <timestamp>}, ...}
            # into (('data_key', <value>) ...).
            values_only = tuple((k, v['value']) for k, v in reading.items())
            state[signal.name] = values_only
        try:
>           snapshot = self.get_snapshot(state)

force_read = True
msg        = Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None)
self       = <DarkFramePreprocessor 0 snapshots cached>
state      = {}

/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky_darkframes/__init__.py:319: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <DarkFramePreprocessor 0 snapshots cached>, state = {}

    def get_snapshot(self, state):
        """
        Access a darkframe.
    
        Parameters
        ----------
        state: dict
            Mapping each of the names of the locked_signals (if any) to its
            value.
        """
        self._evict_old_entries()
        key = frozendict(state)
        try:
            creation_time, snapshot = self._cache[key]
        except KeyError as err:
>           raise NoMatchingSnapshot(
                f"No Snapshot matches the state {state}. Perhaps there *was* "
                f"match but it has aged out of the cache.") from err
E           bluesky_darkframes.NoMatchingSnapshot: 'No Snapshot matches the state {}. Perhaps there *was* match but it has aged out of the cache.'

key        = <frozendict {}>
self       = <DarkFramePreprocessor 0 snapshots cached>
state      = {}

/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky_darkframes/__init__.py:282: NoMatchingSnapshot

During handling of the above exception, another exception occurred:

fresh_xrun = <xpdacq.xpdacq.CustomizedRunEngine object at 0x7f9f3c878790>
area_det = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0...     [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
locked_signals = None

    @pytest.mark.parametrize(
        "area_det, locked_signals",
        [
            (xpd_pe1c, None),
            (xpd_pe1c, [xpd_pe1c.images_per_set]),
            (xpd_pe1c, [xpd_pe1c.cam.acquire_time]),
            (xpd_pe1c, [xpd_pe1c.images_per_set, xpd_pe1c.cam.acquire_time]),
            (DiffractionDetector, None),
            (DiffractionDetector, [DiffractionDetector.exposure_time])
        ]
    )
    def test_dark_frame_preprocessor(fresh_xrun, area_det, locked_signals):
        RE = RunEngine()
        dfp = create_dark_frame_preprocessor(
            area_det=area_det,
            shutter=XPD_shutter,
            open_state=XPD_SHUTTER_CONF["open"],
            close_state=XPD_SHUTTER_CONF["close"],
            locked_signals=locked_signals,
            max_age=60
        )
        RE.preprocessors.append(dfp)
>       RE(bp.count([area_det]))

RE         = <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>
area_det   = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
dfp        = <DarkFramePreprocessor 0 snapshots cached>
fresh_xrun = <xpdacq.xpdacq.CustomizedRunEngine object at 0x7f9f3c878790>
locked_signals = None

/Users/sst/PycharmProjects/xpdAcq/xpdacq/tests/plans/test_dark_plan.py:33: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/run_engine.py:807: in __call__
    self._resume_task(init_func=_build_task)
        _build_task = <function RunEngine.__call__.<locals>._build_task at 0x7f9f3c629ee0>
        args       = (<generator object count at 0x7f9f3c62ea50>,)
        arguments  = OrderedDict([('self', <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>),
             ('plan', <generator object count at 0x7f9f3c62ea50>)])
        funcs      = []
        futs       = []
        gen        = <generator object DarkFramePreprocessor.__call__ at 0x7f9f3c62eac0>
        metadata_kw = {}
        name       = 'descriptor'
        plan       = <generator object count at 0x7f9f3c62ea50>
        self       = <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>
        subs       = None
        tripped_justifications = []
        wrapper_func = <DarkFramePreprocessor 0 snapshots cached>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/run_engine.py:931: in _resume_task
    raise exc
        exc        = AttributeError("'NoneType' object has no attribute 'parent'")
        init_func  = <function RunEngine.__call__.<locals>._build_task at 0x7f9f3c629ee0>
        mgr        = <class 'bluesky.utils.SigintHandler'>
        self       = <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>
        stack      = <contextlib.ExitStack object at 0x7f9f3c894e50>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/run_engine.py:1500: in _run
    raise err
        coro       = <bound method RunEngine._unstage of <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>>
        debug      = <bound method Logger.debug of <Logger bluesky.RE.msg (WARNING)>>
        exit_reason = "'NoneType' object has no attribute 'parent'"
        msg        = Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None)
        new_response = None
        resp       = <object object at 0x7f9f3c0cbdd0>
        self       = <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>
        sentinel   = <object object at 0x7f9f3c0cbdd0>
        stashed_exception = None
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/run_engine.py:1365: in _run
    msg = self._plan_stack[-1].send(resp)
        coro       = <bound method RunEngine._unstage of <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>>
        debug      = <bound method Logger.debug of <Logger bluesky.RE.msg (WARNING)>>
        exit_reason = "'NoneType' object has no attribute 'parent'"
        msg        = Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None)
        new_response = None
        resp       = <object object at 0x7f9f3c0cbdd0>
        self       = <bluesky.run_engine.RunEngine object at 0x7f9f3c894250>
        sentinel   = <object object at 0x7f9f3c0cbdd0>
        stashed_exception = None
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky_darkframes/__init__.py:378: in __call__
    return (yield from bluesky.preprocessors.plan_mutator(
        insert_dark_frame = <function DarkFramePreprocessor.__call__.<locals>.insert_dark_frame at 0x7f9f3c8b0040>
        maybe_insert_dark_frame = <function DarkFramePreprocessor.__call__.<locals>.maybe_insert_dark_frame at 0x7f9f3c8b0310>
        plan       = <generator object count at 0x7f9f3c62ea50>
        self       = <DarkFramePreprocessor 0 snapshots cached>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:170: in plan_mutator
    raise ex
        exception  = None
        failed_gen = <generator object count at 0x7f9f3c62ea50>
        gen        = None
        inner_ret  = None
        msg        = Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None)
        msg_proc   = <function DarkFramePreprocessor.__call__.<locals>.maybe_insert_dark_frame at 0x7f9f3c8b0310>
        msgs_seen  = {140321891779104: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779488: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779968: Msg('open_run', obj=None, args=(), kwargs={'detectors': ['pe1_image'], 'num_points': 1, 'num_intervals': 0, 'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       ...,\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)"], 'num': 1}, 'plan_name': 'count', 'hints': {'dimensions': [(('time',), 'primary')]}}, run=None),
 140321891780544: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891781024: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781216: Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None),
 140321891781312: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781696: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891782368: Msg('close_run', obj=None, args=(), kwargs={'exit_status': 'fail', 'reason': "'NoneType' object has no attribute 'parent'"}, run=None)}
        new_gen    = None
        parent_plan = <generator object count at 0x7f9f3c62ea50>
        plan       = <generator object count at 0x7f9f3c62ea50>
        plan_stack = deque([])
        result_stack = deque([])
        ret        = None
        ret_value  = None
        tail_cache = {}
        tail_gen   = None
        tail_result_cache = {}
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:123: in plan_mutator
    msg = plan_stack[-1].send(ret)
        exception  = None
        failed_gen = <generator object count at 0x7f9f3c62ea50>
        gen        = None
        inner_ret  = None
        msg        = Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None)
        msg_proc   = <function DarkFramePreprocessor.__call__.<locals>.maybe_insert_dark_frame at 0x7f9f3c8b0310>
        msgs_seen  = {140321891779104: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779488: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779968: Msg('open_run', obj=None, args=(), kwargs={'detectors': ['pe1_image'], 'num_points': 1, 'num_intervals': 0, 'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       ...,\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)"], 'num': 1}, 'plan_name': 'count', 'hints': {'dimensions': [(('time',), 'primary')]}}, run=None),
 140321891780544: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891781024: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781216: Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None),
 140321891781312: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781696: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891782368: Msg('close_run', obj=None, args=(), kwargs={'exit_status': 'fail', 'reason': "'NoneType' object has no attribute 'parent'"}, run=None)}
        new_gen    = None
        parent_plan = <generator object count at 0x7f9f3c62ea50>
        plan       = <generator object count at 0x7f9f3c62ea50>
        plan_stack = deque([])
        result_stack = deque([])
        ret        = None
        ret_value  = None
        tail_cache = {}
        tail_gen   = None
        tail_result_cache = {}
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plans.py:77: in count
    return (yield from inner_count())
        _md        = {'detectors': ['pe1_image'],
 'hints': {'dimensions': [(('time',), 'primary')]},
 'num_intervals': 0,
 'num_points': 1,
 'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', "
                             'value=array([[0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       ...,\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.]], '
                             'dtype=float32), timestamp=1602180513.580364)'],
               'num': 1},
 'plan_name': 'count'}
        delay      = None
        detectors  = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        inner_count = <function count.<locals>.inner_count at 0x7f9f3c8b0940>
        md         = None
        num        = 1
        num_intervals = 0
        per_shot   = <function one_shot at 0x7f9f3c43f280>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/utils.py:1114: in dec_inner
    return (yield from plan)
        args       = ([SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)],)
        gen_func   = <function count.<locals>.inner_count at 0x7f9f3c8b0820>
        inner_args = ()
        inner_kwargs = {}
        kwargs     = {}
        plan       = <generator object stage_wrapper at 0x7f9f3c62ef20>
        wrapper    = <function stage_wrapper at 0x7f9f3c43fee0>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:952: in stage_wrapper
    return (yield from finalize_wrapper(inner(), unstage_devices()))
        devices    = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        inner      = <function stage_wrapper.<locals>.inner at 0x7f9f3c8b0700>
        plan       = <generator object count.<locals>.inner_count at 0x7f9f3c62e7b0>
        stage_devices = <function stage_wrapper.<locals>.stage_devices at 0x7f9f3c8b09d0>
        unstage_devices = <function stage_wrapper.<locals>.unstage_devices at 0x7f9f3c8b0790>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:509: in finalize_wrapper
    ret = yield from plan
        cleanup    = True
        final_plan = <generator object stage_wrapper.<locals>.unstage_devices at 0x7f9f3c62e120>
        final_plan_instance = <generator object stage_wrapper.<locals>.unstage_devices at 0x7f9f3c62e120>
        pause_for_debug = False
        plan       = <generator object stage_wrapper.<locals>.inner at 0x7f9f3c62ec10>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:950: in inner
    return (yield from plan)
        plan       = <generator object count.<locals>.inner_count at 0x7f9f3c62e7b0>
        stage_devices = <function stage_wrapper.<locals>.stage_devices at 0x7f9f3c8b09d0>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/utils.py:1114: in dec_inner
    return (yield from plan)
        args       = ()
        gen_func   = <function count.<locals>.inner_count at 0x7f9f3c8b08b0>
        inner_args = ()
        inner_kwargs = {}
        kwargs     = {'md': {'detectors': ['pe1_image'],
        'hints': {'dimensions': [(('time',), 'primary')]},
        'num_intervals': 0,
        'num_points': 1,
        'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', "
                                    'value=array([[0., 0., 0., ..., 0., 0., '
                                    '0.],\n'
                                    '       [0., 0., 0., ..., 0., 0., 0.],\n'
                                    '       [0., 0., 0., ..., 0., 0., 0.],\n'
                                    '       ...,\n'
                                    '       [0., 0., 0., ..., 0., 0., 0.],\n'
                                    '       [0., 0., 0., ..., 0., 0., 0.],\n'
                                    '       [0., 0., 0., ..., 0., 0., 0.]], '
                                    'dtype=float32), '
                                    'timestamp=1602180513.580364)'],
                      'num': 1},
        'plan_name': 'count'}}
        plan       = <generator object run_wrapper at 0x7f9f3c62ecf0>
        wrapper    = <function run_wrapper at 0x7f9f3c43f790>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:325: in run_wrapper
    yield from contingency_wrapper(plan,
        except_plan = <function run_wrapper.<locals>.except_plan at 0x7f9f3c8b0670>
        md         = {'detectors': ['pe1_image'],
 'hints': {'dimensions': [(('time',), 'primary')]},
 'num_intervals': 0,
 'num_points': 1,
 'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', "
                             'value=array([[0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       ...,\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.],\n'
                             '       [0., 0., 0., ..., 0., 0., 0.]], '
                             'dtype=float32), timestamp=1602180513.580364)'],
               'num': 1},
 'plan_name': 'count'}
        plan       = <generator object count.<locals>.inner_count at 0x7f9f3c62e900>
        rs_uid     = '877081e5-a8b8-4eac-90d0-a4c3a3e3196c'
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:575: in contingency_wrapper
    ret = yield from plan
        cleanup    = True
        else_plan  = <function close_run at 0x7f9f3c43dee0>
        except_plan = <function run_wrapper.<locals>.except_plan at 0x7f9f3c8b0670>
        final_plan = None
        pause_for_debug = False
        plan       = <generator object count.<locals>.inner_count at 0x7f9f3c62e900>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plans.py:74: in inner_count
    return (yield from bps.repeat(partial(per_shot, detectors),
        delay      = None
        detectors  = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        num        = 1
        per_shot   = <function one_shot at 0x7f9f3c43f280>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:1183: in repeat
    return (yield from repeated_plan())
        delay      = repeat(None)
        iterator   = range(0, 1)
        num        = 1
        plan       = functools.partial(<function one_shot at 0x7f9f3c43f280>, [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)])
        repeated_plan = <function repeat.<locals>.repeated_plan at 0x7f9f3c8b05e0>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:1166: in repeated_plan
    yield from ensure_generator(plan())
        delay      = repeat(None)
        i          = 0
        iterator   = range(0, 1)
        now        = 1602180515.504436
        num        = 1
        plan       = functools.partial(<function one_shot at 0x7f9f3c43f280>, [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)])
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:1026: in one_shot
    yield from take_reading(list(detectors))
        detectors  = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        take_reading = <function trigger_and_read at 0x7f9f3c43f040>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:911: in trigger_and_read
    return (yield from rewindable_wrapper(inner_trigger_and_read(),
        devices    = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        inner_trigger_and_read = <function trigger_and_read.<locals>.inner_trigger_and_read at 0x7f9f3c8b0550>
        name       = 'primary'
        rewindable = True
        rewindable_wrapper = <function rewindable_wrapper at 0x7f9f3c43fb80>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:693: in rewindable_wrapper
    return (yield from plan)
        capture_rewindable_state = <function rewindable_wrapper.<locals>.capture_rewindable_state at 0x7f9f3c8b04c0>
        initial_rewindable = True
        plan       = <generator object trigger_and_read.<locals>.inner_trigger_and_read at 0x7f9f3c62e270>
        restore_rewindable = <function rewindable_wrapper.<locals>.restore_rewindable at 0x7f9f3c8b03a0>
        rewindable = True
        set_rewindable = <function rewindable_wrapper.<locals>.set_rewindable at 0x7f9f3c8b0430>
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:898: in inner_trigger_and_read
    yield from trigger(obj, group=grp)
        devices    = [SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)]
        grp        = 'trigger-ac53bf'
        name       = 'primary'
        no_wait    = False
        obj        = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:427: in trigger
    ret = yield Msg('trigger', obj, group=group)
        group      = 'trigger-ac53bf'
        obj        = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
        wait       = False
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/preprocessors.py:123: in plan_mutator
    msg = plan_stack[-1].send(ret)
        exception  = None
        failed_gen = <generator object count at 0x7f9f3c62ea50>
        gen        = None
        inner_ret  = None
        msg        = Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None)
        msg_proc   = <function DarkFramePreprocessor.__call__.<locals>.maybe_insert_dark_frame at 0x7f9f3c8b0310>
        msgs_seen  = {140321891779104: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779488: Msg('unstage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891779968: Msg('open_run', obj=None, args=(), kwargs={'detectors': ['pe1_image'], 'num_points': 1, 'num_intervals': 0, 'plan_args': {'detectors': ["SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       ...,\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)"], 'num': 1}, 'plan_name': 'count', 'hints': {'dimensions': [(('time',), 'primary')]}}, run=None),
 140321891780544: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891781024: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781216: Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None),
 140321891781312: Msg('stage', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={}, run=None),
 140321891781696: Msg('checkpoint', obj=None, args=(), kwargs={}, run=None),
 140321891782368: Msg('close_run', obj=None, args=(), kwargs={'exit_status': 'fail', 'reason': "'NoneType' object has no attribute 'parent'"}, run=None)}
        new_gen    = None
        parent_plan = <generator object count at 0x7f9f3c62ea50>
        plan       = <generator object count at 0x7f9f3c62ea50>
        plan_stack = deque([])
        result_stack = deque([])
        ret        = None
        ret_value  = None
        tail_cache = {}
        tail_gen   = None
        tail_result_cache = {}
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky_darkframes/__init__.py:327: in insert_dark_frame
    snapshot = yield from self._partialed_dark_plan()
        force_read = True
        msg        = Msg('trigger', obj=SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364), args=(), kwargs={'group': 'trigger-ac53bf'}, run=None)
        self       = <DarkFramePreprocessor 0 snapshots cached>
        state      = {}
/Users/sst/PycharmProjects/xpdAcq/xpdacq/plans/dark_plan.py:45: in dark_plan
    snapshot_device = yield from basic_dark_plan(
        close_state = 0
        detector   = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
        open_state = 60
        shutter    = None
/Users/sst/PycharmProjects/xpdAcq/xpdacq/plans/dark_plan.py:20: in basic_dark_plan
    yield from bps.mv(shutter, close_state)
        close_state = 0
        detector   = SynSignalWithRegistry(name='pe1_image', value=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), timestamp=1602180513.580364)
        open_state = 60
        shutter    = None
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/plan_stubs.py:254: in mv
    (step,) = utils.merge_cycler(cyl)
        args       = (None, 0)
        cyl        = cycler(None, [0])
        group      = 'c7e4151f-6279-4c38-9bec-51adb56d336d'
        kwargs     = {}
        status_objects = []
/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/utils.py:1372: in merge_cycler
    io, co, gb = merge_axis(cyc.keys)
        cyc        = cycler(None, [0])
        my_name    = <function merge_cycler.<locals>.my_name at 0x7f9f3c8b0af0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

objs = {None}

    def merge_axis(objs):
        '''Merge possibly related axis
    
        This function will take a list of objects and separate it into
    
         - list of completely independent objects (most settable things and
           detectors) that do not have coupled motion.
         - list of devices who have children who are coupled (PseudoPositioner
           ducked by looking for 'RealPosition' as an attribute)
    
        Both of these lists will only contain objects directly passed in
        in objs
    
         - map between parents and objects passed in.  Each value
           of the map is a map between the strings
           {'real', 'pseudo', 'independent'} and a list of objects.  All
           of the objects in the (doubly nested) map are in the input.
    
        Parameters
        ----------
        objs : Iterable[OphydObj]
            The input devices
    
        Returns
        -------
        independent_objs : List[OphydObj]
            Independent 'simple' axis
    
        complex_objs : List[PseudoPositioner]
            Independent objects which have interdependent children
    
        coupled : Dict[PseudoPositioner, Dict[str, List[OphydObj]]]
            Mapping of interdependent axis passed in.
        '''
        def get_parent(o):
            return getattr(o, 'parent')
    
        independent_objs = set()
        maybe_coupled = set()
        complex_objs = set()
        for o in objs:
>           parent = o.parent
E           AttributeError: 'NoneType' object has no attribute 'parent'

complex_objs = set()
get_parent = <function merge_axis.<locals>.get_parent at 0x7f9f3c8b0b80>
independent_objs = set()
maybe_coupled = set()
o          = None
objs       = {None}

/Users/sst/anaconda3/envs/dev_xpdacq/lib/python3.8/site-packages/bluesky/utils.py:1316: AttributeError

When the code raise the error below, the error should propogate to the layer above and then the "except" line should be executed. However, interestingly, the code directly reported it as an error without executing the "except" line.

        except KeyError as err:
>           raise NoMatchingSnapshot(

Support multiple DarkFramePreprocessors

I believe (but have not rigorously verified) that if two DarkFramePreprocessors are applied, they will interfere. The outer one will see the trigger messages added by the inner one, and try to take a dark frame for a dark frame (if that makes sense...).

We briefly tried this at CSX and that theory seemed to be correct; at least we can say for sure that trying two nested preprocessors failed.

The fix I have in mind is to let DarkFramePreprocessors recognize trigger messages that came from itself by using a special convention in the group---that is instead of 'trigger-<uuid>', do 'trigger-dark-frame-preprocessor-<uuid>'. The content of the group has no meaning to any other part of our system.

Documented example produces warnings

It's not immediately clear why these warnings are being generated by this section of the usage documentation:

/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/databroker/assets/core.py:234: UserWarning: Ignoring attempt to insert Datum with duplicate datum_id, assuming that both ophyd and bluesky attempted to insert this document. Remove the Registry (`reg` parameter) from your ophyd instance to remove this warning.
  warnings.warn("Ignoring attempt to insert Datum with duplicate "
/home/travis/virtualenv/python3.7.1/lib/python3.7/site-packages/databroker/assets/core.py:155: UserWarning: Ignoring attempt to insert Resource with duplicate uid, assuming that both ophyd and bluesky attempted to insert this document. Remove the Registry (`reg` parameter) from your ophyd instance to remove this warning.
  warnings.warn("Ignoring attempt to insert Resource with duplicate "

The advice in that warning is not applicable; we are using only the new insertion mechanism. I suspect the asset documents are being collected twice.

Fix Resource document creation to make uid unique

Currently, we re-issue the same Resource document multiple times, resulting in Resource documents with colliding UIDs in the database. (Their run_start keys are different, though.) For awhile we entertained the idea of letting uid be nonunique so long as the pair (run_start, uid) was unique. Now we have thought better of that, so the plan is:

  • Fix the code that was generating clashing UIDs (bluesky-darkframes).
  • Do a database migration to fix the existing documents.
  • An add index in suitcase-mongo to ensure that UIDs are unique going forward.

option to broadcast across multiple exposures

If taking multiple exposures/point, the dark plan currently must also take that number of exposures. In other words, the dark is only broadcast across dim0 of array. it would be better to have options to
a.) take multiple exposures as it does now
b.) take one exposure (broadcast across both dim0 and dim 1) - to do this, the dark plan needs to change the n exposures, take the dark, and then change it back.
c.) take multiple exposures but subtract the mean of the multiple exposures rather than each respective exposure.

Scientifically speaking b and c seem much both much more relevant, with b saving a lot of time, and c resulting in a reduction in noise. There might be a case for a in some cases if the detector has some repeatable dynamic response (e.g. heating up) while taking multiple exposures.

Perhaps a clean option is to take whatever dimensionality that the dark plan produces. if the dark plan only produces one frame, then broadcast it. If it produces m != n frames, average and subtract the average from all frames, if it produces n frames, subtract them from the respective frame.

Reconsider default/recommended stream name.

Continuing discussion from NSLS-II-CSX/profile_collection#32

@jklynch

I still find the stream name "dark" too vague. I propose "dark_frames".

@danielballan

That's fine with me---always one to prefer verbose and specific to succinct and vague---but I think we should poll @DanOlds, @EliotGann, @ambarb. To be clear, this is something that beamlines can vary on if they like with little cost, but it might simplify things to have a consistent convention we apply as a facility unless there is good reason to diverge.

@ambarb

dark_images instead? are all of the key's for image data [camera]_images, e.g., fccd_images. Probably more correct to say fccd_dark_images incase of more than 1 camera we are not accidentally mixing things up.

so then this would extend to the flat field, but depending on how it is collected the last part might not be images. At CSX, we discussed the need to fully process the data and then have one single image that represents that flat field (dark subtracted and gain correct). Choices

  • flatfield_correction
  • flatfield_image (as opposed to the data for flat field, which would be flatfield_images)
  • flatfield_array
  • flatfield_analysis

We have to keep in mind that there is the stream name and there is the field in the Event. For example, we have the primary stream and, for an Event in that stream, we have event['data']['fccd_image']. The current scheme at CSX would add a dark stream with event['data']['fccd_image']. In the near future, we plan to replace dark with several streams representing different gain settings, dark_gain2, dark_gain4, dark_gain8.

The Event makes it fully unambiguous which detector we mean, both through the field name (fccd_image) and associated metadata in the EventDescriptor, which aside from the stream name also carries the object name(s) (fccd) and the associated PVs that uniquely identify the camera on the network.

However, if we set up a second DarkFramePreprocessor for a separate camera that also wants dark_gain2, dark_gain4, dark_gain8, we may find that the stream names clash. Thus, it might be better to follow @ambarb's suggestion and put the detector name in the stream name, as in fccd_dark_gain2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.