def test_trivial_template(RE): text.clear() RE.subscribe(logbook_cb_factory(f, desc_template='hello'), 'start') RE([Msg('open_run', plan_args={}), Msg('close_run')]) assert text[0] == 'hello' # smoke test the long_template RE.subscribe(logbook_cb_factory(f, long_template='hello'), 'start') RE([Msg('open_run', plan_args={}), Msg('close_run')])
def test_trivial_template(fresh_RE): text.clear() fresh_RE.subscribe(logbook_cb_factory(f, desc_template='hello'), 'start') fresh_RE([Msg('open_run', plan_args={}), Msg('close_run')]) assert text[0] == 'hello' # smoke test the long_template fresh_RE.subscribe(logbook_cb_factory(f, long_template='hello'), 'start') fresh_RE([Msg('open_run', plan_args={}), Msg('close_run')])
def test_template_dispatch(fresh_RE): disp = {'a': 'A', 'b': 'B'} text.clear() fresh_RE.subscribe(logbook_cb_factory(f, desc_dispatch=disp), 'start') fresh_RE([Msg('open_run', plan_name='a', plan_args={}), Msg('close_run')]) fresh_RE([Msg('open_run', plan_name='b', plan_args={}), Msg('close_run')]) assert text[0] == 'A' assert text[1] == 'B' # smoke test the long_dispatch fresh_RE.subscribe(logbook_cb_factory(f, long_dispatch=disp), 'start') fresh_RE([Msg('open_run', plan_name='a', plan_args={}), Msg('close_run')]) fresh_RE([Msg('open_run', plan_name='b', plan_args={}), Msg('close_run')])
def test_template_dispatch(RE): disp = {'a': 'A', 'b': 'B'} text.clear() RE.subscribe(logbook_cb_factory(f, desc_dispatch=disp), 'start') RE([Msg('open_run', plan_name='a', plan_args={}), Msg('close_run')]) RE([Msg('open_run', plan_name='b', plan_args={}), Msg('close_run')]) assert text[0] == 'A' assert text[1] == 'B' # smoke test the long_dispatch RE.subscribe(logbook_cb_factory(f, long_dispatch=disp), 'start') RE([Msg('open_run', plan_name='a', plan_args={}), Msg('close_run')]) RE([Msg('open_run', plan_name='b', plan_args={}), Msg('close_run')])
Call: {{ start.signature }} {% endif %} Metadata -------- {% for k, v in start.items() -%} {%- if k not in ['plan_name', 'plan_args'] -%}{{ k }} : {{ v }} {% endif -%} {%- endfor -%}""" bluesky.callbacks.olog.TEMPLATES['desc'] = """ {{- start.plan_name }} ['{{ start.uid[:6] }}'] (scan num: {{ start.scan_id }})""" bluesky.callbacks.olog.TEMPLATES['call'] = """RE({{ start.plan_name }}( {%- for k, v in start.plan_args.items() %}{%- if not loop.first %} {% endif %}{{ k }}={{ v }} {%- if not loop.last %}, {% endif %}{% endfor %})) """ LOGBOOKS = ['Comissioning'] # list of logbook names to publish to simple_olog_client = SimpleOlogClient() generic_logbook_func = simple_olog_client.log configured_logbook_func = partial(generic_logbook_func, logbooks=LOGBOOKS) cb = logbook_cb_factory(configured_logbook_func) RE.subscribe('start', cb) loogbook = simple_olog_client import esm # general ESM routines: e2g(), g2e(), angles()
def test_default_template(RE): text.clear() RE.subscribe(logbook_cb_factory(f), 'start') RE([Msg('open_run', plan_args={}), Msg('close_run')]) assert len(text[0]) > 0
import threading from warnings import warn # Set up the logbook. This configures bluesky's summaries of # data acquisition (scan type, ID, etc.). LOGBOOKS = ['Data Acquisition'] # list of logbook names to publish to simple_olog_client = SimpleOlogClient() generic_logbook_func = simple_olog_client.log configured_logbook_func = partial(generic_logbook_func, logbooks=LOGBOOKS) # This is for ophyd.commands.get_logbook, which simply looks for # a variable called 'logbook' in the global IPython namespace. logbook = simple_olog_client cb = logbook_cb_factory(configured_logbook_func) def submit_to_olog(queue, cb): while True: name, doc = queue.get() # waits until document is available try: cb(name, doc) except Exception as exc: warn('This olog is giving errors. This will not be logged.' 'Error:' + str(exc)) olog_queue = queue.Queue(maxsize=100) olog_thread = threading.Thread(target=submit_to_olog, args=(olog_queue, cb), daemon=True) olog_thread.start()
def test_default_template(fresh_RE): text.clear() fresh_RE.subscribe(logbook_cb_factory(f), 'start') fresh_RE([Msg('open_run', plan_args={}), Msg('close_run')]) assert len(text[0]) > 0
LOGBOOKS = ['Comissioning'] # list of logbook names to publish to # Set up the logbook. This configures bluesky's summaries of # data acquisition (scan type, ID, etc.). LOGBOOKS = ['Data Acquisition'] # list of logbook names to publish to simple_olog_client = SimpleOlogClient() generic_logbook_func = simple_olog_client.log configured_logbook_func = partial(generic_logbook_func, logbooks=LOGBOOKS) # This is for ophyd.commands.get_logbook, which simply looks for # a variable called 'logbook' in the global IPython namespace. logbook = simple_olog_client cb = logbook_cb_factory(configured_logbook_func, desc_dispatch=desc_templates) def submit_to_olog(queue, cb): while True: name, doc = queue.get() # waits until document is available try: cb(name, doc) except Exception as exc: warn('This olog is giving errors. This will not be logged.' 'Error:' + str(exc)) olog_queue = queue.Queue(maxsize=100) olog_thread = threading.Thread(target=submit_to_olog, args=(olog_queue, cb),
def configure_olog(user_ns, *, callback=None, subscribe=True): """ Setup a callback that publishes some metadata from the RunEngine to Olog. Also, add the public contents of pyOlog.ophyd_tools to the namespace. This is expected to be run after :func:`configure_base`. It expects to find an instance of RunEngine named ``RE`` in the user namespace. Additionally, if the user namespace contains the name ``logbook``, that is expected to be an instance ``pyOlog.SimpleOlogClient``. Parameters ---------- user_ns: dict a namespace --- for example, ``get_ipython().user_ns`` callback : callable, optional a hook for customizing the logbook_cb_factory; if None a default is used subscribe : boolean, optional True by default. Set to False to skip the subscription. (You still get pyOlog.ophyd_tools.) Returns ------- names : list list of names added to the namespace Examples -------- Configure the Olog. >>>> configure_olog(get_ipython().user_ns); """ # Conceptually our task is simple: add a subscription to the RunEngine that # publishes to the Olog using the Python wrapper of its REST API, pyOlog. # In practice this is messy because we have deal with the many-layered API # of pyOlog and, more importantly, ensure that slowness or errors from the # Olog do not affect the run. Historically the Olog deployment has not been # reliable, so it is important to be robust against these issues. Of # course, by ignoring Olog errors, we leave gaps in the log, which is not # great, but since all data is saved to a databroker anyway, we can always # re-generate them later. ns = {} # We will update user_ns with this at the end. from bluesky.callbacks.olog import logbook_cb_factory from functools import partial from pyOlog import SimpleOlogClient import queue import threading from warnings import warn # This is for pyOlog.ophyd_tools.get_logbook, which simply looks for # a variable called 'logbook' in the global IPython namespace. if "logbook" in user_ns: simple_olog_client = user_ns["logbook"] else: simple_olog_client = SimpleOlogClient() ns["logbook"] = simple_olog_client if subscribe: if callback is None: # list of logbook names to publish to LOGBOOKS = ("Data Acquisition", ) generic_logbook_func = simple_olog_client.log configured_logbook_func = partial(generic_logbook_func, logbooks=LOGBOOKS) callback = logbook_cb_factory(configured_logbook_func) def submit_to_olog(queue, cb): while True: name, doc = queue.get() # waits until document is available try: cb(name, doc) except Exception as exc: warn("This olog is giving errors. This will not be logged." "Error:" + str(exc)) olog_queue = queue.Queue(maxsize=100) olog_thread = threading.Thread(target=submit_to_olog, args=(olog_queue, callback), daemon=True) olog_thread.start() def send_to_olog_queue(name, doc): try: olog_queue.put((name, doc), block=False) except queue.Full: warn("The olog queue is full. This will not be logged.") RE = user_ns["RE"] RE.subscribe(send_to_olog_queue, "start") import pyOlog.ophyd_tools import_star(pyOlog.ophyd_tools, ns) user_ns.update(ns) return list(ns)
TEMPLATES['ascan'] = single_motor_template TEMPLATES['ID_calibration'] = single_motor_template #from jinja2 import Template # What is this needed for? # connect olog from functools import partial from pyOlog import SimpleOlogClient from bluesky.callbacks.olog import logbook_cb_factory # Set up the logbook. This configures bluesky's summaries of # data acquisition (scan type, ID, etc.). LOGBOOKS = ['Data Acquisition'] # list of logbook names to publish to simple_olog_client = SimpleOlogClient() generic_logbook_func = simple_olog_client.log configured_logbook_func = partial(generic_logbook_func, logbooks=LOGBOOKS) # This is for ophyd.commands.get_logbook, which simply looks for # a variable called 'logbook' in the global IPython namespace. logbook = simple_olog_client #logbook_cb = logbook_cb_factory(configured_logbook_func) logbook_cb = logbook_cb_factory(configured_logbook_func, desc_dispatch=TEMPLATES) # uncomment this for debugging and comment the next two lines #RE.subscribe(logbook_cb) import nslsii nslsii.configure_olog(get_ipython().user_ns, callback=logbook_cb)
{{- start.plan_name }} ['{{ start.uid[:6] }}'] (scan num: {{ start.scan_id }}) Scan Plan --------- {{ start.plan_type }} {%- for k, v in start.plan_args | dictsort %} {{ k }}: {{ v }} {%- endfor %} {% if 'signature' in start -%} Call: {{ start.signature }} {% endif %} Metadata -------- {% for k, v in start.items() -%} {%- if k not in ['plan_type', 'plan_args'] -%}{{ k }} : {{ v }} {% endif -%} {%- endfor -%}""" desc_dispatch = {'edge_ascan': """ {{- start.name }} [{{ start.plan_name }} '{{ start.uid[:6] }}'] (scan num: {{ start.scan_id }})"""} cb = logbook_cb_factory(configured_logbook_func, desc_template=desc_template, desc_dispatch=desc_dispatch) nslsii.configure_olog(get_ipython().user_ns, callback=cb) # WARNING: gs. is no longer supported by bluesky # if needed, you may uncomment these lines and define your own gs at your own # risk #class gs: #DETS=[]