-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add plans used on ndxargus and rikenfe
- Loading branch information
Showing
2 changed files
with
176 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,130 +1,194 @@ | ||
"""Muon scan that uses two DAEs to scan a magnet.""" | ||
|
||
import os | ||
from collections.abc import Generator | ||
|
||
import bluesky.plans as bp | ||
import matplotlib | ||
import matplotlib.pyplot as plt | ||
from bluesky.callbacks import LiveFitPlot, LiveTable | ||
from bluesky.preprocessors import subs_decorator | ||
from bluesky.utils import Msg | ||
from ibex_bluesky_core.callbacks import LiveFitLogger | ||
from ophyd_async.plan_stubs import ensure_connected | ||
|
||
from ibex_bluesky_core.callbacks.fitting import LiveFit | ||
from ibex_bluesky_core.callbacks.fitting.fitting_utils import Linear | ||
from ibex_bluesky_core.callbacks.fitting.fitting_utils import Gaussian | ||
from ibex_bluesky_core.callbacks.plotting import LivePlot | ||
from ibex_bluesky_core.devices.block import block_rw_rbv | ||
from ibex_bluesky_core.devices.block import block_rw_rbv, BlockWriteConfig | ||
from ibex_bluesky_core.devices.simpledae import SimpleDae | ||
from ibex_bluesky_core.devices.simpledae.controllers import ( | ||
RunPerPointController, | ||
) | ||
from ibex_bluesky_core.devices.simpledae.reducers import ( | ||
GoodFramesNormalizer, | ||
PeriodGoodFramesNormalizer, | ||
) | ||
from ibex_bluesky_core.devices.simpledae.waiters import GoodFramesWaiter | ||
from ibex_bluesky_core.plan_stubs import call_qt_aware | ||
from ibex_bluesky_core.run_engine import get_run_engine | ||
|
||
NUM_POINTS: int = 3 | ||
|
||
|
||
def two_dae_scan() -> Generator[Msg, None, None]: | ||
"""Scan a block using two DAEs.""" | ||
magnet = block_rw_rbv(float, "p3") | ||
from ibex_bluesky_core.callbacks.file_logger import HumanReadableFileCallback | ||
|
||
|
||
def two_dae_scan( | ||
magnet_1_block, | ||
start_1, | ||
stop_1, | ||
magnet_2_block, | ||
start_2, | ||
stop_2, | ||
num, | ||
frames=500, | ||
save_run=True, | ||
magnet_tolerance=0.01, | ||
magnet_settle_time=1, | ||
dae_1_prefix="IN:ARGUS:", | ||
dae_2_prefix="IN:CHRONUS:", | ||
spectra_total_1=96, | ||
spectra_total_2=32, | ||
) -> Generator[Msg, None, None]: | ||
"""Scan a block using two DAEs and two magnets.""" | ||
|
||
def check_within_tolerance(setpoint: float, actual: float) -> bool: | ||
return setpoint - magnet_tolerance <= actual <= setpoint + magnet_tolerance | ||
|
||
magnet_1 = block_rw_rbv( | ||
float, | ||
magnet_1_block, | ||
write_config=BlockWriteConfig( | ||
settle_time_s=magnet_settle_time, set_success_func=check_within_tolerance | ||
), | ||
) | ||
|
||
emu_prefix = "IN:EMU:" | ||
controller_emu = RunPerPointController(save_run=True) | ||
waiter_emu = GoodFramesWaiter(500) | ||
reducer_emu = GoodFramesNormalizer( | ||
prefix=emu_prefix, | ||
detector_spectra=[i for i in range(1, 100)], | ||
magnet_2 = block_rw_rbv( | ||
float, | ||
magnet_2_block, | ||
write_config=BlockWriteConfig( | ||
settle_time_s=magnet_settle_time, set_success_func=check_within_tolerance | ||
), | ||
) | ||
|
||
dae_emu = SimpleDae( | ||
prefix=emu_prefix, | ||
controller=controller_emu, | ||
waiter=waiter_emu, | ||
reducer=reducer_emu, | ||
name="emu_dae", | ||
controller_1 = RunPerPointController(save_run=save_run) | ||
waiter_1 = GoodFramesWaiter(frames) | ||
reducer_1 = PeriodGoodFramesNormalizer( | ||
prefix=dae_1_prefix, | ||
detector_spectra=[i for i in range(1, spectra_total_1 + 1)], | ||
) | ||
|
||
musr_prefix = "IN:MUSR:" | ||
dae_1 = SimpleDae( | ||
prefix=dae_1_prefix, | ||
controller=controller_1, | ||
waiter=waiter_1, | ||
reducer=reducer_1, | ||
name="dae_1", | ||
) | ||
|
||
controller_musr = RunPerPointController(save_run=True) | ||
waiter_musr = GoodFramesWaiter(500) | ||
reducer_musr = GoodFramesNormalizer( | ||
prefix=musr_prefix, | ||
detector_spectra=[i for i in range(1, 96)], | ||
controller_2 = RunPerPointController(save_run=save_run) | ||
waiter_2 = GoodFramesWaiter(frames) | ||
reducer_2 = PeriodGoodFramesNormalizer( | ||
prefix=dae_2_prefix, | ||
detector_spectra=[i for i in range(1, spectra_total_2 + 1)], | ||
) | ||
|
||
dae_musr = SimpleDae( | ||
prefix=musr_prefix, | ||
controller=controller_musr, | ||
waiter=waiter_musr, | ||
reducer=reducer_musr, | ||
name="musr_dae", | ||
dae_2 = SimpleDae( | ||
prefix=dae_2_prefix, | ||
controller=controller_2, | ||
waiter=waiter_2, | ||
reducer=reducer_2, | ||
name="dae_2", | ||
) | ||
|
||
_, ax = yield from call_qt_aware(plt.subplots) | ||
|
||
lf = LiveFit( | ||
Linear.fit(), | ||
y=reducer_emu.intensity.name, | ||
x=magnet.name, | ||
yerr=reducer_emu.intensity_stddev.name, | ||
lf_1 = LiveFit( | ||
Gaussian().fit(), | ||
y=reducer_1.intensity.name, | ||
x=magnet_1.name, | ||
yerr=reducer_1.intensity_stddev.name, | ||
) | ||
lf_2 = LiveFit( | ||
Gaussian().fit(), | ||
y=reducer_2.intensity.name, | ||
x=magnet_1.name, | ||
yerr=reducer_2.intensity_stddev.name, | ||
) | ||
|
||
yield from ensure_connected(magnet, dae_emu, dae_musr, force_reconnect=True) | ||
yield from ensure_connected(magnet_1, magnet_2, dae_1, dae_2, force_reconnect=True) | ||
|
||
@subs_decorator( | ||
[ | ||
LiveFitPlot(livefit=lf, ax=ax), | ||
LiveFitPlot(livefit=lf_1, ax=ax), | ||
LiveFitPlot(livefit=lf_2, ax=ax), | ||
LivePlot( | ||
y=reducer_emu.intensity.name, | ||
x=magnet.name, | ||
y=reducer_1.intensity.name, | ||
x=magnet_1.name, | ||
marker="x", | ||
linestyle="none", | ||
ax=ax, | ||
yerr=reducer_emu.intensity_stddev.name, | ||
yerr=reducer_1.intensity_stddev.name, | ||
), | ||
LivePlot( | ||
y=reducer_musr.intensity.name, | ||
x=magnet.name, | ||
y=reducer_2.intensity.name, | ||
x=magnet_1.name, | ||
marker="x", | ||
linestyle="none", | ||
ax=ax, | ||
yerr=reducer_musr.intensity_stddev.name, | ||
yerr=reducer_2.intensity_stddev.name, | ||
), | ||
LiveTable( | ||
[ | ||
magnet.name, | ||
controller_emu.run_number.name, | ||
reducer_emu.intensity.name, | ||
reducer_emu.intensity_stddev.name, | ||
reducer_emu.det_counts.name, | ||
reducer_emu.det_counts_stddev.name, | ||
dae_emu.good_frames.name, | ||
controller_musr.run_number.name, | ||
reducer_musr.intensity.name, | ||
reducer_musr.intensity_stddev.name, | ||
reducer_musr.det_counts.name, | ||
reducer_musr.det_counts_stddev.name, | ||
dae_musr.good_frames.name, | ||
magnet_1.name, | ||
magnet_2.name, | ||
controller_1.run_number.name, | ||
reducer_1.intensity.name, | ||
reducer_1.intensity_stddev.name, | ||
reducer_1.det_counts.name, | ||
reducer_1.det_counts_stddev.name, | ||
dae_1.good_frames.name, | ||
controller_2.run_number.name, | ||
reducer_2.intensity.name, | ||
reducer_2.intensity_stddev.name, | ||
reducer_2.det_counts.name, | ||
reducer_2.det_counts_stddev.name, | ||
dae_2.good_frames.name, | ||
] | ||
), | ||
HumanReadableFileCallback( | ||
fields=[ | ||
magnet_1.name, | ||
magnet_2.name, | ||
controller_1.run_number.name, | ||
reducer_1.intensity.name, | ||
reducer_1.intensity_stddev.name, | ||
reducer_1.det_counts.name, | ||
reducer_1.det_counts_stddev.name, | ||
dae_1.good_frames.name, | ||
controller_2.run_number.name, | ||
reducer_2.intensity.name, | ||
reducer_2.intensity_stddev.name, | ||
reducer_2.det_counts.name, | ||
reducer_2.det_counts_stddev.name, | ||
dae_2.good_frames.name, | ||
] | ||
), | ||
LiveFitLogger( | ||
lf_1, | ||
x=magnet_1.name, | ||
y=reducer_1.intensity.name, | ||
yerr=reducer_1.intensity_stddev.name, | ||
postfix="lf_1", | ||
), | ||
LiveFitLogger( | ||
lf_2, | ||
x=magnet_1.name, | ||
y=reducer_2.intensity.name, | ||
yerr=reducer_2.intensity_stddev.name, | ||
postfix="lf_2", | ||
), | ||
] | ||
) | ||
def _inner() -> Generator[Msg, None, None]: | ||
yield from bp.scan([dae_musr, dae_emu], magnet, 0, 10, num=NUM_POINTS) | ||
print(lf.result.fit_report()) | ||
yield from bp.scan( | ||
[dae_2, dae_1], magnet_1, start_1, stop_1, magnet_2, start_2, stop_2, num=num | ||
) | ||
print(lf_1.result.fit_report()) | ||
print(lf_2.result.fit_report()) | ||
|
||
yield from _inner() | ||
|
||
|
||
if __name__ == "__main__" and not os.environ.get("FROM_IBEX") == "True": | ||
matplotlib.use("qtagg") | ||
plt.ion() | ||
RE = get_run_engine() | ||
RE(two_dae_scan()) | ||
input("Plan complete, press return to close plot and exit") |