ibex_bluesky_core.devices.simpledae

High-level bluesky device interface to the DAE for ‘typical’ measurements.

Members

SimpleDae

DAE with used-defined strategies for data collection, waiting, and reduction.

check_dae_strategies

Check that the provided dae instance has appropriate controller/reducer/waiter configured.

monitor_normalising_dae

Create a SimpleDae which normalises using a monitor and waits for frames.

class ibex_bluesky_core.devices.simpledae.Controller[source]

Bases: ProvidesExtraReadables

Specifies how DAE runs should be started & stopped.

This default implementation does nothing; concrete implementations such as PeriodPerPointController or RunPerPointController implement commonly-used behaviours.

async setup(dae: Dae) None[source]

Pre-scan setup.

async start_counting(dae: Dae) None[source]

Start counting for a single scan point.

async stop_counting(dae: Dae) None[source]

Stop counting for a single scan point.

async teardown(dae: Dae) None[source]

Post-scan teardown.

class ibex_bluesky_core.devices.simpledae.DSpacingMappingReducer(*, prefix: str, detectors: ndarray[tuple[Any, ...], dtype[int64]], l_total: Variable, two_theta: Variable, dspacing_bin_edges: Variable)[source]

Bases: Reducer, StandardReadable

DAE Reducer which exposes an array of d-spacings at each scan point.

This reducer produces one dimensional arrays of d-spacing, generated by converting the time-of-flight coordinates of each configured spectrum to d-spacing, rebinning all spectra to a common set of d-spacing bins, and then summing all spectra together. The conversion method used is scippneutron.conversion.tof.dspacing_from_tof.

For a description of the basic theory behind conversions between time-of-flight and d-spacing, see the introductory slides from the Oxford Neutron School, or the ISIS introduction to ToF neutron diffraction.

Parameters:
  • prefix – PV prefix for the SimpleDae.

  • detectors – numpy array of detector spectra to select. For example, np.array([1, 2, 3]) selects spectra 1-3 inclusive. All detectors in this list are assumed to have the same time channel boundaries.

  • l_total – scipp Variable describing the total flight path length of each selected detector. Must have the same length as detectors, have units of length, and have a scipp dimension label of “spec”

  • two_theta – scipp Variable describing the two theta scattering angle of each selected detector. Must have the same length as detectors, have units of angle, and have a scipp dimension label of “spec”

  • dspacing_bin_edges – scipp Variable describing the required d-spacing bin-edges. This must be bin edge coordinates, aligned along a scipp dimension label of “tof”, have a unit of length, for example Angstroms (scipp.units.angstrom), and must be strictly ascending.

dspacing

d-spacing numpy.ndarray, binned by dspacing_bin_edges.

async reduce_data(dae: Dae) None[source]

Expose calculated d-spacing.

This will be in units of counts, which may be fractional due to rebinning.

The binning of the data, and hence the length of the d-spacing array, has bin edges specified by dspacing_bin_edges.

ibex_bluesky_core.devices.simpledae.GoodFramesNormalizer

alias of PeriodGoodFramesNormalizer

ibex_bluesky_core.devices.simpledae.GoodFramesWaiter

alias of PeriodGoodFramesWaiter

class ibex_bluesky_core.devices.simpledae.GoodUahWaiter(value: float)[source]

Bases: SimpleWaiter[float]

Wait for a specified number of good uAh in the current period.

Parameters:

value – the number of good uAh to wait for

class ibex_bluesky_core.devices.simpledae.MEventsWaiter(value: float)[source]

Bases: SimpleWaiter[float]

Wait for a specified number of events (in millions) in the current period.

Parameters:

value – the number of events (in millions) to wait for

class ibex_bluesky_core.devices.simpledae.MonitorNormalizer(prefix: str, detector_spectra: Sequence[int], monitor_spectra: Sequence[int], sum_detector: Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]] = sum_spectra, sum_monitor: Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]] = sum_spectra)[source]

Bases: Reducer, StandardReadable

