From 4498e840e8502ee7f81d21ae18fb3cd7ce7ba84f Mon Sep 17 00:00:00 2001 From: Bryn <31349775+8ryn@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:51:19 +0100 Subject: [PATCH] Modify jupyter notebook to import from main script --- src/tomoscan/setup.ipynb | 276 +-------------------------------------- 1 file changed, 6 insertions(+), 270 deletions(-) diff --git a/src/tomoscan/setup.ipynb b/src/tomoscan/setup.ipynb index 6204ae9..dc7785d 100644 --- a/src/tomoscan/setup.ipynb +++ b/src/tomoscan/setup.ipynb @@ -1,225 +1,12 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import time as ttime\n", - "\n", - "from bluesky.plans import count, scan\n", - "from ophyd import EpicsSignal" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here the ophyd areadetector classes are setup:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ophyd.areadetector.filestore_mixins import FileStoreHDF5IterativeWrite\n", - "from ophyd.areadetector.plugins import HDF5Plugin_V34\n", - "from ophyd import SingleTrigger, AreaDetector, ADComponent\n", - "from ophyd.areadetector import cam\n", - "\n", - "class MyHDF5Plugin(FileStoreHDF5IterativeWrite, HDF5Plugin_V34):\n", - " ...\n", - "\n", - "\n", - "class MyDetector(SingleTrigger, AreaDetector):\n", - " cam = ADComponent(cam.AreaDetectorCam, \"CAM:\")\n", - " hdf1 = ADComponent(\n", - " MyHDF5Plugin,\n", - " \"HDF1:\",\n", - " write_path_template=\"/out/%Y/%m/%d/\",\n", - " #read_path_template=\"/home/bar/Projects/tomoscan/data/%Y/%m/%d/\",\n", - " read_path_template=\"/home/jovyan/data/%Y/%m/%d/\"\n", - " \n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ophyd import Device, Component, EpicsSignalRO\n", - "\n", - "class MyLaser(Device):\n", - " power = Component(EpicsSignalRO, \"laser:power\")\n", - " pulse_id = Component(EpicsSignalRO, \"EPAC-DEV:PULSE:PULSE_ID\", name=\"pulse_id\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next code block defines a function used to poll PVs until they take a particular value.\n", - "This function should be a temporary measure and a more streamlined approach monitoring the PV integrated proerly with Bluesky/Ophyd is hoped to be used in the future." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def wait_for_value(signal: EpicsSignal, value, poll_time=0.01, timeout=10):\n", - " expiration_time = ttime.time() + timeout\n", - " current_value = signal.get()\n", - " while current_value != value:\n", - " # ttime.sleep(poll_time)\n", - " yield from bps.sleep(poll_time)\n", - " if ttime.time() > expiration_time:\n", - " raise TimeoutError(\n", - " \"Timed out waiting for %r to take value %r after %r seconds\"\n", - " % (signal, value, timeout)\n", - " )\n", - " current_value = signal.get()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This custom plan moves the motor and then waits for the laser pulse before taking the next reading." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from bluesky.plan_stubs import mv\n", - "import bluesky.plan_stubs as bps\n", - "\n", - "def pulse_sync(detectors, motor, laser, start, stop, steps):\n", - " step_size = (stop - start) / (steps - 1)\n", - "\n", - " for det in detectors:\n", - " yield from bps.stage(det)\n", - "\n", - " yield from bps.open_run()\n", - " for i in range(steps):\n", - " yield from bps.checkpoint() # allows pausing/rewinding\n", - " yield from mv(motor, start + i * step_size)\n", - " yield from wait_for_value(\n", - " laser.power, 0, poll_time=0.01, timeout=10\n", - " ) # Want to be at 0 initially such that image taken on pulse\n", - " yield from wait_for_value(laser.power, 1, poll_time=0.001, timeout=10)\n", - " yield from bps.trigger_and_read(list(detectors) + [motor] + [laser])\n", - " yield from bps.close_run()\n", - "\n", - " for det in detectors:\n", - " yield from bps.unstage(det)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This custom plan moves the motor based on the detector status. It is designed to be used when the detector is being directly triggered outside of bluesky." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def passive_scan(detectors, motor, start, stop, steps, adStatus, pulse_ID):\n", - " step_size = (stop - start) / (steps - 1)\n", - "\n", - " yield from mv(motor, start) # Move motor to starting position since may take time\n", - "\n", - " yield from bps.open_run()\n", - "\n", - " for det in detectors:\n", - " yield from bps.stage(det)\n", - "\n", - " for i in range(steps):\n", - " yield from mv(motor, start + i * step_size)\n", - " yield from bps.checkpoint()\n", - " yield from wait_for_value(adStatus, 2, poll_time=0.001, timeout=10)\n", - " yield from bps.trigger_and_read([motor] + [pulse_ID])\n", - " yield from wait_for_value(adStatus, 0, poll_time=0.001, timeout=10)\n", - "\n", - " for det in detectors:\n", - " yield from bps.unstage(det)\n", - "\n", - " yield from bps.close_run()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we initialise the detector object. \n", - "This will give an error saying that caRepeater couldn't be located, this is not an issue. A second related error message may later appear which can also be ignored." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "prefix = \"ADT:USER1:\"\n", - "det = MyDetector(prefix, name=\"det\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The detector's HDF plugin is then set to create the necessary output directory if it does not exist and the detector is primed.\n", - "The plugin's \"kind\" is required to be set to 3 such that the resulting HDF files are accessible via the databroker." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "det.hdf1.create_directory.put(-5)\n", - "det.hdf1.warmup()\n", - "det.hdf1.kind = 3 # config | normal, required to include images in run documents" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The camera's stage signatures are area detector configurations which are set whenever the detector is staged within Bluesky." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "det.cam.stage_sigs[\"image_mode\"] = \"Multiple\"\n", - "det.cam.stage_sigs[\"acquire_time\"] = 0.05\n", - "det.cam.stage_sigs[\"num_images\"] = 1" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The motor and laser objects are created. In the case of the laser we wait for the PVs to connect succesfully." + "First the detector, laser and motor are setup along with the bluesky environment from the ophyd_inter_setup file.\n", + "Due to the different file structure of the Jupyter notebook the read path must be updated.\n", + "An error related to caRepeater will likely appear, this is not a concern." ] }, { @@ -228,59 +15,15 @@ "metadata": {}, "outputs": [], "source": [ - "from ophyd import EpicsMotor\n", - "\n", - "motor1 = EpicsMotor(\"motorS:axis1\", name=\"motor1\")\n", - "laser1 = MyLaser(\"\", name=\"laser1\")\n", - "laser1.wait_for_connection()" + "from ophyd_inter_setup import *\n", + "det.hdf1.read_path_template = \"/home/jovyan/data/%Y/%m/%d/\" " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We load the Bluesky run engine and subscribe the best effort callback. The best effort callback aims to print and plot useful information as scans are performed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from bluesky import RunEngine\n", - "from bluesky.callbacks.best_effort import BestEffortCallback\n", - "\n", - "RE = RunEngine()\n", - "bec = BestEffortCallback()\n", - "RE.subscribe(bec)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The databroker is linked to the running mongoDB database and the run engine is set to insert all data captured to the databroker." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import databroker\n", - "\n", - "catalog = databroker.catalog[\"mongo\"]\n", - "RE.subscribe(catalog.v1.insert)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As a first example run this synced scan which takes 11 readings at intervals between motor positions of -10 and +10\n", - "This will also generate a table and a plot of the motor position. In this case the plot does not show much information." + "The synced scan can then be run. This example scans in 11 steps between -10 and +10." ] }, { @@ -327,13 +70,6 @@ "frame = image[0][0] # Index 1 refers to the time of the image and the second index refers to the frame number\n", "frame.plot.pcolormesh()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": {