From 93ddb3c6164a0e0303bc207c165d221c6e031bc1 Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Fri, 26 Jan 2024 11:02:35 -0800 Subject: [PATCH 1/2] DOC: document how to use hutch-python resources in a jupyter notebook --- docs/hutch_python.ipynb | 496 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 496 insertions(+) create mode 100644 docs/hutch_python.ipynb diff --git a/docs/hutch_python.ipynb b/docs/hutch_python.ipynb new file mode 100644 index 00000000..d6508a53 --- /dev/null +++ b/docs/hutch_python.ipynb @@ -0,0 +1,496 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "be4d831f-7497-4a5d-b726-c70de60ce908", + "metadata": {}, + "source": [ + "# How to Use This Notebook\n", + "This notebook shows how to set up a jupyter notebook to load resources that were designed for use in the hutch-python ipython shell.\n", + "You should follow the instructions in the next cell to set up the server process, and then cherry-pick the following cells as needed based on what you want the user to be able to do in the notebook. Feel free to customize and experiment as needed.\n", + "\n", + "This was written assuming usage in xpp. You should be able to do exactly the same thing for other instruments, replacing references to xpp items with the relevent ones from another hutch." + ] + }, + { + "cell_type": "markdown", + "id": "7029ed26-b999-4eaa-8989-d5cb226a12e2", + "metadata": {}, + "source": [ + "# Setting up the jupyter server\n", + "First, you need to source xppenv (or xcsenv or etc.) to get the right env variables for the jupyter kernel.\n", + "This makes the jupyter kernel find the xpp beamline files and makes the DAQ work.\n", + "Note that this locks your terminal session to being compatible with exactly one particular version of the DAQ.\n", + "```\n", + "zlentz@psbuild-rhel7-02:~$ source /cds/group/pcds/pyps/apps/hutch-python/xpp/xppenv\n", + "Loading NFS python env pcds-5.8.0\n", + "```\n", + "\n", + "This also lets you register the python env for use in the notebook if you haven't already done this:\n", + "```\n", + "(pcds-5.8.0)zlentz@psbuild-rhel7-02:~$ python -m ipykernel install --user --name=pcds-5.8.0\n", + "Installed kernelspec pcds-5.8.0 in /cds/home/z/zlentz/.local/share/jupyter/kernels/pcds-5.8.0\n", + "```\n", + "\n", + "Then you can run the notebook from the same session:\n", + "```\n", + "(pcds-5.8.0)zlentz@psbuild-rhel7-02:~$ jupyter-notebook\n", + "```\n", + "\n", + "If you want to control the DAQ, then the jupyter-nootback process must be run on the same linux host that the DAQ is running on." + ] + }, + { + "cell_type": "markdown", + "id": "3a12ce95-bf6d-4742-a7c5-356aab40f743", + "metadata": {}, + "source": [ + "## Making sure it works\n", + "This cell should import without errors and there should be lots of \"xpp\" on the paths. Mine is slightly different since I'm running on psbuild instead of xpp-daq:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "9117cd79-d0e0-455a-8184-ef22af02b96f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/cds/group/pcds/pyps/apps/hutch-python/device_config/happi.cfg\n", + "/cds/group/pcds/pyps/apps/hutch-python/xpp:/cds/group/pcds/pyps/apps/hutch-python/xpp/dev/devpath:/cds/group/pcds/pyps/apps/hutch-python/xpp/../common/dev/devpath:/reg/g/pcds/dist/pds/xpp/current/build/pdsapp/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/ami-current/build/ami/lib/x86_64-rhel7-opt\n", + ":/reg/g/pcds/dist/pds/xpp/ami-current/build/ami/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/ami-current/build/gsl/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/ami-current/build/qt/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/current/build/pdsapp/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/current/build/psalg/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/current/build/pds/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/current/build/pdsdata/lib/x86_64-rhel7-opt:/reg/g/pcds/dist/pds/xpp/current/build/offlinedb/lib/x86_64-rhel7-opt\n", + "/cds/group/pcds/pyps/apps/hutch-python/xpp/xpp/__init__.py\n", + "/reg/g/pcds/dist/pds/xpp/current/build/pdsapp/lib/x86_64-rhel7-opt/pydaq.abi3.so\n" + ] + } + ], + "source": [ + "import os\n", + "import pydaq\n", + "import xpp\n", + "print(os.environ[\"HAPPI_CFG\"])\n", + "print(os.environ[\"PYTHONPATH\"])\n", + "print(os.environ[\"LD_LIBRARY_PATH\"])\n", + "print(xpp.__file__)\n", + "print(pydaq.__file__)" + ] + }, + { + "cell_type": "markdown", + "id": "1991fab3-67aa-48e3-81ab-cd939c7b1ab2", + "metadata": {}, + "source": [ + "# Session Setup\n", + "It's probably a good idea to do the setup in the same order as done in the full load, even if you skip steps. Below is the order and the current best way to do each step independently." + ] + }, + { + "cell_type": "markdown", + "id": "04ee8cc0-6ad2-4e27-8f15-4bcf48a51133", + "metadata": {}, + "source": [ + "## Virtual Module Cache (xpp.db)\n", + "This is a utility that lets e.g. the beamline file import objects that are created automatically by importing them from xpp.db." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0dc2b08a-e9c0-484a-9182-ab0142e4f468", + "metadata": {}, + "outputs": [], + "source": [ + "from hutch_python.cache import LoadCache\n", + "cache = LoadCache(\"xpp.db\")" + ] + }, + { + "cell_type": "markdown", + "id": "140ff021-9242-4edc-987b-79c1b7c13f5a", + "metadata": {}, + "source": [ + "## Ophyd (EPICS) settings\n", + "These settings are used to deal with having tens of thousands of PV connections in one session. You might not need this for small sessions." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3e0034c7-e866-43ed-a929-433c21a772d8", + "metadata": {}, + "outputs": [], + "source": [ + "from hutch_python.ophyd_settings import setup_ophyd\n", + "setup_ophyd()" + ] + }, + { + "cell_type": "markdown", + "id": "57e513ae-3187-4237-90af-67ff406ed545", + "metadata": {}, + "source": [ + "## Run Engine\n", + "This is required if you want to do bluesky scans. The BEC sets up the text output table.\n", + "TODO: figure out how to get the jupyter plot in (see example at https://github.com/bluesky/tutorials/blob/main/bluesky-tutorial-utils/bluesky_tutorial_utils/beamline_configuration.py)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f0d2e8a7-15d7-48bc-a194-bde683e77c6c", + "metadata": {}, + "outputs": [], + "source": [ + "from bluesky import RunEngine\n", + "from bluesky.callbacks.best_effort import BestEffortCallback\n", + "RE = RunEngine({})\n", + "bec = BestEffortCallback()\n", + "bec.disable_plots()\n", + "RE.subscribe(bec)\n", + "cache(RE=RE, bec=bec)" + ] + }, + { + "cell_type": "markdown", + "id": "648bc843-98cb-43c0-9266-dd4100e318d8", + "metadata": {}, + "source": [ + "## Calc utils\n", + "These are just the calculation utlities e.g. the be lens calcs" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "97e923bb-4e03-4e1d-89a3-470c594a0064", + "metadata": {}, + "outputs": [], + "source": [ + "from pcdscalc.be_lens_calcs import *\n", + "from pcdscalc.common import *\n", + "from pcdscalc.diffraction import *" + ] + }, + { + "cell_type": "markdown", + "id": "2d4f23c4-847c-42cd-b579-36f5d5657987", + "metadata": {}, + "source": [ + "## DAQ\n", + "This is the classic LCLS1 daq. It ingests the RE for proper run closing during a scan.\n", + "TODO: add instructions for LCLS2 daq setup" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "2af01f0d-01c2-41c3-98c1-88328c6efe5f", + "metadata": {}, + "outputs": [], + "source": [ + "from pcdsdaq.daq.original import Daq\n", + "daq = Daq(RE=RE, hutch_name=\"xpp\")\n", + "cache(daq=daq)" + ] + }, + { + "cell_type": "markdown", + "id": "d632e8ab-4027-4e62-b516-2700e3737729", + "metadata": {}, + "source": [ + "## Bluesky Plans\n", + "This makes the standard bluesky plans (scans) available in curated namespaces.\n", + "\n", + "- bp: classic bluesky plans\n", + "- bps: plan stubs, building blocks for bluesky plans\n", + "- bpp: plan preprpocessors, functions that modify other plans\n", + "- re: functions that run as-is without needing to pass them into RE\n", + "\n", + "This also adds some runnable functions onto the daq object, e.g. the daq plans like daq.ascan, for example." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2dff9884-ae0c-4712-bc0b-d5eca4b6da49", + "metadata": {}, + "outputs": [], + "source": [ + "from hutch_python.plan_wrappers import initialize_wrapper_namespaces\n", + "from hutch_python import plan_defaults\n", + "\n", + "re = initialize_wrapper_namespaces(\n", + " RE=RE,\n", + " plan_namespace=plan_defaults.plans,\n", + " daq=daq,\n", + ")\n", + "bp = plan_defaults.plans\n", + "bps = plan_defaults.plan_stubs\n", + "bpp = plan_defaults.preprocessors\n", + "cache(re=re, bp=bp, bps=bps, bpp=bpp)" + ] + }, + { + "cell_type": "markdown", + "id": "cc425f8b-efb1-4d2b-804e-a9994b924996", + "metadata": {}, + "source": [ + "## Scan PVs\n", + "These are the PVs that are used to make run tables in the logbook that update based on scan progress." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7c48bdcf-01a9-41fe-872d-e08b22e3d158", + "metadata": {}, + "outputs": [], + "source": [ + "from pcdsdaq.scan_vars import ScanVars\n", + "scan_pvs = ScanVars(\n", + " \"XPP:SCAN\",\n", + " name=\"scan_pvs\",\n", + " RE=RE,\n", + ")\n", + "scan_pvs.enable()\n", + "cache(scan_pvs=scan_pvs)" + ] + }, + { + "cell_type": "markdown", + "id": "2ff2ee82-0ce9-4845-a3cc-e29061db466f", + "metadata": {}, + "source": [ + "## Happi Devices\n", + "If you want to pick a few beamline devices to include, here's how" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1c5d9bb0-7894-42c5-b65a-11d721edb48c", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Can not enforce type to match attribute prefix_det as it does not exist on the container.\n" + ] + } + ], + "source": [ + "from happi import Client\n", + "client = Client.from_config()\n", + "xpp_sb3_pim = client.load_device(name=\"xpp_sb3_pim\")" + ] + }, + { + "cell_type": "markdown", + "id": "b54cbc6e-1bfc-4b78-bec2-ab71ade1b037", + "metadata": {}, + "source": [ + "## Questionnaire Objects\n", + "Create objects that are defined in the questionnaire" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "9d4a43d3-529e-435c-9e3b-d777068a5d70", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed to create a happi database entry from the questionnaire device: motors:8. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:5. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:6. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:3. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:7. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:2. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:12. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:11. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:10. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:4. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:9. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:13. KeyError: 'pvbase'\n", + "Failed to create a happi database entry from the questionnaire device: motors:1. KeyError: 'pvbase'\n", + "Stage Identity has not been set for this object: jungfrau_y. Configure manually.\n", + "Stage Identity has not been set for this object: g2yaw. Configure manually.\n", + "Stage Identity has not been set for this object: sam_chi. Configure manually.\n", + "Stage Identity has not been set for this object: k_eta. Configure manually.\n", + "Stage Identity has not been set for this object: t5chi. Configure manually.\n", + "Stage Identity has not been set for this object: t2th. Configure manually.\n", + "Stage Identity has not been set for this object: crl_y. Configure manually.\n", + "Stage Identity has not been set for this object: g2x. Configure manually.\n", + "Stage Identity has not been set for this object: sam_th. Configure manually.\n", + "Stage Identity has not been set for this object: t1chi. Configure manually.\n", + "Stage Identity has not been set for this object: g1_x. Configure manually.\n", + "Stage Identity has not been set for this object: g2y. Configure manually.\n", + "Stage Identity has not been set for this object: t3x. Configure manually.\n", + "Stage Identity has not been set for this object: t4th. Configure manually.\n", + "Stage Identity has not been set for this object: t4x. Configure manually.\n", + "Stage Identity has not been set for this object: zyla_z. Configure manually.\n", + "Stage Identity has not been set for this object: d3x. Configure manually.\n", + "Stage Identity has not been set for this object: k_phi. Configure manually.\n", + "Stage Identity has not been set for this object: g1_yaw. Configure manually.\n", + "Stage Identity has not been set for this object: g2roll. Configure manually.\n", + "Stage Identity has not been set for this object: g2pi. Configure manually.\n", + "Stage Identity has not been set for this object: t6x. Configure manually.\n", + "Stage Identity has not been set for this object: t6y. Configure manually.\n", + "Stage Identity has not been set for this object: t6th. Configure manually.\n", + "Stage Identity has not been set for this object: d2x. Configure manually.\n", + "Stage Identity has not been set for this object: t3chi. Configure manually.\n", + "Stage Identity has not been set for this object: d5x. Configure manually.\n", + "Stage Identity has not been set for this object: zyla_x. Configure manually.\n", + "Stage Identity has not been set for this object: d4x. Configure manually.\n", + "Stage Identity has not been set for this object: zyla_y. Configure manually.\n", + "Stage Identity has not been set for this object: t5th. Configure manually.\n", + "Stage Identity has not been set for this object: t1th. Configure manually.\n", + "Stage Identity has not been set for this object: crl_x. Configure manually.\n", + "Stage Identity has not been set for this object: sam_y. Configure manually.\n", + "Stage Identity has not been set for this object: d1x. Configure manually.\n", + "Stage Identity has not been set for this object: t2x. Configure manually.\n", + "Stage Identity has not been set for this object: g1_roll. Configure manually.\n", + "Stage Identity has not been set for this object: g1_y. Configure manually.\n", + "Stage Identity has not been set for this object: t3th. Configure manually.\n", + "Stage Identity has not been set for this object: t1x. Configure manually.\n", + "Successfully loaded questionnaire in 2.05 s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "namespace(jungfrau_y=IMS(HXR:PRT:01:MMS:02, name=jungfrau_y), g2yaw=IMS(XPP:USR:PRT:MMS:21, name=g2yaw), g1_pi=Newport(XPP:USR:MMN:01, name=g1_pi), sam_chi=IMS(HXR:PRT:01:MMS:01, name=sam_chi), k_eta=IMS(XPP:GON:MMS:09, name=k_eta), jungfrau_x=Newport(XPP:USR:PRT:MMN:05, name=jungfrau_x), t5chi=IMS(HXR:PRT:01:MMS:07, name=t5chi), prism_th=Newport(XPP:USR:MMN:07, name=prism_th), t2th=IMS(XPP:USR:MMS:30, name=t2th), crl_y=IMS(XPP:USR:PRT:MMS:22, name=crl_y), bs_y=Newport(XPP:USR:PRT:MMN:02, name=bs_y), bs_x=Newport(XPP:USR:PRT:MMN:01, name=bs_x), g2x=IMS(XPP:USR:PRT:MMS:17, name=g2x), sam_th=IMS(XPP:USR:PRT:MMS:32, name=sam_th), t1chi=IMS(XPP:USR:MMS:29, name=t1chi), g1_x=IMS(XPP:USR:MMS:22, name=g1_x), g2y=IMS(XPP:USR:PRT:MMS:18, name=g2y), t3x=IMS(XPP:USR:MMS:31, name=t3x), t4th=IMS(HXR:PRT:01:MMS:06, name=t4th), t4x=IMS(HXR:PRT:01:MMS:05, name=t4x), zyla_z=IMS(XPP:USR:PRT:MMS:25, name=zyla_z), d3x=IMS(HXR:PRT:01:MMS:10, name=d3x), prism_y=Newport(XPP:USR:MMN:04, name=prism_y), k_phi=IMS(XPP:GON:MMS:11, name=k_phi), g1_yaw=IMS(XPP:USR:MMS:25, name=g1_yaw), crl_chi=Newport(XPP:USR:MMN:11, name=crl_chi), prism_x=Newport(XPP:USR:MMN:03, name=prism_x), g2roll=IMS(XPP:USR:PRT:MMS:20, name=g2roll), g2pi=IMS(XPP:USR:PRT:MMS:19, name=g2pi), t6x=IMS(XPP:USR:PRT:MMS:27, name=t6x), crl_th=Newport(XPP:USR:MMN:10, name=crl_th), t6y=IMS(XPP:USR:PRT:MMS:29, name=t6y), t6th=IMS(XPP:USR:PRT:MMS:28, name=t6th), d2x=IMS(HXR:PRT:01:MMS:09, name=d2x), t3chi=IMS(HXR:PRT:01:MMS:03, name=t3chi), d5x=IMS(HXR:PRT:01:MMS:12, name=d5x), det_x=Newport(XPP:USR:PRT:MMN:04, name=det_x), zyla_x=IMS(XPP:USR:PRT:MMS:26, name=zyla_x), sam_x=Newport(XPP:USR:PRT:MMN:06, name=sam_x), d4x=IMS(HXR:PRT:01:MMS:11, name=d4x), zyla_y=IMS(XPP:USR:PRT:MMS:24, name=zyla_y), t5th=IMS(HXR:PRT:01:MMS:04, name=t5th), t1th=IMS(XPP:USR:MMS:28, name=t1th), crl_x=IMS(XPP:USR:PRT:MMS:23, name=crl_x), sam_y=IMS(XPP:USR:PRT:MMS:31, name=sam_y), d1x=IMS(HXR:PRT:01:MMS:08, name=d1x), t2x=IMS(XPP:USR:PRT:MMS:30, name=t2x), g1_roll=IMS(XPP:USR:MMS:24, name=g1_roll), d6x=Newport(XPP:USR:PRT:MMN:07, name=d6x), g1_y=IMS(XPP:USR:MMS:23, name=g1_y), pump_wp=Newport(XPP:USR:MMN:06, name=pump_wp), det_y=Newport(XPP:USR:PRT:MMN:03, name=det_y), t3th=IMS(XPP:USR:MMS:32, name=t3th), t1x=IMS(XPP:USR:MMS:27, name=t1x))\n" + ] + } + ], + "source": [ + "from types import SimpleNamespace\n", + "from hutch_python.qs_load import get_qs_objs\n", + "qs_objs = get_qs_objs(\"xppc00121\")\n", + "qs = SimpleNamespace(**qs_objs)\n", + "print(qs)" + ] + }, + { + "cell_type": "markdown", + "id": "669e7280-b3ef-4263-b21d-c079140e6d29", + "metadata": {}, + "source": [ + "## Beamline load\n", + "The classic" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "08f634bd-c8c5-44bf-bce5-43c72fae5859", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed to load pyami detectors after 2.11 s\n", + "Successfully loaded Event Sequencers in 0.01 s\n", + "Failed to load K mono after 0.01 s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Successfully loaded fake_delay in 0.00 s\n", + "Failed to load xpp_lens after 0.00 s\n", + "Successfully loaded GON motors XYZ in 0.05 s\n", + "Successfully loaded GON motors Phi-Z in 0.03 s\n", + "Successfully loaded xpp_gon_kappa in 0.40 s\n", + "Failed to load Combine gon objects after 0.00 s\n", + "Failed to load gon and kappa after 0.00 s\n", + "Successfully loaded Roving Spectrometer in 0.00 s\n", + "Successfully loaded Noplot ascan in 0.00 s\n", + "Successfully loaded Mode change in 0.00 s\n", + "Failed to load FS11 & FS14 lxt & lxt_ttc after 0.01 s\n", + "Successfully loaded Delay Scan in 0.00 s\n", + "Successfully loaded Laser Shutters - cp, lp & ep in 0.01 s\n", + "Failed to load Create Aliases after 0.00 s\n", + "Failed to load add pp motors after 0.02 s\n", + "Successfully loaded add crl motors in 0.05 s\n", + "Successfully loaded LIB SmarAct in 0.11 s\n", + "Successfully loaded AMI auto save in 0.00 s\n", + "Failed to load add laser motor groups after 0.00 s\n", + "Successfully loaded enable scan table scientific notation in 0.00 s\n", + "Successfully loaded Time tool target in 0.03 s\n", + "Successfully loaded autorun in 0.00 s\n" + ] + } + ], + "source": [ + "from xpp.beamline import *" + ] + }, + { + "cell_type": "markdown", + "id": "663c1994-88e9-44f3-81ae-2e569d50f238", + "metadata": {}, + "source": [ + "## Experiment file load\n", + "The other classic" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a8d32955-49cf-45e4-be8d-bf785eac8c74", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Successfully loaded c00121 in 0.00 s\n" + ] + } + ], + "source": [ + "from hutch_python.exp_load import get_exp_objs\n", + "x = get_exp_objs(\"c00121\", ask_on_failure=False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pcds-5.8.1", + "language": "python", + "name": "pcds-5.8.1" + }, + "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.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 850477424b6492e158a153f9ddb648781fa249fb Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Thu, 27 Jun 2024 14:16:40 -0700 Subject: [PATCH 2/2] DOC: pre-release notes --- .../377-doc_jupy_usage.rst | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 docs/source/upcoming_release_notes/377-doc_jupy_usage.rst diff --git a/docs/source/upcoming_release_notes/377-doc_jupy_usage.rst b/docs/source/upcoming_release_notes/377-doc_jupy_usage.rst new file mode 100644 index 00000000..6652d38d --- /dev/null +++ b/docs/source/upcoming_release_notes/377-doc_jupy_usage.rst @@ -0,0 +1,22 @@ +377 doc_jupy_usage +################## + +API Changes +----------- +- N/A + +Features +-------- +- N/A + +Bugfixes +-------- +- N/A + +Maintenance +----------- +- Document some first-pass efforts at running these tools in jupyter notebooks. + +Contributors +------------ +- zllentz