Skip to content

Commit 6f02229

Browse files
committed
File-writing docs
1 parent 1d088d7 commit 6f02229

File tree

3 files changed

+58
-50
lines changed

3 files changed

+58
-50
lines changed

doc/callbacks/centre_of_mass.md

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
11
# Centre of Mass
22

3-
{py:obj}`ibex_bluesky_core.callbacks.CentreOfMass` is a callback that provides functionality for calculating our definition of Centre of Mass. We calculate centre of mass from the 2D region bounded by min(y), min(x), max(x), and straight-line segments joining (x, y) data points with their nearest neighbours along the x axis.
3+
{py:obj}`ibex_bluesky_core.callbacks.CentreOfMass` provides functionality for calculating a specific definition of a "centre of mass": it computes the centre of mass of a 2-dimensional region bounded by:
4+
- `min(x)`
5+
- `max(x)`
6+
- `min(y)`
7+
- Straight-line segments joining `(x, y)` data points with their nearest neighbours along the x axis
48

5-
{py:obj}`ibex_bluesky_core.callbacks.CentreOfMass` has a property, {py:obj}`result <ibex_bluesky_core.callbacks.CentreOfMass.result>`, which stores the centre of mass value once the callback has finished.
9+
{py:obj}`~ibex_bluesky_core.callbacks.CentreOfMass` stores its result in the {py:obj}`result <ibex_bluesky_core.callbacks.CentreOfMass.result>` property.
610

7-
## Our CoM Algorithm
11+
:::{note}
12+
This will return **different** results from the `com` property available from {py:obj}`bluesky.callbacks.fitting.PeakStats` in the following cases:
13+
- Points irregularly sampled along the x-axis
14+
- Points with negative y-values
15+
- x data which does not monotonically increase
816

