{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hello, World\n",
"\n",
"Test the new bluesky installation with the _Hello, World!_ code in the `~/bluesky` directory.\n",
"If you need help to get there, follow those links:\n",
"\n",
"- [How to install Bluesky?](https://bcda-aps.github.io/bluesky_training/instrument/_install_new_instrument.html)\n",
"\n",
"- [How to start a Bluesky session?](https://bcda-aps.github.io/bluesky_training/howto/getting_started.html)\n",
"\n",
"- [What does the (~) means in ~/bluesky?](https://bcda-aps.github.io/bluesky_training/reference/_FAQ.html#faq-linux-tilde)\n",
"\n",
"- Not familiar with object-oriented programming glossary: [What are classes, objects, methods and instances?](https://bcda-aps.github.io/bluesky_training/reference/_FAQ.html#faq-obj-oriented)\n",
"\n",
" \n",
"\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Follow these steps to load the `bluesky` and `databroker` packages for data collection activities."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"1"
]
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import bluesky\n",
"import databroker\n",
"from bluesky.callbacks.best_effort import BestEffortCallback\n",
"\n",
"cat = databroker.temp().v2\n",
"RE = bluesky.RunEngine()\n",
"RE.subscribe(cat.v1.insert)\n",
"RE.subscribe(BestEffortCallback())"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"Line by line explanation\n",
"\n",
"- `my_path = ...` define a variable `my_path` as the \"bluesky\" directory located in the user's home directory\n",
"- `sys.path.append(my_path)` adds this directory to the list of directories that Python will search when you try to import a module.\n",
"- `cat = databroker.temp().v2` creates an instance of a databroker temporary catalog (a catalog which is deleted when the python session is exited) and assigns it to the variable `cat`. This allows you to interact with the databroker instance and access its functionality, such as querying for data, creating runs, or accessing metadata.\n",
"- `RE = bluesky.RunEngine()` creates a new instance of the RunEngine class and assigns it to the variable `RE`. The RunEngine is the central component of Bluesky, responsible for managing the execution of experimental plans and coordinating communication between other components, such as detectors and data acquisition devices.\n",
"- `RE.subscribe(cat.v1.insert)` sets up a subscription to the RunEngine instance (`RE`) that will insert data into a databroker instance (using `cat.v1`) as data is collected. This ensures that even partially collected data is stored and available for later analysis and processing.\n",
"- `RE.subscribe(BestEffortCallback())` sets up a subscription to the RunEngine instance (`RE`) that: \n",
" - show a chart during the run\n",
" - print a table of the run data during the run\n",
" - print a summary at the end of the run.\n",
""
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now load the `quick_hello.py` file located in the user directory and execute its contents in the current Python environment."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Loading 'Hello, World!' example.\n"
]
}
],
"source": [
"%run -i ~/bluesky/user/quick_hello.py"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note**: The `Loading 'Hello, World!' example.` text came from a `print()` statement in the file.\n",
"\n",
"This also loads `hello_world()`, a demonstration bluesky *plan*. We can run the `hello_world()` function in the `RE` RunEngine instance, which will execute the corresponding experimental plan. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"\n",
"Transient Scan ID: 1 Time: 2023-05-10 23:00:42\n",
"Persistent Unique Scan ID: '5d1dca55-ed86-47c4-a2d9-6b20e6c76672'\n",
"New stream: 'primary'\n",
"+-----------+------------+------------+\n",
"| seq_num | time | hello |\n",
"+-----------+------------+------------+\n",
"| 1 | 23:00:42.9 | 1 |\n",
"+-----------+------------+------------+\n",
"generator count ['5d1dca55'] (scan num: 1)\n",
"\n",
"\n",
"\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"('5d1dca55-ed86-47c4-a2d9-6b20e6c76672',)"
]
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"RE(hello_world())"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Since we have created a temporary catalog, the data is only available until the end of the IPython session.\n",
"\n",
"When working with a regular (\"not temporary\") catalog, more details about working with the data can be found here: \n",
"\n",
"- [How to access the data later, after the measurement.](https://bcda-aps.github.io/bluesky_training/howto/_after_measurement.html)\n",
"- [How to find Bluesky data.](https://bcda-aps.github.io/apstools/latest/examples/ho_search_databroker.html)\n",
"\n",
"In any case, we can retrieve data for **the most recent run** stored in the `cat` databroker instance, and assign it to the a variable `run`. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"run = cat[-1]\n",
"metadata=run.metadata\n",
"data=run.primary.read()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
" - `run` is a dictionary-like object that can be used to access the data `run.primary` and metadata `run.metadata` from the most recent run: we use [-1], meaning \"1 run ago\".\n",
" \n",
" - `metadata` is a python dictionary containing the information about an experimental run, such as the plan used, the detectors used, the start and end time of the run, and any other relevant experimental conditions. This metadata can be used to help manage and organize experimental data. \n",
"\n",
" - `data` uses the read() method to read the actual data collected during the run from the primary stream.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"BlueskyRun\n",
" uid='5d1dca55-ed86-47c4-a2d9-6b20e6c76672'\n",
" exit_status='success'\n",
" 2023-05-10 23:00:42.934 -- 2023-05-10 23:00:42.979\n",
" Streams:\n",
" * primary\n"
]
},
"metadata": {},
"execution_count": 5
}
],
"source": [
"run"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"{'start': Start({'detectors': ['hello'],\n",
" 'hints': {'dimensions': [[['time'], 'primary']]},\n",
" 'num_intervals': 0,\n",
" 'num_points': 1,\n",
" 'plan_args': {'detectors': [\"HelloDevice(prefix='', name='hello', \"\n",
" \"read_attrs=['number', 'text'], \"\n",
" 'configuration_attrs=[])'],\n",
" 'num': 1},\n",
" 'plan_name': 'count',\n",
" 'plan_type': 'generator',\n",
" 'scan_id': 1,\n",
" 'time': 1683777642.9343226,\n",
" 'title': 'test QS',\n",
" 'uid': '5d1dca55-ed86-47c4-a2d9-6b20e6c76672',\n",
" 'versions': {'bluesky': '1.6.7', 'ophyd': '1.6.0'}}),\n",
" 'stop': Stop({'exit_status': 'success',\n",
" 'num_events': {'primary': 1},\n",
" 'reason': '',\n",
" 'run_start': '5d1dca55-ed86-47c4-a2d9-6b20e6c76672',\n",
" 'time': 1683777642.9791105,\n",
" 'uid': '789202b8-bc55-460f-a4af-9f6f5b6db404'}),\n",
" 'catalog_dir': None}"
]
},
"metadata": {},
"execution_count": 6
}
],
"source": [
"metadata"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"\n",
"Dimensions: (time: 1)\n",
"Coordinates:\n",
" * time (time) float64 1.684e+09\n",
"Data variables:\n",
" hello (time) int64 1\n",
" hello_text (time) \n