-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into 564_organise_testing_utils
- Loading branch information
Showing
49 changed files
with
477 additions
and
365 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
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
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,16 +1,8 @@ | ||
from argparse import ArgumentParser | ||
|
||
from . import __version__ | ||
from .cli import main | ||
|
||
__all__ = ["main"] | ||
|
||
|
||
def main(args=None): | ||
parser = ArgumentParser() | ||
parser.add_argument("-v", "--version", action="version", version=__version__) | ||
args = parser.parse_args(args) | ||
|
||
|
||
# test with: python -m dodal | ||
if __name__ == "__main__": | ||
main() |
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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Beamlines | ||
|
||
Beamline modules are code-as-configuration. They define the set of devices and common device settings needed for a particular beamline or group of similar beamlines (e.g. a beamline and its digital twin). Some of our tooling depends on the convention of _only_ beamline modules going in this package. Common utilities should go somewhere else e.g. `dodal.utils` or `dodal.beamlines.common`. |
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 |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import importlib.util | ||
from functools import lru_cache | ||
from pathlib import Path | ||
from typing import Iterable, Mapping | ||
|
||
# Where beamline names (per the ${BEAMLINE} environment variable don't always | ||
# match up, we have to map between them bidirectionally). The most common use case is | ||
# beamlines with a "-"" in the name such as "i04-1", which is not valid in a Python | ||
# module name. Add any new beamlines whose name differs from their module name to this | ||
# dictionary, which maps ${BEAMLINE} to dodal.beamlines.<MODULE NAME> | ||
_BEAMLINE_NAME_OVERRIDES = { | ||
"i04-1": "i04_1", | ||
"i20-1": "i20_1", | ||
"s03": "i03", | ||
} | ||
|
||
|
||
def all_beamline_modules() -> Iterable[str]: | ||
""" | ||
Get the names of all importable modules in beamlines | ||
Returns: | ||
Iterable[str]: Generator of beamline module names | ||
""" | ||
|
||
# This is done by inspecting file names rather than modules to avoid | ||
# premature importing | ||
spec = importlib.util.find_spec(__name__) | ||
if spec is not None: | ||
search_paths = [Path(path) for path in spec.submodule_search_locations] | ||
for path in search_paths: | ||
for subpath in path.glob("**/*"): | ||
if ( | ||
subpath.name.endswith(".py") | ||
and subpath.name != "__init__.py" | ||
and ("__pycache__" not in str(subpath)) | ||
): | ||
yield subpath.with_suffix("").name | ||
else: | ||
raise KeyError(f"Unable to find {__name__} module") | ||
|
||
|
||
def all_beamline_names() -> Iterable[str]: | ||
""" | ||
Get the names of all beamlines as per the ${BEAMLINE} environment variable | ||
Returns: | ||
Iterable[str]: Generator of beamline names that dodal supports | ||
""" | ||
inverse_mapping = _module_name_overrides() | ||
for module_name in all_beamline_modules(): | ||
yield from inverse_mapping.get(module_name, set()).union({module_name}) | ||
|
||
|
||
@lru_cache | ||
def _module_name_overrides() -> Mapping[str, set[str]]: | ||
""" | ||
Get the inverse of _BEAMLINE_NAME_OVERRIDES so that modules can be mapped back to | ||
beamlines. _BEAMLINE_NAME_OVERRIDES is expected to be a constant so the return | ||
value is cached. | ||
Returns: | ||
Mapping[str, set[str]]: A dictionary mapping the name of a dodal module to the | ||
set of beamlines it supports. | ||
""" | ||
|
||
inverse_mapping: dict[str, set[str]] = {} | ||
for beamline, module in _BEAMLINE_NAME_OVERRIDES.items(): | ||
inverse_mapping[module] = inverse_mapping.get(module, set()).union({beamline}) | ||
return inverse_mapping | ||
|
||
|
||
def module_name_for_beamline(beamline: str) -> str: | ||
""" | ||
Get the module name for a particular beamline, it may differ from the beamline | ||
name e.g. i04-1 -> i04_1 | ||
Args: | ||
beamline: The beamline name as per the ${BEAMLINE} environment variable | ||
Returns: | ||
str: The importable module name | ||
""" | ||
|
||
return _BEAMLINE_NAME_OVERRIDES.get(beamline, beamline) |
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
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
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
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
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 |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import os | ||
|
||
import click | ||
from bluesky.run_engine import RunEngine | ||
|
||
from dodal.beamlines import all_beamline_names, module_name_for_beamline | ||
from dodal.utils import make_all_devices | ||
|
||
from . import __version__ | ||
|
||
|
||
@click.group(invoke_without_command=True) | ||
@click.version_option(version=__version__, message="%(version)s") | ||
@click.pass_context | ||
def main(ctx: click.Context) -> None: | ||
if ctx.invoked_subcommand is None: | ||
print("Please invoke subcommand!") | ||
|
||
|
||
@main.command(name="connect") | ||
@click.argument( | ||
"beamline", | ||
type=click.Choice(list(all_beamline_names())), | ||
required=True, | ||
) | ||
@click.option( | ||
"-a", | ||
"--all", | ||
is_flag=True, | ||
help="Attempt to connect to devices marked as skipped", | ||
default=False, | ||
) | ||
@click.option( | ||
"-s", | ||
"--sim-backend", | ||
is_flag=True, | ||
help="Connect to a sim backend, this initializes all device objects but does not " | ||
"attempt any I/O. Useful as a a dry-run.", | ||
default=False, | ||
) | ||
def connect(beamline: str, all: bool, sim_backend: bool) -> None: | ||
"""Initialises a beamline module, connects to all devices, reports | ||
any connection issues.""" | ||
|
||
os.environ["BEAMLINE"] = beamline | ||
|
||
module_name = module_name_for_beamline(beamline) | ||
full_module_path = f"dodal.beamlines.{module_name}" | ||
|
||
# We need to make a RunEngine to allow ophyd-async devices to connect. | ||
# See https://blueskyproject.io/ophyd-async/main/explanations/event-loop-choice.html | ||
RunEngine() | ||
|
||
print(f"Attempting connection to {beamline} (using {full_module_path})") | ||
devices = make_all_devices( | ||
full_module_path, | ||
include_skipped=all, | ||
fake_with_ophyd_sim=sim_backend, | ||
) | ||
sim_statement = "sim mode" if sim_backend else "" | ||
print(f"{len(devices)} devices connected ({sim_statement}): ") | ||
print("\n".join([f"\t{key}" for key in devices.keys()])) |
Empty file.
File renamed without changes.
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
3 changes: 1 addition & 2 deletions
3
src/dodal/beamlines/_device_helpers.py → src/dodal/common/beamlines/device_helpers.py
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
Oops, something went wrong.