Skip to content

Commit c19ad41

Browse files
committed
Proofread chained_fitting
1 parent 2dfb5c7 commit c19ad41

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed
Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
# Chained Fitting (`ChainedLiveFit`)
1+
# Chained Fitting ({py:obj}`ChainedLiveFit <ibex_bluesky_core.callbacks.ChainedLiveFit>`)
22

3-
[`ChainedLiveFit`](ibex_bluesky_core.callbacks.ChainedLiveFit) is a specialised callback that manages multiple LiveFit instances in a chain, where each fit's results inform the next fit's initial parameters. This is particularly useful when dealing with complex data sets where subsequent fits depend on the parameters obtained from previous fits.
3+
{py:obj}`ChainedLiveFit <ibex_bluesky_core.callbacks.ChainedLiveFit>` is a specialised callback that manages multiple {py:obj}`LiveFit <ibex_bluesky_core.callbacks.LiveFit>` instances in a chain, where each fit's results inform the next fit's initial parameters. This is particularly useful when fitting datasets where the initial guess for each fit depends on the parameters obtained from a previous fit.
44

55
This is useful for when you need to be careful with your curve fitting due to the presence of noisy data. It allows you to fit your widest (full) wavelength band first and then using its fit parameters as the initial guess of the parameters for the next fit
66

7-
To show how we expect this to be used, we will use the PolarisingDae and wavelength bands to highlight the need for the carry over of fitting parameters. Below shows two wavelength bands, first bigger than the second, we will fit to the data in the first and carry it over to the data in the second to improve its, otherwise worse, fit.
7+
To show how we expect this to be used, we will use a {py:obj}`DualRunDae <ibex_bluesky_core.devices.polarisingdae.DualRunDae>` configured with multiple wavelength bands, to highlight the need to carry over fitting parameters. The example below shows two wavelength bands, first wider than the second. We will fit to the data in the widest wavelength band first, and carry over the results of that fit to the guess of the next fit, to improve the chances of that fit converging.
88

99
```python
10+
from typing import Generator
11+
import scipp as sc
12+
import matplotlib.pyplot as plt
13+
from ibex_bluesky_core.devices.block import block_rw, BlockWriteConfig
14+
from ibex_bluesky_core.devices.polarisingdae import polarising_dae
15+
from ibex_bluesky_core.plan_stubs import call_qt_aware
16+
from ibex_bluesky_core.fitting import Linear
17+
from ibex_bluesky_core.callbacks import ChainedLiveFit
18+
from bluesky.utils import Msg
19+
20+
1021
# Needed for PolarisingDae
1122
flipper = block_rw(float, "flipper")
1223
total_flight_path_length = sc.scalar(value=10, unit=sc.units.m)
@@ -15,33 +26,30 @@ x_axis = block_rw(float, "x_axis", write_config=BlockWriteConfig(settle_time_s=0
1526
wavelength_band_0 = sc.array(dims=["tof"], values=[0, 9999999999.0], unit=sc.units.angstrom, dtype="float64")
1627
wavelength_band_1 = sc.array(dims=["tof"], values=[0.0, 0.07], unit=sc.units.angstrom, dtype="float64")
1728

18-
dae = polarising_dae(det_pixels=[1], frames=50, flipper=flipper, flipper_states=(0.0, 1.0),
29+
dae = polarising_dae(det_pixels=[1], frames=50, movable=flipper, movable_states=[0.0, 1.0],
1930
intervals=[wavelength_band_0, wavelength_band_1],
2031
total_flight_path_length=total_flight_path_length, monitor=2)
2132

2233

2334
def plan() -> Generator[Msg, None, None]:
24-
fig, (ax1, ax2) = yield from call_qt_aware(plt.subplots, 2)
25-
chained_fit = ChainedLiveFit(method=Linear.fit(), y=[dae.reducer.wavelength_bands[0].calculate_polarisation.name,
35+
fig, (ax1, ax2) = yield from call_qt_aware(plt.subplots, 2)
36+
chained_fit = ChainedLiveFit(method=Linear.fit(), y=[dae.reducer.wavelength_bands[0].calculate_polarisation.name,
2637
dae.reducer.wavelength_bands[1].calculate_polarisation.name],
27-
x=bob.name, ax=[ax1, ax2])
28-
29-
# Subscribe chained_fit to RE and run do a scan for example
30-
# chained_fit.get_livefits()[-1].result will give you the fitting results for the last wavelength band
38+
x=x_axis.name, ax=[ax1, ax2])
39+
40+
... # perform a scan with chained_fit subscribed
41+
42+
# will give you the fitting results for the last wavelength band
43+
chained_fit.get_livefits()[-1].result
3144
```
3245

33-
- You are expected to pass in the list of signal names for each independent variable to `y` in order of how you want the subsequent fitting to go.
34-
- You may also pass in a list of matplotlib axes, which will mean that LiveFitPlots are created per LiveFit, and it will plot the each respective fit to an axis. LiveFitPlots are not created if you do not pass `ax`.
35-
- Similar to the `y` parameter, you may pass signal names which correspond to uncertainty values for each independent variable.
46+
The list of signal names for each independent variable should be passed in the same order that the fits are to be applied.
3647

37-
```{hint}
38-
The method for fitting is the same across all independent variables.
39-
```
48+
A list of matplotlib axes is accepted, which will mean that {external+bluesky:py:obj}`LiveFitPlots <bluesky.callbacks.mpl_plotting.LiveFitPlot>` are created per {py:obj}`LiveFit <ibex_bluesky_core.callbacks.LiveFit>`, and it will plot the each respective fit to an axis. {external+bluesky:py:obj}`LiveFitPlots <bluesky.callbacks.mpl_plotting.LiveFitPlot>` are not created if you do not pass `ax`.
4049

41-
```{note}
42-
Parameter uncertainties are not carried over between fits
43-
```
50+
Similar to the `y` parameter, uncertainties for each dependent variable are accepted in `yerr`.
4451

45-
```{important}
46-
If a fit fails to converge, subsequent fits will use their default guess functions
47-
```
52+
{py:obj}`ChainedLiveFit <ibex_bluesky_core.callbacks.ChainedLiveFit>` currently has the following limitations:
53+
- The method for fitting must be the same across all dependent variables.
54+
- Parameter uncertainties are not carried over between fits
55+
- If a fit fails to converge, subsequent fits will use their default guess functions

0 commit comments

Comments
 (0)