2424from ibex_bluesky_core .callbacks ._plotting import LivePlot , show_plot
2525from ibex_bluesky_core .callbacks ._utils import get_default_output_path
2626from ibex_bluesky_core .fitting import FitMethod
27+ from ibex_bluesky_core .utils import is_matplotlib_backend_qt
2728
2829logger = logging .getLogger (__name__ )
2930
4546class ISISCallbacks :
4647 """ISIS standard callbacks for use within plans."""
4748
48- def __init__ (
49+ def __init__ ( # noqa: PLR0912
4950 self ,
5051 * ,
5152 x : str ,
@@ -66,6 +67,8 @@ def __init__(
6667 live_fit_logger_output_dir : str | PathLike [str ] | None = None ,
6768 live_fit_logger_postfix : str = "" ,
6869 human_readable_file_postfix : str = "" ,
70+ live_fit_update_every : int | None = 1 ,
71+ live_plot_show_every_event : bool = True ,
6972 ) -> None :
7073 """A collection of ISIS standard callbacks for use within plans.
7174
@@ -124,6 +127,8 @@ def _inner():
124127 live_fit_logger_output_dir: the output directory for live fit logger.
125128 live_fit_logger_postfix: the postfix to add to live fit logger.
126129 human_readable_file_postfix: optional postfix to add to human-readable file logger.
130+ live_fit_update_every: How often to recompute the fit. If None, do not compute until the end.
131+ live_plot_show_every_event: whether to show the live plot on every event, or just at the end.
127132 """ # noqa
128133 self ._subs = []
129134 self ._peak_stats = None
@@ -164,31 +169,41 @@ def _inner():
164169
165170 if (add_plot_cb or show_fit_on_plot ) and not ax :
166171 logger .debug ("No axis provided, creating a new one" )
167- fig , ax , exc , result = None , None , None , None
168- done_event = threading .Event ()
169-
170- class _Cb (QtAwareCallback ):
171- def start (self , doc : RunStart ) -> None :
172- nonlocal result , exc , fig , ax
173- try :
174- plt .close ("all" )
175- fig , ax = plt .subplots ()
176- finally :
177- done_event .set ()
178-
179- cb = _Cb ()
180- cb ("start" , {"time" : 0 , "uid" : "" })
181- done_event .wait (10.0 )
172+ fig , ax = None , None
173+
174+ if is_matplotlib_backend_qt ():
175+ done_event = threading .Event ()
176+
177+ class _Cb (QtAwareCallback ):
178+ def start (self , doc : RunStart ) -> None :
179+ nonlocal fig , ax
180+ try :
181+ plt .close ("all" )
182+ fig , ax = plt .subplots ()
183+ finally :
184+ done_event .set ()
185+
186+ cb = _Cb ()
187+ cb ("start" , {"time" : 0 , "uid" : "" })
188+ done_event .wait (10.0 )
189+ else :
190+ plt .close ("all" )
191+ fig , ax = plt .subplots ()
182192
183193 if fit is not None :
184- self ._live_fit = LiveFit (fit , y = y , x = x , yerr = yerr )
194+ self ._live_fit = LiveFit (fit , y = y , x = x , yerr = yerr , update_every = live_fit_update_every )
185195
186- # Ideally this would append either livefitplot or livefit, not both, but there's a
187- # race condition if using the Qt backend where a fit result can be returned before
188- # the QtAwareCallback has had a chance to process it.
189- self ._subs .append (self ._live_fit )
190196 if show_fit_on_plot :
197+ if is_matplotlib_backend_qt ():
198+ # Ideally this would append either livefitplot
199+ # or livefit, not both, but there's a
200+ # race condition if using the Qt backend
201+ # where a fit result can be returned before
202+ # the QtAwareCallback has had a chance to process it.
203+ self ._subs .append (self ._live_fit )
191204 self ._subs .append (LiveFitPlot (livefit = self ._live_fit , ax = ax ))
205+ else :
206+ self ._subs .append (self ._live_fit )
192207
193208 if add_live_fit_logger :
194209 self ._subs .append (
@@ -211,6 +226,7 @@ def start(self, doc: RunStart) -> None:
211226 linestyle = "none" ,
212227 ax = ax ,
213228 yerr = yerr ,
229+ show_every_event = live_plot_show_every_event ,
214230 )
215231 )
216232
0 commit comments