Normalize a set of user-specified detector spectra by user-specified monitor spectra.

Parameters:
  • prefix – the PV prefix of the instrument to get spectra from (e.g. IN:DEMO:)

  • detector_spectra – a sequence of spectra numbers (detectors) to sum.

  • monitor_spectra – a sequence of spectra number (monitors) to sum and normalize by.

  • sum_detector – takes spectra objects, reads from them, and returns a scipp.scalar describing the detector intensity. Defaults to summing over the entire spectrum.

  • sum_monitor – takes spectra objects, reads from them, and returns a scipp.scalar describing the monitor intensity. Defaults to summing over the entire spectrum.

det_counts

Total detector counts.

det_counts_stddev

Standard deviation of the detector counts.

intensity

Normalised intensity.

intensity_stddev

Standard deviation of the normalised intensity.

mon_counts

Total monitor counts.

mon_counts_stddev

Standard deviation of the monitor counts.

class ibex_bluesky_core.devices.simpledae.PeriodGoodFramesNormalizer(prefix: str, detector_spectra: Sequence[int], sum_detector: Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]] = sum_spectra)[source]

Bases: ScalarNormalizer

Sum a set of user-specified spectra, then normalize by period good frames.

Parameters:
  • prefix – The PV prefix of the instrument to get spectra from (e.g. IN:DEMO:)

  • detector_spectra – A sequence of spectra numbers (detectors) to sum.

  • sum_detector – Takes spectra objects, reads from them, and returns a scipp.scalar describing the detector intensity. Defaults to summing over the entire spectrum.

class ibex_bluesky_core.devices.simpledae.PeriodGoodFramesWaiter(value: int)[source]

Bases: SimpleWaiter[int]

Wait for a specified number of good frames in the current period.

Parameters:

value – the number of good frames to wait for

class ibex_bluesky_core.devices.simpledae.PeriodPerPointController(save_run: bool)[source]

Bases: Controller

Period-per-point DAE controller.

Parameters:

save_runTrue to terminate runs using end_run, saving the data. False to terminate runs using abort_run, discarding the data.

async setup(dae: Dae) None[source]

Pre-scan setup (begin a new run in paused mode).

async start_counting(dae: Dae) None[source]

Start counting a single point.

Increments the period by 1, then unpauses the run.

async stop_counting(dae: Dae) None[source]

Stop counting a scan point, by pausing the run.

async teardown(dae: Dae) None[source]

Finish taking data, ending or aborting the run.

class ibex_bluesky_core.devices.simpledae.PeriodSpecIntegralsReducer(*, monitors: ndarray[tuple[Any, ...], dtype[int64]], detectors: ndarray[tuple[Any, ...], dtype[int64]])[source]

Bases: Reducer, StandardReadable

DAE Reducer which exposes integrals of many spectra in the current period.

Two types of integrals are available: detectors and monitors. Other than defaults, their behaviour is identical.

Parameters:
  • monitors – an array representing the mapping of monitors to acquire integrals from. For example, passing np.array([1]) selects spectrum 1.

  • detectors – an array representing the mapping of detectors to acquire integrals from. For example, passing np.array([5, 6, 7, 8]) would select detector spectra 5-8 inclusive, and so the output of this reducer would be an array of dimension 4.

det_integrals

Detector integrals, as a numpy.ndarray.

det_sum

Sum of detector integrals, as a int

property detectors: ndarray[tuple[Any, ...], dtype[int64]]

Get the detectors used by this reducer.

intensity

Normalised intensity (detectors/monitors), as a float

intensity_stddev

Standard deviation of normalised intensity (detectors/monitors), as a float

mon_integrals

Monitor integrals, as a numpy.ndarray.

mon_sum

Sum of monitor integrals, as a int

property monitors: ndarray[tuple[Any, ...], dtype[int64]]

Get the monitors used by this reducer.

async reduce_data(dae: Dae) None[source]

Expose detector & monitor integrals.

After this method returns, it is valid to read from det_integrals and mon_integrals.

Note

