You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{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
4
8
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.
6
10
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
8
16
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
+
:::
10
19
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
14
25
- Should support non-constant point spacing without skewing the centre of mass
15
26
16
27
```{note}
17
28
Note that this is designed for only **positive** peaks.
18
29
```
19
30
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**
21
36
22
37
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:
26
42
```{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`.
Copy file name to clipboardExpand all lines: doc/callbacks/file_writing.md
+7-8Lines changed: 7 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,11 +3,10 @@
3
3
{#hr_file_cb}
4
4
## Human readable files
5
5
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.
7
7
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`.
9
9
10
-
### Example
11
10
An example of using this could be:
12
11
13
12
```{code} python
@@ -47,15 +46,15 @@ RE(some_plan())
47
46
```
48
47
49
48
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>`.
51
50
52
51
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
-`postfix` an optional suffix to append to the end of the file name, to disambiguate scans. Default is no suffix.
56
55
57
56
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.
59
58
60
59
The file also contains metadata such as the bluesky version, plan type, and rb number.
61
60
@@ -74,6 +73,6 @@ See {ref}`plot_png_saver`
74
73
This callback is added automatically and is not intended to be user-facing - it is primarily for developer diagnostics.
75
74
```
76
75
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.
78
77
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>`.
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.
25
21
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
27
23
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.
29
25
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.
32
27
33
28
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 logarithmicallyscaled y-axis:
35
30
36
31
```python
37
32
import matplotlib.pyplot as plt
@@ -55,25 +50,25 @@ See [docs for `call_qt_aware`](../plan_stubs/matplotlib_helpers.md) for a descri
55
50
`yield from call_qt_aware` rather than calling `matplotlib` functions directly.
56
51
```
57
52
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.
59
54
60
55
The `plot_callback` object can then be subscribed to the run engine, using either:
61
56
- 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)**
63
58
- Globally attached to the run engine using {py:obj}`RE.subscribe<bluesky.run_engine.RunEngine.subscribe>`
64
59
* Not recommended, not all scans will use the same variables and a plot setup that works
65
60
for one scan is unlikely to be optimal for a different type of scan.
66
61
67
62
By subsequently re-using the same `ax` object in later scans, rather than creating a new
68
63
`ax` object for each scan, two scans can be "overplotted" with each other for comparison.
This callback updates live as the scan progresses. It is otherwise very similar to the
79
74
existing bluesky plotting callbacks.
@@ -84,13 +79,13 @@ the plot will only appear once at least *two* rows of data have been collected.
84
79
:::
85
80
86
81
{#plot_png_saver}
87
-
## Saving plots to PNG files
82
+
## Saving plots to PNG files ({py:obj}`~ibex_bluesky_core.callbacks.PlotPNGSaver`)
88
83
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.
90
85
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.
92
87
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:
0 commit comments