Skip to content

Commit a9e3c9b

Browse files
committed
add plans used on ndxargus and rikenfe
1 parent 45e06d2 commit a9e3c9b

File tree

2 files changed

+176
-108
lines changed

2 files changed

+176
-108
lines changed

src/ibex_bluesky_core/plans/muons/dae_magnet_scan.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,71 +15,75 @@
1515
from ibex_bluesky_core.devices.simpledae import SimpleDae
1616
from ibex_bluesky_core.devices.simpledae.controllers import (
1717
RunPerPointController,
18+
PeriodPerPointController,
1819
)
19-
from ibex_bluesky_core.devices.simpledae.reducers import (
20-
GoodFramesNormalizer,
21-
)
22-
from ibex_bluesky_core.devices.simpledae.waiters import GoodFramesWaiter
20+
from ibex_bluesky_core.devices.simpledae.reducers import PeriodGoodFramesNormalizer
21+
from ibex_bluesky_core.devices.simpledae.waiters import GoodFramesWaiter, PeriodGoodFramesWaiter
2322
from ibex_bluesky_core.plans import set_num_periods
2423
from ibex_bluesky_core.run_engine import get_run_engine
2524

26-
NUM_POINTS: int = 3
27-
28-
MAGNET_SETTLE_TIME = 3
29-
MAGNET_BLOCK_NAME = "p3"
30-
MAGNET_TOLERANCE = 0.1
25+
from ibex_bluesky_core.callbacks.fitting.fitting_utils import Gaussian
3126

3227

33-
def dae_magnet_plan() -> Generator[Msg, None, None]:
28+
def dae_magnet_plan(
29+
block,
30+
start,
31+
stop,
32+
num,
33+
periods=True,
34+
frames=500,
35+
save_run=True,
36+
magnet_tolerance=0.01,
37+
magnet_settle_time=1,
38+
) -> Generator[Msg, None, None]:
3439
"""Scan a DAE against a magnet."""
3540

3641
def check_within_tolerance(setpoint: float, actual: float) -> bool:
37-
return setpoint - MAGNET_TOLERANCE <= actual <= setpoint + MAGNET_TOLERANCE
42+
return setpoint - magnet_tolerance <= actual <= setpoint + magnet_tolerance
3843

3944
magnet = block_rw_rbv(
4045
float,
41-
MAGNET_BLOCK_NAME,
46+
block,
4247
write_config=BlockWriteConfig(
43-
settle_time_s=MAGNET_SETTLE_TIME, set_success_func=check_within_tolerance
48+
settle_time_s=magnet_settle_time, set_success_func=check_within_tolerance
4449
),
4550
)
4651

4752
prefix = get_pv_prefix()
48-
controller_chronus = RunPerPointController(save_run=True)
49-
waiter_chronus = GoodFramesWaiter(500)
50-
reducer_chronus = GoodFramesNormalizer(
51-
prefix=prefix,
52-
detector_spectra=[i for i in range(1, 32 + 1)],
53-
)
5453