Could use SPECINTEGRALS PV here, which seems more efficient initially, but it gets bounded by some areadetector settings under-the-hood which may be a bit surprising on some instruments.

We can’t just change these settings in this reducer, as they only apply to new events that come in.

class ibex_bluesky_core.devices.simpledae.ProvidesExtraReadables[source]

Bases: object

Protocol for specifying extra ‘interesting’ signals for SimpleDae.

Strategies may specify interesting DAE signals using the additional_readable_signals method. Those signals will then be added to read and describe on the top-level SimpleDae instance.

additional_readable_signals(dae: Dae) list[Device][source]

Define signals that this strategy considers important.

These will be added to the dae’s default-read signals and made available by SimpleDae.read.

class ibex_bluesky_core.devices.simpledae.Reducer[source]

Bases: ProvidesExtraReadables

Reducer specifies any post-processing which needs to be done after a scan point completes.

async reduce_data(dae: Dae) None[source]

Triggers a reduction of DAE data after a scan point has been measured.

Data that should be published by this reducer should be added as soft signals, in a class which both implements this protocol and derives from StandardReadable.

class ibex_bluesky_core.devices.simpledae.RunPerPointController(save_run: bool)[source]

Bases: Controller, StandardReadable

SimpleDae controller which counts using a run per point.

The runs can be either ended or aborted once counting is finished.

Parameters:

save_run – whether to end the run (True) or abort the run (False) on completion.

run_number

The run number which this run counted into.

This property is added to the interesting signals only if save_run is True.

async start_counting(dae: Dae) None[source]

Start counting a scan point, by starting a DAE run.

async stop_counting(dae: Dae) None[source]

Stop counting a scan point, by ending or aborting the run.

class ibex_bluesky_core.devices.simpledae.ScalarNormalizer(prefix: str, detector_spectra: Sequence[int], sum_detector: Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]] = sum_spectra)[source]

Bases: Reducer, StandardReadable, ABC

Sum a set of user-specified spectra, then normalize by a scalar signal.

Parameters:
  • prefix – the PV prefix of the instrument to get spectra from (e.g. IN:DEMO:)

  • detector_spectra – a sequence of spectra numbers (detectors) to sum.

  • sum_detector – takes spectra objects, reads from them, and returns a scipp.scalar describing the detector intensity. Defaults to summing over the entire spectrum.

abstractmethod denominator(dae: Dae) SignalR[int] | SignalR[float][source]

Get the normalization denominator, which is assumed to be a scalar signal.

det_counts

Total detector counts.

det_counts_stddev

Standard deviation of detector counts.

intensity

Normalised intensity.

intensity_stddev

Standard deviation of intensity.

class ibex_bluesky_core.devices.simpledae.SimpleDae(*, prefix: str, name: str = 'DAE', controller: TController_co, waiter: TWaiter_co, reducer: TReducer_co)[source]

Bases: Dae, Triggerable, AsyncStageable, Generic[TController_co, TWaiter_co, TReducer_co]

DAE with used-defined strategies for data collection, waiting, and reduction.

See also

DAE (Data Acquisition Electronics) user documentation.

Parameters:
  • prefix – the PV prefix of the instrument being controlled.

  • name – A friendly name for this DAE object. Defaults to “DAE”.

  • controller – A DAE control strategy, defines how the DAE begins and ends data acquisition Should implement the Controller protocol.

  • waiter – A waiting strategy, defines how the DAE waits for an acquisition to be complete Should implement the Waiter protocol.

  • reducer – A data reduction strategy, defines the post-processing on raw DAE data, for example normalization or unit conversion. Should implement the Reducer protocol.

stage() None[source]

Pre-scan setup.

The behaviour of this method is defined by Controller.setup.

trigger() None[source]

Take a single measurement, and prepare it for subsequent reading.

This waits for the acquisition and any defined reduction to be complete, such that after this coroutine completes, all relevant data is available via bluesky.protocols.Readable.read.

The behaviour of this method is defined by the following method calls (in order):