9-
Given non-continuous arrays of collected data `x` and `y`, ({py:obj}`ibex_bluesky_core.callbacks.CentreOfMass`) returns the `x` value of the centre of mass.
17+
For a detailed comparison of the two implementations, see [unit tests written to expose tricky cases](https://github.com/bluesky/bluesky/blob/2d6fecd45e8de3a7d53d1c16dcd1a7b8f6f88d69/src/bluesky/tests/test_scientific.py#L142).
18+
:::
1019

11-
Our use cases require that our algorithm abides to the following rules:
12-
- Any background on data does not skew the centre of mass
13-
- The order in which data is received does not skew the centre of mass
20+
Given non-continuous arrays of collected data `x` and `y`, {py:obj}`~ibex_bluesky_core.callbacks.CentreOfMass` returns the `x` value of the centre of mass.
21+
22+
Many of our use cases require that our algorithm follows the following rules:
23+
- Any background on data should not change the centre of mass.
24+
- The order in which data is received should not change the centre of mass
1425
- Should support non-constant point spacing without skewing the centre of mass
1526

1627
```{note}
1728
Note that this is designed for only **positive** peaks.
1829
```
1930

20-
### Step-by-step
31+
{py:obj}`ibex_bluesky_core.callbacks.CentreOfMass` is included in {doc}`our callbacks collection <isiscallbacks>`.
32+
33+
---
34+
35+
**Implementation details**
2136

2237
1) Sort `x` and `y` arrays in respect of `x` ascending. This is so that data can be received in any order.
23-
2) From each `y` element, subtract `min(y)`. This means that any constant background over data is ignored. (Does not work for negative peaks)
24-
3) Calculate weight/widths for each point; based on it's `x` distances from neighbouring points. This ensures non-constant point spacing is accounted for in our calculation.
25-
4) For each decomposed shape that makes up the total area under the curve, `CoM` is calculated as the following:
38+
2) From each `y` element, subtract `min(y)`. This means that any constant background over data is ignored.
39+
3) Decompose the curve into a series of trapezoidal regions, and then further decompose those
40+
trapezoidal regions into rectangular and triangular regions.
41+
4) Compute centre of mass of the overall shape by composition of each region:
2642
```{math}
27-
com_x = \frac{\sum_{}^{}x * y * \text{weight}}{\sum_{}^{}y * \text{weight}}
28-
```
29-
30-
{py:obj}`ibex_bluesky_core.callbacks.CentreOfMass` can be used from our callbacks collection. See {doc}`isiscallbacks`.
43+
C_x = \frac{\sum_{i}^{} C_{ix} * A_i}{\sum_{i}^{} A_i}
44+
```

doc/callbacks/file_writing.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
{#hr_file_cb}
44
## Human readable files
55

6-
A callback ([`HumanReadableFileCallback`](ibex_bluesky_core.callbacks.HumanReadableFileCallback)) exists to write all documents to a separate human-readable file which contains the specified fields.
6+
{py:obj}`~ibex_bluesky_core.callbacks.HumanReadableFileCallback` can be configured to write all documents to a human-readable file which contains the specified fields.
77

8-
This callback will add units and honour precision for each field as well as add some metadata ie. the `uid` of each scan as well as the RB number, which is injected using the {doc}`/dev/rbnumberpp`
8+
This callback will add units and honour precision for each field as well as add some metadata, for example the RB number, which is injected using the {doc}`/dev/rbnumberpp`.
99

10-
### Example
1110
An example of using this could be:
1211

1312
```{code} python
@@ -47,15 +46,15 @@ RE(some_plan())
4746
```
4847

4948
This will put the `block` and `dae.good_frames` data collected over the run into a `.txt` file, named after the `uid`
50-
of the scan, in `C:\instrument\var\logs\bluesky\output_files\`.
49+
of the scan, in `\\isis\inst$\ndx<inst>\user\bluesky_scans\<rbnumber>`.
5150

5251
Optional parameters, not shown above, include:
53-
- `output_dir` parameter is optional, if not input the file will by default be placed in
52+
- `output_dir` parameter is optional; if not provided, the file will by default be placed in
5453
`\\isis\inst$\ndx<inst>\user\bluesky_scans\<rbnumber>`.
5554
- `postfix` an optional suffix to append to the end of the file name, to disambiguate scans. Default is no suffix.
5655

5756
The data is prepended on the first event with the names and units of each logged field, and then subsequently the data
58-
for each scan separated by a newline. All of this is separated by commas, though the metadata is not.
57+
for each scan separated by a newline. The data is separated by commas, though the metadata is not.
5958

6059
The file also contains metadata such as the bluesky version, plan type, and rb number.
6160

@@ -74,6 +73,6 @@ See {ref}`plot_png_saver`
7473
This callback is added automatically and is not intended to be user-facing - it is primarily for developer diagnostics.
7574
```
7675

77-
The [`DocLoggingCallback`](ibex_bluesky_core.callbacks.DocLoggingCallback) is a callback that the BlueSky RunEngine subscribes to unconditionally in {py:obj}`RunEngine import level<ibex_bluesky_core.run_engine.get_run_engine>`. After receiving each document, if they share the same start document (in the same run) then it will write them to the same file. These logs are stored under `C:/instrument/var/logs/bluesky/raw_documents` and are handled by the log rotation.
76+
The {py:obj}`~ibex_bluesky_core.callbacks.DocLoggingCallback` is a callback that the BlueSky RunEngine subscribes to unconditionally during {py:obj}`~ibex_bluesky_core.run_engine.get_run_engine>`. It logs all documents it receives into files grouped by unique scan identifier. These logs are stored under `C:/instrument/var/logs/bluesky/raw_documents`; older logs are moved to long-term storage by a log rotation script.
7877