55-
dae_chronus = SimpleDae(
54+
if periods:
55+
controller = PeriodPerPointController(save_run=save_run)
56+
waiter = PeriodGoodFramesWaiter(frames)
57+
else:
58+
controller = RunPerPointController(save_run=save_run)
59+
waiter = GoodFramesWaiter(frames)
60+
61+
reducer = PeriodGoodFramesNormalizer(prefix, detector_spectra=[i for i in range(1, 32 + 1)])
62+
63+
dae = SimpleDae(
5664
prefix=prefix,
57-
controller=controller_chronus,
58-
waiter=waiter_chronus,
59-
reducer=reducer_chronus,
65+
controller=controller,
66+
waiter=waiter,
67+
reducer=reducer,
6068
)
6169

62-
# yield from set_num_periods(dae_chronus, 100)
70+
yield from ensure_connected(magnet, dae, force_reconnect=True)
6371

64-
yield from ensure_connected(magnet, dae_chronus, force_reconnect=True)
72+
if periods:
73+
yield from set_num_periods(dae, num)
74+
else:
75+
yield from set_num_periods(dae, 1)
6576

6677
icc = ISISCallbacks(
67-
y=reducer_chronus.intensity.name,
78+
y=reducer.intensity.name,
6879
x=magnet.name,
69-
yerr=reducer_chronus.intensity_stddev.name,
80+
yerr=reducer.intensity_stddev.name,
81+
fit=Gaussian().fit(),
7082
)
7183

7284
@icc
7385
def _inner() -> Generator[Msg, None, None]:
74-
yield from bp.scan([dae_chronus], magnet, 0, 10, num=NUM_POINTS)
86+
yield from bp.scan([dae], magnet, start, stop, num=num)
7587

7688
yield from _inner()
7789
print(icc.live_fit.result.fit_report())
78-
79-
80-
if __name__ == "__main__" and not os.environ.get("FROM_IBEX") == "True":
81-
matplotlib.use("qtagg")
82-
plt.ion()
83-
RE = get_run_engine()
84-
RE(dae_magnet_plan())
85-
input("Plan complete, press return to close plot and exit")

src/ibex_bluesky_core/plans/muons/two_dae_scan.py

Lines changed: 136 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,194 @@
11
"""Muon scan that uses two DAEs to scan a magnet."""
22

3-
import os
43
from collections.abc import Generator
54

65
import bluesky.plans as bp
7-
import matplotlib
86
import matplotlib.pyplot as plt
97
from bluesky.callbacks import LiveFitPlot, LiveTable
108
from bluesky.preprocessors import subs_decorator
119
from bluesky.utils import Msg
10+
from ibex_bluesky_core.callbacks import LiveFitLogger
1211
from ophyd_async.plan_stubs import ensure_connected
1312

1413
from ibex_bluesky_core.callbacks.fitting import LiveFit
15-
from ibex_bluesky_core.callbacks.fitting.fitting_utils import Linear
14+
from ibex_bluesky_core.callbacks.fitting.fitting_utils import Gaussian
1615
from ibex_bluesky_core.callbacks.plotting import LivePlot
17-
from ibex_bluesky_core.devices.block import block_rw_rbv
16+
from ibex_bluesky_core.devices.block import block_rw_rbv, BlockWriteConfig
1817
from ibex_bluesky_core.devices.simpledae import SimpleDae
1918
from ibex_bluesky_core.devices.simpledae.controllers import (
2019
RunPerPointController,
2120
)
2221
from ibex_bluesky_core.devices.simpledae.reducers import (
23-
GoodFramesNormalizer,
22+
PeriodGoodFramesNormalizer,
2423
)
2524
from ibex_bluesky_core.devices.simpledae.waiters import GoodFramesWaiter
2625
from ibex_bluesky_core.plan_stubs import call_qt_aware
27-
from ibex_bluesky_core.run_engine import get_run_engine
2826

29-
NUM_POINTS: int = 3
30-
31-
32-
def two_dae_scan() -> Generator[Msg, None, None]:
33-
"""Scan a block using two DAEs."""
34-
magnet = block_rw_rbv(float, "p3")
27+
from ibex_bluesky_core.callbacks.file_logger import HumanReadableFileCallback
28+
29+
30+
def two_dae_scan(
31+
magnet_1_block,
32+
start_1,
33+
stop_1,
34+
magnet_2_block,
35+
start_2,
36+
stop_2,
37+
num,
38+
frames=500,
39+
save_run=True,
40+
magnet_tolerance=0.01,
41+
magnet_settle_time=1,
42+
dae_1_prefix="IN:ARGUS:",
43+
dae_2_prefix="IN:CHRONUS:",
44+
spectra_total_1=96,
45+
spectra_total_2=32,
46+
) -> Generator[Msg, None, None]:
47+
"""Scan a block using two DAEs and two magnets."""
48+
49+
def check_within_tolerance(setpoint: float, actual: float) -> bool:
50+
return setpoint - magnet_tolerance <= actual <= setpoint + magnet_tolerance
51+
52+
magnet_1 = block_rw_rbv(
53+
float,
54+
magnet_1_block,
55+
write_config=BlockWriteConfig(
56+
settle_time_s=magnet_settle_time, set_success_func=check_within_tolerance
57+
),
58+
)
3559

36-
emu_prefix = "IN:EMU:"
37-
controller_emu = RunPerPointController(save_run=True)
38-
waiter_emu = GoodFramesWaiter(500)
39-
reducer_emu = GoodFramesNormalizer(
40-
prefix=emu_prefix,
41-
detector_spectra=[i for i in range(1, 100)],
60+
magnet_2 = block_rw_rbv(
61+
float,
62+
magnet_2_block,
63+
write_config=BlockWriteConfig(
64+
settle_time_s=magnet_settle_time, set_success_func=check_within_tolerance
65+
),
4266
)
4367

44-
dae_emu = SimpleDae(
45-
prefix=emu_prefix,
46-
controller=controller_emu,
47-
waiter=waiter_emu,
48-
reducer=reducer_emu,
49-
name="emu_dae",
68+
controller_1 = RunPerPointController(save_run=save_run)
69+
waiter_1 = GoodFramesWaiter(frames)
70+
reducer_1 = PeriodGoodFramesNormalizer(
71+
prefix=dae_1_prefix,
72+
detector_spectra=[i for i in range(1, spectra_total_1 + 1)],
5073
)
5174

52-
musr_prefix = "IN:MUSR:"
75+
dae_1 = SimpleDae(
76+
prefix=dae_1_prefix,
77+
controller=controller_1,
78+
waiter=waiter_1,
79+
reducer=reducer_1,
80+
name="dae_1",
81+
)
5382

54-
controller_musr = RunPerPointController(save_run=True)
55-
waiter_musr = GoodFramesWaiter(500)
56-
reducer_musr = GoodFramesNormalizer(
57-
prefix=musr_prefix,
58-
detector_spectra=[i for i in range(1, 96)],
83+
controller_2 = RunPerPointController(save_run=save_run)
84+
waiter_2 = GoodFramesWaiter(frames)
85+
reducer_2 = PeriodGoodFramesNormalizer(
86+
prefix=dae_2_prefix,
87+
detector_spectra=[i for i in range(1, spectra_total_2 + 1)],
5988
)
6089

61-
dae_musr = SimpleDae(
62-
prefix=musr_prefix,
63-
controller=controller_musr,
64-
waiter=waiter_musr,
65-
reducer=reducer_musr,
66-
name="musr_dae",
90+
dae_2 = SimpleDae(
91+
prefix=dae_2_prefix,
92+
controller=controller_2,
93+
waiter=waiter_2,
94+
reducer=reducer_2,
95+
name="dae_2",
6796
)
6897

6998
_, ax = yield from call_qt_aware(plt.subplots)
7099

71-
lf = LiveFit(
72-
Linear.fit(),
73-
y=reducer_emu.intensity.name,
74-
x=magnet.name,
75-
yerr=reducer_emu.intensity_stddev.name,
100+
lf_1 = LiveFit(
101+
Gaussian().fit(),
102+
y=reducer_1.intensity.name,
103+
x=magnet_1.name,
104+
yerr=reducer_1.intensity_stddev.name,
105+
)
106+
lf_2 = LiveFit(
107+
Gaussian().fit(),
108+
y=reducer_2.intensity.name,
109+
x=magnet_1.name,
110+
yerr=reducer_2.intensity_stddev.name,
76111
)
77112

78-
yield from ensure_connected(magnet, dae_emu, dae_musr, force_reconnect=True)
113+
yield from ensure_connected(magnet_1, magnet_2, dae_1, dae_2, force_reconnect=True)
79114

80115
@subs_decorator(
81116
[
82-
LiveFitPlot(livefit=lf, ax=ax),
117+
LiveFitPlot(livefit=lf_1, ax=ax),
118+
LiveFitPlot(livefit=lf_2, ax=ax),
83119
LivePlot(
84-
y=reducer_emu.intensity.name,
85-
x=magnet.name,
120+
y=reducer_1.intensity.name,
121+
x=magnet_1.name,
86122
marker="x",
87123
linestyle="none",
88124
ax=ax,
89-
yerr=reducer_emu.intensity_stddev.name,
125+
yerr=reducer_1.intensity_stddev.name,
90126
),
91127
LivePlot(
92-
y=reducer_musr.intensity.name,
93-
x=magnet.name,
128+
y=reducer_2.intensity.name,
129+
x=magnet_1.name,
94130
marker="x",
95131
linestyle="none",
96132
ax=ax,
97-
yerr=reducer_musr.intensity_stddev.name,
133+
yerr=reducer_2.intensity_stddev.name,
98134
),
99135
LiveTable(
100136
[
101-
magnet.name,
102-
controller_emu.run_number.name,
103-
reducer_emu.intensity.name,
104-
reducer_emu.intensity_stddev.name,
105-
reducer_emu.det_counts.name,
106-
reducer_emu.det_counts_stddev.name,
107-
dae_emu.good_frames.name,
108-
controller_musr.run_number.name,
109-
reducer_musr.intensity.name,
110-
reducer_musr.intensity_stddev.name,
111-
reducer_musr.det_counts.name,
112-
reducer_musr.det_counts_stddev.name,
113-
dae_musr.good_frames.name,
137+
magnet_1.name,
138+
magnet_2.name,
139+
controller_1.run_number.name,
140+
reducer_1.intensity.name,
141+
reducer_1.intensity_stddev.name,
142+
reducer_1.det_counts.name,
143+
reducer_1.det_counts_stddev.name,
144+
dae_1.good_frames.name,
145+
controller_2.run_number.name,
146+
reducer_2.intensity.name,
147+
reducer_2.intensity_stddev.name,
148+
reducer_2.det_counts.name,
149+
reducer_2.det_counts_stddev.name,
150+
dae_2.good_frames.name,
114151
]
115152
),
153+
HumanReadableFileCallback(
154+
fields=[
155+
magnet_1.name,
156+
magnet_2.name,
157+
controller_1.run_number.name,
158+
reducer_1.intensity.name,
159+
reducer_1.intensity_stddev.name,
160+
reducer_1.det_counts.name,
161+
reducer_1.det_counts_stddev.name,
162+
dae_1.good_frames.name,
163+
controller_2.run_number.name,
164+
reducer_2.intensity.name,
165+
reducer_2.intensity_stddev.name,
166+
reducer_2.det_counts.name,
167+
reducer_2.det_counts_stddev.name,
168+
dae_2.good_frames.name,
169+
]
170+
),
171+
LiveFitLogger(
172+
lf_1,
173+
x=magnet_1.name,
174+
y=reducer_1.intensity.name,
175+
yerr=reducer_1.intensity_stddev.name,
176+
postfix="lf_1",
177+
),
178+
LiveFitLogger(
179+
lf_2,
180+
x=magnet_1.name,
181+
y=reducer_2.intensity.name,
182+
yerr=reducer_2.intensity_stddev.name,
183+
postfix="lf_2",
184+
),
116185
]
117186
)
118187
def _inner() -> Generator[Msg, None, None]:
119-
yield from bp.scan([dae_musr, dae_emu], magnet, 0, 10, num=NUM_POINTS)
120-
print(lf.result.fit_report())
188+
yield from bp.scan(
189+
[dae_2, dae_1], magnet_1, start_1, stop_1, magnet_2, start_2, stop_2, num=num
190+
)
191+
print(lf_1.result.fit_report())
192+
print(lf_2.result.fit_report())
121193

122194
yield from _inner()
123-
124-
125-
if __name__ == "__main__" and not os.environ.get("FROM_IBEX") == "True":
126-
matplotlib.use("qtagg")
127-
plt.ion()
128-
RE = get_run_engine()
129-
RE(two_dae_scan())
130-
input("Plan complete, press return to close plot and exit")

0 commit comments

Comments
 (0)