Skip to content

Commit f71b9f2

Browse files
authored
Merge pull request #172 from ISISComputingGroup/reword_adrs
Reword adrs
2 parents ea7eefb + 354433e commit f71b9f2

File tree

7 files changed

+113
-39
lines changed

7 files changed

+113
-39
lines changed

doc/architectural_decisions/001-repo-structure.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Repository structure
1+
# 1. Repository structure
22

33
## Status
44

5-
Current
5+
Current, partially superseded by [ADR 6](006-where-to-put-code.md)
66

77
## Context
88

@@ -15,25 +15,26 @@ Tom & Kathryn
1515

1616
## Decision
1717

18-
We will create a `core` repository, and publish it on PyPI.
18+
We will create a `core` repository, called `ibex_bluesky_core`, and publish it on PyPI.
1919

2020
This repository will provide core building blocks, including plan stubs,
2121
devices, and utilities which are generic and expected to be useful across
2222
different science groups.
2323

24-
Beamline or technique specific repositories will then depend on the `core`
25-
repository via PyPI.
24+
~~Beamline or technique specific repositories will then depend on the `core` repository via PyPI.~~
25+
Superseded by [ADR 6](006-where-to-put-code.md).
2626

27-
The core repository will not depend on `genie_python`, so that other groups
28-
at RAL can use this repository. The genie python *distribution* may in future
29-
depend on this repository.
27+
The core repository will not depend on [`genie_python`](https://github.com/isiscomputinggroup/genie), so that other
28+
groups at RAL can use this repository. The [uktena](https://github.com/isiscomputinggroup/uktena) python *distribution*
29+
includes this repository as one of its included libraries.
3030

31-
This `core` repository is analogous to a similar repo, `dodal`, being used at
32-
Diamond.
31+
This `ibex_bluesky_core` repository is analogous to a similar repo,
32+
[dodal](https://github.com/diamondlightsource/dodal), being used at Diamond Light Source, or
33+
[apstools](https://github.com/BCDA-APS/apstools), being used at the Advanced Photon Source.
3334

3435
## Consequences
3536

36-
- We will have some bluesky code across multiple repositories.
37+
- We will have some bluesky code across multiple locations.
3738
- Other groups should be able to:
3839
- Pull this code easily from PyPI
3940
- Contribute to the code without depending on all of IBEX's infrastructure

doc/architectural_decisions/002-use-ophyd-async.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Use `ophyd-async`
1+
# 2. Use `ophyd-async`
22

33
## Status
44

@@ -9,13 +9,18 @@ Current
99
We need to decide whether to use `ophyd` or `ophyd-async` as our bluesky
1010
device abstraction layer.
1111

12+
| | Docs | Source | PyPi |
13+
| - |-| - | - |
14+
| ophyd | [Docs](https://blueskyproject.io/ophyd/) | [Source](https://github.com/bluesky/ophyd) | [PyPi](https://pypi.org/project/ophyd/) |
15+
| ophyd-async | [Docs](https://blueskyproject.io/ophyd-async/) | [Source](https://github.com/bluesky/ophyd-async) | [PyPi](https://pypi.org/project/ophyd-async/) |
16+
1217
`ophyd` has been the default device abstraction layer for bluesky EPICS devices for
1318
some time.
1419

1520
`ophyd-async` is a newer (and therefore less mature) device abstraction layer,
1621
with similar concepts to `ophyd`. It has been implemented primarily by DLS.
1722

18-
The *primary* differences are:
23+
The *primary* differences which are relevant for ISIS are:
1924
- In `ophyd-async` many functions are implemented as `asyncio` coroutines.
2025
- `ophyd-async` has better support for non-channel-access backends (notably, PVA)
2126
- Reduction in boilerplate

doc/architectural_decisions/003-run-in-process.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Run in-process
1+
# 3. Run in-process
22

33
## Status
44

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,70 @@
1-
# Use `scipp`
1+
# 4. Use `scipp`
22

33
## Status
44

55
Current
66

77
## Context
88

9-
A decision needs to be made about whether to use scipp, numpy, uncertainties or develop our own library for the purpose of providing support for generating uncertanties on our counts data.
9+
We need to choose a library which helps us to transform "raw" neutron or muon data from the DAE, into processed
10+
quantities that we scan over.
11+
12+
Desirable features include:
13+
- Uncertainty propagation, following standard uncertainty propagation rules. While this could apply to any data in
14+
principle, it will be especially relevant for neutron/muon counts data.
15+
- Unit handling & conversions
16+
- Simple unit conversions, like microns to millimetres.
17+
- Neutron-specific unit conversions, like time-of-flight to wavelength
18+
- Ability to handle the typical types of data we would acquire from the DAE and process as part of a scan:
19+
- Histograms of neutron/muon counts
20+
- N-dimensional arrays
21+
- Event-mode data (in future)
22+
23+
Candidate solutions include:
24+
25+
- `mantid`
26+
- `scipp`
27+
- `uncertainties`
28+
- `numpy` + home-grown uncertainty-propagation
1029

1130
## Decision
1231

13-
We will be using scipp.
32+
- Default to using `scipp` for most cases
33+
- Explore using `mantid` via autoreduction APIs, where we need to do more complex reductions
1434

1535
## Justification & Consequences
1636

17-
- `scipp` is being developed at ESS with past input from STFC, so is well suited for neutron counts data.
18-
- `scipp` has a `numpy`-like interface but handles units and uncertainties by default under-the-hood.
19-
- Neither `numpy` or `uncertanties` have exactly the functionality we would need, so the solution using them would be a mix of the libraries and our own code, there would be more places to go wrong. Maintainability.
20-
- `uncertainties` package tracks correlations so may have bad scaling on "large" arrays like counts data from the DAE.
21-
- Developing our own uncertainties library will take time to understand and then implement. All of the functionality that we need has been done beforehand, so better to not waste time & effort.
22-
- Less expertise with this library on site (mitigation: don't do too much which is very complicated with it)
23-
- Potentially duplicates some of `mantid`'s functionality: (mitigation: use `scipp` for "simple" things, use `mantid` in future if people want to do "full" data reduction pipelines)
37+
### `numpy`
38+
39+
Using `numpy` by itself is eliminated on the basis that we would need to write our own uncertainty-propagation code,
40+
which is error prone.
41+
42+
`numpy` by itself may still be used in places where uncertainty propagation is not needed.
43+
44+
### `uncertainties`
45+
46+
The `uncertainties` package tracks correlations so may have bad scaling on "large" arrays, where correlation matrices
47+
can become large in some cases. Would need to be combined with another library, e.g. `pint`, in order to also support
48+
physical units. No neutron-specific functionality.
49+
50+
### `mantid`
51+
52+
Mantid is not easily installable (e.g. via `pip` at present).
53+
54+
While we have a way to call out to mantid via a REST API, initial tests have shown that the latency of this approach
55+
is around 15 seconds. This means it is unsuitable for many types of scans, for example alignment scans, where count
56+
times are far lower than 15 seconds.
57+
58+
However, for complex reductions, we should still consider the option of passing data out to mantid. This is especially
59+
true if reductions depend significantly on instrument geometry, on instrument-specific corrections, or on other details
60+
for which mantid is best-equipped to deal with.
61+
62+
Calling out to mantid via an API should also be considered if a reduction step may use significant compute resource.
63+
64+
### `scipp`
65+
66+
`scipp` will be our default way of taking raw data from the DAE and processing it into a scanned-over quantity.
67+
68+
However, in cases where the reduction is expensive (in terms of compute cost) or complex (either implementation, or
69+
in terms of required knowledge of geometry/instrument-specific corrections), then we should consider using mantid via
70+
the autoreduction API in those cases instead.

doc/architectural_decisions/005-variance-addition.md

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1-
# Variance addition to counts data
1+
# 5. Variance addition to counts data
22

33
## Status
44

55
Current
66

77
## Context
88

9-
For counts data, the uncertainty on counts is typically defined by poisson counting statistics, i.e. the standard deviation on `N` counts is `sqrt(N)`.
9+
For counts data, the uncertainty on counts is typically defined by poisson counting statistics, i.e. the standard
10+
deviation on `N` counts is `sqrt(N)`.
1011

11-
This can be problematic in cases where zero counts have been collected, as the standard deviation will then be zero, which will subsequently lead to "infinite" point weightings in downstream fitting routines for example.
12+
This can be problematic in cases where zero counts have been collected, as the standard deviation will then be zero,
13+
which will subsequently lead to "infinite" point weightings in downstream fitting routines for example.
1214

1315
A number of possible approaches were considered:
1416

15-
| Option | Description |
16-
| --- | --- |
17-
| A | Reject data with zero counts, i.e. explicitly throw an exception if any data with zero counts is seen as part of a scan. |
18-
| B | Use a standard deviation of `NaN` for points with zero counts. |
19-
| C | Define the standard deviation of `N` counts as `1` if counts are zero, otherwise `sqrt(N)`. This is one of the approaches available in mantid for example. |
20-
| D | Define the standard deviation of `N` counts as `sqrt(N+0.5)` unconditionally - on the basis that "half a count" is smaller than the smallest possible actual measurement which can be taken. |
21-
| E | No special handling, calculate std. dev. as `sqrt(N)`. |
17+
### Option A
18+
19+
Reject data with zero counts, i.e. explicitly throw an exception if any data with zero counts is seen as part of a scan.
20+
21+
### Option B
22+
23+
Use a standard deviation of `NaN` for points with zero counts.
24+
25+
### Option C
26+
27+
Define the standard deviation of `N` counts as `1` if counts are zero, otherwise `sqrt(N)`. This is one of the
28+
approaches [available in mantid](https://github.com/mantidproject/mantid/blob/bbbb86edc2c3fa554499770463aa25c2b46984e5/docs/source/algorithms/SetUncertainties-v1.rst#L16) for example.
29+
30+
### Option D
31+
32+
Define the standard deviation of `N` counts as `sqrt(N+0.5)` unconditionally - on the basis that "half a count" is
33+
smaller than the smallest possible actual measurement which can be taken.
34+
35+
### Option E
36+
37+
No special handling, calculate std. dev. as `sqrt(N)`.
38+
39+
---
2240

2341
For clarity, the following table shows the value and associated uncertainty for each option:
2442

@@ -53,6 +71,8 @@ The consensus was to go with Option D.
5371
## Justification
5472

5573
- Option A will cause real-life scans to crash in low counts regions.
56-
- Option B involves `NaN`s, which have many surprising floating-point characteristics and are highly likely to be a source of future bugs.
57-
- Option D was preferred to option C by scientists present.
58-
- Option E causes surprising results and/or crashes downstream, for example fitting may consider points with zero uncertainty to have "infinite" weight, therefore effectively disregarding all other data.
74+
- Option B involves `NaN`s, which have many surprising floating-point characteristics and are highly likely to be a
75+
source of future bugs.
76+
- Option D was preferred to option C by scientists present, because it is continuous.
77+
- Option E causes surprising results and/or crashes downstream, for example fitting may consider points with zero
78+
uncertainty to have "infinite" weight, therefore effectively disregarding all other data.

doc/architectural_decisions/006-where-to-put-code.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Where to put code
1+
# 6. Where to put code
22

33
## Status
44

doc/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
("py:obj", r"^.*\.T.*_co$"),
3030
]
3131

32-
myst_enable_extensions = ["dollarmath"]
32+
myst_enable_extensions = ["dollarmath", "strikethrough"]
33+
suppress_warnings = ["myst.strikethrough"]
3334

3435
extensions = [
3536
"myst_parser",

0 commit comments

Comments
 (0)