diff --git a/.copier-answers.yml b/.copier-answers.yml index e3d184b..031c161 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: 2.3.0 +_commit: 2.5.0 _src_path: gh:diamondlightsource/python-copier-template author_email: giles.knap@diamond.ac.uk author_name: Giles Knap diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c5e850a..1057d4c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.3.0/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.5.0/how-to.html). diff --git a/.github/pages/make_switcher.py b/.github/pages/make_switcher.py index dbf8acc..c06813a 100755 --- a/.github/pages/make_switcher.py +++ b/.github/pages/make_switcher.py @@ -1,12 +1,14 @@ +"""Make switcher.json to allow docs to switch between different versions.""" + import json import logging from argparse import ArgumentParser from pathlib import Path from subprocess import CalledProcessError, check_output -from typing import Optional def report_output(stdout: bytes, label: str) -> list[str]: + """Print and return something received frm stdout.""" ret = stdout.decode().strip().split("\n") print(f"{label}: {ret}") return ret @@ -24,7 +26,7 @@ def get_sorted_tags_list() -> list[str]: return report_output(stdout, "Tags list") -def get_versions(ref: str, add: Optional[str]) -> list[str]: +def get_versions(ref: str, add: str | None) -> list[str]: """Generate the file containing the list of all GitHub Pages builds.""" # Get the directories (i.e. builds) from the GitHub Pages branch try: @@ -53,14 +55,12 @@ def get_versions(ref: str, add: Optional[str]) -> list[str]: return versions -def write_json(path: Path, repository: str, versions: str): +def write_json(path: Path, repository: str, versions: list[str]): + """Write the JSON switcher to path.""" org, repo_name = repository.split("/") - pages_url = f"https://{org}.github.io" - if repo_name != f"{org}.github.io": - # Only add the repo name if it isn't the source for the org pages site - pages_url += f"/{repo_name}" struct = [ - {"version": version, "url": f"{pages_url}/{version}/"} for version in versions + {"version": version, "url": f"https://{org}.github.io/{repo_name}/{version}/"} + for version in versions ] text = json.dumps(struct, indent=2) print(f"JSON switcher:\n{text}") @@ -68,6 +68,7 @@ def write_json(path: Path, repository: str, versions: str): def main(args=None): + """Parse args and write switcher.""" parser = ArgumentParser( description="Make a versions.json file from gh-pages directories" ) diff --git a/.github/workflows/_pypi.yml b/.github/workflows/_pypi.yml index 0c5258d..8032bba 100644 --- a/.github/workflows/_pypi.yml +++ b/.github/workflows/_pypi.yml @@ -15,3 +15,5 @@ jobs: - name: Publish to PyPI using trusted publishing uses: pypa/gh-action-pypi-publish@release/v1 + with: + attestations: false diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index 10d8ed8..81b6264 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -23,7 +23,7 @@ jobs: - name: Create GitHub Release # We pin to the SHA, not the tag, for security reasons. # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8 + uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9 with: prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }} files: "*" diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 36d8f50..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Debug Unit Test", - "type": "debugpy", - "request": "launch", - "justMyCode": false, - "program": "${file}", - "purpose": [ - "debug-test" - ], - "console": "integratedTerminal", - "env": { - // Enable break on exception when debugging tests (see: tests/conftest.py) - "PYTEST_RAISE": "1", - }, - } - ] -} diff --git a/Dockerfile b/Dockerfile index c4404ec..35d2abf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # The devcontainer should use the developer target and run as root with podman # or docker with user namespaces. ARG PYTHON_VERSION=3.11 -FROM python:${PYTHON_VERSION} as developer +FROM python:${PYTHON_VERSION} AS developer # Add any system dependencies for the developer/build environment here RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/README.md b/README.md index cf97681..933dee4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![CI](https://github.com/epics-containers/builder2ibek/actions/workflows/ci.yml/badge.svg)](https://github.com/epics-containers/builder2ibek/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/epics-containers/builder2ibek/branch/main/graph/badge.svg)](https://codecov.io/gh/epics-containers/builder2ibek) [![PyPI](https://img.shields.io/pypi/v/builder2ibek.svg)](https://pypi.org/project/builder2ibek) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) # builder2ibek diff --git a/src/builder2ibek/__main__.py b/src/builder2ibek/__main__.py index 250b4c9..2179568 100644 --- a/src/builder2ibek/__main__.py +++ b/src/builder2ibek/__main__.py @@ -88,6 +88,5 @@ def beamline( raise typer.Exit(code=1) -# test with: python -m builder2ibek if __name__ == "__main__": cli() diff --git a/src/builder2ibek/convert.py b/src/builder2ibek/convert.py index 2943e26..b1db250 100644 --- a/src/builder2ibek/convert.py +++ b/src/builder2ibek/convert.py @@ -5,7 +5,6 @@ from typing import Any from builder2ibek.builder import Builder, Element -from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.moduleinfos import module_infos from builder2ibek.types import Entity, Generic_IOC @@ -51,27 +50,23 @@ def do_one_element(element: Element, ioc: Generic_IOC): # then dispatch to a specific handler if there is one assert isinstance(element, Element) - if element.module in module_infos: - info = module_infos[element.module] - entity.type = f"{info.yaml_component}.{element.name}" - - new_xml = globalHandler(entity, element.name, ioc, info.handler) - if new_xml: - handle_new_xml(new_xml, entity, ioc, info) - else: - new_xml = globalHandler(entity, element.name, ioc) - if new_xml: - handle_new_xml(new_xml, entity, ioc) + info = ( + module_infos[element.module] + if element.module in module_infos + else module_infos["generic"] + ) -def handle_new_xml(new_xml: str, entity: Entity, ioc: Generic_IOC, info=None): - new_builder = Builder() - new_builder.load_string(new_xml) - ioc.entities.remove(entity) - do_dispatch(new_builder, ioc) + entity.type = f"{info.yaml_component}.{element.name}" + new_xml = info.handler(entity, element.name, ioc) + if new_xml: + new_builder = Builder() + new_builder.load_string(new_xml) + ioc.entities.remove(entity) + do_dispatch(new_builder, ioc) if entity.is_deleted(): ioc.entities.remove(entity) - if not entity.is_deleted() and info: + else: add_defaults(entity, info.defaults) diff --git a/src/builder2ibek/converters/ADAravis.py b/src/builder2ibek/converters/ADAravis.py index 107888f..9c609ec 100644 --- a/src/builder2ibek/converters/ADAravis.py +++ b/src/builder2ibek/converters/ADAravis.py @@ -1,3 +1,4 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = ["aravisGigE", "ADAravis"] @@ -5,6 +6,7 @@ yaml_component = "ADAravis" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): if entity_type == "aravisCamera": entity.remove("PV_ALIAS") diff --git a/src/builder2ibek/converters/ADZMQ.py b/src/builder2ibek/converters/ADZMQ.py index 81c3ebd..7f02a48 100644 --- a/src/builder2ibek/converters/ADZMQ.py +++ b/src/builder2ibek/converters/ADZMQ.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "ADZMQ" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/src/builder2ibek/converters/BL20J.py b/src/builder2ibek/converters/BL20J.py index 55c88b7..714b40a 100644 --- a/src/builder2ibek/converters/BL20J.py +++ b/src/builder2ibek/converters/BL20J.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "BL20J" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/src/builder2ibek/converters/BL46P-BUILDER.py b/src/builder2ibek/converters/BL46P-BUILDER.py index 920ecb2..c6c6571 100644 --- a/src/builder2ibek/converters/BL46P-BUILDER.py +++ b/src/builder2ibek/converters/BL46P-BUILDER.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "BL46P-BUILDER" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function diff --git a/src/builder2ibek/converters/adUtil.py b/src/builder2ibek/converters/adUtil.py index 2f3dfe9..bf196a7 100644 --- a/src/builder2ibek/converters/adUtil.py +++ b/src/builder2ibek/converters/adUtil.py @@ -4,6 +4,7 @@ import ruamel.yaml as yaml +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "adUtil" @@ -13,6 +14,7 @@ GDA_PLUGINS = Path(__file__).parent / "gdaPlugins.yaml" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): if entity_type == "gdaPlugins": ioc.entities.remove(entity) diff --git a/src/builder2ibek/converters/autosave.py b/src/builder2ibek/converters/autosave.py index b469d59..e4cceff 100644 --- a/src/builder2ibek/converters/autosave.py +++ b/src/builder2ibek/converters/autosave.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "autosave" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/src/builder2ibek/converters/deviocstats.py b/src/builder2ibek/converters/deviocstats.py index e8dafdb..54cf133 100644 --- a/src/builder2ibek/converters/deviocstats.py +++ b/src/builder2ibek/converters/deviocstats.py @@ -1,3 +1,4 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "devIocStats" @@ -12,6 +13,7 @@ } +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): if ( entity_type == "devIocStatsHelper" or entity_type == "iocAdminSoft" diff --git a/src/builder2ibek/converters/digitelMpc.py b/src/builder2ibek/converters/digitelMpc.py index d8e6ec7..6285666 100644 --- a/src/builder2ibek/converters/digitelMpc.py +++ b/src/builder2ibek/converters/digitelMpc.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "digitelMpc" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pmac support module diff --git a/src/builder2ibek/converters/dlsPLC.py b/src/builder2ibek/converters/dlsPLC.py index 99223d1..6ebd561 100644 --- a/src/builder2ibek/converters/dlsPLC.py +++ b/src/builder2ibek/converters/dlsPLC.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "dlsPLC" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pmac support module diff --git a/src/builder2ibek/converters/epics_base.py b/src/builder2ibek/converters/epics_base.py index 464f681..3ee93d7 100644 --- a/src/builder2ibek/converters/epics_base.py +++ b/src/builder2ibek/converters/epics_base.py @@ -1,9 +1,11 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "EPICS_BASE" yaml_component = "epics" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): if entity_type == "EpicsEnvSet": if entity["key"] == "EPICS_CA_MAX_ARRAY_BYTES": diff --git a/src/builder2ibek/converters/ffmpegServer.py b/src/builder2ibek/converters/ffmpegServer.py index e21ea0c..1a4f89b 100644 --- a/src/builder2ibek/converters/ffmpegServer.py +++ b/src/builder2ibek/converters/ffmpegServer.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "ffmpegServer" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/src/builder2ibek/converters/globalHandler.py b/src/builder2ibek/converters/globalHandler.py index 1ce1aa3..8ba72ca 100644 --- a/src/builder2ibek/converters/globalHandler.py +++ b/src/builder2ibek/converters/globalHandler.py @@ -1,13 +1,23 @@ -from builder2ibek.types import Entity, Generic_IOC +xml_component = "generic" -xml_component = "global" - -def globalHandler( - entity: Entity, entity_type: str, ioc: Generic_IOC, target_handler=None -): +def handler(entity, entity_type, ioc, realHandler=None): + """ + Generic/global entity handler + """ entity.remove("gda_name") entity.remove("gda_desc") - if target_handler: - return target_handler(entity, entity_type, ioc) + if realHandler: + return realHandler(entity, entity_type, ioc) + else: + return None + + +def globalHandler(realHandler): + """ + Decorator for generic/global handler + """ + return lambda entity, entity_type, ioc: handler( + entity, entity_type, ioc, realHandler + ) diff --git a/src/builder2ibek/converters/mks937a.py b/src/builder2ibek/converters/mks937a.py index daef4a2..34ab984 100644 --- a/src/builder2ibek/converters/mks937a.py +++ b/src/builder2ibek/converters/mks937a.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "mks937a" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pmac support module diff --git a/src/builder2ibek/converters/pmac.py b/src/builder2ibek/converters/pmac.py index b4123a3..3308b9e 100644 --- a/src/builder2ibek/converters/pmac.py +++ b/src/builder2ibek/converters/pmac.py @@ -2,6 +2,7 @@ The convertor handler module for pmac support module """ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC # The prefix for Builder XML Tags that this support module uses @@ -16,6 +17,7 @@ ) +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pmac support module diff --git a/src/builder2ibek/converters/pvlogging.py b/src/builder2ibek/converters/pvlogging.py index 93186f1..2c23064 100644 --- a/src/builder2ibek/converters/pvlogging.py +++ b/src/builder2ibek/converters/pvlogging.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "pvlogging" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/src/builder2ibek/converters/records.py b/src/builder2ibek/converters/records.py index b7dd77a..0a60ed9 100644 --- a/src/builder2ibek/converters/records.py +++ b/src/builder2ibek/converters/records.py @@ -1,8 +1,10 @@ +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.types import Entity, Generic_IOC xml_component = "records" +@globalHandler def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ XML to YAML specialist convertor function for the pvlogging support module diff --git a/tests/samples/BL45P-MO-IOC-01.xml b/tests/samples/BL45P-MO-IOC-01.xml index 14cb66e..2ca672c 100644 --- a/tests/samples/BL45P-MO-IOC-01.xml +++ b/tests/samples/BL45P-MO-IOC-01.xml @@ -4,7 +4,7 @@ - + diff --git a/tests/samples/xml2yaml.yaml b/tests/samples/xml2yaml.yaml new file mode 100644 index 0000000..d511517 --- /dev/null +++ b/tests/samples/xml2yaml.yaml @@ -0,0 +1,319 @@ +# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json + +ioc_name: "{{ __utils__.get_env('IOC_NAME') }}" + +description: auto-generated by https://github.com/epics-containers/builder2ibek + +entities: + + - type: epics.EpicsEnvSet + name: EPICS_TS_MIN_WEST + value: '0' + + - type: devIocStats.iocAdminSoft + IOC: '{{ ioc_name | upper }}' + + - type: epics.EpicsCaMaxArrayBytes + max_bytes: 6000000 + + - type: pmac.pmacAsynIPPort + IP: 172.23.59.21:1025 + name: BRICK1port + + - type: pmac.GeoBrick + P: BL45P-MO-STEP-01 + name: BRICK1 + pmacAsynPort: BRICK1port + + - type: pmac.pmacDisableLimitsCheck + Axis: 2 + Controller: BRICK1 + + - type: pmac.pmacDisableLimitsCheck + Axis: 3 + Controller: BRICK1 + + - type: pmac.pmacDisableLimitsCheck + Axis: 4 + Controller: BRICK1 + + - type: pmac.pmacDisableLimitsCheck + Axis: 5 + Controller: BRICK1 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 2 + Controller: BRICK1 + DESC: Theta top + DHLM: 10000000 + DIR: Pos + DLLM: -10000000 + EGU: deg + FOFF: Variable + HOMEVISSTR: Absolute Encoder + M: :THETA:TOP + MRES: 0.087890625 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 1 + UEIP: No + VELO: 90 + VMAX: '1080' + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 3 + Controller: BRICK1 + DESC: Theta bottom + DHLM: 10000000 + DIR: Pos + DLLM: -10000000 + EGU: deg + FOFF: Variable + HOMEVISSTR: Absolute Encoder + M: :THETA:BOT + MRES: 0.087890625 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 1 + UEIP: No + VELO: 90 + VMAX: '1080' + + - type: pmac.dls_pmac_asyn_motor + ADDR: 4 + Controller: BRICK1 + DESC: Hor EnDat chopper + DHLM: 10000000 + DIR: Pos + DLLM: -10000000 + EGU: deg + FOFF: Variable + HOMEVIS: 0 + HOMEVISSTR: Absolute Encoder + M: :ENDAT + MRES: 4.3e-05 + P: BL45P-MO-CHOP-01 + PREC: 5 + TWV: 1 + UEIP: No + VELO: 43 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.01 + ADDR: 5 + Controller: BRICK1 + DESC: Ver Biss chopper + DHLM: 10000000 + DIR: Pos + DLLM: -10000000 + EGU: deg + ERES: '' + FOFF: Variable + HOMEVIS: 0 + HOMEVISSTR: Absolute Encoder + M: :BISS + MRES: 0.000687 + P: BL45P-MO-CHOP-01 + PREC: 5 + TWV: 1 + UEIP: No + VELO: 720 + + - type: pmac.dls_pmac_asyn_motor + ADDR: 6 + Controller: BRICK1 + DESC: Sample X + DHLM: 19 + DIR: Pos + DLLM: 0 + EGU: mm + FOFF: Variable + M: :X + MRES: 0.0001 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 1 + UEIP: No + VELO: 5 + + - type: pmac.dls_pmac_asyn_motor + ADDR: 7 + Controller: BRICK1 + DESC: Sample Y top + DHLM: 4 + DIR: Pos + DLLM: -1 + EGU: mm + FOFF: Variable + M: :Y:TOP + MRES: 0.0005 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 1 + UEIP: No + VELO: 5 + + - type: pmac.dls_pmac_asyn_motor + ADDR: 8 + Controller: BRICK1 + DESC: Sample Y bottom + DHLM: 4 + DIR: Pos + DLLM: -1 + EGU: mm + FOFF: Variable + M: :Y:BOT + MRES: 0.0005 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 1 + UEIP: No + VELO: 5 + + - type: pmac.autohome + GRP2: Theta + GRP3: X + GRP4: Y top + GRP5: Y bottom + P: BL45P-MO-STAGE-01 + PLC: 10 + PmacController: BRICK1 + + - type: pmac.CS + CS: 1 + IdlePoll: 1000 + PmacController: BRICK1 + name: BRICK1.CS1 + + - type: pmac.CS + CS: 2 + IdlePoll: 1000 + PmacController: BRICK1 + name: BRICK1.CS2 + + - type: pmac.CS + CS: 3 + IdlePoll: 1000 + PmacController: BRICK1 + name: BRICK1.CS3 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 7 + Controller: BRICK1.CS2 + DESC: Theta position + DHLM: 10000 + DIR: Pos + DLLM: -10000 + EGU: deg + FOFF: Variable + M: :THETA:POS + MRES: 0.0001 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 5 + UEIP: No + VELO: 30 + is_cs: true + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 8 + Controller: BRICK1.CS2 + DESC: Theta skew + DHLM: 360 + DIR: Pos + DLLM: -360 + EGU: deg + FOFF: Variable + M: :THETA:SKEW + MRES: 0.0001 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 5 + UEIP: No + VELO: 10 + is_cs: true + + - type: pmac.dls_pmac_asyn_motor + ADDR: 7 + Controller: BRICK1.CS3 + DESC: CS Y + DHLM: 4 + DIR: Pos + DLLM: -1 + EGU: mm + FOFF: Variable + M: :CS:Y + MRES: 0.0001 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 0.5 + UEIP: No + VELO: 5 + is_cs: true + + - type: pmac.dls_pmac_asyn_motor + ADDR: 8 + Controller: BRICK1.CS3 + DESC: CS Y stretch + DHLM: 2 + DIR: Pos + DLLM: -2 + EGU: mm + FOFF: Variable + M: :CS:Y:STRETCH + MRES: 0.0001 + P: BL45P-MO-STAGE-01 + PREC: 3 + TWV: 0.5 + UEIP: No + VELO: 5 + is_cs: true + + - type: pmac.GeoBrickTrajectoryControl + NPOINTS: 500000 + PmacController: BRICK1 + + - type: pmac.pmacCreateCsGroup + AxisCount: 9 + Controller: BRICK1 + GroupName: Default + GroupNumber: 0 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 2 + Controller: BRICK1 + CoordSysNumber: 2 + GroupNumber: 0 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 3 + Controller: BRICK1 + CoordSysNumber: 2 + GroupNumber: 0 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: Z + AxisNumber: 6 + Controller: BRICK1 + CoordSysNumber: 3 + GroupNumber: 0 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 7 + Controller: BRICK1 + CoordSysNumber: 3 + GroupNumber: 0 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 8 + Controller: BRICK1 + CoordSysNumber: 3 + GroupNumber: 0