unstage() None[source]

Post-scan teardown.

The behaviour of this method is defined by Controller.teardown.

class ibex_bluesky_core.devices.simpledae.SimpleWaiter(value: T)[source]

Bases: Waiter, Generic[T], ABC

Wait for a single DAE variable to be greater or equal to the specified value.

Note

This is a generic base class. Implementations such as PeriodGoodFramesWaiter should generally be used rather than this class directly.

Parameters:

value – the value to wait for

finish_wait_at

Value at which to finish waiting.

It is possible to change this signal dynamically at runtime, using:

yield from bps.mv(waiter.finish_wait_at, new_finish_value)
abstractmethod get_signal(dae: Dae) SignalR[T][source]

Get the numeric signal to wait for.

async wait(dae: Dae) None[source]

Wait for signal to reach the user-specified value.

class ibex_bluesky_core.devices.simpledae.TimeWaiter(*, seconds: float)[source]

Bases: Waiter

Wait for a user-specified time duration.

Parameters:

seconds – number of seconds to wait for.

class ibex_bluesky_core.devices.simpledae.Waiter[source]

Bases: ProvidesExtraReadables

Waiter specifies how the dae will wait for a scan point to complete counting.

async wait(dae: Dae) None[source]

Wait for the acquisition to complete.

ibex_bluesky_core.devices.simpledae.check_dae_strategies(dae: SimpleDae, *, expected_controller: type[Controller] | None = None, expected_waiter: type[Waiter] | None = None, expected_reducer: type[Reducer] | None = None) None[source]

Check that the provided dae instance has appropriate controller/reducer/waiter configured.

Parameters:
  • dae – The SimpleDae instance to check.

  • expected_controller – The expected controller type, or None to not check.

  • expected_waiter – The expected controller type, or None to not check.

  • expected_reducer – The expected controller type, or None to not check.

ibex_bluesky_core.devices.simpledae.monitor_normalising_dae(*, det_pixels: list[int], frames: int, periods: bool = True, monitor: int = 1, save_run: bool = False) SimpleDae[source]

Create a SimpleDae which normalises using a monitor and waits for frames.

This is a shortcut to reduce code in plans used on the majority of instruments that normalise using a monitor, wait for a number of frames and optionally use software periods.

Parameters:
  • det_pixels – list of detector pixel to use for scanning.

  • frames – number of frames to wait for.

  • periods – whether or not to use software periods.

  • monitor – the monitor spectra number.

  • save_run – whether or not to save the run of the DAE.

async ibex_bluesky_core.devices.simpledae.sum_spectra(spectra: Collection[DaeSpectra]) Variable | DataArray[source]

Read and sum a number of spectra from the DAE.

Parameters:

spectra – a Collection type object of DAE spectra

Returns:

scipp Variable or DataArray describing the sum of the provided spectra.

ibex_bluesky_core.devices.simpledae.tof_bounded_spectra(bounds: Variable) Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]][source]

Sum a set of neutron spectra between the specified time of flight bounds.

Parameters:

bounds – A scipp array of size 2, no variances, unit of us, where the second element must be larger than the first.

Returns:

scipp scalar describing summed intensity, which has value and variance properties for accessing the sum and variance respectively of the summed counts.

ibex_bluesky_core.devices.simpledae.wavelength_bounded_spectra(bounds: Variable, total_flight_path_length: Variable) Callable[[Collection[DaeSpectra]], Awaitable[Variable | DataArray]][source]

Sum a set of neutron spectra between the specified wavelength bounds.

Time of flight is converted to wavelength using scipp neutron’s library function wavelength_from_tof.

Parameters:
  • bounds – A scipp array of size 2 of wavelength bounds, in units of angstrom, where the second element must be larger than the first.

  • total_flight_path_length – A scipp scalar of \(L_{total}\) (total flight path length), the path length from neutron source to detector or monitor, in units of meters.

Returns:

scipp scalar, which has value and variance properties for accessing the sum and variance respectively of the summed counts.