79-
Each document is stored in a JSON format so can be both machine and human readable. It is in the format `{"type": name, "document": document}` whereby `name` is the type of the document, e.g start, stop, event, descriptor and the `document` is the [document from BlueSky in JSON format](https://blueskyproject.io/bluesky/main/documents.html). As these files are produced per BlueSky run, these will be useful for debugging.
78+
Each document is stored in a JSON format so can be both machine and human readable. The format is line-delimited JSON, `{"type": name, "document": document}` whereby `name` is the type of the document, e.g start, stop, event, descriptor and the `document` is the {external+bluesky:doc}`document from bluesky in JSON format <documents>`.

doc/callbacks/plotting.md

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,32 @@
11
# Plotting
22

3-
## `LivePlot`
3+
## {py:obj}`~ibex_bluesky_core.callbacks.LivePlot`
44

55
Bluesky has good integration with {py:obj}`matplotlib` for data visualization, and data from scans
6-
may be easily plotted using the {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>` callback.
6+
may be easily plotted using the {py:obj}`~ibex_bluesky_core.callbacks.LivePlot` callback.
77

8-
{py:obj}`ibex_bluesky_core` provides a thin wrapper over bluesky's default
9-
{py:obj}`LivePlot<bluesky.callbacks.mpl_plotting.LivePlot>` callback,
8+
{py:obj}`ibex_bluesky_core.callbacks.LivePlot` provides a thin wrapper over bluesky's default
9+
{py:obj}`bluesky.callbacks.mpl_plotting.LivePlot` callback,
1010
which ensures that plots are promptly displayed in IBEX.
1111

12-
In order to use the wrapper, import {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>`
12+
In order to use the wrapper, import {py:obj}`~ibex_bluesky_core.callbacks.LivePlot`
1313
from {py:obj}`ibex_bluesky_core.callbacks` rather than importing
1414
{py:obj}`bluesky.callbacks.mpl_plotting.LivePlot` directly:
1515

16+
```python
17+
from ibex_bluesky_core.callbacks import LivePlot
1618
```
17-
from ibex_bluesky_core.callbacks.plotting import LivePlot
18-
```
19-
20-
## Configuration
2119

22-
A range of configuration options for {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>` are available - see the
23-
[bluesky `LivePlot` documentation](https://blueskyproject.io/bluesky/main/callbacks.html#bluesky.callbacks.mpl_plotting.LivePlot)
24-
for more details about available options.
20+
A range of configuration options for {py:obj}`~ibex_bluesky_core.callbacks.LivePlot` are available - see bluesky's {py:obj}`bluesky.callbacks.mpl_plotting.LivePlot` documentation for more details about available options.
2521

26-
The {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>` object allows an arbitrary set of matplotlib `Axes` to be passed in, onto
22+
The {py:obj}`~ibex_bluesky_core.callbacks.LivePlot` object allows an arbitrary set of matplotlib {py:obj}`~matplotlib.axes.Axes` to be passed in, onto
2723
which it will plot. This can be used to configure properties which are not directly exposed
28-
on the {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>` object, for example log-scaled axes.
24+
on the {py:obj}`~ibex_bluesky_core.callbacks.LivePlot` object, for example log-scaled axes.
2925

30-
See the [matplotlib `Axes` documentation](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html)
31-
for a full range of options on how to configure an {py:obj}`Axes<matplotlib.axes.Axes>` object.
26+
See the {py:obj}`matplotlib.axes.Axes` documentation for a full range of options on how to configure an {py:obj}`~matplotlib.axes.Axes` object.
3227

3328
Below is a full example showing how to use standard {py:obj}`matplotlib` & {py:obj}`bluesky` functionality
34-
to plot a scan with a logarithmically-scaled y-axis:
29+
to plot a scan with a logarithmically scaled y-axis:
3530

3631
```python
3732
import matplotlib.pyplot as plt
@@ -55,25 +50,25 @@ See [docs for `call_qt_aware`](../plan_stubs/matplotlib_helpers.md) for a descri
5550
`yield from call_qt_aware` rather than calling `matplotlib` functions directly.
5651
```
5752

58-
By providing a signal name to the `yerr` argument you can pass uncertainties to {py:obj}`LivePlot<ibex_bluesky_core.callbacks.LivePlot>`, by not providing anything for this argument means that no errorbars will be drawn. Errorbars are drawn after each point collected, displaying their standard deviation- uncertainty data is collected from Bluesky event documents and errorbars are updated after every new point added.
53+
By providing a signal name to the `yerr` argument you can pass uncertainties to {py:obj}`~ibex_bluesky_core.callbacks.LivePlot`, by not providing anything for this argument means that no errorbars will be drawn. Errorbars are drawn after each point collected, displaying their standard deviation- uncertainty data is collected from Bluesky event documents and errorbars are updated after every new point added.
5954

6055
The `plot_callback` object can then be subscribed to the run engine, using either:
6156
- An explicit callback when calling the run engine: `RE(some_plan(), plot_callback)`
62-
- Be subscribed in a plan using {py:obj}`subs_decorator<bluesky.preprocessors.subs_decorator>` from bluesky **(recommended)**
57+
- Be subscribed in a plan using {py:obj}`~bluesky.preprocessors.subs_decorator` from bluesky **(recommended)**
6358
- Globally attached to the run engine using {py:obj}`RE.subscribe<bluesky.run_engine.RunEngine.subscribe>`
6459
* Not recommended, not all scans will use the same variables and a plot setup that works
6560
for one scan is unlikely to be optimal for a different type of scan.
6661

6762
By subsequently re-using the same `ax` object in later scans, rather than creating a new
6863
`ax` object for each scan, two scans can be "overplotted" with each other for comparison.
6964

70-
## `LivePColorMesh`
65+
## {py:obj}`~ibex_bluesky_core.callbacks.LivePColorMesh`
7166

72-
{py:obj}`LivePColorMesh<ibex_bluesky_core.callbacks.LivePColorMesh>` is a specialized heatmap
67+
{py:obj}`~ibex_bluesky_core.callbacks.LivePColorMesh` is a specialized heatmap
7368
plotting callback which reacts to *rows* of data at a time. This is suitable for use by DAE reducers
7469
which emit rows of data at a time, such as
75-
{py:obj}`ibex_bluesky_core.devices.simpledae.PeriodSpecIntegralsReducer` or
76-
{py:obj}`ibex_bluesky_core.devices.simpledae.DSpacingMappingReducer`.
70+
{py:obj}`~ibex_bluesky_core.devices.simpledae.PeriodSpecIntegralsReducer` or
71+
{py:obj}`~ibex_bluesky_core.devices.simpledae.DSpacingMappingReducer`.
7772

7873
This callback updates live as the scan progresses. It is otherwise very similar to the
7974
existing bluesky plotting callbacks.
@@ -84,13 +79,13 @@ the plot will only appear once at least *two* rows of data have been collected.
8479
:::
8580

8681
{#plot_png_saver}
87-
## Saving plots to PNG files
82+
## Saving plots to PNG files ({py:obj}`~ibex_bluesky_core.callbacks.PlotPNGSaver`)
8883

89-
`ibex_bluesky_core` provides a {py:obj}`PlotPNGSaver<ibex_bluesky_core.callbacks.PlotPNGSaver>` callback to save plots on a run stop to PNG files, which by saves them to the default output file location unless a filepath is explicitly given.
84+
{py:obj}`~ibex_bluesky_core.callbacks.PlotPNGSaver` is used to save plots to PNG files at the end of a scan.
9085

91-
This is enabled by default in the {py:obj}`ISISCallbacks<ibex_bluesky_core.callbacks.ISISCallbacks>` callbacks collection.
86+
This is enabled by default in the {py:obj}`~ibex_bluesky_core.callbacks.ISISCallbacks` callbacks collection.
9287

93-
Using the above example (i.e. without the {py:obj}`ISISCallbacks<ibex_bluesky_core.callbacks.ISISCallbacks>` helper) it can be used like so:
88+
Using the above example (i.e. without the {py:obj}`~ibex_bluesky_core.callbacks.ISISCallbacks` helper) it can be used like so:
9489

9590
```python
9691
from pathlib import Path

0 commit comments

Comments
 (0)