Live Data Reduction#

From Terminal#

You can run the beamlime command from your terminal to run the application and see the real-time update of a plot.

beamlime --image-path beamlime_plot.png

This command will save the plot into beamlime_plot.png.

Jupyter Environment#

You can also run the same thing in jupyter environment and use plopp matplotlib widget to see the real-time updated plot.

It uses the same ``PlotHandler`` as above, so running this application will create a file called ``beamlime_plot.png`` in the current directory.

[2]:
%matplotlib widget
import scipp as sc

sc.get_logger().addHandler(sc.logging.make_widget_handler())
sc.display_logs()
[3]:
from tests.applications.data import get_path

file_path = get_path('ymir_detectors.nxs').as_posix()  # Path to the example file
[4]:
from matplotlib import pyplot as plt

from beamlime.constructors import (
    multiple_constant_providers,
    SingletonProvider,
    Factory,
)
from beamlime.logging import BeamlimeLogger

from beamlime.executables.prototypes import collect_default_providers
from beamlime.applications.base import Application
from beamlime.applications.handlers import (
    DataReductionHandler,
    WorkflowResultUpdate,
    PlotStreamer,
    DataAssembler,
    DataReady,
    ResultRegistry,
)
from beamlime.applications.daemons import (
    DataPieceReceived,
    FakeListener,
    NexusTemplatePath,
    NumFrames,
    DataFeedingSpeed,
    EventRate,
    FrameRate,
    RunStart,
    NexusFilePath,
)
from beamlime.workflow_protocols import WorkflowName


prototype_factory = Factory(collect_default_providers())
prototype_factory.providers[FakeListener] = SingletonProvider(FakeListener)
prototype_factory.providers[PlotStreamer] = SingletonProvider(PlotStreamer)
prototype_factory.providers[DataAssembler] = DataAssembler

result_registry = ResultRegistry({})
with multiple_constant_providers(
    prototype_factory,
    {
        BeamlimeLogger: sc.get_logger(),
        DataFeedingSpeed: DataFeedingSpeed(0.3),
        NumFrames: NumFrames(5),
        EventRate: EventRate(10_000),
        FrameRate: FrameRate(14),
        WorkflowName: WorkflowName('dummy'),
        NexusTemplatePath: NexusTemplatePath(
            '../../tests/applications/ymir_detectors.json'
        ),
        NexusFilePath: NexusFilePath(file_path),
        # TODO: Make a matching file for the template
        ResultRegistry: result_registry,
    },
):
    prototype_factory[BeamlimeLogger].setLevel("INFO")

    # Build the application
    app = prototype_factory[Application]
    # Register Handlers
    plot_saver = prototype_factory[PlotStreamer]
    app.register_handling_method(WorkflowResultUpdate, plot_saver.update_histogram)
    data_assembler = prototype_factory[DataAssembler]
    app.register_handling_method(RunStart, data_assembler.set_run_start)
    app.register_handling_method(DataPieceReceived, data_assembler.merge_data_piece)
    data_reduction_handler = prototype_factory[DataReductionHandler]
    app.register_handling_method(RunStart, data_reduction_handler.set_run_start)
    app.register_handling_method(DataReady, data_reduction_handler.reduce_data)
    # Register Daemons
    app.register_daemon(prototype_factory[FakeListener])

    app.run()
    plt.close()  # Close the plot from this cell.
[5]:
plot_saver.show()
[5]:
[6]:
# Retrieve the result from the registry
next(iter(result_registry.values()))
[6]:
Show/Hide data repr Show/Hide attributes
scipp.DataArray (1.16 KB)
    • x: 10
    • x
      (x)
      int64
      m
      0, 1, ..., 8, 9
      Values:
      array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    • (x)
      float64
      counts
      0.749, 0.154, ..., 0.563, 0.563
      Values:
      array([0.74883689, 0.15385377, 0.85148016, 0.66848975, 0.39107809, 0.52122185, 0.34140029, 0.68566077, 0.5632588 , 0.56283065])