{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pause, Resume, and Suspend\n", "\n", "In this notebook you will:\n", "\n", "* Pause data acquisition interactively.\n", "* Resume or stop. Understand the various ways to stop.\n", "* Set up a \"suspender\" that will pause data acquisition automatically if a condition is met (e.g. beam dump) and resume when it is safe to do so.\n", "\n", "Recommended Prerequisites:\n", "\n", "* [Hello Bluesky](./Hello%20Bluesky.ipynb)\n", "\n", "## Configuration\n", "Below, we will connect to EPICS IOC(s) controlling simulated hardware in lieu of actual motors, detectors. The IOCs should already be running in the background. Run this command to verify that they are running: it should produce output with RUNNING on each line. In the event of a problem, edit this command to replace status with restart all and run again.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!supervisorctl -c supervisor/supervisord.conf status" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%run scripts/beamline_configuration.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# aliases for convenience/readability\n", "motor = motor_ph\n", "det = ph" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Acquisition\n", "\n", "### Interactively Pausing" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# counts forever until interrupted -- press 'stop' button in the notebook (in the terminal, you would use Ctrl+C)\n", "RE(count([det], delay=1, num=None))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The RunEngine is paused! Our choices:\n", "\n", "|Command | Outcome|\n", "|-----|-----|\n", "|`RE.resume()` |Safely resume plan.|\n", "|`RE.abort()` |Perform cleanup. Mark as aborted.|\n", "|`RE.stop()` |Perform cleanup. Mark as success.|\n", "|`RE.halt()` |Do not perform cleanup --- just stop.|\n", "|`RE.state` |Check if 'paused' or 'idle'.|" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While the RunEngine is paused, you have control of the prompt. You can check on things." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1 + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "det.read()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Safely Resuming" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Again, we need to press 'stop' or this will run forever....\n", "RE.resume()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exit options: abort, stop, and halt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Paused again. Once more, our choices:\n", "\n", "|Command | Outcome|\n", "|-----|-----|\n", "|`RE.resume()` |Safely resume plan.|\n", "|`RE.abort()` |Perform cleanup. Mark as aborted.|\n", "|`RE.stop()` |Perform cleanup. Mark as success.|\n", "|`RE.halt()` |Do not perform cleanup --- just stop.|\n", "|`RE.state` |Check if 'paused' or 'idle'.|" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.abort()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare 'abort' to 'stop' and 'halt':" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE(count([det], delay=1, num=None))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.stop()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE(count([det], delay=1, num=None))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.halt()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### What happens if we try to run a new plan from a paused state?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE(count([det], delay=1, num=None))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE(count([det], delay=1, num=None))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.state" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.abort()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "RE.state" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Configure a \"suspender\"\n", "\n", "Suspenders are agents set up in advance to run in the background and pause/resume a scan in response to some condition (like a beam dump)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from bluesky.suspenders import SuspendFloor\n", "import ophyd\n", "\n", "current = ophyd.Signal(name='beam_current')\n", "\n", "sus = SuspendFloor(current, 50, sleep=1)\n", "RE.install_suspender(sus)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "##### Simulate a beam dump and recovery after 3 seconds....\n", "import threading\n", "import time\n", "\n", "def delay_dump_delay_recover():\n", " time.sleep(3)\n", " current.set(0)\n", " time.sleep(5)\n", " current.set(100)\n", "\n", "current.set(100)\n", "thread = threading.Thread(target=delay_dump_delay_recover)\n", "thread.start()\n", "#####\n", "\n", "RE(count([det], num=10, delay=1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercises\n", "\n", "1. Execute a `count` with a delay (as we have done many times above) and practice pausing and resuming.\n", "2. Revisit the examples of abort, stop, and halt above." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }