diff --git a/.gitignore b/.gitignore index d36cd46..896218d 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,4 @@ lib/ # Output files data/* !data/.placeholder +src/tomoscan/.ipynb_checkpoints/setup-checkpoint.ipynb diff --git a/docker-compose.yml b/docker-compose.yml index ad3afbb..a092a4d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,7 +102,7 @@ services: - --pv-prefix - "EPAC-DEV:PULSE:" - --period - - "5" + - "2" - --epics-time-offset - "-0.05" - --enable-gate diff --git a/docs/user/how-to/run-scan.rst b/docs/user/how-to/run-scan.rst index 7a97fa9..3336195 100644 --- a/docs/user/how-to/run-scan.rst +++ b/docs/user/how-to/run-scan.rst @@ -1,5 +1,9 @@ Running a scan ================== +Scans can either be run within an IPython terminal or a Jupyter notebook. + +IPython terminal +---------------- * Start the interactive bluesky environment. It is important to mount the output directory and run the container within the same network as the docker-compose environment. This can be achieved by running: @@ -11,6 +15,21 @@ Running a scan There are two scan modes which are explained below. Outputs from the scan are saved to the data directory. +Jupyter notebook +----------------- + +* Start the Jupyter notebook container, mounting the output directory and the directory containing the example Jupyter notebook. The container must also be run within the same network as the docker-compose environment. Do this by running: + +.. code-block:: bash + + docker run -p 8888:8888 -v `pwd`/src/tomoscan:/home/jovyan/work -v `pwd`/data:/home/jovyan/data --net tomoscan_default tomoscan_jupyter + +* Copy and paste the URL starting :code:`http://127.0.0.1:8888` that appears in the terminal into a browser to launch the Jupyter server +* Launch the setup notebook which is found in the work folder +* Start the phoebus screen to monitor the scan's progress. Navigate to the display folder and run :code:`./startOverview.sh` +* Follow the steps in the Jupyter notebook + + Synced scan ------------- In the default setup the pulse generator triggers the laser IOC and then when running the synced scan the motor moves to its next position, waits for the laser PV to diff --git a/sim/build.sh b/sim/build.sh index 30d51bd..91faf41 100755 --- a/sim/build.sh +++ b/sim/build.sh @@ -2,7 +2,7 @@ set -e -BUILD_DIRECTORIES="areaDetectorDock motorDock pmac pulsedLaser" +BUILD_DIRECTORIES="areaDetectorDock motorDock pmac pulsedLaser jupyter" for DIR in $BUILD_DIRECTORIES; do echo "+--------------------------" diff --git a/sim/jupyter/Dockerfile b/sim/jupyter/Dockerfile new file mode 100644 index 0000000..e41d9a2 --- /dev/null +++ b/sim/jupyter/Dockerfile @@ -0,0 +1,7 @@ +#Due to copying a top level file this must be run from the top level directory +FROM jupyter/base-notebook + +#Long term this list should somehow be synced with the bluesky pip install list +RUN set -ex && pip install h5py bluesky ophyd ipython matplotlib databroker pyepics area-detector-handlers +RUN mkdir -p ~/.config/databroker +COPY ./mongo.yml /home/jovyan/.config/databroker/mongo.yml \ No newline at end of file diff --git a/sim/jupyter/build.sh b/sim/jupyter/build.sh new file mode 100755 index 0000000..f101981 --- /dev/null +++ b/sim/jupyter/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash +DIR=$(pwd) +cd ../.. +docker build -t tomoscan_jupyter -f sim/jupyter/Dockerfile . +cd $DIR \ No newline at end of file diff --git a/src/tomoscan/setup.ipynb b/src/tomoscan/setup.ipynb new file mode 100644 index 0000000..dc7785d --- /dev/null +++ b/src/tomoscan/setup.ipynb @@ -0,0 +1,96 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ophyd_inter_setup import *\n", + "det.hdf1.read_path_template = \"/home/jovyan/data/%Y/%m/%d/\" " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The synced scan can then be run. This example scans in 11 steps between -10 and +10." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "uids = RE(pulse_sync([det], motor1, laser1, -10, 10, 11))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To access the data stored in the databroker catalog run the following:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run = catalog[uids[0]] #Accesses the run based on its uid, the most recent run can also be accessed as catalog[-1]\n", + "data = run.primary.read()\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The image data is accessed as shown below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "image = data[\"det_image\"]\n", + "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()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}