Getting Started#

Running Beamlime#

Run the beamlime command, and specify which workflow to use. Usually this would be done from a terminal. The current setup plots the results of the workflow and saves them to a file, which can we specify using the --image-path flag:

[2]:
!beamlime \
    --workflow dummy \
    --nexus-template-path ../../tests/applications/ymir_detectors.json \
    --nexus-file-path $TEST_NEXUS_FILE_PATH \
    --image-path-prefix reduction-result \
    --fill-dummy-data
[10/28/24 15:09:50] INFO     Application     | Start running         ]8;id=125937;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=543285;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#265\265]8;;\
                             Application...
                    INFO     Application     | Running daemon        ]8;id=688874;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=982364;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#220\220]8;;\
                             MessageRouter
                    INFO     Application     | Running daemon        ]8;id=834347;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=454469;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#220\220]8;;\
                             FakeListener
                    INFO     FakeListener    | Fake data          ]8;id=151264;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py\daemons.py]8;;\:]8;id=642000;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py#170\170]8;;\
                             streaming started...
                    INFO     FakeListener    | Frame #0: sending  ]8;id=600393;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py\daemons.py]8;;\:]8;id=775454;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py#204\204]8;;\
                             neutron events for 
                             StreamModuleKey(module_type='ev44', 
                             topic='hypothetical_detector', 
                             source='ymir_0').
                    INFO     FakeListener    | Frame #0: sending  ]8;id=636200;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py\daemons.py]8;;\:]8;id=222640;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py#204\204]8;;\
                             neutron events for 
                             StreamModuleKey(module_type='ev44', 
                             topic='hypothetical_detector', 
                             source='ymir_1').
                    INFO     DataReductionHandler | Running data ]8;id=618110;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/handlers.py\handlers.py]8;;\:]8;id=209033;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/handlers.py#373\373]8;;\
                             reduction
                    INFO     FakeListener    | Neutron events of  ]8;id=793347;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py\daemons.py]8;;\:]8;id=703701;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/daemons.py#212\212]8;;\
                             frame #0 were sent.
                    INFO     PlotSaver       | Received          ]8;id=569934;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/handlers.py\handlers.py]8;;\:]8;id=339571;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/handlers.py#566\566]8;;\
                             histogram(s), saving into 
                             reduction-result.png...
                    WARNING  MessageRouter   | Failed to handle event ]8;id=647727;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=164822;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#77\77]8;;\
                             <class 
                             'beamlime.applications.handlers.Workflow
                             ResultUpdate'>
                    ERROR    Application     | Daemon                ]8;id=915867;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=658212;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#227\227]8;;\
                             <beamlime.applications.base.MessageRout
                             er object at 0x7fab4fded930> failed. 
                             Cancelling all other tasks...
                    INFO     Application     | Stop running          ]8;id=54404;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py\base.py]8;;\:]8;id=758624;file:///home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py#188\188]8;;\
                             application Application...
Traceback (most recent call last):
  File "/home/runner/work/beamlime/beamlime/.tox/docs/bin/beamlime", line 8, in <module>
    sys.exit(main())
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/__main__.py", line 18, in main
    run_standalone_prototype(factory, arg_name_space=arg_parser.parse_args())
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/executables/prototypes.py", line 113, in run_standalone_prototype
    app.run()
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py", line 277, in run
    loop.run_until_complete(asyncio.gather(*self.tasks))
  File "/opt/hostedtoolcache/Python/3.10.15/x64/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py", line 241, in run_daemon
    async for message in daemon.run():
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py", line 150, in run
    await self.route(self.message_pipe.get())
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/base.py", line 124, in route
    results.extend(self._collect_results(handler(message)))
  File "/home/runner/work/beamlime/beamlime/.tox/docs/lib/python3.10/site-packages/beamlime/applications/handlers.py", line 569, in save_histogram
    dashboard = detector_registry[instrument]['dashboard']
KeyError: 'r'

The dummy workflow returns a single result named “reduction-result.png”, which is added as a suffix to the output file name:

Plot of reduction result

Adding Workflow Constructors#

Python packages can add workflow constructors as plugins to Beamlime. To do this, create a Python package with a beamlime.workflow_plugin entry point in the pyproject.toml file. This is how the “dummy” workflow is added to Beamlime:

# In beamlime's pyproject.toml
[project.entry-points."beamlime.workflow_plugin"]
dummy = "beamlime.workflow_protocols:DummyLiveWorkflow"

Above, ‘dummy’ is the name of the workflow (which can then be passed to beamlime --workflow), and ‘beamlime.workflow_protocols:’ is the name of the Python package and module containing the workflow constructor. As an example, for a Loki monitor workflow plugin provided by esssans, the entry point might look as follows:

# In esssans' pyproject.toml
[project.entry-points."beamlime.workflow_plugin"]
ess-loki-monitor = "ess.loki.live:LokiMonitorWorkflow"

where live_workflow must adhere to the beamlime.LiveWorkflow protocol:

[3]:
import inspect

from beamlime import LiveWorkflow

print(inspect.getsource(LiveWorkflow))
@runtime_checkable
class LiveWorkflow(Protocol):
    def __init__(self, nexus_filename: Path) -> None:
        """Initialize the workflow with all static information.

        The only argument we need is the path to the nexus file or
        a file object that workflow can read from,
        since the file carrys all the static information.
        """
        ...

    def __call__(
        self, nxevent_data: dict[str, JSONGroup], nxlog: dict[str, JSONGroup]
    ) -> WorkflowResult:
        """Call the workflow and return the computed results that can be visualized.

        Parameters
        ----------
        nxevent_data:
            Dictionary of event data groups.
            It should contain empty events even if no events was received
            since the last call.

        nxlog:
            Dictionary of log data groups.
            It should only contain keys that we received since the last call.


        Returns
        -------
        :
            A dictionary of objects that can be visualized.

        """
        ...

This can be fulfilled by a class with - a constructor that accepts a nexus file path - __call__ method that accepts JSONGroups of each types, (nxlog, nxevent) - __call__ method that returns a dictionary of a plottable results: beamlime.WorkflowResult.