From 01f67c3a052274e3ea5844b9c51f9e6a6edc1d93 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 01/42] feature: add new service taupct --- docs/ioc/ioc_overview.md | 1 + services/taupct/current/app/pyproject.toml | 47 ++ .../current/app/src/agebd_taupct/__init__.py | 1 + .../current/app/src/agebd_taupct/main.py | 31 ++ .../current/app/src/agebd_taupct/service.py | 93 ++++ services/taupct/current/app/tests/test_app.py | 9 + services/taupct/current/app/uv.lock | 275 +++++++++ .../current/ioc/AGEBD-CPCL-TAUPCT_main.subs | 4 + .../ioc/AGEBD-CPCL-TAUPCT_parameters.yaml | 6 + services/taupct/current/ioc/TAUPCT.template | 70 +++ services/taupct/current/ioc/startup.script | 1 + .../taupct/current/qt/A_BD_LifetimePCT.ui | 527 ++++++++++++++++++ .../systemd/AGEBD-SERVICE-TAUPCT.service | 16 + 13 files changed, 1081 insertions(+) create mode 100644 services/taupct/current/app/pyproject.toml create mode 100644 services/taupct/current/app/src/agebd_taupct/__init__.py create mode 100644 services/taupct/current/app/src/agebd_taupct/main.py create mode 100644 services/taupct/current/app/src/agebd_taupct/service.py create mode 100644 services/taupct/current/app/tests/test_app.py create mode 100644 services/taupct/current/app/uv.lock create mode 100644 services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs create mode 100644 services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_parameters.yaml create mode 100644 services/taupct/current/ioc/TAUPCT.template create mode 100644 services/taupct/current/ioc/startup.script create mode 100644 services/taupct/current/qt/A_BD_LifetimePCT.ui create mode 100644 services/taupct/current/systemd/AGEBD-SERVICE-TAUPCT.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 5d5d558..cad0d2d 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,3 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | +| AGEBD-CPCL-TAUPCT | | diff --git a/services/taupct/current/app/pyproject.toml b/services/taupct/current/app/pyproject.toml new file mode 100644 index 0000000..cf97407 --- /dev/null +++ b/services/taupct/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-taupct" +version = "0.1.0" +description = "AGEBD-TAUPCT Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/taupct/current/app/src/agebd_taupct/__init__.py b/services/taupct/current/app/src/agebd_taupct/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/taupct/current/app/src/agebd_taupct/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py new file mode 100644 index 0000000..64fb8a6 --- /dev/null +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_taupct import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TAUPCT" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/taupct/current/app/src/agebd_taupct/service.py b/services/taupct/current/app/src/agebd_taupct/service.py new file mode 100644 index 0000000..b1d2135 --- /dev/null +++ b/services/taupct/current/app/src/agebd_taupct/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TAUPCT:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TAUPCT:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TAUPCT:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/taupct/current/app/tests/test_app.py b/services/taupct/current/app/tests/test_app.py new file mode 100644 index 0000000..a8bf6c4 --- /dev/null +++ b/services/taupct/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_taupct import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/taupct/current/app/uv.lock b/services/taupct/current/app/uv.lock new file mode 100644 index 0000000..5a4fc6b --- /dev/null +++ b/services/taupct/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-taupct" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs new file mode 100644 index 0000000..f25a3bd --- /dev/null +++ b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs @@ -0,0 +1,4 @@ +file TAUPCT.template { + pattern { DEVICE } + { AGEBD-TAUPCT } +} \ No newline at end of file diff --git a/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_parameters.yaml b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/taupct/current/ioc/TAUPCT.template b/services/taupct/current/ioc/TAUPCT.template new file mode 100644 index 0000000..e984743 --- /dev/null +++ b/services/taupct/current/ioc/TAUPCT.template @@ -0,0 +1,70 @@ +record(ao, "$(DEVICE):CONTROL-NSAMPLES-FIT-TAU") { + field(DESC, "Nr. of charge points for TAU fit") + field(VAL, "60") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-NSAMPLES-FIT-ROC") { + field(DESC, "Nr. of charge points for ROC fit") + field(VAL, "5") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-MIN-CURR") { + field(DESC, "Minimum current") + field(VAL, "0.1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):TAU") { + field(DESC, "PCT injection rate") + field(PREC, "3") + field(EGU, "hours") +} + +record(ao, "$(DEVICE):TAU-ERR") { + field(DESC, "PCT injection rate error") + field(PREC, "3") + field(EGU, "hours") +} + +record(ao, "$(DEVICE):INJRATE") { + field(DESC, "PCT injection rate") + field(PREC, "3") + field(EGU, "mA/min") + field(FLNK, "$(DEVICE):INJRATE-nC") +} + +record(ao, "$(DEVICE):INJRATE-ERR") { + field(DESC, "PCT injection rate error") + field(PREC, "3") + field(EGU, "mA/min") + field(FLNK, "$(DEVICE):INJRATE-ERR-nC") +} + +record(calc, "$(DEVICE):INJRATE-nC") { + field(DESC, "Rate der Akkumulation im Speicherring") + field(ASG, "READONLY") + field(PREC, "3") + field(EGU, "nC/shot") + field(CALC, "A / 60 / 3.125 * 0.96") + field(INPA, "$(DEVICE):INJRATE") +} + +record(calc, "$(DEVICE):INJRATE-ERR-nC") { + field(DESC, "Fehler der Injektionsrate Speicherring") + field(ASG, "READONLY") + field(PREC, "3") + field(EGU, "nC/shot") + field(CALC, "A / 60 / 3.125 * 0.96") + field(INPA, "$(DEVICE):INJRATE-ERR") +} + +record(calc, "$(DEVICE):LOSSRATIO") { + field(DESC, "Lossratio now to nominal 400 mA, 10 h") + field(ASG, "READONLY") + field(PREC, "3") + field(CALC, "(I / B) / 50") # = (strom / e / tau) / (400 / e / 10) + field(INPB, "$(DEVICE):TAU CP") + field(INPI, "ARS07-DPCT-0000:CURR") +} \ No newline at end of file diff --git a/services/taupct/current/ioc/startup.script b/services/taupct/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/taupct/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/taupct/current/qt/A_BD_LifetimePCT.ui b/services/taupct/current/qt/A_BD_LifetimePCT.ui new file mode 100644 index 0000000..8ab773b --- /dev/null +++ b/services/taupct/current/qt/A_BD_LifetimePCT.ui @@ -0,0 +1,527 @@ + + + MainWindow + + + + 0 + 0 + 570 + 260 + + + + MainWindow + + + + + + 10 + 60 + 260 + 30 + + + + Nr. of points for Lifetime fit + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 140 + 260 + 30 + + + + Minimum Current + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 180 + 260 + 30 + + + + Lifetime + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 280 + 180 + 120 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TAUPCT:TAU + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 440 + 180 + 120 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TAUPCT:TAU-ERR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 410 + 180 + 21 + 30 + + + + ± + + + Qt::AlignCenter + + + + + + 280 + 220 + 120 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TAUPCT:INJRATE + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 440 + 220 + 120 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TAUPCT:INJRATE-ERR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 410 + 220 + 21 + 30 + + + + ± + + + Qt::AlignCenter + + + + + + 660 + 130 + 70 + 20 + + + + + + + 660 + 70 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:TAUPCT-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 10 + 220 + 260 + 30 + + + + Injection rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 280 + 60 + 280 + 30 + + + + AGEBD-TAUPCT:CONTROL-NSAMPLES-FIT-TAU + + + caLineEdit::User + + + + + + 280 + 140 + 280 + 30 + + + + AGEBD-TAUPCT:CONTROL-MIN-CURR + + + 12 + + + caLineEdit::User + + + + + + 0 + 10 + 561 + 40 + + + + AGEBD-ALH:TAUPCT-ONOFF + + + caChoice::Column + + + 1 + + + + + + 280 + 100 + 280 + 30 + + + + AGEBD-TAUPCT:CONTROL-NSAMPLES-FIT-ROC + + + caLineEdit::User + + + + + + 10 + 100 + 260 + 30 + + + + Nr. of points for inj. rate fit + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + caChoice + QWidget +
caChoice
+
+ + caTextEntry + caLineEdit +
caTextEntry
+
+ + caLabel + QLabel +
caLabel
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 695 + 80 + + + 699 + 145 + + + + +
diff --git a/services/taupct/current/systemd/AGEBD-SERVICE-TAUPCT.service b/services/taupct/current/systemd/AGEBD-SERVICE-TAUPCT.service new file mode 100644 index 0000000..95c1241 --- /dev/null +++ b/services/taupct/current/systemd/AGEBD-SERVICE-TAUPCT.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TAUPCT +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TAUPCT +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TAUPCT.service +# systemctl --user start AGEBD-SERVICE-TAUPCT From 120575e29fd6c6416d2be4f41a348135a254af89 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 02/42] feature: add new service timing --- docs/ioc/ioc_overview.md | 2 +- services/timing/current/app/pyproject.toml | 47 + .../current/app/src/agebd_timing/__init__.py | 1 + .../current/app/src/agebd_timing/main.py | 31 + .../current/app/src/agebd_timing/service.py | 93 + services/timing/current/app/tests/test_app.py | 9 + services/timing/current/app/uv.lock | 275 + .../current/ioc/AGEBD-CPCL-TIMING_main.subs | 4 + .../ioc/AGEBD-CPCL-TIMING_parameters.yaml | 6 + services/timing/current/ioc/TIMING.template | 409 ++ services/timing/current/ioc/startup.script | 1 + services/timing/current/qt/A_BD_Timing.ui | 4571 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TIMING.service | 16 + 13 files changed, 5464 insertions(+), 1 deletion(-) create mode 100644 services/timing/current/app/pyproject.toml create mode 100644 services/timing/current/app/src/agebd_timing/__init__.py create mode 100644 services/timing/current/app/src/agebd_timing/main.py create mode 100644 services/timing/current/app/src/agebd_timing/service.py create mode 100644 services/timing/current/app/tests/test_app.py create mode 100644 services/timing/current/app/uv.lock create mode 100644 services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs create mode 100644 services/timing/current/ioc/AGEBD-CPCL-TIMING_parameters.yaml create mode 100644 services/timing/current/ioc/TIMING.template create mode 100644 services/timing/current/ioc/startup.script create mode 100644 services/timing/current/qt/A_BD_Timing.ui create mode 100644 services/timing/current/systemd/AGEBD-SERVICE-TIMING.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index cad0d2d..a27a863 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TAUPCT | | +| AGEBD-CPCL-TIMING | | diff --git a/services/timing/current/app/pyproject.toml b/services/timing/current/app/pyproject.toml new file mode 100644 index 0000000..7bad054 --- /dev/null +++ b/services/timing/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-timing" +version = "0.1.0" +description = "AGEBD-TIMING Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/timing/current/app/src/agebd_timing/__init__.py b/services/timing/current/app/src/agebd_timing/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/timing/current/app/src/agebd_timing/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py new file mode 100644 index 0000000..5312def --- /dev/null +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_timing import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TIMING" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/timing/current/app/src/agebd_timing/service.py b/services/timing/current/app/src/agebd_timing/service.py new file mode 100644 index 0000000..3f81c3e --- /dev/null +++ b/services/timing/current/app/src/agebd_timing/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TIMING:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TIMING:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TIMING:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/timing/current/app/tests/test_app.py b/services/timing/current/app/tests/test_app.py new file mode 100644 index 0000000..f058e5e --- /dev/null +++ b/services/timing/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_timing import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/timing/current/app/uv.lock b/services/timing/current/app/uv.lock new file mode 100644 index 0000000..d427488 --- /dev/null +++ b/services/timing/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-timing" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs b/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs new file mode 100644 index 0000000..d880674 --- /dev/null +++ b/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs @@ -0,0 +1,4 @@ +file TIMING.template { + pattern { DEVICE } + { AGEBD-TIMING } +} \ No newline at end of file diff --git a/services/timing/current/ioc/AGEBD-CPCL-TIMING_parameters.yaml b/services/timing/current/ioc/AGEBD-CPCL-TIMING_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/timing/current/ioc/AGEBD-CPCL-TIMING_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/timing/current/ioc/TIMING.template b/services/timing/current/ioc/TIMING.template new file mode 100644 index 0000000..a9bd791 --- /dev/null +++ b/services/timing/current/ioc/TIMING.template @@ -0,0 +1,409 @@ +############################### +## follow bucket flags +############################### + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-GUN") { + field(DESC, "Gun") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lindi-ictone") { + field(DESC, "Linac ICT 1/2") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lindi-icts23") { + field(DESC, "Linac ICT 3") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-llemast") { + field(DESC, "Linac RF LLE Master") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-preamp1") { + field(DESC, "Linac RF Preamp 1") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-preamp2") { + field(DESC, "Linac RF Preamp 2") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-klystr1") { + field(DESC, "Linac RF Klystron 1") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-klystr2") { + field(DESC, "Linac RF Klystron 2") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-3GHzQdm") { + field(DESC, "Linac RF 3GHz Qdm") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-500-PBU") { + field(DESC, "Linac RF 500 MHz PBU") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-3GHzScp") { + field(DESC, "Linac RF 3 GHz Scope") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-Kly1PMU") { + field(DESC, "Linac RF Klystron 1 PMU") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-lirf-Kly2PMU") { + field(DESC, "Linac RF Klystron 2 PMU") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BOINKI") { + field(DESC, "Booster Inj. Kicker") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BOINSE") { + field(DESC, "Booster Inj. Septum") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BOEXKI") { + field(DESC, "Booster Ext. Kicker") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BOEXSE") { + field(DESC, "Booster Ext. Septum") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BTRICT") { + field(DESC, "BRTL ICT") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-BTRBPM") { + field(DESC, "BRTL BPM") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-SRINSE") { + field(DESC, "Ring Inj. Septum") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-SRINK1") { + field(DESC, "Ring Inj. Kicker 1") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-SRINK2") { + field(DESC, "Ring Inj. Kicker 2") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-SRINK3") { + field(DESC, "Ring Inj. Kicker 3") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CONTROL-FLW-BCKT-SRINK4") { + field(DESC, "Ring Inj. Kicker 4") + field(ASG, "PROTECTED") + field(PINI, "YES") +} + +############################### +## base delays for bucket zero +############################### + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-GUN") { + field(DESC, "Gun delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lindi-ictone") { + field(DESC, "Linac ICT delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lindi-icts23") { + field(DESC, "Linac ICT delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-llemast") { + field(DESC, "Linac RF lemast delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-preamp1") { + field(DESC, "Linac RF reamp1 delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-preamp2") { + field(DESC, "Linac RF reamp2 delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-klystr1") { + field(DESC, "Linac RF lystr1 delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-klystr2") { + field(DESC, "Linac RF lystr2 delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-3GHzQdm") { + field(DESC, "Linac RF GHzQdm delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-500-PBU") { + field(DESC, "Linac RF 00-PBU delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-3GHzScp") { + field(DESC, "Linac RF GHzScp delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-Kly1PMU") { + field(DESC, "Linac RF ly1PMU delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-lirf-Kly2PMU") { + field(DESC, "Linac RF ly2PMU delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BOINKI") { + field(DESC, "Booster inj kicker delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BOINSE") { + field(DESC, "Booster inj sept delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BOEXKI") { + field(DESC, "Booster ext kicker delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BOEXSE") { + field(DESC, "Booster ext septum delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BTRICT") { + field(DESC, "BRTL ICT delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-BTRBPM") { + field(DESC, "BRTL BPM delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-SRINSE") { + field(DESC, "SR septum delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-SRINK1") { + field(DESC, "SR kicker bump delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-SRINK2") { + field(DESC, "SR kicker bump delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-SRINK3") { + field(DESC, "SR kicker bump delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZERO-DELAY-SRINK4") { + field(DESC, "SR kicker bump delay for bucket zero") + field(ASG, "PROTECTED") + field(PREC, "0") + field(PINI, "YES") +} + +############################### +## HLA pvs +############################### + +record(lso, "$(DEVICE):CONTROL-FILLPATTERN-string") { + field(DESC, "Fillpattern - String Define") + field(OMSL, "supervisory") + field(SIZV, "1000") + field(PINI, "YES") +} + +record(waveform,"$(DEVICE):TARGET-BUCKET") { + field(DESC, "Fillpattern - current bucket of 0...480") + field(ASG, "PROTECTED") + field(FTVL, "FLOAT") + field(NELM, "480") + field(PINI, "YES") +} + +record(waveform,"$(DEVICE):TARGET-FILLPATTERN") { + field(DESC, "Fillpattern reference plot") + field(ASG, "PROTECTED") + field(FTVL, "FLOAT") + field(NELM, "480") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):SETALL-DELAY") { + field(DESC, "Delay for setting all timings") + field(EGU, "seconds") + field(VAL, "0") + field(PREC, "5") + field(PINI, "YES") +} + +record(int64out, "$(DEVICE):SETALL-ERROR") { + field(DESC, "Error counter for setting all timings") + field(ASG, "PROTECTED") + field(VAL, "0") +} + +record(bo,"$(DEVICE):ZERO-TARGET-BUCKET") { + field(DESC, "request target bucket 0") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):SYNC-BASE-DELAYS") { + field(DESC, "request base delay sync to master") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):GO") { + field(DESC, "pause/stop timing service callbacks") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CURRENT-THRESHOLD") { + field(DESC, "current above which fpfb is started") + field(ASG, "PROTECTED") + field(EGU, "mA") + field(VAL, "300") + field(PREC, "5") + field(PINI, "YES") +} + +record(int64out, "$(DEVICE):FPFB-NTH") { + field(DESC, "n for every nth bucket fpfb mode") + field(ASG, "PROTECTED") + field(VAL, "2") + field(PINI, "YES") +} + +record(mbbo, "$(DEVICE):FPFB-MODE") { + field(DESC, "choice of fpfb mode to use") + field(ASG, "PROTECTED") + field(ZRST, "Sorted BPM Measurement") + field(ONST, "Sorted APD Measurement") + field(TWST, "FPFB from Pedro via EPICS") + field(THST, "Every Nth Bucket") + field(PINI, "YES") + field(VAL, "0") +} \ No newline at end of file diff --git a/services/timing/current/ioc/startup.script b/services/timing/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/timing/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/timing/current/qt/A_BD_Timing.ui b/services/timing/current/qt/A_BD_Timing.ui new file mode 100644 index 0000000..596cb26 --- /dev/null +++ b/services/timing/current/qt/A_BD_Timing.ui @@ -0,0 +1,4571 @@ + + + MainWindow + + + + 0 + 0 + 750 + 880 + + + + + + + (Qt::Window | Qt::FramelessWindowHint); + + + + + + 1390 + 270 + 70 + 20 + + + + + + + 1390 + 210 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:TIMING-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 10 + 20 + 161 + 31 + + + + + 18 + 75 + true + + + + Fillpattern + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 170 + 431 + 705 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 10 + 200 + 25 + + + + + 14 + + + + GUN + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 100 + 200 + 25 + + + + + 14 + + + + Linac - LLE Master + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 10 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-GUN + + + caSpinbox::User + + + true + + + 500.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 100 + 210 + 25 + + + + 6 + + + 3 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-llemast + + + caSpinbox::User + + + true + + + 5.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 400 + 200 + 25 + + + + + 14 + + + + Booster Inj Kicker + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 400 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINKI + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 430 + 200 + 25 + + + + + 14 + + + + Booster Inj Septum + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 430 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINSE + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 460 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXKI + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 460 + 200 + 25 + + + + + 14 + + + + Booster Ext Kicker + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 490 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXSE + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 490 + 200 + 25 + + + + + 14 + + + + Booster Ext Septum + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 550 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINSE + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 550 + 200 + 25 + + + + + 14 + + + + Ring Inj Septum + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 580 + 200 + 25 + + + + + 14 + + + + Ring Inj 4 Kicker K1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 520 + 200 + 25 + + + + + 14 + + + + ICT 4 (BRTL) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 520 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-BTRICT + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 190 + 200 + 25 + + + + + 14 + + + + Linac - Klystron 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 310 + 200 + 25 + + + + + 14 + + + + Linac - 3 GHz Scope + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 220 + 200 + 25 + + + + + 14 + + + + Linac - klystron 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 160 + 200 + 25 + + + + + 14 + + + + Linac - Preamp2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 130 + 200 + 25 + + + + + 14 + + + + Linac - Preamp1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 250 + 200 + 25 + + + + + 14 + + + + Linac - 3 GHz Qdm + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 340 + 200 + 25 + + + + + 14 + + + + Linac - Kly 1 PMU + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 280 + 200 + 25 + + + + + 14 + + + + Linac - 500 MHz_PBU + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 370 + 200 + 25 + + + + + 14 + + + + Linac - Kly 2 PMU + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 220 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr2 + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 310 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzScp + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 280 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-500-PBU + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 340 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly1PMU + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 190 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr1 + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 130 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp1 + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 250 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzQdm + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 160 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp2 + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 370 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly2PMU + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 40 + 200 + 25 + + + + + 14 + + + + ICT 1 & 2 (Linac) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 610 + 200 + 25 + + + + + 14 + + + + Ring Inj 4 Kicker K2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 640 + 200 + 25 + + + + + 14 + + + + Ring Inj 4 Kicker K3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 670 + 200 + 25 + + + + + 14 + + + + Ring Inj 4 Kicker K4 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 580 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK1 + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 610 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK2 + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 640 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK3 + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 670 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK4 + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 70 + 200 + 25 + + + + + 14 + + + + ICT 3 (LTB) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 210 + 40 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-ictone + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + 210 + 70 + 210 + 25 + + + + 6 + + + 0 + + + AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-icts23 + + + caSpinbox::User + + + true + + + 10000000.000000000000000 + + + 0.000000000000000 + + + + + + + 480 + 170 + 260 + 705 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-GUN:CH1-DLY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 100 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-A1-LLE-CTR:MASTER-DELF + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 400 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR0:SETUP.OT1D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 430 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR0:SETUP.OT0D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 460 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OT1D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 520 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIDI-CECL-DIAG:EEVR-EVENT2-PULSE-DELAY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 490 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OT0D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 550 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OT2D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 580 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OT3D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 130 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT0D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 160 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT1D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 190 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT2D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 220 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT3D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 250 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT4D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 340 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OTAD + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 280 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT5D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 370 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OTCD + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 310 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-EVR2:SETUP.OT6D + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 40 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIDI-CECL-DIAG:EEVR-EVENT0-PULSE-DELAY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 1000000.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 610 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OTBD + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 640 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OTCD + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 670 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ABOMA-VME-KY-EVR1:SETUP.OTDD + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 70 + 100 + 25 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIDI-CECL-DIAG:EEVR-EVENT1-PULSE-DELAY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 1000000.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 120 + 310 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 340 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 280 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 160 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 220 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 610 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 130 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 370 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 40 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 400 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 520 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 430 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 550 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 190 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 640 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 10 + 131 + 25 + + + + + 14 + + + + in 2 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 100 + 151 + 25 + + + + + 14 + + + + in us, 4 ns res + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 460 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 670 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 250 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 70 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 580 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 120 + 490 + 131 + 25 + + + + + 14 + + + + in 8 ns ticks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + + 10 + 50 + 411 + 30 + + + + + 9 + + + + space separated bucket ranges (e.g., 0-450) and single buckets + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::WidthAndHeight + + + + + + 550 + 10 + 100 + 60 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ALIRF-VME-A-GUN:CH1-DLY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 410 + 10 + 140 + 40 + + + + + 25 + 75 + true + + + + Bucket + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 440 + 170 + 41 + 705 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-GUN + + + + + + 10 + 100 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-llemast + + + + + + 10 + 400 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-BOINKI + + + + + + 10 + 430 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-BOINSE + + + + + + 10 + 460 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXKI + + + + + + 10 + 490 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXSE + + + + + + 10 + 520 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-BTRICT + + + + + + 10 + 550 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-SRINSE + + + + + + 10 + 670 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK4 + + + + + + 10 + 130 + 30 + 30 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp1 + + + + + + 10 + 250 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzQdm + + + + + + 10 + 280 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-500-PBU + + + + + + 10 + 160 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp2 + + + + + + 10 + 220 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr2 + + + + + + 10 + 310 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzScp + + + + + + 10 + 340 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly1PMU + + + + + + 10 + 190 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr1 + + + + + + 10 + 370 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly2PMU + + + + + + 10 + 40 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-ictone + + + + + + 10 + 70 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-icts23 + + + + + + 10 + 640 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK3 + + + + + + 10 + 610 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK2 + + + + + + 10 + 580 + 30 + 25 + + + + + + + + 30 + 30 + + + + false + + + AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK1 + + + catogglebutton_3 + catogglebutton_6 + catogglebutton_7 + catogglebutton_10 + catogglebutton_12 + catogglebutton_15 + catogglebutton_16 + catogglebutton_19 + catogglebutton_21 + catogglebutton_23 + catogglebutton_24 + catogglebutton_28 + catogglebutton_29 + catogglebutton_32 + catogglebutton_33 + catogglebutton_34 + catogglebutton_37 + catogglebutton_2 + catogglebutton + catogglebutton_5 + catogglebutton_20 + catogglebutton_22 + catogglebutton_25 + + + + + 571 + 75 + 80 + 25 + + + + + 13 + + + + Put Time + + + Qt::AlignCenter + + + ESimpleLabel::WidthAndHeight + + + + + + 661 + 80 + 80 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TIMING:SETALL-DELAY + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 5 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 660 + 105 + 80 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TIMING:SETALL-ERROR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 0 + + + caLineEdit::User + + + caLineEdit::Channel + + + 400.000000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + true + + + + 570 + 105 + 80 + 25 + + + + + 12 + + + + > 150 ms + + + Qt::AlignCenter + + + ESimpleLabel::WidthAndHeight + + + + + + 10 + 80 + 550 + 45 + + + + AGEBD-TIMING:CONTROL-FILLPATTERN-string.VAL + + + 0 + + + caLineEdit::User + + + caLineEdit::User + + + 479.000000000000000 + + + + + + 660 + 40 + 80 + 30 + + + + + 14 + + + + Reset + + + EPushButton::WidthAndHeight + + + AGEBD-TIMING:ZERO-TARGET-BUCKET + + + Reset + + + + 160 + 160 + 160 + + + + + 160 + 160 + 160 + + + + onoff + + + 0 + + + 1 + + + + + + 400 + 140 + 81 + 30 + + + + + 16 + 75 + true + + + + Follow + + + Qt::AlignCenter + + + + + + 10 + 140 + 271 + 30 + + + + + 15 + 75 + true + + + + Base Delays (Bucket 0) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 490 + 140 + 241 + 30 + + + + + 15 + 75 + true + + + + Changed EVR Delays + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 410 + 50 + 131 + 20 + + + + + + + + 183 + 157 + 92 + + + + Timing Master + + + /ioc/modules/qt/A_GE_TI_MASTER_control_expert.ui + + + SYS=AGETI-CVME-MASTER,DEVICE=EVG0,TMA=TMA,DBUFF=DBUFF230,EVT=12,LINAC=ALIRF-VME-A,DEV_LINAC=EVR2,PM=ABOMA-VME-KY,DEV_PM1=EVR0,DEV_PM2=EVR1;stylefile=/sls/controls/config/qt/slses.qss + + + caRelatedDisplay::as_is + + + + + + 310 + 130 + 70 + 20 + + + + onoff + + + + 0 + 0 + 0 + + + + + 192 + 192 + 192 + + + + !A + + + AGEBD-ALH:TIMING-ONOFF + + + + + + 660 + 10 + 80 + 30 + + + + + 14 + + + + Reset + + + EPushButton::WidthAndHeight + + + AGETI-CVME-MASTER-TMA:FP-Local-Reset-Bucket-SP + + + Reset + + + + 160 + 160 + 160 + + + + + 160 + 160 + 160 + + + + AGEBD-ALH:TIMING-ONOFF + + + 0 + + + 1 + + + frame + wmsignalpropagator + cacalc_2 + calabel + frame_2 + calabel_42 + caLineEdit_35 + calabel_43 + frame_3 + calabel_44 + caLineEdit_47 + caLineEdit_48 + calabel_49 + catextentry_5 + camessagebutton_39 + calabel_45 + calabel_5 + calabel_39 + carelateddisplay_20 + cacalc + camessagebutton_40 + + + + + caRelatedDisplay + QWidget +
caRelatedDisplay
+
+ + caTextEntry + caLineEdit +
caTextEntry
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 1220 + 224 + + + 1222 + 277 + + + + +
diff --git a/services/timing/current/systemd/AGEBD-SERVICE-TIMING.service b/services/timing/current/systemd/AGEBD-SERVICE-TIMING.service new file mode 100644 index 0000000..596bcec --- /dev/null +++ b/services/timing/current/systemd/AGEBD-SERVICE-TIMING.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TIMING +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TIMING +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TIMING.service +# systemctl --user start AGEBD-SERVICE-TIMING From 60b38249e0d3435248f1826235851c1d122c3291 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 03/42] feature: add new service scrubbing --- docs/ioc/ioc_overview.md | 2 +- services/scrubbing/current/app/pyproject.toml | 47 + .../app/src/agebd_scrubbing/__init__.py | 1 + .../current/app/src/agebd_scrubbing/main.py | 31 + .../app/src/agebd_scrubbing/service.py | 93 + .../scrubbing/current/app/tests/test_app.py | 9 + services/scrubbing/current/app/uv.lock | 275 + .../ioc/AGEBD-CPCL-SCRUBBING_main.subs | 4 + .../ioc/AGEBD-CPCL-SCRUBBING_parameters.yaml | 6 + .../scrubbing/current/ioc/SCRUBBING.template | 290 + services/scrubbing/current/ioc/startup.script | 1 + .../scrubbing/current/qt/A_BD_Scrubbing.ui | 5326 +++++++++++++++++ .../systemd/AGEBD-SERVICE-SCRUBBING.service | 16 + 13 files changed, 6100 insertions(+), 1 deletion(-) create mode 100644 services/scrubbing/current/app/pyproject.toml create mode 100644 services/scrubbing/current/app/src/agebd_scrubbing/__init__.py create mode 100644 services/scrubbing/current/app/src/agebd_scrubbing/main.py create mode 100644 services/scrubbing/current/app/src/agebd_scrubbing/service.py create mode 100644 services/scrubbing/current/app/tests/test_app.py create mode 100644 services/scrubbing/current/app/uv.lock create mode 100644 services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs create mode 100644 services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_parameters.yaml create mode 100644 services/scrubbing/current/ioc/SCRUBBING.template create mode 100644 services/scrubbing/current/ioc/startup.script create mode 100644 services/scrubbing/current/qt/A_BD_Scrubbing.ui create mode 100644 services/scrubbing/current/systemd/AGEBD-SERVICE-SCRUBBING.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index a27a863..1e81495 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TIMING | | +| AGEBD-CPCL-SCRUBBING | | diff --git a/services/scrubbing/current/app/pyproject.toml b/services/scrubbing/current/app/pyproject.toml new file mode 100644 index 0000000..f984959 --- /dev/null +++ b/services/scrubbing/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-scrubbing" +version = "0.1.0" +description = "AGEBD-SCRUBBING Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/__init__.py b/services/scrubbing/current/app/src/agebd_scrubbing/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/scrubbing/current/app/src/agebd_scrubbing/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py new file mode 100644 index 0000000..b92c9fc --- /dev/null +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_scrubbing import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "SCRUBBING" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/service.py b/services/scrubbing/current/app/src/agebd_scrubbing/service.py new file mode 100644 index 0000000..06d6f6d --- /dev/null +++ b/services/scrubbing/current/app/src/agebd_scrubbing/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-SCRUBBING:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-SCRUBBING:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-SCRUBBING:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/scrubbing/current/app/tests/test_app.py b/services/scrubbing/current/app/tests/test_app.py new file mode 100644 index 0000000..4e3b1a8 --- /dev/null +++ b/services/scrubbing/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_scrubbing import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/scrubbing/current/app/uv.lock b/services/scrubbing/current/app/uv.lock new file mode 100644 index 0000000..fadbe6f --- /dev/null +++ b/services/scrubbing/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-scrubbing" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs new file mode 100644 index 0000000..ec5596b --- /dev/null +++ b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs @@ -0,0 +1,4 @@ +file SCRUBBING.template { + pattern { DEVICE } + { AGEBD-SCRUBBING } +} \ No newline at end of file diff --git a/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_parameters.yaml b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/scrubbing/current/ioc/SCRUBBING.template b/services/scrubbing/current/ioc/SCRUBBING.template new file mode 100644 index 0000000..94ad8aa --- /dev/null +++ b/services/scrubbing/current/ioc/SCRUBBING.template @@ -0,0 +1,290 @@ +# HLA Service Control Parameters + +record(mbbo, "$(DEVICE):CONTROL-SCRUB") { + field(DESC, "Scrubbing Mode") + field(ASG, "PROTECTED") + field(ZRST, "Off") + field(ZRVL, "0") + field(ONST, "Vertical Pinger") + field(ONVL, "1") + field(TWST, "Horizontal Pingers") + field(TWVL, "2") + field(THST, "Both Pingers") + field(THVL, "3") + field(FRST, "Vertical MBFB") + field(FRVL, "4") + field(FVST, "Horizontal MBFB") + field(FVVL, "5") + field(SXST, "Both MBFBs") + field(SXVL, "6") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-MAX") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "PROTECTED") + field(EGU, "1e-9 mbar") + field(VAL, "360") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-MAX-PLOT") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-DYN") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "PROTECTED") + field(EGU, "1e-9 mbar") + field(VAL, "27") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-DYN-PLOT") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-DYN-FRAC") { + field(DESC, "Fraction defining dynamic pressure ") + field(ASG, "PROTECTED") + field(VAL, "1.2") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-MIN") { + field(DESC, "Start injection at this vacuum pressure") + field(ASG, "PROTECTED") + field(EGU, "1e-9 mbar") + field(VAL, "0") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-MIN-PLOT") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-MAX-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-MAX") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-DYN-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-DYN") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-MIN-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-MIN") +} + +record(ao, "$(DEVICE):CONTROL-CURRENT-MAX") { + field(DESC, "Stop injection at this current") + field(ASG, "PROTECTED") + field(EGU, "mA") + field(VAL, "403") + field(PREC, "3") + field(PINI, "YES") + field(DRVH, "425") + field(DRVL, "0") +} + +record(ao, "$(DEVICE):CONTROL-CURRENT-MIN") { + field(DESC, "Start injection at this current") + field(ASG, "PROTECTED") + field(EGU, "mA") + field(VAL, "400") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-TIME-MAX") { + field(DESC, "Stop injection after this time") + field(ASG, "PROTECTED") + field(EGU, "s") + field(VAL, "30") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-TIME-MIN") { + field(DESC, "Start injection after this time") + field(ASG, "PROTECTED") + field(EGU, "s") + field(VAL, "300") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):MBFBY-GAIN-SP") { + field(DESC, "MBFBy Gain SP for scrubbing") + field(ASG, "PROTECTED") + field(EGU, "%") + field(VAL, "1") + field(PREC, "3") + field(PINI, "YES") + field(DRVH, "100") + field(DRVL, "0") +} + +record(ao, "$(DEVICE):MBFBX-GAIN-SP") { + field(DESC, "MBFBx Gain SP for scrubbing") + field(ASG, "PROTECTED") + field(EGU, "%") + field(VAL, "1") + field(PREC, "3") + field(PINI, "YES") + field(DRVH, "100") + field(DRVL, "0") +} + +record(ao, "$(DEVICE):CONTROL-GUNGRID-ACCUM") { + field(DESC, "Gungrid val for accumulation") + field(ASG, "PROTECTED") + field(EGU, "V") + field(VAL, "100") + field(PREC, "3") + field(PINI, "YES") + field(DRVH, "180") + field(DRVL, "40") +} + +record(ao, "$(DEVICE):CONTROL-GUNGRID-FPFB") { + field(DESC, "Gungrid val for FPFB Injection") + field(ASG, "PROTECTED") + field(EGU, "V") + field(VAL, "160") + field(PREC, "3") + field(PINI, "YES") + field(DRVH, "180") + field(DRVL, "40") +} + +# HLA Service Output/Result Parameters + +record(ao, "$(DEVICE):TOPUP-TAU") { + field(DESC, "Average tau since last top up") + field(ASG, "PROTECTED") + field(EGU, "h") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):TOPUP-DELTAT") { + field(DESC, "Time since last top up") + field(ASG, "PROTECTED") + field(EGU, "min") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):TOPUP-DELTAI") { + field(DESC, "Current change since last top up") + field(ASG, "PROTECTED") + field(EGU, "mA") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOIN-SP") { + field(DESC, "Warmup cycles for booster injection") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOMB-SP") { + field(DESC, "Warmup cycles for ABOMA-B") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "5") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOME-SP") { + field(DESC, "Warmup cycles for ABOMA-ELSE") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOEX-SP") { + field(DESC, "Warmup cycles for booster extraction") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-SRIN-SP") { + field(DESC, "Warmup cycles for SR Injection") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOIN-RB") { + field(DESC, "Warmup cycles for booster injection") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOMB-RB") { + field(DESC, "Warmup cycles for ABOMA-B") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "5") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOME-RB") { + field(DESC, "Warmup cycles for ABOMA-ELSE") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-BOEX-RB") { + field(DESC, "Warmup cycles for booster extraction") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):WARMUPCYCLES-SRIN-RB") { + field(DESC, "Warmup cycles for SR Injection") + field(ASG, "PROTECTED") + field(EGU, "") + field(VAL, "15") + field(PREC, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/scrubbing/current/ioc/startup.script b/services/scrubbing/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/scrubbing/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/scrubbing/current/qt/A_BD_Scrubbing.ui b/services/scrubbing/current/qt/A_BD_Scrubbing.ui new file mode 100644 index 0000000..00f96bd --- /dev/null +++ b/services/scrubbing/current/qt/A_BD_Scrubbing.ui @@ -0,0 +1,5326 @@ + + + MainWindow + + + + 0 + 0 + 1500 + 1000 + + + + MainWindow + + + + + + 10 + 10 + 211 + 61 + + + + AGEBD-ALH:SCRUBBING-ONOFF + + + caChoice::Column + + + 1 + + + + + + 640 + 280 + 861 + 461 + + + + + 10 + 75 + true + + + + Vakuum (last 60 seconds) + + + + + + + + + ARIVA-VMAVE:PRESS-MAX;ARIVA-VMAVE-FE:PRESS-MAX;ARIVA-VMAVE-ALL:PRESS-MAX;AGEBD-SCRUBBING:CONTROL-VACUUM-MAX-PLOT;AGEBD-SCRUBBING:CONTROL-VACUUM-MIN-PLOT;AGEBD-SCRUBBING:CONTROL-VACUUM-DYN-PLOT + + + caStripPlot::Second + + + 60.000000000000000 + + + caStripPlot::High + + + caStripPlot::log10 + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 255 + 127 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + 260 + 40 + 350 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + ARIVA-VMAVE-ALL:PRESS-MAX + + + + 252 + 192 + 11 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::WidthAndHeight + + + true + + + caLineEdit::exponential + + + + + + 260 + 100 + 350 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + ARIVA-VMAVE:PRESS-MAX + + + + 255 + 255 + 127 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::WidthAndHeight + + + true + + + caLineEdit::exponential + + + + + + 70 + 40 + 190 + 50 + + + + + 31 + 50 + false + + + + Frontend + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 252 + 192 + 11 + + + + + + + 70 + 100 + 230 + 50 + + + + + 31 + 50 + false + + + + Machine + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 255 + 255 + 127 + + + + + + + + 1990 + 540 + 70 + 20 + + + + + + + 1980 + 360 + 71 + 20 + + + + RELOAD + + + Qt::AlignCenter + + + RELOAD + + + A + + + AGEBD-ALH:SCRUBBING-GUIRELOAD + + + caCalc::TriggerOneToZero + + + + + + 10 + 80 + 391 + 41 + + + + AGEBD-ALH:SCRUBBING-INFO + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 230 + 40 + 50 + 30 + + + + AGEBD-SCRUBBING:TOPUP-DELTAT + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 349 + 40 + 50 + 30 + + + + AGEBD-SCRUBBING:TOPUP-TAU + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 350 + 10 + 50 + 30 + + + + + 18 + 75 + true + + + + Tau + + + Qt::AlignCenter + + + + + + 290 + 10 + 50 + 30 + + + + + 18 + 75 + true + + + + dI + + + Qt::AlignCenter + + + + + + 230 + 10 + 50 + 30 + + + + + 18 + 75 + true + + + + dt + + + Qt::AlignCenter + + + + + + 290 + 40 + 50 + 30 + + + + AGEBD-SCRUBBING:TOPUP-DELTAI + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 5 + 450 + 631 + 291 + + + + Events, Trigger und Top-Up Save + + + + + 135 + 173 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 215 + 32 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 10 + 31 + 100 + 22 + + + + + Sans Serif + 13 + + + + true + + + Master + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 211 + 173 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 215 + 177 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 135 + 28 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=0 + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 139 + 177 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 10 + 176 + 100 + 22 + + + + + Sans Serif + 13 + + + + true + + + Booster Ext + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 211 + 28 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 139 + 32 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 139 + 119 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 10 + 118 + 121 + 22 + + + + + Sans Serif + 13 + + + + true + + + ABOMA-B + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 135 + 115 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 215 + 119 + 70 + 20 + + + + true + + + External + + + AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel + + + External + + + + 219 + 212 + 157 + + + + 1 + + + + + + 211 + 115 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 139 + 206 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 215 + 206 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 211 + 202 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 10 + 205 + 150 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Ring Inj + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 135 + 202 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 211 + 57 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 215 + 61 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 135 + 57 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 10 + 60 + 91 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Gun + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 139 + 61 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 139 + 90 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 215 + 90 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 135 + 86 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 211 + 86 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 10 + 89 + 111 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Booster Inj + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 95 + 28 + 28 + 28 + + + + true + + + false + + + 22 + + + 22 + + + AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER + + + caLed::Alarm + + + + + + 520 + 28 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Event-Seq-Cnt-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 520 + 86 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 520 + 115 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 520 + 173 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 520 + 202 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 520 + 231 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 135 + 231 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 139 + 235 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 211 + 231 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 215 + 235 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 10 + 234 + 101 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Hor. Pinger + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 520 + 260 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 10 + 263 + 101 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Ver. Pinger + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 139 + 264 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 215 + 264 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 135 + 260 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 211 + 260 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 10 + 147 + 121 + 22 + + + + + Sans Serif + 13 + + + + true + + + ABOMA-ELSE + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 135 + 144 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 139 + 148 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 211 + 144 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 520 + 144 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 215 + 148 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 520 + 57 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-LI-Gun-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 300 + 88 + 100 + 28 + + + + 2 + + + 0 + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-SP.VAL + + + caSpinbox::User + + + true + + + + + + 300 + 120 + 100 + 28 + + + + 2 + + + 0 + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-SP.VAL + + + caSpinbox::User + + + true + + + + + + 300 + 150 + 100 + 25 + + + + 2 + + + 0 + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOME-SP.VAL + + + caSpinbox::User + + + true + + + + + + 300 + 180 + 100 + 25 + + + + 2 + + + 0 + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-SP.VAL + + + caSpinbox::User + + + true + + + + + + 300 + 210 + 100 + 25 + + + + 2 + + + 0 + + + AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-SP.VAL + + + caSpinbox::User + + + true + + + + + + 300 + 30 + 100 + 41 + + + + + 9 + 75 + true + + + + Warmup Cycles +Setpoint + + + Qt::PlainText + + + Qt::AlignCenter + + + true + + + + + + 410 + 117 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-RB.VAL + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + + + + 410 + 88 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-RB.VAL + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + + + + 410 + 146 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOME-RB.VAL + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + + + + 410 + 204 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-RB.VAL + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + + + + 410 + 175 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-RB.VAL + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + + + + 410 + 30 + 100 + 41 + + + + + 9 + 75 + true + + + + Warmup Cycles +Remaining + + + Qt::AlignCenter + + + true + + + BOO_Ext_External_frame_8 + BOO_Ext_Disable_frame_8 + BOO_Ext_Disable_frame_5 + BOO_Ext_External_frame_5 + BOO_Ext_Disable_frame_4 + BOO_Ext_External_frame_4 + Inj_trig_Enable_frame + BOO_Ext_Disable_frame_2 + BOO_Ext_External_frame_2 + Inj_trig_Enable + Inj_trig_ + BOO_Ext_External_2 + Inj_trig_Disable_frame + BOO_Ext_Diasable_2 + BOO_Ext + Inj_trig_Disable + Gun_trig_2 + Gun_trig_Disable_frame_2 + Gun_trig_External_frame_2 + Gun_trig_External_2 + Gun_trig_Diasable_2 + BOO_Ext_Diasable_4 + BOO_Ext_External_4 + BOO_Ext_3 + BOO_Ext_External_frame_6 + BOO_Ext_External_6 + BOO_Ext_Disable_frame_6 + BOO_Ext_5 + BOO_Ext_Diasable_6 + BOO_Ext_Diasable_5 + BOO_Ext_External_5 + BOO_Ext_4 + caled_23 + calineedit + calineedit_4 + calineedit_6 + calineedit_7 + calineedit_8 + calineedit_9 + BOO_Ext_Disable_frame_7 + BOO_Ext_Diasable_7 + BOO_Ext_External_frame_7 + BOO_Ext_External_7 + BOO_Ext_6 + calineedit_10 + BOO_Ext_7 + BOO_Ext_Diasable_8 + BOO_Ext_External_8 + Gun_trig_3 + BOO_Ext_Disable_frame_3 + BOO_Ext_Diasable_3 + BOO_Ext_External_frame_3 + calineedit_13 + BOO_Ext_External_3 + calineedit_2 + caspinbox_10 + caspinbox_11 + caspinbox_12 + caspinbox_13 + caspinbox_14 + calabel_18 + calineedit_16 + calineedit_5 + calineedit_17 + calineedit_18 + calineedit_19 + calabel_19 + + + + + 420 + 750 + 1081 + 241 + + + + + + + ;AGEBD-TIMING:TARGET-BUCKET + + + caCartesianPlot::Sticks + + + + 0 + 255 + 0 + + + + ;X08DB-DFPM-DI:FW-SIS0DAQ-CH0-FPM-WF + + + caCartesianPlot::Sticks + + + + 255 + 170 + 255 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 255 + 255 + 255 + + + + + 160 + 160 + 160 + + + + caCartesianPlot::User + + + caCartesianPlot::User + + + 0;480 + + + 0;1.3 + + + true + + + false + + + 24 + + + + + + 5 + 750 + 410 + 241 + + + + Filling Pattern Feedback (FPFB) + + + + + 0 + 20 + 40 + 40 + + + + AGEBD-TIMING:GO + + + + 0 + 255 + 0 + + + + + + + 10 + 60 + 391 + 30 + + + + + 9 + + + + space separated bucket ranges (e.g., 0-450) and single buckets + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::WidthAndHeight + + + + + + 10 + 90 + 391 + 45 + + + + AGEBD-TIMING:CONTROL-FILLPATTERN-string.VAL + + + 0 + + + caLineEdit::User + + + caLineEdit::User + + + 479.000000000000000 + + + + + + 40 + 25 + 361 + 40 + + + + + 16 + 75 + true + + + + AGEBD-TIMING:FPFB-MODE + + + + + + 210 + 190 + 191 + 40 + + + + + 20 + + + + Reset + + + EPushButton::WidthAndHeight + + + AGEBD-TIMING:ZERO-TARGET-BUCKET + + + Reset + + + + 160 + 160 + 160 + + + + + 160 + 160 + 160 + + + + + + + + + + 1 + + + + + + 240 + 140 + 150 + 40 + + + + 3 + + + 0 + + + true + + + AGEBD-TIMING:CURRENT-THRESHOLD + + + caSpinbox::User + + + true + + + caSpinbox::Channel + + + + + + 10 + 190 + 80 + 40 + + + + + 25 + 75 + true + + + + Nth + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 90 + 190 + 111 + 40 + + + + 3 + + + 0 + + + AGEBD-TIMING:FPFB-NTH + + + caSpinbox::User + + + true + + + caSpinbox::Channel + + + + + + 10 + 140 + 211 + 40 + + + + + 18 + 75 + true + + + + FPFB Threshold + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + 5 + 130 + 530 + 140 + + + + Top-Up Grenzen + + + + + 220 + 95 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-SCRUBBING:CONTROL-CURRENT-MIN + + + caSpinbox::User + + + true + + + + + + 220 + 50 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-SCRUBBING:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 10 + 95 + 50 + 40 + + + + + 12 + 75 + true + + + + Start + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 50 + 50 + 40 + + + + + 13 + 75 + true + + + + Stop + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 70 + 95 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-SCRUBBING:CONTROL-VACUUM-MIN + + + caSpinbox::User + + + true + + + + + + 220 + 20 + 140 + 30 + + + + + 18 + 75 + true + + + + Strom + + + Qt::AlignCenter + + + + + + 70 + 20 + 140 + 30 + + + + + 18 + 75 + true + + + + Vakuum + + + Qt::AlignCenter + + + + + + 70 + 50 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-SCRUBBING:CONTROL-VACUUM-MAX + + + caSpinbox::User + + + true + + + + + + 370 + 20 + 140 + 30 + + + + + 18 + 75 + true + + + + Zeit + + + Qt::AlignCenter + + + + + + 370 + 50 + 140 + 40 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:CONTROL-TIME-MAX + + + caSpinbox::User + + + true + + + + + + 370 + 95 + 140 + 40 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:CONTROL-TIME-MIN + + + caSpinbox::User + + + true + + + + + + + 5 + 280 + 255 + 160 + + + + Gun Ladung + + + + + 50 + 20 + 211 + 40 + + + + + 20 + 75 + true + + + + Gun Grid + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 125 + 120 + 120 + 40 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:CONTROL-GUNGRID-FPFB + + + caSpinbox::User + + + true + + + + + + 125 + 70 + 120 + 40 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:CONTROL-GUNGRID-ACCUM + + + caSpinbox::User + + + true + + + + + + 5 + 70 + 110 + 40 + + + + + 12 + 75 + true + + + + Accumulate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 5 + 120 + 110 + 40 + + + + + 12 + 75 + true + + + + Top-Up + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + + 550 + 0 + 951 + 271 + + + + + 10 + 75 + true + + + + Beam Current (last 10 minutes) + + + + + + + + + ARS07-DPCT-0000:CURR;AGEBD-SCRUBBING:CONTROL-CURRENT-MAX;AGEBD-SCRUBBING:CONTROL-CURRENT-MIN + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + 11 + + + caStripPlot::linear + + + 404.000000000000000 + + + 399.000000000000000 + + + caStripPlot::User + + + caStripPlot::User + + + caStripPlot::Lines + + + + 0 + 255 + 0 + + + + 404.000000000000000 + + + 399.000000000000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 0 + + + + 404.000000000000000 + + + 399.000000000000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 0 + + + + 404.000000000000000 + + + 399.000000000000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + 60 + 30 + 250 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + ARS07-DPCT-0000:CURR + + + + 0 + 255 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::WidthAndHeight + + + true + + + + + + 660 + 30 + 250 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing + + + AGEBD-PARAMS:LIFETIME + + + + 0 + 255 + 255 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::WidthAndHeight + + + true + + + + + + 350 + 30 + 250 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + AGEBD-PARAMS:TRANSMISSION + + + + 255 + 170 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::Height + + + true + + + + + + + 410 + 30 + 120 + 40 + + + + + 12 + 75 + true + + + + Dyn Vac Frac + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 410 + 80 + 120 + 40 + + + + 1 + + + 2 + + + +AGEBD-SCRUBBING:CONTROL-VACUUM-DYN-FRAC + + + caSpinbox::User + + + true + + + + + + 270 + 280 + 360 + 180 + + + + Strahlwaschen + + + + + 10 + 60 + 340 + 35 + + + + + 16 + 75 + true + + + + AGEBD-SCRUBBING:CONTROL-SCRUB + + + + + + 10 + 20 + 191 + 40 + + + + + 20 + 75 + true + + + + Scrubbing + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 95 + 360 + 85 + + + + + 85 + 170 + 0 + + + + caFrame::Calc + + + A>3 + + + AGEBD-SCRUBBING:CONTROL-SCRUB + + + + + 230 + 45 + 100 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + true + + + + + + 65 + 45 + 100 + 35 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:MBFBY-GAIN-SP.VAL + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 230 + 5 + 100 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-X-DDS-FRQ + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + true + + + + + + 10 + 45 + 45 + 35 + + + + + 8 + 75 + true + + + + MBFBy + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 65 + 5 + 100 + 35 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING:MBFBX-GAIN-SP.VAL + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 5 + 45 + 35 + + + + + 8 + 75 + true + + + + MBFBx + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 175 + 45 + 45 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + false + + + + + + 175 + 5 + 45 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + false + + + + + + 335 + 5 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-03:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 23 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-04:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 45 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + ARSGE-MBFBT-AMP-01:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 63 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-02:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + + 0 + 95 + 360 + 85 + + + + + 85 + 170 + 0 + + + + caFrame::Calc + + + A<4 & A>0 + + + AGEBD-SCRUBBING:CONTROL-SCRUB + + + + + 70 + 45 + 150 + 35 + + + + 4 + + + 2 + + + ARS01-MKIK-0320:I-SET + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 45 + 50 + 35 + + + + + 10 + 75 + true + + + + PINGy + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 70 + 5 + 150 + 35 + + + + 4 + + + 2 + + + ARS01-MKIK-0290:I-SET + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 5 + 50 + 35 + + + + + 10 + 75 + true + + + + PINGx + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 230 + 5 + 35 + 35 + + + + + 35 + 35 + + + + ARS01-MKIK-0290:CTRL-ON-OFF + + + + + + 230 + 45 + 35 + 35 + + + + + 35 + 35 + + + + ARS01-MKIK-0320:CTRL-ON-OFF + + + + + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caTextEntry + caLineEdit +
caTextEntry
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caFrame + QFrame +
caFrame
+ 1 +
+ + caLabel + QLabel +
caLabel
+
+ + caGraphics + QWidget +
caGraphics
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 2020 + 374 + + + 2022 + 545 + + + + +
diff --git a/services/scrubbing/current/systemd/AGEBD-SERVICE-SCRUBBING.service b/services/scrubbing/current/systemd/AGEBD-SERVICE-SCRUBBING.service new file mode 100644 index 0000000..1bf2013 --- /dev/null +++ b/services/scrubbing/current/systemd/AGEBD-SERVICE-SCRUBBING.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-SCRUBBING +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh SCRUBBING +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-SCRUBBING.service +# systemctl --user start AGEBD-SERVICE-SCRUBBING From 250d90b7bb7562674655e9535c63c625ad4418d6 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 04/42] feature: add new service tunebump --- docs/ioc/ioc_overview.md | 2 +- services/tunebump/current/app/pyproject.toml | 47 + .../app/src/agebd_tunebump/__init__.py | 1 + .../current/app/src/agebd_tunebump/main.py | 31 + .../current/app/src/agebd_tunebump/service.py | 93 + .../tunebump/current/app/tests/test_app.py | 9 + services/tunebump/current/app/uv.lock | 275 + .../current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs | 4 + .../ioc/AGEBD-CPCL-TUNEBUMP_parameters.yaml | 6 + .../tunebump/current/ioc/TUNEBUMP.template | 493 ++ services/tunebump/current/ioc/startup.script | 1 + services/tunebump/current/qt/A_BD_TuneBump.ui | 6779 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TUNEBUMP.service | 16 + 13 files changed, 7756 insertions(+), 1 deletion(-) create mode 100644 services/tunebump/current/app/pyproject.toml create mode 100644 services/tunebump/current/app/src/agebd_tunebump/__init__.py create mode 100644 services/tunebump/current/app/src/agebd_tunebump/main.py create mode 100644 services/tunebump/current/app/src/agebd_tunebump/service.py create mode 100644 services/tunebump/current/app/tests/test_app.py create mode 100644 services/tunebump/current/app/uv.lock create mode 100644 services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs create mode 100644 services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_parameters.yaml create mode 100644 services/tunebump/current/ioc/TUNEBUMP.template create mode 100644 services/tunebump/current/ioc/startup.script create mode 100644 services/tunebump/current/qt/A_BD_TuneBump.ui create mode 100644 services/tunebump/current/systemd/AGEBD-SERVICE-TUNEBUMP.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 1e81495..1e9c4d1 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-SCRUBBING | | +| AGEBD-CPCL-TUNEBUMP | | diff --git a/services/tunebump/current/app/pyproject.toml b/services/tunebump/current/app/pyproject.toml new file mode 100644 index 0000000..e1009e9 --- /dev/null +++ b/services/tunebump/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-tunebump" +version = "0.1.0" +description = "AGEBD-TUNEBUMP Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/tunebump/current/app/src/agebd_tunebump/__init__.py b/services/tunebump/current/app/src/agebd_tunebump/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/tunebump/current/app/src/agebd_tunebump/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py new file mode 100644 index 0000000..092188a --- /dev/null +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_tunebump import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TUNEBUMP" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/tunebump/current/app/src/agebd_tunebump/service.py b/services/tunebump/current/app/src/agebd_tunebump/service.py new file mode 100644 index 0000000..f39cf83 --- /dev/null +++ b/services/tunebump/current/app/src/agebd_tunebump/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TUNEBUMP:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TUNEBUMP:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TUNEBUMP:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/tunebump/current/app/tests/test_app.py b/services/tunebump/current/app/tests/test_app.py new file mode 100644 index 0000000..ea2bb02 --- /dev/null +++ b/services/tunebump/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_tunebump import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/tunebump/current/app/uv.lock b/services/tunebump/current/app/uv.lock new file mode 100644 index 0000000..e28b4bb --- /dev/null +++ b/services/tunebump/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-tunebump" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs new file mode 100644 index 0000000..8e9d768 --- /dev/null +++ b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs @@ -0,0 +1,4 @@ +file TUNEBUMP.template { + pattern { DEVICE } + { AGEBD-TUNEBUMP } +} \ No newline at end of file diff --git a/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_parameters.yaml b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/tunebump/current/ioc/TUNEBUMP.template b/services/tunebump/current/ioc/TUNEBUMP.template new file mode 100644 index 0000000..b2bb298 --- /dev/null +++ b/services/tunebump/current/ioc/TUNEBUMP.template @@ -0,0 +1,493 @@ +#################################### +## USED BPMs +#################################### +# HORIZONTAL ARS01-DBPM-0760 (Im FOFB) +# ARS07-DBPM-0840 (BPMA) +# ---------------------------------- +# VERTICAL ARS09-DBPM-0570 (Im FOFB) +# ARS07-DBPM-5530 (BPMA) +# ---------------------------------- +# LONGITUDINAL ARS02-DBPM-2910 (Im FOFB) +# +#################################### + + +record(bo, "$(DEVICE):WRITE2MAG") { + field(DESC, "Only print or apply setpoints") + field(VAL, "1") + field(PINI, "YES") +} + +record(waveform,"$(DEVICE):CHANGELOG") { + field(DESC, "overview of to be applied changes") + field(FTVL, "UCHAR") + field(NELM, "$(SIZE=60000)") + field(PINI, "YES") +} + +record(calcout, "$(DEVICE):CALLBACK"){ + field(DESC, "1 if a tune step has been requested") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "A + B + C + D") + field(INPA, "$(DEVICE):QX-STEPUP") + field(INPB, "$(DEVICE):QX-STEPDOWN") + field(INPC, "$(DEVICE):QY-STEPUP") + field(INPD, "$(DEVICE):QY-STEPDOWN") +} + +record(ao, "$(DEVICE):QX-STEPSIZE"){ + field(DESC, "hor. tune step size, e.g. 0.0001") + field(VAL, "0.0001") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):QX-FIT"){ + field(DESC, "hor. tune from fit") + field(VAL, "0.0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):QX-STEPUP"){ + field(DESC, "request hor. tune step up") + field(FLNK, "$(DEVICE):CALLBACK") + field(VAL, "0") + field(PINI, "YES") + field(HIGH, "1") +} + +record(bo, "$(DEVICE):QX-STEPDOWN"){ + field(DESC, "request hor. tune step down") + field(FLNK, "$(DEVICE):CALLBACK") + field(VAL, "0") + field(PINI, "YES") + field(HIGH, "1") +} + +record(ao, "$(DEVICE):QY-STEPSIZE"){ + field(DESC, "ver. tune step size, e.g. 0.0001") + field(VAL, "0.0001") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):QY-FIT"){ + field(DESC, "ver. tune from fit") + field(VAL, "0.0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):QY-STEPUP"){ + field(DESC, "request ver. tune step up") + field(FLNK, "$(DEVICE):CALLBACK") + field(VAL, "0") + field(PINI, "YES") + field(HIGH, "1") +} + +record(bo, "$(DEVICE):QY-STEPDOWN"){ + field(DESC, "request ver. tune step down") + field(FLNK, "$(DEVICE):CALLBACK") + field(VAL, "0") + field(PINI, "YES") + field(HIGH, "1") +} + + +## spectra + +record (waveform, "$(DEVICE):SIGN-X"){ + field (DESC, "Copy of ARS07-DBPM-0840:DAQ-BEAM-STG0-X") + field (FTVL, "FLOAT") + field (NELM, "16384") + field (INP, "ARS07-DBPM-0840:DAQ-BEAM-STG0-X CP MS") + field (FLNK, "$(DEVICE):SPEC-X") + field (PREC, "6") +} + +record (waveform, "$(DEVICE):SPEC-X"){ + field (FTVL, "FLOAT") + field (DTYP, "FFT spsd") + field (NELM, "8193") + field (INP, "$(DEVICE):SIGN-X MS") + field (FLNK, "$(DEVICE):SPEC-FREQ-qX") + field (PREC, "3") +} + +record(calcout, "$(DEVICE):OVERSAMPLE-2-qxVEC"){ + field(DESC, "Sampling Rate") + field(CALC, "0.5 * A / (299792458 / 288 / 1000)") + field(INPA, "ARS07-DBPM-0840:DWC-STG0-RATE CP") + field(OUT, "$(DEVICE):SPEC-FREQ-qX.HOPR PP") +} + +record (waveform, "$(DEVICE):SPEC-FREQ-qX"){ + field (FTVL, "FLOAT") + field (DTYP, "sequence") + field (NELM, "8193") + field (LOPR, "0") + field (HOPR, "0.5") + field (PREC, "3") + field (PINI, "YES") +} + +record (waveform, "$(DEVICE):SIGN-Y"){ + field (DESC, "Copy of ARS07-DBPM-5530:DAQ-BEAM-STG0-Y") + field (FTVL, "FLOAT") + field (NELM, "16384") + field (INP, "ARS07-DBPM-5530:DAQ-BEAM-STG0-Y CP MS") + field (FLNK, "$(DEVICE):SPEC-Y") + field (PREC, "6") +} + +record (waveform, "$(DEVICE):SPEC-Y"){ + field (FTVL, "FLOAT") + field (DTYP, "FFT spsd") + field (NELM, "8192") + field (INP, "$(DEVICE):SIGN-Y MS") + field (FLNK, "$(DEVICE):SPEC-FREQ-qY") + field (PREC, "3") +} + +record(calcout, "$(DEVICE):OVERSAMPLE-2-qYVEC"){ + field(DESC, "Sampling Rate") + field(CALC, "0.5 * A / (299792458 / 288 / 1000)") + field(INPA, "ARS07-DBPM-5530:DWC-STG0-RATE CP") + field(OUT, "$(DEVICE):SPEC-FREQ-qY.HOPR PP") +} + +record (waveform, "$(DEVICE):SPEC-FREQ-qY"){ + field (FTVL, "FLOAT") + field (DTYP, "sequence") + field (NELM, "8192") + field (LOPR, "0") + field (HOPR, "0.5") + field (PREC, "3") + field (PINI, "YES") +} + +record (waveform, "$(DEVICE):SIGN-Z"){ + field (DESC, "Copy of ARS02-DBPM-2910:DAQ-BEAM-STG1-X") + field (FTVL, "FLOAT") + field (NELM, "16384") + field (INP, "ARS02-DBPM-2910:DAQ-BEAM-STG1-X CP MS") + field (FLNK, "$(DEVICE):SPEC-Z") + field (PREC, "6") +} + +record (waveform, "$(DEVICE):SPEC-Z"){ + field (FTVL, "FLOAT") + field (DTYP, "FFT spsd") + field (NELM, "8192") + field (INP, "$(DEVICE):SIGN-Z MS") + field (FLNK, "$(DEVICE):SPEC-FREQ-qZ") + field (PREC, "3") +} + +record(calcout, "$(DEVICE):OVERSAMPLE-2-qZVEC"){ + field(DESC, "Sampling Rate") + field(CALC, "0.5 * A / (299792458 / 288 / 1000)") + field(INPA, "ARS02-DBPM-2910:DWC-STG1-RATE CP") + field(OUT, "$(DEVICE):SPEC-FREQ-qZ.HOPR PP") +} + +record (waveform, "$(DEVICE):SPEC-FREQ-qZ"){ + field (FTVL, "FLOAT") + field (DTYP, "sequence") + field (NELM, "8192") + field (LOPR, "0") + field (HOPR, "0.5") + field (PREC, "3") + field (PINI, "YES") +} + +record(ao, "$(DEVICE):REF-QX") { + field(DESC, "PV for the hor. reference tune") + field(PREC, "3") + field(ASG, "READONLY") + field(VAL, "39.37") +} + +record(ao, "$(DEVICE):QX") { + field(DESC, "PV for the measured hor. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QX-FREQ") + field(HIHI, "0.40") + field(HHSV, "MAJOR") + field(HIGH, "0.38") + field(HSV, "MINOR") + field(LOW, "0.36") + field(LSV, "MINOR") + field(LOLO, "0.34") + field(LLSV, "MAJOR") +} + +record(calcout, "$(DEVICE):QX-FREQ") { + field(DESC, "Freq hor. tune") + field(EGU, "kHz") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "A * B / 480 / 1000") + field(INPA, "$(DEVICE):QX") + field(INPB, "AGERF-MO01:FREQ-GET") +} + +record(ao, "$(DEVICE):QX-SB1") { + field(DESC, "PV for the measured hor. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QX-SB1-DIFF") +} + +record(calcout, "$(DEVICE):QX-SB1-DIFF") { + field(DESC, "PV for the measured hor. tune") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "ABS(A - B)") + field(INPA, "$(DEVICE):QX") + field(INPB, "$(DEVICE):QX-SB1") +} + +record(ao, "$(DEVICE):QX-SB2") { + field(DESC, "PV for the measured hor. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QX-SB2-DIFF") +} + +record(calcout, "$(DEVICE):QX-SB2-DIFF") { + field(DESC, "PV for the measured hor. tune") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "ABS(A - B)") + field(INPA, "$(DEVICE):QX") + field(INPB, "$(DEVICE):QX-SB2") +} + +record(ao, "$(DEVICE):QX-ULIM") { + field(DESC, "upper limit qx search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.44") +} +record(ao, "$(DEVICE):QX-LLIM") { + field(DESC, "lower limit qx search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.30") +} + +record(waveform, "$(DEVICE):NORM-QX-AMP") { + field(DESC, "normalized, hor. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):NORM-QX-FREQ") { + field(DESC, "normalized, hor. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QX-PEAKS-FREQ") { + field(DESC, "peaks in hor. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QX-PEAKS") { + field(DESC, "peaks in hor. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(ao, "$(DEVICE):REF-QY") { + field(DESC, "PV for the ver. reference tune") + field(PREC, "3") + field(ASG, "READONLY") + field(VAL, "15.22") +} + +record(ao, "$(DEVICE):QY") { + field(DESC, "PV for the measured ver. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QY-FREQ") + field(HIHI, "0.25") + field(HHSV, "MAJOR") + field(HIGH, "0.23") + field(HSV, "MINOR") + field(LOW, "0.21") + field(LSV, "MINOR") + field(LOLO, "0.19") + field(LLSV, "MAJOR") +} + +record(calcout, "$(DEVICE):QY-FREQ") { + field(DESC, "Freq ver. tune") + field(EGU, "kHz") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "A * B / 480 / 1000") + field(INPA, "$(DEVICE):QY") + field(INPB, "AGERF-MO01:FREQ-GET") +} + +record(ao, "$(DEVICE):QY-SB1") { + field(DESC, "PV for the measured ver. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QY-SB1-DIFF") +} + +record(calcout, "$(DEVICE):QY-SB1-DIFF") { + field(DESC, "PV for the measured ver. tune") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "ABS(A - B)") + field(INPA, "$(DEVICE):QY") + field(INPB, "$(DEVICE):QY-SB1") +} + +record(ao, "$(DEVICE):QY-SB2") { + field(DESC, "PV for the measured ver. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QY-SB2-DIFF") +} + +record(calcout, "$(DEVICE):QY-SB2-DIFF") { + field(DESC, "PV for the measured ver. tune") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "ABS(A - B)") + field(INPA, "$(DEVICE):QY") + field(INPB, "$(DEVICE):QY-SB2") +} + +record(ao, "$(DEVICE):QY-ULIM") { + field(DESC, "upper limit qy search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.29") +} +record(ao, "$(DEVICE):QY-LLIM") { + field(DESC, "lower limit qy search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.15") +} + +record(waveform, "$(DEVICE):NORM-QY-AMP") { + field(DESC, "normalized, ver. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):NORM-QY-FREQ") { + field(DESC, "normalized, ver. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QY-PEAKS-FREQ") { + field(DESC, "peaks in ver. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QY-PEAKS") { + field(DESC, "peaks in ver. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(ao, "$(DEVICE):REF-QZ") { + field(DESC, "PV for the long. reference tune, no 3HC") + field(PREC, "3") + field(ASG, "READONLY") + field(VAL, "0.0027") +} + +record(ao, "$(DEVICE):QZ") { + field(DESC, "PV for the measured long. tune") + field(PREC, "3") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QZ-FREQ") + field(HIHI, "0.004") + field(HHSV, "MAJOR") + field(HIGH, "0.003") + field(HSV, "MINOR") + field(LOW, "0.001") + field(LSV, "MINOR") + field(LOLO, "0.0005") + field(LLSV, "MAJOR") +} + +record(calcout, "$(DEVICE):QZ-FREQ") { + field(DESC, "Freq ver. tune") + field(EGU, "kHz") + field(PREC, "3") + field(ASG, "READONLY") + field(PINI, "YES") + field(VAL, "0") + field(CALC, "A * B / 480 / 1000") + field(INPA, "$(DEVICE):QZ") + field(INPB, "AGERF-MO01:FREQ-GET") +} + +record(ao, "$(DEVICE):QZ-ULIM") { + field(DESC, "upper limit qz search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.0025") +} +record(ao, "$(DEVICE):QZ-LLIM") { + field(DESC, "lower limit qz search range") + field(PREC, "3") + field(ASG, "PROTECTED") + field(VAL, "0.0005") +} + +record(waveform, "$(DEVICE):NORM-QZ-AMP") { + field(DESC, "normalized, long. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):NORM-QZ-FREQ") { + field(DESC, "normalized, long. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QZ-PEAKS-FREQ") { + field(DESC, "peaks in long. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):QZ-PEAKS") { + field(DESC, "peaks in long. spectrum") + field(NELM, "8192") + field(FTVL, "FLOAT") +} + +record(bo, "$(DEVICE):MEAS-VALID") { + field(DESC, "reflects validity of tune measurement") + field(VAL, "0") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/tunebump/current/ioc/startup.script b/services/tunebump/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/tunebump/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/tunebump/current/qt/A_BD_TuneBump.ui b/services/tunebump/current/qt/A_BD_TuneBump.ui new file mode 100644 index 0000000..22fe977 --- /dev/null +++ b/services/tunebump/current/qt/A_BD_TuneBump.ui @@ -0,0 +1,6779 @@ + + + MainWindow + + + + 0 + 0 + 605 + 960 + + + + MainWindow + + + /*################################################*/ +/*# Settings for new templates/forms #*/ +/*################################################*/ +QMainWindow#MainWindow, QWidget#Form, QDialog#Dialog{ + background: rgba(236, 236, 236, 255); +} + +QMainWindow#MainWindow[transparent=true], QWidget#Form[transparent=true], QDialog#Dialog[transparent=true]{ + background: rgba(0, 0, 0, 0); +} + +/*-----------------------------------------------*/ +/* Title */ +/*-----------------------------------------------*/ +/* Operation panels */ +caLabel[statusTip="Operation"]{ + color: rgba(0, 0, 0, 255); + font: bold 18pt; + font-family: Sans Serif; + padding: 1px; + margin: 0px; + qproperty-alignment: AlignLeft; + qproperty-frameShape: StyledPanel; + /*qproperty-geometry: rect(-2 0 1600 33);*/ + background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(218, 218, 218, 255), + stop:0.5 rgba(200, 200, 200, 255), + stop:1 rgba(218, 218, 218, 255)); +} + + QGroupBox { + background: rgba(225,225,225,255); + border: 2px solid black; + border-radius: 5px; + margin-top: 1ex; /* leave space at the top for the title */ + } + + + + + + 810 + 120 + 70 + 20 + + + + + + + 810 + 60 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:TUNEBUMP-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 340 + 60 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QX-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 390 + 60 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QX-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 160 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QY-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 35 + 150 + 20 + + + + + 12 + 75 + true + + + + Step Size + + + Qt::AlignCenter + + + + + + 340 + 160 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QY-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 10 + 60 + 50 + 30 + + + + + 18 + 75 + true + + + + Qx + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 160 + 50 + 30 + + + + + 18 + 75 + true + + + + Qy + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 550 + 160 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QY-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 547 + 60 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QX-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 0 + 0 + 600 + 32 + + + + + Sans Serif + 18 + 75 + false + true + + + + Operation + + + Tune Shift + + + Qt::AlignLeading + + + + 218 + 218 + 218 + + + + caLabel::Default + + + + + + 0 + 300 + 605 + 660 + + + + 0 + + + + Meas + + + + + 5 + 210 + 590 + 200 + + + + Vertical Tune (nominal: Qy = 15.22) + + + AGEBD-TUNEBUMP:NORM-QY-FREQ;AGEBD-TUNEBUMP:NORM-QY-AMP + + + + 139 + 26 + 150 + + + + AGEBD-TUNEBUMP:QY-PEAKS-FREQ;AGEBD-TUNEBUMP:QY-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + 5 + 415 + 590 + 200 + + + + Synchrotron Tune (nominal: 0.0027) + + + AGEBD-TUNEBUMP:NORM-QZ-FREQ;AGEBD-TUNEBUMP:NORM-QZ-AMP + + + + 205 + 97 + 0 + + + + AGEBD-TUNEBUMP:QZ-PEAKS-FREQ;AGEBD-TUNEBUMP:QZ-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 205 + 97 + 0 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + false + + + 10 + + + caCartesianPlot::linear + + + + + + 5 + 5 + 590 + 200 + + + + Horizontal Tune (nominal: Qx = 39.37) + + + AGEBD-TUNEBUMP:NORM-QX-FREQ;AGEBD-TUNEBUMP:NORM-QX-AMP + + + + 42 + 99 + 228 + + + + AGEBD-TUNEBUMP:QX-PEAKS-FREQ;AGEBD-TUNEBUMP:QX-PEAKS + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + + + + false + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + FFT + + + + + 0 + 415 + 590 + 200 + + + + Tune Z + + + AGEBD-TUNEBUMP:SPEC-FREQ-qZ;AGEBD-TUNEBUMP:SPEC-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + 10 + + + caCartesianPlot::log10 + + + + + + 0 + 210 + 590 + 200 + + + + Tune Y + + + AGEBD-TUNEBUMP:SPEC-FREQ-qY;AGEBD-TUNEBUMP:SPEC-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + 14 + + + caCartesianPlot::log10 + + + + + + 0 + 5 + 590 + 200 + + + + Tune X + + + AGEBD-TUNEBUMP:SPEC-FREQ-qX;AGEBD-TUNEBUMP:SPEC-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + 0:1 + + + 14 + + + caCartesianPlot::log10 + + + + + + Raw + + + + + 0 + 210 + 590 + 200 + + + + Vertical TbT data + + + ;AGEBD-TUNEBUMP:SIGN-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + 0 + 415 + 590 + 200 + + + + Longitudinal Stage 1 Data + + + ;AGEBD-TUNEBUMP:SIGN-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 10 + + + caCartesianPlot::linear + + + + + + 0 + 5 + 590 + 200 + + + + Horizontal TbT data + + + ;AGEBD-TUNEBUMP:SIGN-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + Settings + + + + + 10 + 260 + 371 + 51 + + + + + 19 + 75 + true + + + + Pinger Settings (ca. 10 A) + + + Qt::AlignCenter + + + + + + 440 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0320:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 140 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0290:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 160 + 490 + 291 + 30 + + + + + 15 + 50 + false + + + + Enable Energy Stabelization: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 10 + 450 + 581 + 30 + + + + + 12 + 75 + true + + + + Defined by FOFB Mean Horizontal Corrector Integral Setpoint: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 250 + 530 + 110 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-ERR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Alarm_Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 30 + 490 + 110 + 30 + + + + 1 + + + 4 + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + -1.000000000000000 + + + + + + 10 + 10 + 400 + 40 + + + + + 24 + 75 + true + + + + Qx Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 130 + 400 + 40 + + + + + 25 + 75 + true + + + + Qy Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 440 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 140 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 440 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 140 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 320 + 121 + 40 + + + + + 17 + 50 + false + + + + Horizontal + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 320 + 121 + 40 + + + + + 24 + 50 + false + + + + Vertical + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 390 + 371 + 51 + + + + + 22 + 75 + true + + + + Beam Energy Setpoint + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 450 + 490 + 31 + 30 + + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT-EN + + + + + + 160 + 530 + 91 + 30 + + + + + 15 + 50 + false + + + + ERROR: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + BPMs + + + + + 10 + 20 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 140 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 270 + 400 + 30 + + + + + 18 + 75 + true + + + + Longitudinal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 10 + 180 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Y.INP + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 60 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-X.INP + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 310 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Z.INP + + + + 205 + 97 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-INT-SWITCH + + + + + + 170 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-EXT-SWITCH + + + + + + 330 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:CHOPPER-MODE + + + + + + 170 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-EXT-SWITCH + + + + + + 10 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-INT-SWITCH + + + + + + 330 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:CHOPPER-MODE + + + + + + FeedBack QX + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 60 + 80 + 40 + + + + + 23 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 160 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBX:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBX:CONTROL-QX-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBX:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBX:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBX-ONOFF + + + caChoice::Column + + + 1 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 30 + 30 + + + + true + + + true + + + AGEBD-TUNEFBX:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Feedback QY + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QY + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBY:CONTROL-QY-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 160 + 80 + 40 + + + + + 18 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 60 + 80 + 40 + + + + + 24 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBY:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 33 + 30 + + + + true + + + 18 + + + 18 + + + true + + + AGEBD-TUNEFBY:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBY-ONOFF + + + caChoice::Column + + + 1 + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBY:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBY:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Debug + + + + + 250 + 20 + 31 + 30 + + + + AGEBD-TUNEBUMP:WRITE2MAG + + + + + + 10 + 20 + 231 + 30 + + + + + 15 + 50 + false + + + + Apply MQCO Setpoints + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 4 + 50 + 595 + 575 + + + + + Monospace + 10 + PreferDefault + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + AGEBD-TUNEBUMP:CHANGELOG + + + caMultiLineString::None + + + + + + + + 60 + 60 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 60 + 160 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 110 + 100 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 130 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 380 + 100 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 130 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 200 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 200 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 230 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 110 + 230 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 170 + 60 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-FREQ + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 170 + 160 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-FREQ + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 10 + 260 + 50 + 30 + + + + + 18 + 75 + true + + + + Qz + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 60 + 260 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 170 + 260 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ-FREQ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 340 + 60 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBX-ONOFF + + + + + + 340 + 160 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBY-ONOFF + + + calabel_3 + wmsignalpropagator + cacalc_2 + camessagebutton_14 + caspinbox + caspinbox_2 + calabel_12 + camessagebutton_15 + calabel_13 + calabel_14 + camessagebutton_16 + camessagebutton_17 + tabWidget + caLineEdit_39 + caLineEdit_40 + calabel_18 + caLineEdit_43 + caLineEdit_45 + calabel_19 + caLineEdit_48 + caLineEdit_49 + calabel_20 + calabel_21 + calabel_22 + caLineEdit_44 + calabel_23 + calabel_24 + calabel_25 + caLineEdit_50 + caLineEdit_46 + caLineEdit_51 + caLineEdit_42 + caLineEdit_54 + calabel_33 + caLineEdit_55 + caLineEdit_56 + calabel + calabel_2 + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caMultiLineString + QPlainTextEdit +
caMultiLineString
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 598 + 89 + + + 608 + 152 + + + + +
diff --git a/services/tunebump/current/systemd/AGEBD-SERVICE-TUNEBUMP.service b/services/tunebump/current/systemd/AGEBD-SERVICE-TUNEBUMP.service new file mode 100644 index 0000000..09eeef8 --- /dev/null +++ b/services/tunebump/current/systemd/AGEBD-SERVICE-TUNEBUMP.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TUNEBUMP +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TUNEBUMP +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TUNEBUMP.service +# systemctl --user start AGEBD-SERVICE-TUNEBUMP From 385b9a760b19eaa7a52835cc8bb9058fef57f5c5 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 05/42] feature: add new service tunefbx --- docs/ioc/ioc_overview.md | 2 +- services/tunefbx/current/app/pyproject.toml | 47 + .../current/app/src/agebd_tunefbx/__init__.py | 1 + .../current/app/src/agebd_tunefbx/main.py | 31 + .../current/app/src/agebd_tunefbx/service.py | 93 + .../tunefbx/current/app/tests/test_app.py | 9 + services/tunefbx/current/app/uv.lock | 275 + .../current/ioc/AGEBD-CPCL-TUNEFBX_main.subs | 4 + .../ioc/AGEBD-CPCL-TUNEFBX_parameters.yaml | 6 + services/tunefbx/current/ioc/TUNEFBX.template | 185 + services/tunefbx/current/ioc/startup.script | 1 + services/tunefbx/current/qt/A_BD_TuneBump.ui | 6779 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TUNEFBX.service | 16 + 13 files changed, 7448 insertions(+), 1 deletion(-) create mode 100644 services/tunefbx/current/app/pyproject.toml create mode 100644 services/tunefbx/current/app/src/agebd_tunefbx/__init__.py create mode 100644 services/tunefbx/current/app/src/agebd_tunefbx/main.py create mode 100644 services/tunefbx/current/app/src/agebd_tunefbx/service.py create mode 100644 services/tunefbx/current/app/tests/test_app.py create mode 100644 services/tunefbx/current/app/uv.lock create mode 100644 services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs create mode 100644 services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_parameters.yaml create mode 100644 services/tunefbx/current/ioc/TUNEFBX.template create mode 100644 services/tunefbx/current/ioc/startup.script create mode 100644 services/tunefbx/current/qt/A_BD_TuneBump.ui create mode 100644 services/tunefbx/current/systemd/AGEBD-SERVICE-TUNEFBX.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 1e9c4d1..eb600ba 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TUNEBUMP | | +| AGEBD-CPCL-TUNEFBX | | diff --git a/services/tunefbx/current/app/pyproject.toml b/services/tunefbx/current/app/pyproject.toml new file mode 100644 index 0000000..04d77bf --- /dev/null +++ b/services/tunefbx/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-tunefbx" +version = "0.1.0" +description = "AGEBD-TUNEFBX Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/__init__.py b/services/tunefbx/current/app/src/agebd_tunefbx/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/tunefbx/current/app/src/agebd_tunefbx/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py new file mode 100644 index 0000000..a589168 --- /dev/null +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_tunefbx import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TUNEFBX" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/service.py b/services/tunefbx/current/app/src/agebd_tunefbx/service.py new file mode 100644 index 0000000..9e58ff5 --- /dev/null +++ b/services/tunefbx/current/app/src/agebd_tunefbx/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TUNEFBX:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TUNEFBX:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TUNEFBX:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/tunefbx/current/app/tests/test_app.py b/services/tunefbx/current/app/tests/test_app.py new file mode 100644 index 0000000..b0158a0 --- /dev/null +++ b/services/tunefbx/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_tunefbx import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/tunefbx/current/app/uv.lock b/services/tunefbx/current/app/uv.lock new file mode 100644 index 0000000..f4a9ae0 --- /dev/null +++ b/services/tunefbx/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-tunefbx" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs new file mode 100644 index 0000000..3e0664b --- /dev/null +++ b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs @@ -0,0 +1,4 @@ +file TUNEFBX.template { + pattern { DEVICE } + { AGEBD-TUNEFBX } +} \ No newline at end of file diff --git a/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_parameters.yaml b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/tunefbx/current/ioc/TUNEFBX.template b/services/tunefbx/current/ioc/TUNEFBX.template new file mode 100644 index 0000000..b11ca9a --- /dev/null +++ b/services/tunefbx/current/ioc/TUNEFBX.template @@ -0,0 +1,185 @@ +record(ao, "$(DEVICE):CONTROL-KP") { + field(DESC, "PID Proportional Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-KI") { + field(DESC, "PID Integral Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-KD") { + field(DESC, "PID Derivative Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QX") { + field(DESC, "PID Setpoint for QX") + field(ASG, "PROTECTED") + field(VAL, "0.37") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QX-OKRNG") { + field(DESC, "PID THRESHOLD") + field(ASG, "PROTECTED") + field(VAL, "0.0005") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QXMIN") { + field(DESC, "PID LOWER LIMIT") + field(ASG, "PROTECTED") + field(VAL, "0.31") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QXMAX") { + field(DESC, "PID UPPER LIMIT") + field(ASG, "PROTECTED") + field(VAL, "0.43") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-MIN-CURR") { + field(DESC, "PID MIN CURR") + field(ASG, "PROTECTED") + field(VAL, "400") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ") { + field(DESC, "PID SETPOINT for archive") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ-ULIM") { + field(DESC, "PID SETPOINT upper limit") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "0.001") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ-LLIM") { + field(DESC, "PID SETPOINT lower limit") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "-0.001") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):QSTEPS") { + field(DESC, "PID SETPOINT accumulated") + field(ASG, "READONLY") + field(PREC, "4") + field(VAL, "0") + field(PINI, "YES") + field(CALC, "VAL + A") + field(INPA, "$(DEVICE):DELTAQ") +} + +record(bo, "$(DEVICE):CHECK1") { + field(DESC, "measured tune realistic") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK2") { + field(DESC, "measured tune okrng") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK3") { + field(DESC, "injection not active") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK4") { + field(DESC, "current above min") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK5") { + field(DESC, "tune bpm config") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK6") { + field(DESC, "pingers on") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK7") { + field(DESC, "dt corresponds to 3.125 Hz") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK8") { + field(DESC, "calculated step within limits") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):CHECKALL") { + field(DESC, "Check SUM, written by IOC") + field(ASG, "READONLY") + field(LOLO, "0.1") + field(LLSV, "MINOR") + field(CALC, "A & B & C & D & E & F & G & H") + field(INPA, "$(DEVICE):CHECK1") + field(INPB, "$(DEVICE):CHECK2") + field(INPC, "$(DEVICE):CHECK3") + field(INPD, "$(DEVICE):CHECK4") + field(INPE, "$(DEVICE):CHECK5") + field(INPF, "$(DEVICE):CHECK6") + field(INPG, "$(DEVICE):CHECK7") + field(INPH, "$(DEVICE):CHECK8") +} \ No newline at end of file diff --git a/services/tunefbx/current/ioc/startup.script b/services/tunefbx/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/tunefbx/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/tunefbx/current/qt/A_BD_TuneBump.ui b/services/tunefbx/current/qt/A_BD_TuneBump.ui new file mode 100644 index 0000000..22fe977 --- /dev/null +++ b/services/tunefbx/current/qt/A_BD_TuneBump.ui @@ -0,0 +1,6779 @@ + + + MainWindow + + + + 0 + 0 + 605 + 960 + + + + MainWindow + + + /*################################################*/ +/*# Settings for new templates/forms #*/ +/*################################################*/ +QMainWindow#MainWindow, QWidget#Form, QDialog#Dialog{ + background: rgba(236, 236, 236, 255); +} + +QMainWindow#MainWindow[transparent=true], QWidget#Form[transparent=true], QDialog#Dialog[transparent=true]{ + background: rgba(0, 0, 0, 0); +} + +/*-----------------------------------------------*/ +/* Title */ +/*-----------------------------------------------*/ +/* Operation panels */ +caLabel[statusTip="Operation"]{ + color: rgba(0, 0, 0, 255); + font: bold 18pt; + font-family: Sans Serif; + padding: 1px; + margin: 0px; + qproperty-alignment: AlignLeft; + qproperty-frameShape: StyledPanel; + /*qproperty-geometry: rect(-2 0 1600 33);*/ + background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(218, 218, 218, 255), + stop:0.5 rgba(200, 200, 200, 255), + stop:1 rgba(218, 218, 218, 255)); +} + + QGroupBox { + background: rgba(225,225,225,255); + border: 2px solid black; + border-radius: 5px; + margin-top: 1ex; /* leave space at the top for the title */ + } + + + + + + 810 + 120 + 70 + 20 + + + + + + + 810 + 60 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:TUNEBUMP-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 340 + 60 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QX-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 390 + 60 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QX-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 160 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QY-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 35 + 150 + 20 + + + + + 12 + 75 + true + + + + Step Size + + + Qt::AlignCenter + + + + + + 340 + 160 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QY-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 10 + 60 + 50 + 30 + + + + + 18 + 75 + true + + + + Qx + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 160 + 50 + 30 + + + + + 18 + 75 + true + + + + Qy + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 550 + 160 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QY-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 547 + 60 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QX-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 0 + 0 + 600 + 32 + + + + + Sans Serif + 18 + 75 + false + true + + + + Operation + + + Tune Shift + + + Qt::AlignLeading + + + + 218 + 218 + 218 + + + + caLabel::Default + + + + + + 0 + 300 + 605 + 660 + + + + 0 + + + + Meas + + + + + 5 + 210 + 590 + 200 + + + + Vertical Tune (nominal: Qy = 15.22) + + + AGEBD-TUNEBUMP:NORM-QY-FREQ;AGEBD-TUNEBUMP:NORM-QY-AMP + + + + 139 + 26 + 150 + + + + AGEBD-TUNEBUMP:QY-PEAKS-FREQ;AGEBD-TUNEBUMP:QY-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + 5 + 415 + 590 + 200 + + + + Synchrotron Tune (nominal: 0.0027) + + + AGEBD-TUNEBUMP:NORM-QZ-FREQ;AGEBD-TUNEBUMP:NORM-QZ-AMP + + + + 205 + 97 + 0 + + + + AGEBD-TUNEBUMP:QZ-PEAKS-FREQ;AGEBD-TUNEBUMP:QZ-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 205 + 97 + 0 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + false + + + 10 + + + caCartesianPlot::linear + + + + + + 5 + 5 + 590 + 200 + + + + Horizontal Tune (nominal: Qx = 39.37) + + + AGEBD-TUNEBUMP:NORM-QX-FREQ;AGEBD-TUNEBUMP:NORM-QX-AMP + + + + 42 + 99 + 228 + + + + AGEBD-TUNEBUMP:QX-PEAKS-FREQ;AGEBD-TUNEBUMP:QX-PEAKS + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + + + + false + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + FFT + + + + + 0 + 415 + 590 + 200 + + + + Tune Z + + + AGEBD-TUNEBUMP:SPEC-FREQ-qZ;AGEBD-TUNEBUMP:SPEC-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + 10 + + + caCartesianPlot::log10 + + + + + + 0 + 210 + 590 + 200 + + + + Tune Y + + + AGEBD-TUNEBUMP:SPEC-FREQ-qY;AGEBD-TUNEBUMP:SPEC-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + 14 + + + caCartesianPlot::log10 + + + + + + 0 + 5 + 590 + 200 + + + + Tune X + + + AGEBD-TUNEBUMP:SPEC-FREQ-qX;AGEBD-TUNEBUMP:SPEC-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + 0:1 + + + 14 + + + caCartesianPlot::log10 + + + + + + Raw + + + + + 0 + 210 + 590 + 200 + + + + Vertical TbT data + + + ;AGEBD-TUNEBUMP:SIGN-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + 0 + 415 + 590 + 200 + + + + Longitudinal Stage 1 Data + + + ;AGEBD-TUNEBUMP:SIGN-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 10 + + + caCartesianPlot::linear + + + + + + 0 + 5 + 590 + 200 + + + + Horizontal TbT data + + + ;AGEBD-TUNEBUMP:SIGN-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + Settings + + + + + 10 + 260 + 371 + 51 + + + + + 19 + 75 + true + + + + Pinger Settings (ca. 10 A) + + + Qt::AlignCenter + + + + + + 440 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0320:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 140 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0290:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 160 + 490 + 291 + 30 + + + + + 15 + 50 + false + + + + Enable Energy Stabelization: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 10 + 450 + 581 + 30 + + + + + 12 + 75 + true + + + + Defined by FOFB Mean Horizontal Corrector Integral Setpoint: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 250 + 530 + 110 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-ERR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Alarm_Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 30 + 490 + 110 + 30 + + + + 1 + + + 4 + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + -1.000000000000000 + + + + + + 10 + 10 + 400 + 40 + + + + + 24 + 75 + true + + + + Qx Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 130 + 400 + 40 + + + + + 25 + 75 + true + + + + Qy Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 440 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 140 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 440 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 140 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 320 + 121 + 40 + + + + + 17 + 50 + false + + + + Horizontal + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 320 + 121 + 40 + + + + + 24 + 50 + false + + + + Vertical + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 390 + 371 + 51 + + + + + 22 + 75 + true + + + + Beam Energy Setpoint + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 450 + 490 + 31 + 30 + + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT-EN + + + + + + 160 + 530 + 91 + 30 + + + + + 15 + 50 + false + + + + ERROR: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + BPMs + + + + + 10 + 20 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 140 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 270 + 400 + 30 + + + + + 18 + 75 + true + + + + Longitudinal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 10 + 180 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Y.INP + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 60 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-X.INP + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 310 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Z.INP + + + + 205 + 97 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-INT-SWITCH + + + + + + 170 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-EXT-SWITCH + + + + + + 330 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:CHOPPER-MODE + + + + + + 170 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-EXT-SWITCH + + + + + + 10 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-INT-SWITCH + + + + + + 330 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:CHOPPER-MODE + + + + + + FeedBack QX + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 60 + 80 + 40 + + + + + 23 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 160 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBX:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBX:CONTROL-QX-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBX:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBX:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBX-ONOFF + + + caChoice::Column + + + 1 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 30 + 30 + + + + true + + + true + + + AGEBD-TUNEFBX:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Feedback QY + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QY + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBY:CONTROL-QY-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 160 + 80 + 40 + + + + + 18 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 60 + 80 + 40 + + + + + 24 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBY:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 33 + 30 + + + + true + + + 18 + + + 18 + + + true + + + AGEBD-TUNEFBY:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBY-ONOFF + + + caChoice::Column + + + 1 + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBY:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBY:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Debug + + + + + 250 + 20 + 31 + 30 + + + + AGEBD-TUNEBUMP:WRITE2MAG + + + + + + 10 + 20 + 231 + 30 + + + + + 15 + 50 + false + + + + Apply MQCO Setpoints + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 4 + 50 + 595 + 575 + + + + + Monospace + 10 + PreferDefault + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + AGEBD-TUNEBUMP:CHANGELOG + + + caMultiLineString::None + + + + + + + + 60 + 60 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 60 + 160 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 110 + 100 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 130 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 380 + 100 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 130 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 200 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 200 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 230 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 110 + 230 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 170 + 60 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-FREQ + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 170 + 160 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-FREQ + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 10 + 260 + 50 + 30 + + + + + 18 + 75 + true + + + + Qz + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 60 + 260 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 170 + 260 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ-FREQ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 340 + 60 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBX-ONOFF + + + + + + 340 + 160 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBY-ONOFF + + + calabel_3 + wmsignalpropagator + cacalc_2 + camessagebutton_14 + caspinbox + caspinbox_2 + calabel_12 + camessagebutton_15 + calabel_13 + calabel_14 + camessagebutton_16 + camessagebutton_17 + tabWidget + caLineEdit_39 + caLineEdit_40 + calabel_18 + caLineEdit_43 + caLineEdit_45 + calabel_19 + caLineEdit_48 + caLineEdit_49 + calabel_20 + calabel_21 + calabel_22 + caLineEdit_44 + calabel_23 + calabel_24 + calabel_25 + caLineEdit_50 + caLineEdit_46 + caLineEdit_51 + caLineEdit_42 + caLineEdit_54 + calabel_33 + caLineEdit_55 + caLineEdit_56 + calabel + calabel_2 + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caMultiLineString + QPlainTextEdit +
caMultiLineString
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 598 + 89 + + + 608 + 152 + + + + +
diff --git a/services/tunefbx/current/systemd/AGEBD-SERVICE-TUNEFBX.service b/services/tunefbx/current/systemd/AGEBD-SERVICE-TUNEFBX.service new file mode 100644 index 0000000..84b2c61 --- /dev/null +++ b/services/tunefbx/current/systemd/AGEBD-SERVICE-TUNEFBX.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TUNEFBX +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TUNEFBX +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TUNEFBX.service +# systemctl --user start AGEBD-SERVICE-TUNEFBX From 1b3992075cf5593d22c57270345ca18814bfee37 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:29:53 +0200 Subject: [PATCH 06/42] feature: add new service tunefby --- docs/ioc/ioc_overview.md | 2 +- services/tunefby/current/app/pyproject.toml | 47 + .../current/app/src/agebd_tunefby/__init__.py | 1 + .../current/app/src/agebd_tunefby/main.py | 31 + .../current/app/src/agebd_tunefby/service.py | 93 + .../tunefby/current/app/tests/test_app.py | 9 + services/tunefby/current/app/uv.lock | 275 + .../current/ioc/AGEBD-CPCL-TUNEFBY_main.subs | 4 + .../ioc/AGEBD-CPCL-TUNEFBY_parameters.yaml | 6 + services/tunefby/current/ioc/TUNEFBY.template | 185 + services/tunefby/current/ioc/startup.script | 1 + services/tunefby/current/qt/A_BD_TuneBump.ui | 6779 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TUNEFBY.service | 16 + 13 files changed, 7448 insertions(+), 1 deletion(-) create mode 100644 services/tunefby/current/app/pyproject.toml create mode 100644 services/tunefby/current/app/src/agebd_tunefby/__init__.py create mode 100644 services/tunefby/current/app/src/agebd_tunefby/main.py create mode 100644 services/tunefby/current/app/src/agebd_tunefby/service.py create mode 100644 services/tunefby/current/app/tests/test_app.py create mode 100644 services/tunefby/current/app/uv.lock create mode 100644 services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs create mode 100644 services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_parameters.yaml create mode 100644 services/tunefby/current/ioc/TUNEFBY.template create mode 100644 services/tunefby/current/ioc/startup.script create mode 100644 services/tunefby/current/qt/A_BD_TuneBump.ui create mode 100644 services/tunefby/current/systemd/AGEBD-SERVICE-TUNEFBY.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index eb600ba..cdc14db 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TUNEFBX | | +| AGEBD-CPCL-TUNEFBY | | diff --git a/services/tunefby/current/app/pyproject.toml b/services/tunefby/current/app/pyproject.toml new file mode 100644 index 0000000..b3dd565 --- /dev/null +++ b/services/tunefby/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-tunefby" +version = "0.1.0" +description = "AGEBD-TUNEFBY Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/tunefby/current/app/src/agebd_tunefby/__init__.py b/services/tunefby/current/app/src/agebd_tunefby/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/tunefby/current/app/src/agebd_tunefby/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py new file mode 100644 index 0000000..ff69b86 --- /dev/null +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_tunefby import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TUNEFBY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/tunefby/current/app/src/agebd_tunefby/service.py b/services/tunefby/current/app/src/agebd_tunefby/service.py new file mode 100644 index 0000000..736310e --- /dev/null +++ b/services/tunefby/current/app/src/agebd_tunefby/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TUNEFBY:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TUNEFBY:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TUNEFBY:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/tunefby/current/app/tests/test_app.py b/services/tunefby/current/app/tests/test_app.py new file mode 100644 index 0000000..d8727c2 --- /dev/null +++ b/services/tunefby/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_tunefby import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/tunefby/current/app/uv.lock b/services/tunefby/current/app/uv.lock new file mode 100644 index 0000000..c79326d --- /dev/null +++ b/services/tunefby/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-tunefby" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs new file mode 100644 index 0000000..3d9cb1b --- /dev/null +++ b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs @@ -0,0 +1,4 @@ +file TUNEFBY.template { + pattern { DEVICE } + { AGEBD-TUNEFBY } +} \ No newline at end of file diff --git a/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_parameters.yaml b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/tunefby/current/ioc/TUNEFBY.template b/services/tunefby/current/ioc/TUNEFBY.template new file mode 100644 index 0000000..756df39 --- /dev/null +++ b/services/tunefby/current/ioc/TUNEFBY.template @@ -0,0 +1,185 @@ +record(ao, "$(DEVICE):CONTROL-KP") { + field(DESC, "PID Proportional Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-KI") { + field(DESC, "PID Integral Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-KD") { + field(DESC, "PID Derivative Gain") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QY") { + field(DESC, "PID Setpoint for QY") + field(ASG, "PROTECTED") + field(VAL, "0.22") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QY-OKRNG") { + field(DESC, "PID THRESHOLD") + field(ASG, "PROTECTED") + field(VAL, "0.0005") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QYMIN") { + field(DESC, "PID LOWER LIMIT") + field(ASG, "PROTECTED") + field(VAL, "0.15") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-QYMAX") { + field(DESC, "PID UPPER LIMIT") + field(ASG, "PROTECTED") + field(VAL, "0.28") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-MIN-CURR") { + field(DESC, "PID MIN CURR") + field(ASG, "PROTECTED") + field(VAL, "400") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ") { + field(DESC, "PID SETPOINT for archive") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ-ULIM") { + field(DESC, "PID SETPOINT upper limit") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "0.001") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):DELTAQ-LLIM") { + field(DESC, "PID SETPOINT lower limit") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):QSTEPS") + field(VAL, "-0.001") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):QSTEPS") { + field(DESC, "PID SETPOINT accumulated") + field(ASG, "READONLY") + field(PREC, "4") + field(VAL, "0") + field(PINI, "YES") + field(CALC, "VAL + A") + field(INPA, "$(DEVICE):DELTAQ") +} + +record(bo, "$(DEVICE):CHECK1") { + field(DESC, "measured tune realistic") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK2") { + field(DESC, "measured tune okrng") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK3") { + field(DESC, "injection not active") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK4") { + field(DESC, "current above min") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK5") { + field(DESC, "tune bpm config") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK6") { + field(DESC, "pingers on") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK7") { + field(DESC, "dt corresponds to 3.125 Hz") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):CHECK8") { + field(DESC, "calculated step within limits") + field(FLNK, "$(DEVICE):CHECKALL") + field(ASG, "PROTECTED") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "0") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):CHECKALL") { + field(DESC, "Check SUM, written by IOC") + field(ASG, "READONLY") + field(LOLO, "0.1") + field(LLSV, "MINOR") + field(CALC, "A & B & C & D & E & F & G & H") + field(INPA, "$(DEVICE):CHECK1") + field(INPB, "$(DEVICE):CHECK2") + field(INPC, "$(DEVICE):CHECK3") + field(INPD, "$(DEVICE):CHECK4") + field(INPE, "$(DEVICE):CHECK5") + field(INPF, "$(DEVICE):CHECK6") + field(INPG, "$(DEVICE):CHECK7") + field(INPH, "$(DEVICE):CHECK8") +} \ No newline at end of file diff --git a/services/tunefby/current/ioc/startup.script b/services/tunefby/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/tunefby/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/tunefby/current/qt/A_BD_TuneBump.ui b/services/tunefby/current/qt/A_BD_TuneBump.ui new file mode 100644 index 0000000..22fe977 --- /dev/null +++ b/services/tunefby/current/qt/A_BD_TuneBump.ui @@ -0,0 +1,6779 @@ + + + MainWindow + + + + 0 + 0 + 605 + 960 + + + + MainWindow + + + /*################################################*/ +/*# Settings for new templates/forms #*/ +/*################################################*/ +QMainWindow#MainWindow, QWidget#Form, QDialog#Dialog{ + background: rgba(236, 236, 236, 255); +} + +QMainWindow#MainWindow[transparent=true], QWidget#Form[transparent=true], QDialog#Dialog[transparent=true]{ + background: rgba(0, 0, 0, 0); +} + +/*-----------------------------------------------*/ +/* Title */ +/*-----------------------------------------------*/ +/* Operation panels */ +caLabel[statusTip="Operation"]{ + color: rgba(0, 0, 0, 255); + font: bold 18pt; + font-family: Sans Serif; + padding: 1px; + margin: 0px; + qproperty-alignment: AlignLeft; + qproperty-frameShape: StyledPanel; + /*qproperty-geometry: rect(-2 0 1600 33);*/ + background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(218, 218, 218, 255), + stop:0.5 rgba(200, 200, 200, 255), + stop:1 rgba(218, 218, 218, 255)); +} + + QGroupBox { + background: rgba(225,225,225,255); + border: 2px solid black; + border-radius: 5px; + margin-top: 1ex; /* leave space at the top for the title */ + } + + + + + + 810 + 120 + 70 + 20 + + + + + + + 810 + 60 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:TUNEBUMP-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 340 + 60 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QX-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 390 + 60 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QX-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 160 + 150 + 30 + + + + 1 + + + 4 + + + AGEBD-TUNEBUMP:QY-STEPSIZE + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + caSpinbox::as_is + + + + + + 390 + 35 + 150 + 20 + + + + + 12 + 75 + true + + + + Step Size + + + Qt::AlignCenter + + + + + + 340 + 160 + 40 + 30 + + + + << + + + false + + + AGEBD-TUNEBUMP:QY-STEPDOWN + + + << + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 10 + 60 + 50 + 30 + + + + + 18 + 75 + true + + + + Qx + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 160 + 50 + 30 + + + + + 18 + 75 + true + + + + Qy + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 550 + 160 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QY-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 547 + 60 + 40 + 30 + + + + >> + + + false + + + AGEBD-TUNEBUMP:QX-STEPUP + + + >> + + + + 160 + 160 + 160 + + + + + + + 1 + + + caMessageButton::as_is + + + + + + 0 + 0 + 600 + 32 + + + + + Sans Serif + 18 + 75 + false + true + + + + Operation + + + Tune Shift + + + Qt::AlignLeading + + + + 218 + 218 + 218 + + + + caLabel::Default + + + + + + 0 + 300 + 605 + 660 + + + + 0 + + + + Meas + + + + + 5 + 210 + 590 + 200 + + + + Vertical Tune (nominal: Qy = 15.22) + + + AGEBD-TUNEBUMP:NORM-QY-FREQ;AGEBD-TUNEBUMP:NORM-QY-AMP + + + + 139 + 26 + 150 + + + + AGEBD-TUNEBUMP:QY-PEAKS-FREQ;AGEBD-TUNEBUMP:QY-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + 5 + 415 + 590 + 200 + + + + Synchrotron Tune (nominal: 0.0027) + + + AGEBD-TUNEBUMP:NORM-QZ-FREQ;AGEBD-TUNEBUMP:NORM-QZ-AMP + + + + 205 + 97 + 0 + + + + AGEBD-TUNEBUMP:QZ-PEAKS-FREQ;AGEBD-TUNEBUMP:QZ-PEAKS + + + caCartesianPlot::Sticks + + + + 255 + 255 + 255 + + + + + 205 + 97 + 0 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + false + + + 10 + + + caCartesianPlot::linear + + + + + + 5 + 5 + 590 + 200 + + + + Horizontal Tune (nominal: Qx = 39.37) + + + AGEBD-TUNEBUMP:NORM-QX-FREQ;AGEBD-TUNEBUMP:NORM-QX-AMP + + + + 42 + 99 + 228 + + + + AGEBD-TUNEBUMP:QX-PEAKS-FREQ;AGEBD-TUNEBUMP:QX-PEAKS + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + + + + false + + + false + + + 14 + + + caCartesianPlot::linear + + + + + + FFT + + + + + 0 + 415 + 590 + 200 + + + + Tune Z + + + AGEBD-TUNEBUMP:SPEC-FREQ-qZ;AGEBD-TUNEBUMP:SPEC-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.0005;0.0025 + + + 10 + + + caCartesianPlot::log10 + + + + + + 0 + 210 + 590 + 200 + + + + Tune Y + + + AGEBD-TUNEBUMP:SPEC-FREQ-qY;AGEBD-TUNEBUMP:SPEC-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.15;0.29 + + + 14 + + + caCartesianPlot::log10 + + + + + + 0 + 5 + 590 + 200 + + + + Tune X + + + AGEBD-TUNEBUMP:SPEC-FREQ-qX;AGEBD-TUNEBUMP:SPEC-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0.3;0.44 + + + 0:1 + + + 14 + + + caCartesianPlot::log10 + + + + + + Raw + + + + + 0 + 210 + 590 + 200 + + + + Vertical TbT data + + + ;AGEBD-TUNEBUMP:SIGN-Y + + + + 139 + 26 + 150 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + 0 + 415 + 590 + 200 + + + + Longitudinal Stage 1 Data + + + ;AGEBD-TUNEBUMP:SIGN-Z + + + + 205 + 97 + 0 + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 10 + + + caCartesianPlot::linear + + + + + + 0 + 5 + 590 + 200 + + + + Horizontal TbT data + + + ;AGEBD-TUNEBUMP:SIGN-X + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + + + + + 255 + 255 + 255 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;16384 + + + + + + 14 + + + caCartesianPlot::linear + + + + + + Settings + + + + + 10 + 260 + 371 + 51 + + + + + 19 + 75 + true + + + + Pinger Settings (ca. 10 A) + + + Qt::AlignCenter + + + + + + 440 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0320:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 140 + 320 + 150 + 40 + + + + 3 + + + 2 + + + ARS01-MKIK-0290:I-SET + + + caSpinbox::User + + + caSpinbox::User + + + 300.000000000000000 + + + 0.000000000000000 + + + + + + 160 + 490 + 291 + 30 + + + + + 15 + 50 + false + + + + Enable Energy Stabelization: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 10 + 450 + 581 + 30 + + + + + 12 + 75 + true + + + + Defined by FOFB Mean Horizontal Corrector Integral Setpoint: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 250 + 530 + 110 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-ERR + + + + 0 + 0 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Alarm_Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 30 + 490 + 110 + 30 + + + + 1 + + + 4 + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + -1.000000000000000 + + + + + + 10 + 10 + 400 + 40 + + + + + 24 + 75 + true + + + + Qx Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 130 + 400 + 40 + + + + + 25 + 75 + true + + + + Qy Search Range + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 60 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 440 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 140 + 60 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QX-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 440 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Upper limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 140 + 180 + 150 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEBUMP:QY-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 180 + 121 + 40 + + + + + 16 + 50 + false + + + + Lower limit + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 320 + 121 + 40 + + + + + 17 + 50 + false + + + + Horizontal + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 320 + 121 + 40 + + + + + 24 + 50 + false + + + + Vertical + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 10 + 390 + 371 + 51 + + + + + 22 + 75 + true + + + + Beam Energy Setpoint + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 450 + 490 + 31 + 30 + + + + ARSGE-CECL-FOFB1:MCOX-INTEGRAL-REF-DEFAULT-EN + + + + + + 160 + 530 + 91 + 30 + + + + + 15 + 50 + false + + + + ERROR: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + BPMs + + + + + 10 + 20 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 10 + 140 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 10 + 270 + 400 + 30 + + + + + 18 + 75 + true + + + + Longitudinal Tune BPM + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 10 + 180 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Y.INP + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 60 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-X.INP + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 310 + 580 + 30 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:SIGN-Z.INP + + + + 205 + 97 + 0 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 10 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-INT-SWITCH + + + + + + 170 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:PILOT-EXT-SWITCH + + + + + + 330 + 100 + 150 + 30 + + + + ARS07-DBPM-0840:CHOPPER-MODE + + + + + + 170 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-EXT-SWITCH + + + + + + 10 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:PILOT-INT-SWITCH + + + + + + 330 + 220 + 150 + 30 + + + + ARS07-DBPM-5530:CHOPPER-MODE + + + + + + FeedBack QX + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Horizontal Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 42 + 99 + 228 + + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 60 + 80 + 40 + + + + + 23 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBX:CONTROL-QXMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 160 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">X,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBX:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBX:CONTROL-QX-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBX:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBX:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBX-ONOFF + + + caChoice::Column + + + 1 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBX:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 30 + 30 + + + + true + + + true + + + AGEBD-TUNEFBX:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBX:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Feedback QY + + + + + 10 + 10 + 400 + 30 + + + + + 18 + 75 + true + + + + Vertical Tune Feedback + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 139 + 26 + 150 + + + + + + + 120 + 60 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QY + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 210 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">P</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 210 + 171 + 40 + + + + 1 + + + 4 + + + true + + + AGEBD-TUNEFBY:CONTROL-QY-OKRNG + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 200 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 260 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KI + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 60 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>ΔQ</p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 310 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">D</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 270 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK4 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 400 + 210 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KP + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 110 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMAX + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 250 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 300 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 160 + 80 + 40 + + + + + 18 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVL</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 310 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:CONTROL-KD + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 220 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK3 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 350 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 150 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 60 + 80 + 40 + + + + + 24 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,set</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 210 + 80 + 40 + + + + + 16 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">OKrange</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 60 + 150 + 40 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEFBY:DELTAQ + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 500 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + = + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 520 + 350 + 33 + 30 + + + + true + + + 18 + + + 18 + + + true + + + AGEBD-TUNEFBY:CHECKALL + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 320 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK5 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 170 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK2 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 310 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>K<span style=" vertical-align:sub;">I</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 160 + 171 + 40 + + + + 1 + + + 2 + + + AGEBD-TUNEFBY:CONTROL-QYMIN + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 120 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK1 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 40 + 355 + 80 + 20 + + + + + 11 + 50 + false + + + + <html><head/><body><p>Conditions<br/></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 390 + 10 + 160 + 30 + + + + AGEBD-ALH:TUNEFBY-ONOFF + + + caChoice::Column + + + 1 + + + + + + 370 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK6 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 20 + 380 + 571 + 240 + + + + + 10 + 75 + true + + + + Accumulated Tune Steps + + + + + + + + + AGEBD-TUNEFBY:QSTEPS + + + caStripPlot::Second + + + 600.000000000000000 + + + caStripPlot::High + + + caStripPlot::linear + + + caStripPlot::autoScale + + + 0.000000000000000 + + + 0.000000001000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 42 + 99 + 228 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 252 + 192 + 11 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000410000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 255 + 0 + 255 + + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + true + + + false + + + + + + 20 + 260 + 80 + 40 + + + + + 25 + 50 + false + + + + <html><head/><body><p>I<span style=" vertical-align:sub;">min</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 20 + 110 + 80 + 40 + + + + + 17 + 50 + false + + + + <html><head/><body><p>Q<span style=" vertical-align:sub;">Y,DRVH</span></p><p><br/></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 120 + 260 + 171 + 40 + + + + 3 + + + 1 + + + AGEBD-TUNEFBY:CONTROL-MIN-CURR + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 420 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK7 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 470 + 350 + 30 + 30 + + + + AGEBD-TUNEFBY:CHECK8 + + + + 0 + 205 + 0 + + + + 0 + + + 1 + + + + + + 450 + 350 + 20 + 30 + + + + + 15 + 50 + false + + + + + + + + Qt::AlignCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 310 + 160 + 80 + 40 + + + + + 21 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">min</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 400 + 110 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-ULIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 400 + 160 + 150 + 40 + + + + 1 + + + 3 + + + AGEBD-TUNEFBY:DELTAQ-LLIM + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 310 + 110 + 80 + 40 + + + + + 20 + 50 + false + + + + <html><head/><body><p>ΔQ<span style=" vertical-align:sub;">max</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + Debug + + + + + 250 + 20 + 31 + 30 + + + + AGEBD-TUNEBUMP:WRITE2MAG + + + + + + 10 + 20 + 231 + 30 + + + + + 15 + 50 + false + + + + Apply MQCO Setpoints + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 4 + 50 + 595 + 575 + + + + + Monospace + 10 + PreferDefault + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + AGEBD-TUNEBUMP:CHANGELOG + + + caMultiLineString::None + + + + + + + + 60 + 60 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 60 + 160 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 110 + 100 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 100 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB1-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 130 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2 + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 130 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-SB2-DIFF + + + + 42 + 99 + 228 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 380 + 100 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 130 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 200 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 110 + 200 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 380 + 230 + 91 + 20 + + + + + 12 + 75 + true + + + + Distance + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 110 + 230 + 121 + 20 + + + + + 12 + 75 + true + + + + Sideband 2 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 0 + 0 + 0 + + + + + 255 + 252 + 255 + + + + + + + 250 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2 + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 200 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB1-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 480 + 230 + 110 + 20 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-SB2-DIFF + + + + 139 + 26 + 150 + + + + + 255 + 255 + 225 + + + + caLineEdit::Static + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::Height + + + false + + + caLineEdit::decimal + + + + + + 170 + 60 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QX-FREQ + + + + 42 + 99 + 228 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 42 + 99 + 228 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 170 + 160 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QY-FREQ + + + + 139 + 26 + 150 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 139 + 26 + 150 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 10 + 260 + 50 + 30 + + + + + 18 + 75 + true + + + + Qz + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 205 + 97 + 0 + + + + + + + 60 + 260 + 100 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + false + + + caLineEdit::decimal + + + + + + 170 + 260 + 160 + 30 + + + + + Lucida Sans Typewriter + 16 + + + + true + + + + + + Qt::AlignAbsolute|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + AGEBD-TUNEBUMP:QZ-FREQ + + + + 205 + 97 + 0 + + + + + 0 + 0 + 0 + + + + caLineEdit::Static + + + true + + + + 205 + 97 + 0 + + + + 1 + + + caLineEdit::onBackground + + + 3 + + + caLineEdit::User + + + caLineEdit::Channel + + + 0.100000000000000 + + + 0.000000000000000 + + + caLineEdit::None + + + true + + + caLineEdit::decimal + + + + + + 340 + 60 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBX-ONOFF + + + + + + 340 + 160 + 250 + 30 + + + + + Sans Serif + 18 + + + + Feedback ON + + + Qt::AlignCenter + + + + 0 + 205 + 0 + + + + caLabel::Calc + + + A + + + AGEBD-ALH:TUNEFBY-ONOFF + + + calabel_3 + wmsignalpropagator + cacalc_2 + camessagebutton_14 + caspinbox + caspinbox_2 + calabel_12 + camessagebutton_15 + calabel_13 + calabel_14 + camessagebutton_16 + camessagebutton_17 + tabWidget + caLineEdit_39 + caLineEdit_40 + calabel_18 + caLineEdit_43 + caLineEdit_45 + calabel_19 + caLineEdit_48 + caLineEdit_49 + calabel_20 + calabel_21 + calabel_22 + caLineEdit_44 + calabel_23 + calabel_24 + calabel_25 + caLineEdit_50 + caLineEdit_46 + caLineEdit_51 + caLineEdit_42 + caLineEdit_54 + calabel_33 + caLineEdit_55 + caLineEdit_56 + calabel + calabel_2 + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caMultiLineString + QPlainTextEdit +
caMultiLineString
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 598 + 89 + + + 608 + 152 + + + + +
diff --git a/services/tunefby/current/systemd/AGEBD-SERVICE-TUNEFBY.service b/services/tunefby/current/systemd/AGEBD-SERVICE-TUNEFBY.service new file mode 100644 index 0000000..3cbbb68 --- /dev/null +++ b/services/tunefby/current/systemd/AGEBD-SERVICE-TUNEFBY.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TUNEFBY +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TUNEFBY +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TUNEFBY.service +# systemctl --user start AGEBD-SERVICE-TUNEFBY From d48fe45b028ccf48287c6242d27c40005552bc29 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:43:21 +0200 Subject: [PATCH 07/42] feature: add new service injectionguard --- docs/ioc/ioc_overview.md | 2 +- .../injectionguard/current/app/pyproject.toml | 47 + .../app/src/agebd_injectionguard/__init__.py | 1 + .../app/src/agebd_injectionguard/main.py | 31 + .../app/src/agebd_injectionguard/service.py | 93 ++ .../current/app/tests/test_app.py | 9 + services/injectionguard/current/app/uv.lock | 275 +++++ .../ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs | 31 + .../AGEBD-CPCL-INJECTIONGUARD_parameters.yaml | 6 + .../current/ioc/INJECTIONGUARD.template | 37 + .../injectionguard/current/ioc/startup.script | 1 + .../current/qt/A_BD_InjectionGuard.ui | 988 ++++++++++++++++++ .../AGEBD-SERVICE-INJECTIONGUARD.service | 16 + 13 files changed, 1536 insertions(+), 1 deletion(-) create mode 100644 services/injectionguard/current/app/pyproject.toml create mode 100644 services/injectionguard/current/app/src/agebd_injectionguard/__init__.py create mode 100644 services/injectionguard/current/app/src/agebd_injectionguard/main.py create mode 100644 services/injectionguard/current/app/src/agebd_injectionguard/service.py create mode 100644 services/injectionguard/current/app/tests/test_app.py create mode 100644 services/injectionguard/current/app/uv.lock create mode 100644 services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs create mode 100644 services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_parameters.yaml create mode 100644 services/injectionguard/current/ioc/INJECTIONGUARD.template create mode 100644 services/injectionguard/current/ioc/startup.script create mode 100644 services/injectionguard/current/qt/A_BD_InjectionGuard.ui create mode 100644 services/injectionguard/current/systemd/AGEBD-SERVICE-INJECTIONGUARD.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index cdc14db..20d50a6 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TUNEFBY | | +| AGEBD-CPCL-INJECTIONGUARD | | diff --git a/services/injectionguard/current/app/pyproject.toml b/services/injectionguard/current/app/pyproject.toml new file mode 100644 index 0000000..0344692 --- /dev/null +++ b/services/injectionguard/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-injectionguard" +version = "0.1.0" +description = "AGEBD-INJECTIONGUARD Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/__init__.py b/services/injectionguard/current/app/src/agebd_injectionguard/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/injectionguard/current/app/src/agebd_injectionguard/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py new file mode 100644 index 0000000..afd7c4a --- /dev/null +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_injectionguard import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "INJECTIONGUARD" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/service.py b/services/injectionguard/current/app/src/agebd_injectionguard/service.py new file mode 100644 index 0000000..dddb14a --- /dev/null +++ b/services/injectionguard/current/app/src/agebd_injectionguard/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-INJECTIONGUARD:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-INJECTIONGUARD:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-INJECTIONGUARD:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/injectionguard/current/app/tests/test_app.py b/services/injectionguard/current/app/tests/test_app.py new file mode 100644 index 0000000..c6a1df9 --- /dev/null +++ b/services/injectionguard/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_injectionguard import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/injectionguard/current/app/uv.lock b/services/injectionguard/current/app/uv.lock new file mode 100644 index 0000000..943f9eb --- /dev/null +++ b/services/injectionguard/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-injectionguard" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs new file mode 100644 index 0000000..9fe790b --- /dev/null +++ b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs @@ -0,0 +1,31 @@ +file INJECTIONGUARD_individual.template { + pattern { DEVICE } + { AGEBD-INJECTIONGUARD } +} + +file INJECTIONGUARD_automated.template { + pattern { NR Latch Description } + { 01 1 "Beam Dump Kicker"} + { 02 1 "Dump Valve"} + { 03 1 "MIS"} + { 04 1 "VCS"} + { 05 1 "Linac KV/BB/BY"} + { 06 1 "RF Linac"} + { 07 1 "RF Booster"} + { 08 1 "RF Ring"} + { 09 1 "Magnets Pulsed"} + { 10 1 "Magnets Booster"} + { 11 1 "Magnets Corrector"} + { 12 1 "Magnets Ring"} + { 13 1 "Current Limit"} + { 14 1 "IDs Ready"} + { 15 1 "Single Bunch Charge"} + { 16 1 "Injection Quality"} + { 17 1 "Dump Quality"} + { 18 1 "Lifetime"} + { 19 1 "Tune"} + { 20 0 "Pingers"} + { 21 1 "Vacuum Pressure"} + { 22 1 "Orbit Deviation"} + { 23 1 "Beam Dump Controller"} +} \ No newline at end of file diff --git a/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_parameters.yaml b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD.template b/services/injectionguard/current/ioc/INJECTIONGUARD.template new file mode 100644 index 0000000..857d84a --- /dev/null +++ b/services/injectionguard/current/ioc/INJECTIONGUARD.template @@ -0,0 +1,37 @@ +# This is a template for preaparing an IOC providing BD Service specific PVs +# Access Security Groups: +# DEFAULT - logt wenn EGU oder so veraendert werden +# LOG - logt wenn neuer wert geschrieben wird +# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL +# READONLY - verhindert versuchte caputs und aktiviert caputlog +# Input links can specify CA, CP, or CPP. +# If the input link specifies CA, it will be forced to be a Channel Access link. +# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. +# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. +# + +record(ao, "$(DEVICE):AO") { + field(DESC, "Analog Output Record (ao)") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):BO") { + field(DESC, "Binary Output Record (bo)") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# TODO: ok? +record(bo, "$(DEVICE):CALLBACK") { + field(DESC, "Callback PV to listen to for changes") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/injectionguard/current/ioc/startup.script b/services/injectionguard/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/injectionguard/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/injectionguard/current/qt/A_BD_InjectionGuard.ui b/services/injectionguard/current/qt/A_BD_InjectionGuard.ui new file mode 100644 index 0000000..d452d7b --- /dev/null +++ b/services/injectionguard/current/qt/A_BD_InjectionGuard.ui @@ -0,0 +1,988 @@ + + + MainWindow + + + + 0 + 0 + 600 + 1195 + + + + MainWindow + + + + +/*-----------------------------------------------*/ +/* Title */ +/*-----------------------------------------------*/ +/* Operation panels */ +caLabel[statusTip="Operation"]{ + color: rgba(0, 0, 0, 255); + font: bold 18pt; + font-family: Sans Serif; + padding: 1px; + margin: 0px; + qproperty-alignment: AlignLeft; + qproperty-frameShape: StyledPanel; + /*qproperty-geometry: rect(-2 0 1600 33);*/ + background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(218, 218, 218, 255), + stop:0.5 rgba(200, 200, 200, 255), + stop:1 rgba(218, 218, 218, 255)); +} + + + + + + + 670 + 140 + 70 + 20 + + + + + + + 670 + 80 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:INJECTIONGUARD-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 130 + 36 + 460 + 40 + + + + + 16 + 75 + true + + + + AGEBD-INJECTIONGUARD:CONTROL-MODE + + + + + + 10 + 36 + 110 + 40 + + + + + 25 + 75 + true + + + + Mode + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 78 + 580 + 60 + + + + AGEBD-INJECTIONGUARD:CHECK-SUM + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 652 + 394 + 150 + 22 + + + + + 9 + + + + Ring Reset + + + ARS00-VCS:PLC_ARS_RESET_REQUEST + + + Ring Reset + + + + 212 + 219 + 157 + + + + 1 + + + + + + 652 + 346 + 150 + 22 + + + + + 9 + + + + LI LTB Reset + + + ARS00-VCS:PLC_ALIVA_RESET_REQUEST + + + LI LTB Reset + + + + 212 + 219 + 157 + + + + 1 + + + + + + 652 + 370 + 150 + 22 + + + + + 9 + + + + Boster Reset + + + ARS00-VCS:PLC_ABOVA_RESET_REQUEST + + + Boster Reset + + + + 212 + 219 + 157 + + + + 1 + + + + + + 722 + 438 + 150 + 22 + + + + + + + MIS Alarm Reset + + + ARS00-MIS-PLC-01:Alarm_Reset + + + MIS Alarm Reset + + + 1 + + + + + + 722 + 474 + 150 + 22 + + + + + + + MIS-FE Alarm Reset + + + ACOSA-MIS-FE:ACKERR-REQUEST + + + MIS-FE Alarm Reset + + + 0 + + + 1 + + + + + + 722 + 544 + 150 + 22 + + + + + + + VCS ALIVA Reset + + + ARS00-VCS:PLC_ALIVA_RESET_REQUEST + + + VCS ALIVA Reset + + + 1 + + + + + + 722 + 506 + 150 + 22 + + + + + + + VCS ABOVA Reset + + + ARS00-VCS:PLC_ABOVA_RESET_REQUEST + + + VCS ABOVA Reset + + + 1 + + + + + + 726 + 578 + 150 + 22 + + + + + + + VCS ARS Reset + + + ARS00-VCS:PLC_ARS_RESET_REQUEST + + + VCS ARS Reset + + + 1 + + + + + + 10 + 140 + 580 + 1050 + + + + 0 + + + + Checks + + + + + 10 + 10 + 40 + 40 + + + + true + + + false + + + 30 + + + 30 + + + AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER + + + caLed::Alarm + + + + + + 60 + 10 + 300 + 40 + + + + + Sans Serif + 16 + 75 + true + + + + true + + + Qt::LeftToRight + + + Master Trigger Freigabe + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 0 + 110 + 580 + 901 + + + + checknr=01,bridge=1,latch=1;checknr=02,bridge=1,latch=1;checknr=03,bridge=1,latch=1;checknr=04,bridge=1,latch=1;checknr=05,bridge=1,latch=1;checknr=06,bridge=1,latch=1;checknr=07,bridge=1,latch=1;checknr=08,bridge=1,latch=1;checknr=09,bridge=1,latch=1;checknr=10,bridge=1,latch=1;checknr=11,bridge=1,latch=1;checknr=12,bridge=1,latch=1;checknr=13,bridge=1,latch=1;checknr=14,bridge=1,latch=1;checknr=15,bridge=1,latch=1;checknr=16,bridge=1,latch=1;checknr=17,bridge=1,latch=1;checknr=18,bridge=1,latch=1;checknr=19,bridge=1,latch=1;checknr=20,bridge=0,latch=0;checknr=21,bridge=1,latch=1;checknr=22,bridge=1,latch=1;checknr=23,bridge=1,latch=1 + + + A_BD_InjectionGuard_inc.ui + + + 23 + + + + + + 270 + 60 + 20 + 900 + + + + Qt::Vertical + + + + + + 10 + 96 + 560 + 20 + + + + Qt::Horizontal + + + + + + 210 + 60 + 20 + 900 + + + + Qt::Vertical + + + + + + 230 + 66 + 40 + 30 + + + + + Monospace + 19 + 75 + true + PreferDefault + + + + OP + + + OP + + + Qt::AlignCenter + + + AGEBD-INJECTIONGUARD:CHECK-SUM-OP + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 340 + 66 + 111 + 30 + + + + + 18 + 75 + false + true + + + + false + + + BRIDGE + + + Qt::AlignCenter + + + ESimpleLabel::None + + + + + + 290 + 66 + 40 + 30 + + + + + Monospace + 19 + 75 + true + PreferDefault + + + + M\D + + + MD + + + Qt::AlignCenter + + + AGEBD-INJECTIONGUARD:CHECK-SUM-MD + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 9 + 66 + 201 + 30 + + + + + 18 + 75 + true + + + + Check + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 440 + 60 + 20 + 900 + + + + Qt::Vertical + + + + + + 470 + 66 + 80 + 30 + + + + + Monospace + 19 + 75 + true + PreferDefault + + + + L\ATC\H + + + LATCH + + + Qt::AlignCenter + + + AGEBD-INJECTIONGUARD:CHECK-SUM-LATCH + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 460 + 10 + 100 + 40 + + + + Reset + + + false + + + AGEBD-INJECTIONGUARD:RESET-LATCHES + + + Reset + + + + 160 + 160 + 160 + + + + + + + 1 + + + + + + Logs + + + + + 0 + 38 + 575 + 983 + + + + + Monospace + 10 + PreferDefault + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + AGEBD-INJECTIONGUARD:LOG + + + caMultiLineString::None + + + + + + 470 + 2 + 101 + 30 + + + + Clear Logs + + + AGEBD-INJECTIONGUARD:LOG-CLEAR + + + Clear Logs + + + + 160 + 160 + 160 + + + + 0 + + + 1 + + + + + + 10 + 2 + 101 + 30 + + + + AGEBD-INJECTIONGUARD:LOG-PAUSE + + + + 160 + 160 + 160 + + + + caChoice::Default + + + caChoice::Column + + + 1 + + + + + + + + -2 + 2 + 628 + 30 + + + + + Sans Serif + 18 + 75 + false + true + + + + Operation + + + Injection Guard + + + Qt::AlignLeading + + + + 218 + 218 + 218 + + + + caLabel::Default + + + + + + 556 + 6 + 40 + 22 + + + + -Wiki + + + + 183 + 157 + 92 + + + + Injection Guard + + + https://acceleratorwiki.psi.ch/wiki/Injection_Guard + + + + + + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caLabel + QLabel +
caLabel
+
+ + caInclude + QWidget +
caInclude
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caMultiLineString + QPlainTextEdit +
caMultiLineString
+
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + caMimeDisplay + QWidget +
caMimeDisplay
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 598 + 89 + + + 608 + 152 + + + + +
diff --git a/services/injectionguard/current/systemd/AGEBD-SERVICE-INJECTIONGUARD.service b/services/injectionguard/current/systemd/AGEBD-SERVICE-INJECTIONGUARD.service new file mode 100644 index 0000000..8bc6ae5 --- /dev/null +++ b/services/injectionguard/current/systemd/AGEBD-SERVICE-INJECTIONGUARD.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-INJECTIONGUARD +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh INJECTIONGUARD +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-INJECTIONGUARD.service +# systemctl --user start AGEBD-SERVICE-INJECTIONGUARD From 7b34c743eec371474544f65950c6a2133973db84 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:44:53 +0200 Subject: [PATCH 08/42] feature: add new service orbitbump --- docs/ioc/ioc_overview.md | 2 +- services/orbitbump/current/app/pyproject.toml | 47 ++ .../app/src/agebd_orbitbump/__init__.py | 1 + .../current/app/src/agebd_orbitbump/main.py | 31 ++ .../app/src/agebd_orbitbump/service.py | 93 ++++ .../orbitbump/current/app/tests/test_app.py | 9 + services/orbitbump/current/app/uv.lock | 275 ++++++++++++ .../ioc/AGEBD-CPCL-ORBITBUMP_main.subs | 62 +++ .../ioc/AGEBD-CPCL-ORBITBUMP_parameters.yaml | 6 + .../orbitbump/current/ioc/ORBITBUMP.template | 37 ++ services/orbitbump/current/ioc/startup.script | 1 + .../orbitbump/current/qt/A_BD_OrbitBump.ui | 409 ++++++++++++++++++ .../systemd/AGEBD-SERVICE-ORBITBUMP.service | 16 + 13 files changed, 988 insertions(+), 1 deletion(-) create mode 100644 services/orbitbump/current/app/pyproject.toml create mode 100644 services/orbitbump/current/app/src/agebd_orbitbump/__init__.py create mode 100644 services/orbitbump/current/app/src/agebd_orbitbump/main.py create mode 100644 services/orbitbump/current/app/src/agebd_orbitbump/service.py create mode 100644 services/orbitbump/current/app/tests/test_app.py create mode 100644 services/orbitbump/current/app/uv.lock create mode 100644 services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_main.subs create mode 100644 services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_parameters.yaml create mode 100644 services/orbitbump/current/ioc/ORBITBUMP.template create mode 100644 services/orbitbump/current/ioc/startup.script create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump.ui create mode 100644 services/orbitbump/current/systemd/AGEBD-SERVICE-ORBITBUMP.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 20d50a6..fd4b8de 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-INJECTIONGUARD | | +| AGEBD-CPCL-ORBITBUMP | | diff --git a/services/orbitbump/current/app/pyproject.toml b/services/orbitbump/current/app/pyproject.toml new file mode 100644 index 0000000..7ef40d4 --- /dev/null +++ b/services/orbitbump/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-orbitbump" +version = "0.1.0" +description = "AGEBD-ORBITBUMP Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/orbitbump/current/app/src/agebd_orbitbump/__init__.py b/services/orbitbump/current/app/src/agebd_orbitbump/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/orbitbump/current/app/src/agebd_orbitbump/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/orbitbump/current/app/src/agebd_orbitbump/main.py b/services/orbitbump/current/app/src/agebd_orbitbump/main.py new file mode 100644 index 0000000..d81391d --- /dev/null +++ b/services/orbitbump/current/app/src/agebd_orbitbump/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_orbitbump import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "ORBITBUMP" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/orbitbump/current/app/src/agebd_orbitbump/service.py b/services/orbitbump/current/app/src/agebd_orbitbump/service.py new file mode 100644 index 0000000..8b71fcb --- /dev/null +++ b/services/orbitbump/current/app/src/agebd_orbitbump/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-ORBITBUMP:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-ORBITBUMP:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-ORBITBUMP:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/orbitbump/current/app/tests/test_app.py b/services/orbitbump/current/app/tests/test_app.py new file mode 100644 index 0000000..a0e737f --- /dev/null +++ b/services/orbitbump/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_orbitbump import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/orbitbump/current/app/uv.lock b/services/orbitbump/current/app/uv.lock new file mode 100644 index 0000000..7f329ec --- /dev/null +++ b/services/orbitbump/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-orbitbump" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_main.subs b/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_main.subs new file mode 100644 index 0000000..e485117 --- /dev/null +++ b/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_main.subs @@ -0,0 +1,62 @@ +file ORBITBUMP_machine.template { + pattern + {sourcepoint beamline LOX HIX X LOXP HIXP XP LOY HIY Y LOYP HIYP YP BPM1 C1xx C1xpx C1yy C1ypy BPM2 C2xx C2xpx C2yy C2ypy BPM3 C3xx C3xpx C3yy C3ypy BPM4 C4xx C4xpx C4yy C4ypy} + # Diagnostic dipole beamlines + {X01DD NEMO -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS01-DBPM-1080 -0.0009920 -0.0006308 -0.0001141 0.0001109 ARS01-DBPM-1460 0.9742755 -0.1432472 0.9455447 -0.0865934 ARS01-DBPM-1900 0.9277200 1.0454287 0.1445141 1.5920941 ARS01-DBPM-2410 -0.0809412 -0.0384293 0.0058229 0.1036650} + {X08DB DISCO -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS08-DBPM-1900 -0.2500389 -0.0365053 0.0001023 0.0000595 ARS08-DBPM-2410 1.2775662 -0.9246414 0.5814965 -0.4999301 ARS08-DBPM-2910 0.6885552 0.9211364 0.4873898 1.7550023 ARS08-DBPM-4220 -0.2391394 -0.0169593 0.0309046 0.1234665} + {X10DG X11HEAT -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS10-DBPM-4720 -0.0187 -0.0188 0 0 ARS10-DBPM-5250 1.6016 -1.2108 0.5496 -0.5376 ARS10-DBPM-5880 0.7075 1.0654 1.1093 1.9515 ARS11-DBPM-0850 0.0026 0.0044 0.0166 0.0304} + # User dipole beamlines + {X01DA DEBYE -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS01-DBPM-2410 -0.2169694 -0.0006291 0.0001170 0.0000325 ARS01-DBPM-2910 1.2765938 -0.9208697 0.5792863 -0.5011470 ARS01-DBPM-4220 0.6866207 0.9198858 0.4842977 1.7595080 ARS01-DBPM-4720 -0.1924402 0.0258918 0.0307458 0.1239361} + {X02DA S-TOMCAT -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS02-DBPM-2410 -0.2089937 0.0072435 0.0001169 0.0000325 ARS02-DBPM-2910 1.2772588 -0.9200089 0.5792866 -0.5011606 ARS02-DBPM-4220 0.6864959 0.9194778 0.4843170 1.7595616 ARS02-DBPM-4720 -0.1833930 0.0352770 0.0307471 0.1239392} + {X03DA PEARL -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS03-DBPM-2410 -0.2016647 0.0152728 0.0001171 0.0000326 ARS03-DBPM-2910 1.2831552 -0.9190247 0.5819894 -0.5004911 ARS03-DBPM-4220 0.6905553 0.9206615 0.4875028 1.7552635 ARS03-DBPM-4720 -0.1749243 0.0438144 0.0309089 0.1234182} + {X04DB VUV -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS04-DBPM-1900 -0.1917962 0.0214714 0.0001022 0.0000595 ARS04-DBPM-2410 1.2842031 -0.9179380 0.5814999 -0.5000284 ARS04-DBPM-2910 0.6887599 0.9211626 0.4874732 1.7553295 ARS04-DBPM-4220 -0.1710439 0.0514609 0.0309080 0.1234788} + {X05DA Optics -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS05-DBPM-2410 -0.2740176 -0.0571105 0.0001170 0.0000321 ARS05-DBPM-2910 1.2732647 -0.9287209 0.5819890 -0.5003730 ARS05-DBPM-4220 0.6913367 0.9213802 0.4873370 1.7548006 ARS05-DBPM-4720 -0.2592981 -0.0408063 0.0308988 0.1233928} + {X06DA PXIII -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS06-DBPM-2410 -0.2675305 -0.0508248 0.0001170 0.0000321 ARS06-DBPM-2910 1.2749858 -0.9266845 0.5818007 -0.5004548 ARS06-DBPM-4220 0.6916389 0.9218001 0.4871613 1.7552275 ARS06-DBPM-4720 -0.2517260 -0.0332473 0.0308895 0.1234316} + {X07DB nanoXAS -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS07-DBPM-1900 -0.2563387 -0.0425222 0.0001023 0.0000596 ARS07-DBPM-2410 1.2761628 -0.9263027 0.5814954 -0.4999177 ARS07-DBPM-2910 0.6888233 0.9216262 0.4873810 1.7549631 ARS07-DBPM-4220 -0.2469055 -0.0248794 0.0309043 0.1234651} + {X07DA PolLux -300 300 0 -150 150 0 -300 300 0 -250 250 0 ARS07-DBPM-2410 -0.2606076 -0.0450539 0.0001170 0.0000326 ARS07-DBPM-2910 1.2750718 -0.9205684 0.5819899 -0.4976199 ARS07-DBPM-4220 0.6915728 0.9246379 0.4873668 1.7572153 ARS07-DBPM-4720 -0.2433555 -0.0254434 0.0309006 0.1235450} + {X10DA SuperXAS -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS10-DBPM-2410 -0.2392400 -0.0226765 0.0001170 0.0000321 ARS10-DBPM-2910 1.2780895 -0.9235140 0.5818007 -0.5005005 ARS10-DBPM-4220 0.6911875 0.9212713 0.4872251 1.7554059 ARS10-DBPM-4720 -0.2190626 -0.0004438 0.0308933 0.1234413} + # ID beamlines + {X02SA I-TOMCAT -500 500 0 -150 150 0 -500 500 0 -150 150 0 ARS01-DBPM-5250 -0.0161762 0.0645315 -0.0000522 0.0002217 ARS01-DBPM-5880 1.3057217 -3.1586368 0.7340909 -1.7908669 ARS02-DBPM-1080 1.1637103 2.7703664 0.8405251 2.0415012 ARS02-DBPM-1460 0.0473369 0.1176477 0.0354851 0.0914118} + {X03MA ADRESS -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS02-DBPM-5250 -0.0056074 0.0805576 -0.0000533 0.0001427 ARS02-DBPM-5880 1.2522257 -3.5240592 0.7649336 -2.1576328 ARS03-DBPM-0810 1.1134798 3.0406278 0.8874945 2.4488073 ARS03-DBPM-1080 0.0367597 0.0902093 0.0491615 0.1421129} + {X04SA ADDAMS -500 500 0 -150 150 0 -500 500 0 -150 150 0 ARS03-DBPM-5250 0.0006041 0.0811354 -0.0000524 0.0002222 ARS03-DBPM-5880 1.3048037 -3.1594991 0.7340820 -1.7909262 ARS04-DBPM-1080 1.1649402 2.7718322 0.8405182 2.0415768 ARS04-DBPM-1460 0.0441826 0.1145073 0.0354841 0.0914133} + {X05LA QUEST -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS04-DBPM-5880 0.0008866 0.0002252 -0.0001045 0.0002529 ARS05-DBPM-0410 0.8976150 -2.8499257 1.0112790 -2.8592349 ARS05-DBPM-1080 1.0880889 5.0183256 0.9137175 4.2390359 ARS05-DBPM-1460 0.0421489 0.1947713 0.0433357 0.2067705} + {X06SA PXI -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS05-DBPM-5250 -0.0776973 0.0030268 -0.0000523 0.0002212 ARS05-DBPM-5880 1.3044906 -3.1590695 0.7341239 -1.7906420 ARS06-DBPM-1080 1.1642809 2.7699897 0.8405515 2.0412179 ARS06-DBPM-1460 0.0604868 0.1306028 0.0354886 0.0914055} + {X07MA Phoenix/XTreme -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS06-DBPM-5250 -0.0684380 0.0189547 -0.0000531 0.0001447 ARS06-DBPM-5880 1.2508776 -3.5845660 0.7649630 -2.1939024 ARS07-DBPM-0810 1.1137188 2.9863773 0.8875136 2.4060190 ARS07-DBPM-1080 0.0093629 0.0606390 0.0491634 0.1397441} + {X08SA micro-XAS -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS07-DBPM-5250 -0.0624701 0.0181621 -0.0000523 0.0002216 ARS07-DBPM-5880 1.3039931 -3.1597229 0.7341156 -1.7906968 ARS08-DBPM-1080 1.1652753 2.7714013 0.8405450 2.0412871 ARS08-DBPM-1460 0.0575855 0.1278140 0.0354876 0.0914065} + {X09LA PEARL/XIL-II -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS08-DBPM-5880 0.0011254 0.0009724 -0.0000942 0.0002317 ARS09-DBPM-0570 0.8843735 -2.4344684 1.1263977 -3.0082085 ARS09-DBPM-1080 1.0591734 3.0395499 0.9413643 2.7184391 ARS09-DBPM-1460 0.0394021 0.1139547 0.0465775 0.1402264} + {X10SA PXII -500 500 0 -150 150 0 -500 500 0 -150 150 0 ARS09-DBPM-5250 -0.0473875 0.0333454 -0.0000523 0.0002213 ARS09-DBPM-5880 1.3047178 -3.1592507 0.7341077 -1.7907518 ARS10-DBPM-1080 1.1639981 2.7701547 0.8405387 2.0413565 ARS10-DBPM-1460 0.0540084 0.1242161 0.0354869 0.0914087} + {X11MA SIM -500 500 0 -150 150 0 -500 500 0 -150 150 0 ARS10-DBPM-5250 -0.0383667 0.0514782 -0.0000499 0.0001646 ARS10-DBPM-5880 1.2526899 -3.7342542 0.7640638 -2.2804441 ARS11-DBPM-0850 1.1168967 3.1441871 0.8845808 2.5170397 ARS11-DBPM-1080 0.0219427 0.0928506 0.0546028 0.1626088} + {X12SA cSAXS -300 300 0 -150 150 0 -300 300 0 -150 150 0 ARS11-DBPM-5250 -0.0326376 0.0479239 -0.0000524 0.0002219 ARS11-DBPM-5880 1.3047910 -3.1591765 0.7340995 -1.7908066 ARS12-DBPM-1080 1.1653151 2.7718178 0.8405322 2.0414257 ARS12-DBPM-1460 0.0513287 0.1216036 0.0354860 0.0914097} +} + + +file ORBITBUMP_beamline.template { + pattern + {sourcepoint beamline DRVL DRVH X XP Y YP } + # Diagnostic dipole beamlines + {X01DD NEMO -10 10 0 0 0 0 } + {X08DB DISCO -10 10 0 0 0 0 } + {X10DG X11HEAT -10 10 0 0 0 0 } + # User dipole beamlines + {X01DA DEBYE -10 10 0 0 0 0 } + {X02DA S-TOMCAT -10 10 0 0 0 0 } + {X03DA PEARL -10 10 0 0 0 0 } + {X04DB VUV -10 10 0 0 0 0 } + {X05DA Optics -10 10 0 0 0 0 } + {X06DA PXIII -10 10 0 0 0 0 } + {X07DB nanoXAS -10 10 0 0 0 0 } + {X07DA PolLux -10 10 0 0 0 0 } + {X10DA SuperXAS -10 10 0 0 0 0 } + # ID beamlines + {X02SA I-TOMCAT -10 10 0 0 0 0 } + {X03MA ADRESS -10 10 0 0 0 0 } + {X04SA ADDAMS -10 10 0 0 0 0 } + {X05LA QUEST -10 10 0 0 0 0 } + {X06SA PXI -10 10 0 0 0 0 } + {X07MA Phoenix/XTreme -10 10 0 0 0 0 } + {X08SA micro-XAS -10 10 0 0 0 0 } + {X09LA PEARL/XIL-II -10 10 0 0 0 0 } + {X10SA PXII -10 10 0 0 0 0 } + {X11MA SIM -10 10 0 0 0 0 } + {X12SA cSAXS -10 10 0 0 0 0 } +} \ No newline at end of file diff --git a/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_parameters.yaml b/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/orbitbump/current/ioc/AGEBD-CPCL-ORBITBUMP_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/orbitbump/current/ioc/ORBITBUMP.template b/services/orbitbump/current/ioc/ORBITBUMP.template new file mode 100644 index 0000000..857d84a --- /dev/null +++ b/services/orbitbump/current/ioc/ORBITBUMP.template @@ -0,0 +1,37 @@ +# This is a template for preaparing an IOC providing BD Service specific PVs +# Access Security Groups: +# DEFAULT - logt wenn EGU oder so veraendert werden +# LOG - logt wenn neuer wert geschrieben wird +# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL +# READONLY - verhindert versuchte caputs und aktiviert caputlog +# Input links can specify CA, CP, or CPP. +# If the input link specifies CA, it will be forced to be a Channel Access link. +# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. +# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. +# + +record(ao, "$(DEVICE):AO") { + field(DESC, "Analog Output Record (ao)") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):BO") { + field(DESC, "Binary Output Record (bo)") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# TODO: ok? +record(bo, "$(DEVICE):CALLBACK") { + field(DESC, "Callback PV to listen to for changes") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/orbitbump/current/ioc/startup.script b/services/orbitbump/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/orbitbump/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump.ui b/services/orbitbump/current/qt/A_BD_OrbitBump.ui new file mode 100644 index 0000000..fcc9232 --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump.ui @@ -0,0 +1,409 @@ + + + MainWindow + + + + 0 + 0 + 770 + 990 + + + + MainWindow + + + + + + 10 + 220 + 750 + 346 + + + + sourcepoint=X01DA,beamline=Debye;sourcepoint=X02DA,beamline=S-TOMCAT;sourcepoint=X03DA,beamline=PEARL;sourcepoint=X04DB,beamline=VUV;sourcepoint=X05DA,beamline=Optics;sourcepoint=X06DA,beamline=PXIII;sourcepoint=X07DB,beamline=nanoXAS;sourcepoint=X07DA,beamline=PolLux;sourcepoint=X10DA,beamline=SuperXAS + + + A_BD_OrbitBump_Operator_inc.ui + + + 9 + + + 5 + + + + + + 10 + 80 + 750 + 100 + + + + sourcepoint=X01DD,beamline=NEMO;sourcepoint=X08DB,beamline=DISCO;sourcepoint=X10DG,beamline=X11HEAT + + + A_BD_OrbitBump_Operator_inc.ui + + + 3 + + + 5 + + + + + + 10 + 190 + 261 + 30 + + + + + 18 + 75 + true + + + + Dipole Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 50 + 291 + 30 + + + + + 18 + 75 + true + + + + Diagnostic Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 570 + 261 + 30 + + + + + 18 + 75 + true + + + + ID Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 600 + 750 + 541 + + + + sourcepoint=X02SA,beamline=I-TOMCAT;sourcepoint=X03MA,beamline=ADRESS;sourcepoint=X04SA,beamline=ADDAMS;sourcepoint=X05LA,beamline=QUEST;sourcepoint=X06SA,beamline=PXI;sourcepoint=X07MA,beamline=Phoenix/XTreme;sourcepoint=X08SA,beamline=micro-XAS;sourcepoint=X09LA,beamline=PEARL/XIL-II;sourcepoint=X10SA,beamline=PXII;sourcepoint=X11MA,beamline=SIM;sourcepoint=X12SA,beamline=cSAXS + + + A_BD_OrbitBump_Operator_inc.ui + + + 11 + + + 5 + + + + + + 330 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 440 + 50 + 100 + 30 + + + + + 15 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + 550 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 660 + 50 + 100 + 30 + + + + + 15 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 598 + 4 + 170 + 30 + + + + Expert Panel All + + + + 183 + 157 + 92 + + + + Expert Panel All + + + A_BD_OrbitBump_Expert_all.ui + + + + + + 2 + 2 + 767 + 33 + + + + + Sans Serif + 20 + 75 + false + true + + + + Beamline local Bumps + + + Qt::AlignLeading + + + + 255 + 255 + 255 + + + + + 100 + 100 + 100 + + + + caLabel::Static + + + + + + 800 + 260 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:ORBITBUMP-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 800 + 320 + 70 + 20 + + + + cainclude + cainclude_2 + calabel + calabel_2 + calabel_3 + cainclude_3 + calabel_4 + calabel_5 + calabel_6 + calabel_7 + calabel_8 + carelateddisplay + cacalc_2 + wmsignalpropagator + + + + + caRelatedDisplay + QWidget +
caRelatedDisplay
+
+ + caLabel + QLabel +
caLabel
+
+ + caInclude + QWidget +
caInclude
+
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 844 + 271 + + + 847 + 327 + + + + +
diff --git a/services/orbitbump/current/systemd/AGEBD-SERVICE-ORBITBUMP.service b/services/orbitbump/current/systemd/AGEBD-SERVICE-ORBITBUMP.service new file mode 100644 index 0000000..4358d12 --- /dev/null +++ b/services/orbitbump/current/systemd/AGEBD-SERVICE-ORBITBUMP.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-ORBITBUMP +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh ORBITBUMP +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-ORBITBUMP.service +# systemctl --user start AGEBD-SERVICE-ORBITBUMP From 637594bb829eeefdea52ecc14fcb70fd1f6c1da3 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:50:04 +0200 Subject: [PATCH 09/42] feature: add new service postmortemlog --- docs/ioc/ioc_overview.md | 2 +- .../postmortemlog/current/app/pyproject.toml | 47 + .../app/src/agebd_postmortemlog/__init__.py | 1 + .../app/src/agebd_postmortemlog/main.py | 31 + .../app/src/agebd_postmortemlog/service.py | 93 ++ .../current/app/tests/test_app.py | 9 + services/postmortemlog/current/app/uv.lock | 275 ++++ .../ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs | 129 ++ .../AGEBD-CPCL-POSTMORTEMLOG_parameters.yaml | 6 + .../current/ioc/POSTMORTEMLOG.template | 37 + .../postmortemlog/current/ioc/startup.script | 1 + .../current/qt/A_BD_PostMortemLog.ui | 1197 +++++++++++++++++ .../AGEBD-SERVICE-POSTMORTEMLOG.service | 16 + 13 files changed, 1843 insertions(+), 1 deletion(-) create mode 100644 services/postmortemlog/current/app/pyproject.toml create mode 100644 services/postmortemlog/current/app/src/agebd_postmortemlog/__init__.py create mode 100644 services/postmortemlog/current/app/src/agebd_postmortemlog/main.py create mode 100644 services/postmortemlog/current/app/src/agebd_postmortemlog/service.py create mode 100644 services/postmortemlog/current/app/tests/test_app.py create mode 100644 services/postmortemlog/current/app/uv.lock create mode 100644 services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs create mode 100644 services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_parameters.yaml create mode 100644 services/postmortemlog/current/ioc/POSTMORTEMLOG.template create mode 100644 services/postmortemlog/current/ioc/startup.script create mode 100644 services/postmortemlog/current/qt/A_BD_PostMortemLog.ui create mode 100644 services/postmortemlog/current/systemd/AGEBD-SERVICE-POSTMORTEMLOG.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index fd4b8de..4a9d401 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-ORBITBUMP | | +| AGEBD-CPCL-POSTMORTEMLOG | | diff --git a/services/postmortemlog/current/app/pyproject.toml b/services/postmortemlog/current/app/pyproject.toml new file mode 100644 index 0000000..dc6c4c3 --- /dev/null +++ b/services/postmortemlog/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-postmortemlog" +version = "0.1.0" +description = "AGEBD-POSTMORTEMLOG Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/__init__.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py new file mode 100644 index 0000000..0c762eb --- /dev/null +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_postmortemlog import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "POSTMORTEMLOG" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py new file mode 100644 index 0000000..f0d50db --- /dev/null +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-POSTMORTEMLOG:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-POSTMORTEMLOG:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-POSTMORTEMLOG:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/postmortemlog/current/app/tests/test_app.py b/services/postmortemlog/current/app/tests/test_app.py new file mode 100644 index 0000000..3da58c5 --- /dev/null +++ b/services/postmortemlog/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_postmortemlog import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/postmortemlog/current/app/uv.lock b/services/postmortemlog/current/app/uv.lock new file mode 100644 index 0000000..4d2e5ff --- /dev/null +++ b/services/postmortemlog/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-postmortemlog" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs new file mode 100644 index 0000000..ff33687 --- /dev/null +++ b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs @@ -0,0 +1,129 @@ +file POSTMORTEMLOG.template { + pattern + { DEVICE } + { AGEBD-POSTMORTEMLOG } +} + +file POSTMORTEMLOG_15min10Hz.template { + pattern + { NAME INP} + # ---------- BEAM CURRENT -------------- + { CURRBPM AGEBD-DBPM3CURR:CURRENT-AVG } + { CURRPCT ARS07-DPCT-0000:CURR } + # ---------- BEAM LIFETIME -------------- + { TAUBPM AGEBD-TAUBPM:TAU } + { TAUPCT AGEBD-TAUPCT:TAU } + # ---------- TUNES -------------- + { QX AGEBD-TUNEBUMP:QX } + { QY AGEBD-TUNEBUMP:QY } + { QZ AGEBD-TUNEBUMP:QZ } + # ---------- LOSSES -------------- + { ARS01-DDRM-0375 ARS01-DDRM-0375:FET1_DOSE } + { ABRTL-DDRM-0670 ABRTL-DDRM-0670:FET1_BIAS_DOSE } + { ABRTL-DDRM-0950 ABRTL-DDRM-0950:FET1_DOSE } + { ARS01-DDRM-1530 ARS01-DDRM-1530:FET1_BIAS_DOSE } + { X05LA-DDRM-0330 X05LA-DDRM-0330:FET1_BIAS_DOSE } + { ARS05-DDRM-1530 ARS05-DDRM-1530:FET1_BIAS_DOSE } + { ARS05-DDRM-3500 ARS05-DDRM-3500:FET1_BIAS_DOSE } + { X09LA-DDRM-0330 X09LA-DDRM-0330:FET1_BIAS_DOSE } + { ARS09-DDRM-1530 ARS09-DDRM-1530:FET1_BIAS_DOSE } + { ARS09-DDRM-3500 ARS09-DDRM-3500:FET2_BIAS_DOSE } + { ARS12-DDRM-1530 ARS12-DDRM-1530:FET1_BIAS_DOSE } + { ARS12-DDRM-3500 ARS12-DDRM-3500:FET2_BIAS_DOSE } + { ARS12-DDRM-4400 ARS12-DDRM-4400:FET2_BIAS_DOSE } + { ARS12-DDRM-5480 ARS12-DDRM-5480:FET1_BIAS_DOSE } + # ---------- RF -------------- + { MASTERFREQ-SET AGERF-MO01:FREQ-SET } + { MASTERFREQ-GET AGERF-MO01:FREQ-GET } + { RFPOW-0140-INP ARS05-RCAV-0140:CO1i-POWER-MAX } + { RFPOW-0060-INP ARS05-RCAV-0060:CO1i-POWER-MAX } + { RFPOW-0230-INP ARS05-RCAV-0230:CO1i-POWER-MAX } + { RFPOW-0310-INP ARS05-RCAV-0310:CO1i-POWER-MAX } + { RFPOW-0060-REF ARS05-RCAV-0060:CO1r-POWER-MAX } + { RFPOW-0140-REF ARS05-RCAV-0140:CO1r-POWER-MAX } + { RFPOW-0230-REF ARS05-RCAV-0230:CO1r-POWER-MAX } + { RFPOW-0310-REF ARS05-RCAV-0310:CO1r-POWER-MAX } + # ---------- BEAM SIZE -------------- + { X01DD-SIGX X01DD-FE-CAM1:SIG-X } + { X01DD-SIGY X01DD-FE-CAM1:SIG-Y } + { X08DB-SIGX X08DB-FE-CAM1:SIG-X } + { X08DB-SIGY X08DB-FE-CAM1:SIG-Y } + # ---------- VACUUM -------------- + { VACMAX ARIVA-VMAVE:PRESS-MAX } + { VACMAXFE ARIVA-VMAVE-FE:PRESS-MAX } + { ARS01-VMCC-0110 ARS01-VMCC-0110:PRESSURE } + { ARS01-VMCC-0210 ARS01-VMCC-0210:PRESSURE } + { ARS01-VMCC-0225 ARS01-VMCC-0225:PRESSURE } + { ARS01-VMCC-0310 ARS01-VMCC-0310:PRESSURE } + { ARS01-VMCC-1550 ARS01-VMCC-1550:PRESSURE } + { ARS01-VMCC-3510 ARS01-VMCC-3510:PRESSURE } + { ARS01-VMCC-5460 ARS01-VMCC-5460:PRESSURE } + { ARS02-VMCC-0110 ARS02-VMCC-0110:PRESSURE } + { ARS02-VMCC-0210 ARS02-VMCC-0210:PRESSURE } + { ARS02-VMCC-0310 ARS02-VMCC-0310:PRESSURE } + { ARS02-VMCC-1550 ARS02-VMCC-1550:PRESSURE } + { ARS02-VMCC-3510 ARS02-VMCC-3510:PRESSURE } + { ARS02-VMCC-5460 ARS02-VMCC-5460:PRESSURE } + { ARS03-VMCC-0110 ARS03-VMCC-0110:PRESSURE } + { ARS03-VMCC-0320 ARS03-VMCC-0320:PRESSURE } + { ARS03-VMCC-1550 ARS03-VMCC-1550:PRESSURE } + { ARS03-VMCC-3510 ARS03-VMCC-3510:PRESSURE } + { ARS03-VMCC-5460 ARS03-VMCC-5460:PRESSURE } + { ARS04-VMCC-0110 ARS04-VMCC-0110:PRESSURE } + { ARS04-VMCC-1550 ARS04-VMCC-1550:PRESSURE } + { ARS04-VMCC-3510 ARS04-VMCC-3510:PRESSURE } + { ARS04-VMCC-5460 ARS04-VMCC-5460:PRESSURE } + { ARS05-VMCC-0110 ARS05-VMCC-0110:PRESSURE } + { ARS05-VMCC-0115 ARS05-VMCC-0115:PRESSURE } + { ARS05-VMCC-0210 ARS05-VMCC-0210:PRESSURE } + { ARS05-VMCC-0215 ARS05-VMCC-0215:PRESSURE } + { ARS05-VMCC-0310 ARS05-VMCC-0310:PRESSURE } + { ARS05-VMCC-0315 ARS05-VMCC-0315:PRESSURE } + { ARS05-VMCC-0410 ARS05-VMCC-0410:PRESSURE } + { ARS05-VMCC-0415 ARS05-VMCC-0415:PRESSURE } + { ARS05-VMCC-0510 ARS05-VMCC-0510:PRESSURE } + { ARS05-VMCC-0520 ARS05-VMCC-0520:PRESSURE } + { ARS05-VMCC-0530 ARS05-VMCC-0530:PRESSURE } + { ARS05-VMCC-0810 ARS05-VMCC-0810:PRESSURE } + { ARS05-VMCC-1550 ARS05-VMCC-1550:PRESSURE } + { ARS05-VMCC-3510 ARS05-VMCC-3510:PRESSURE } + { ARS05-VMCC-5460 ARS05-VMCC-5460:PRESSURE } + { ARS06-VMCC-0110 ARS06-VMCC-0110:PRESSURE } + { ARS06-VMCC-1550 ARS06-VMCC-1550:PRESSURE } + { ARS06-VMCC-3510 ARS06-VMCC-3510:PRESSURE } + { ARS06-VMCC-5460 ARS06-VMCC-5460:PRESSURE } + { ARS07-VMCC-0010 ARS07-VMCC-0010:PRESSURE } + { ARS07-VMCC-0120 ARS07-VMCC-0120:PRESSURE } + { ARS07-VMCC-0210 ARS07-VMCC-0210:PRESSURE } + { ARS07-VMCC-1550 ARS07-VMCC-1550:PRESSURE } + { ARS07-VMCC-3510 ARS07-VMCC-3510:PRESSURE } + { ARS07-VMCC-5460 ARS07-VMCC-5460:PRESSURE } + { ARS08-VMCC-0110 ARS08-VMCC-0110:PRESSURE } + { ARS08-VMCC-1550 ARS08-VMCC-1550:PRESSURE } + { ARS08-VMCC-3510 ARS08-VMCC-3510:PRESSURE } + { ARS08-VMCC-5460 ARS08-VMCC-5460:PRESSURE } + { ARS09-VMCC-0110 ARS09-VMCC-0110:PRESSURE } + { ARS09-VMCC-0120 ARS09-VMCC-0120:PRESSURE } + { ARS09-VMCC-0410 ARS09-VMCC-0410:PRESSURE } + { ARS09-VMCC-0510 ARS09-VMCC-0510:PRESSURE } + { ARS09-VMCC-0810 ARS09-VMCC-0810:PRESSURE } + { ARS09-VMCC-1550 ARS09-VMCC-1550:PRESSURE } + { ARS09-VMCC-3510 ARS09-VMCC-3510:PRESSURE } + { ARS09-VMCC-5460 ARS09-VMCC-5460:PRESSURE } + { ARS10-VMCC-0110 ARS10-VMCC-0110:PRESSURE } + { ARS10-VMCC-1550 ARS10-VMCC-1550:PRESSURE } + { ARS10-VMCC-3510 ARS10-VMCC-3510:PRESSURE } + { ARS10-VMCC-5460 ARS10-VMCC-5460:PRESSURE } + { ARS11-VMCC-0110 ARS11-VMCC-0110:PRESSURE } + { ARS11-VMCC-0210 ARS11-VMCC-0210:PRESSURE } + { ARS11-VMCC-0310 ARS11-VMCC-0310:PRESSURE } + { ARS11-VMCC-0410 ARS11-VMCC-0410:PRESSURE } + { ARS11-VMCC-0510 ARS11-VMCC-0510:PRESSURE } + { ARS11-VMCC-1550 ARS11-VMCC-1550:PRESSURE } + { ARS11-VMCC-3510 ARS11-VMCC-3510:PRESSURE } + { ARS11-VMCC-5460 ARS11-VMCC-5460:PRESSURE } + { ARS12-VMCC-0110 ARS12-VMCC-0110:PRESSURE } + { ARS12-VMCC-1550 ARS12-VMCC-1550:PRESSURE } + { ARS12-VMCC-3510 ARS12-VMCC-3510:PRESSURE } + { ARS12-VMCC-5460 ARS12-VMCC-5460:PRESSURE } +} \ No newline at end of file diff --git a/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_parameters.yaml b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/postmortemlog/current/ioc/POSTMORTEMLOG.template b/services/postmortemlog/current/ioc/POSTMORTEMLOG.template new file mode 100644 index 0000000..857d84a --- /dev/null +++ b/services/postmortemlog/current/ioc/POSTMORTEMLOG.template @@ -0,0 +1,37 @@ +# This is a template for preaparing an IOC providing BD Service specific PVs +# Access Security Groups: +# DEFAULT - logt wenn EGU oder so veraendert werden +# LOG - logt wenn neuer wert geschrieben wird +# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL +# READONLY - verhindert versuchte caputs und aktiviert caputlog +# Input links can specify CA, CP, or CPP. +# If the input link specifies CA, it will be forced to be a Channel Access link. +# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. +# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. +# + +record(ao, "$(DEVICE):AO") { + field(DESC, "Analog Output Record (ao)") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):BO") { + field(DESC, "Binary Output Record (bo)") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# TODO: ok? +record(bo, "$(DEVICE):CALLBACK") { + field(DESC, "Callback PV to listen to for changes") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/postmortemlog/current/ioc/startup.script b/services/postmortemlog/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/postmortemlog/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/postmortemlog/current/qt/A_BD_PostMortemLog.ui b/services/postmortemlog/current/qt/A_BD_PostMortemLog.ui new file mode 100644 index 0000000..0d48d96 --- /dev/null +++ b/services/postmortemlog/current/qt/A_BD_PostMortemLog.ui @@ -0,0 +1,1197 @@ + + + MainWindow + + + Qt::WindowModal + + + + 0 + 0 + 1200 + 1275 + + + + MainWindow + + + false + + + + + + + + + 1460 + 210 + 70 + 20 + + + + + + + 1460 + 150 + 70 + 20 + + + + Reload + + + RELOAD + + + A + + + AGEBD-ALH:POSTMORTEMLOG-GUIRELOAD + + + caCalc::TriggerZeroToOne + + + + + + 1450 + 260 + 91 + 21 + + + + 99999 + + + true + + + AGEBD-MASTER:LOG + + + + + + 5 + 5 + 1190 + 1265 + + + + 3 + + + + Live + + + + + 5 + 415 + 1175 + 200 + + + + Horizontal Tune (nominal: Qx = 39.37) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-QX + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 620 + 1175 + 200 + + + + Vertival Tune (nominal: Qy = 15.22) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-QY + + + + 139 + 26 + 150 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 1030 + 1175 + 200 + + + + Vertival Beam Size (nominal: Sig_y = 10) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGY + + + + 118 + 23 + 130 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGY + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 154 + 30 + 170 + + + + + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 825 + 1175 + 200 + + + + Horizontal Beam Size (nominal: Sig_x = 9) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGX + + + + 38 + 92 + 208 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGX + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 46 + 113 + 248 + + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 5 + 1175 + 200 + + + + Stored Beam Current + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-CURRPCT + + + + 0 + 255 + 0 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-CURRBPM + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 0 + 200 + 0 + + + + + + + + 255 + 255 + 255 + + + + + 0 + 200 + 0 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 210 + 1175 + 200 + + + + Beam Lifetime + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-TAUBPM + + + caCartesianPlot::FatDots + + + + 38 + 92 + 208 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-TAUPCT + + + caCartesianPlot::FatDots + + + caCartesianPlot::NoSymbol + + + + 46 + 113 + 248 + + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::User + + + -870;30 + + + 0;15 + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + Last + + + + + 5 + 1030 + 1175 + 200 + + + + Vertival Beam Size (nominal: Sig_y = 10) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGY-LAST + + + + 118 + 23 + 130 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGY-LAST + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 154 + 30 + 170 + + + + + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 5 + 1175 + 200 + + + + Stored Beam Current + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-CURRPCT-LAST + + + + 0 + 255 + 0 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-CURRBPM-LAST + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 0 + 200 + 0 + + + + + + + + 255 + 255 + 255 + + + + + 0 + 200 + 0 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 415 + 1175 + 200 + + + + Horizontal Tune (nominal: Qx = 39.37) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-QX-LAST + + + + 42 + 99 + 228 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 825 + 1175 + 200 + + + + Horizontal Beam Size (nominal: Sig_x = 9) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGX-LAST + + + + 38 + 92 + 208 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGX-LAST + + + caCartesianPlot::Lines + + + caCartesianPlot::NoSymbol + + + + 46 + 113 + 248 + + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 620 + 1175 + 200 + + + + Vertival Tune (nominal: Qy = 15.22) + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-QY-LAST + + + + 139 + 26 + 150 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::NoSymbol + + + + + + + 255 + 255 + 255 + + + + + 139 + 26 + 150 + + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + -870;30 + + + + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + 5 + 210 + 1175 + 200 + + + + Beam Lifetime + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-TAUBPM-LAST + + + caCartesianPlot::FatDots + + + + 38 + 92 + 208 + + + + AGEBD-POSTMORTEMLOG:BUFFER-TIME;AGEBD-POSTMORTEMLOG:BUFFER-TAUPCT-LAST + + + caCartesianPlot::FatDots + + + caCartesianPlot::NoSymbol + + + + 46 + 113 + 248 + + + + + + + + 255 + 255 + 255 + + + + + 42 + 99 + 228 + + + + caCartesianPlot::User + + + caCartesianPlot::User + + + -870;30 + + + 0;15 + + + true + + + false + + + 9 + + + caCartesianPlot::linear + + + + + + Historic + + + + + Debug + + + + + 0 + 40 + 1187 + 1200 + + + + QTextEdit::NoWrap + + + + + + 250 + 5 + 241 + 30 + + + + Update Logs + + + AGEBD-MASTER:POSTMORTEMLOG-LOGS-REQ + + + Update Logs + + + + 160 + 160 + 160 + + + + + + + 1 + + + + + + 0 + 5 + 241 + 30 + + + + Test Trigger Post Mortem + + + AGEBD-POSTMORTEMLOG:TEST + + + Test Trigger Post Mortem + + + + 160 + 160 + 160 + + + + + + + 1 + + + + + + + + + caMessageButton + QPushButton +
caMessageButton
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 1460 + 159 + + + 1460 + 222 + + + + + calineedit + textChanged(QString) + textBrowser + setHtml(QString) + + + 1495 + 270 + + + 600 + 671 + + + + +
diff --git a/services/postmortemlog/current/systemd/AGEBD-SERVICE-POSTMORTEMLOG.service b/services/postmortemlog/current/systemd/AGEBD-SERVICE-POSTMORTEMLOG.service new file mode 100644 index 0000000..eb0ff43 --- /dev/null +++ b/services/postmortemlog/current/systemd/AGEBD-SERVICE-POSTMORTEMLOG.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-POSTMORTEMLOG +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh POSTMORTEMLOG +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-POSTMORTEMLOG.service +# systemctl --user start AGEBD-SERVICE-POSTMORTEMLOG From f2537a62206b790770bfd3572e9def3719df5ac2 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 09:51:51 +0200 Subject: [PATCH 10/42] feature: add new service plots --- docs/ioc/ioc_overview.md | 2 +- services/plots/current/app/pyproject.toml | 47 +++ .../current/app/src/agebd_plots/__init__.py | 1 + .../plots/current/app/src/agebd_plots/main.py | 31 ++ .../current/app/src/agebd_plots/service.py | 93 ++++++ services/plots/current/app/tests/test_app.py | 9 + services/plots/current/app/uv.lock | 275 ++++++++++++++++++ .../current/ioc/AGEBD-CPCL-PLOTS_main.subs | 65 +++++ .../ioc/AGEBD-CPCL-PLOTS_parameters.yaml | 6 + services/plots/current/ioc/PLOTS.template | 37 +++ services/plots/current/ioc/startup.script | 1 + services/plots/current/qt/A_BD_.ui | 103 +++++++ .../systemd/AGEBD-SERVICE-PLOTS.service | 16 + 13 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 services/plots/current/app/pyproject.toml create mode 100644 services/plots/current/app/src/agebd_plots/__init__.py create mode 100644 services/plots/current/app/src/agebd_plots/main.py create mode 100644 services/plots/current/app/src/agebd_plots/service.py create mode 100644 services/plots/current/app/tests/test_app.py create mode 100644 services/plots/current/app/uv.lock create mode 100644 services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs create mode 100644 services/plots/current/ioc/AGEBD-CPCL-PLOTS_parameters.yaml create mode 100644 services/plots/current/ioc/PLOTS.template create mode 100644 services/plots/current/ioc/startup.script create mode 100644 services/plots/current/qt/A_BD_.ui create mode 100644 services/plots/current/systemd/AGEBD-SERVICE-PLOTS.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 4a9d401..843d604 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-POSTMORTEMLOG | | +| AGEBD-CPCL-PLOTS | | diff --git a/services/plots/current/app/pyproject.toml b/services/plots/current/app/pyproject.toml new file mode 100644 index 0000000..facd875 --- /dev/null +++ b/services/plots/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-plots" +version = "0.1.0" +description = "AGEBD-PLOTS Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/plots/current/app/src/agebd_plots/__init__.py b/services/plots/current/app/src/agebd_plots/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/plots/current/app/src/agebd_plots/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py new file mode 100644 index 0000000..a89cd64 --- /dev/null +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_plots import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "PLOTS" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/plots/current/app/src/agebd_plots/service.py b/services/plots/current/app/src/agebd_plots/service.py new file mode 100644 index 0000000..cbd8253 --- /dev/null +++ b/services/plots/current/app/src/agebd_plots/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-PLOTS:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-PLOTS:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-PLOTS:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/plots/current/app/tests/test_app.py b/services/plots/current/app/tests/test_app.py new file mode 100644 index 0000000..842d66f --- /dev/null +++ b/services/plots/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_plots import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/plots/current/app/uv.lock b/services/plots/current/app/uv.lock new file mode 100644 index 0000000..f8e7691 --- /dev/null +++ b/services/plots/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-plots" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs new file mode 100644 index 0000000..911e4f2 --- /dev/null +++ b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs @@ -0,0 +1,65 @@ +file AGEBD-CPCL-PLOTS_timeaxis.template { + pattern + { DEVICE } + { AGEBD-PLOTS } +} + + +file AGEBD-CPCL-PLOTS_9h.template { + pattern + { NAME, INP } + { CURRENT, AGEBD-PARAMS:CURRENT } + { CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } + { CURRENT-PCT, ARS07-DPCT-0000:CURR } + { INJECTION-RATE, AGEBD-PARAMS:INJECTION-RATE } + { TRANSMISSION, AGEBD-PARAMS:TRANSMISSION } + { LIFETIME, AGEBD-PARAMS:LIFETIME } + { MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } + { MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } + { FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } + { FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } + { ABRTL-DDRM-0670, ABRTL-DDRM-0670:FET1_BIAS_DOSE} + { ABRTL-DDRM-0950, ABRTL-DDRM-0950:FET1_DOSE} + { X05LA-DDRM-0330, X05LA-DDRM-0330:FET1_BIAS_DOSE} + { X05LA-DDRM-0650, X05LA-DDRM-0650:FET1_BIAS_DOSE} + { X09LA-DDRM-0330, X09LA-DDRM-0330:FET1_BIAS_DOSE} + { X09LA-DDRM-0790, X09LA-DDRM-0790:FET1_BIAS_DOSE} + { ARS01-DDRM-0375, ARS01-DDRM-0375:FET1_DOSE} + { ARS01-DDRM-1530, ARS01-DDRM-1530:FET1_BIAS_DOSE} + { ARS05-DDRM-1530, ARS05-DDRM-1530:FET1_BIAS_DOSE} + { ARS05-DDRM-3500, ARS05-DDRM-3500:FET1_BIAS_DOSE} + { ARS09-DDRM-1530, ARS09-DDRM-1530:FET1_BIAS_DOSE} + { ARS09-DDRM-3500, ARS09-DDRM-3500:FET2_BIAS_DOSE} + { ARS12-DDRM-1530, ARS12-DDRM-1530:FET1_BIAS_DOSE} + { ARS12-DDRM-3500, ARS12-DDRM-3500:FET1_BIAS_DOSE} + { ARS12-DDRM-4400, ARS12-DDRM-4400:FET1_BIAS_DOSE} + { ARS12-DDRM-5480, ARS12-DDRM-5480:FET1_BIAS_DOSE} + { X02SA-UIND-GAP, AGEOP-STATUS:X02SA-UIND-GAP} # Soft Blue #A0C4FF + # { X03MA-UIND-GAP, AGEOP-STATUS:X03MA-UIND-GAP} # Warm Orange #FFD6A5 + { X04SA-UIND-GAP, AGEOP-STATUS:X04SA-UIND-GAP} # Light Green #CAFFBF + # { X05LA-UIND-GAP, AGEOP-STATUS:X05LA-UIND-GAP} # Coral Red #FFADAD + { X06SA-UIND-GAP, AGEOP-STATUS:X06SA-UIND-GAP} # Lavender #CDB4DB + # { X07MA-UIND-GAP, AGEOP-STATUS:X07MA-UIND-GAP} # Desert Tan #DDB892 + # { X08SA-UIND-GAP, AGEOP-STATUS:X08SA-UIND-GAP} # Peach Pink #FFB5A7 + { X09LB-UIND-GAP, AGEOP-STATUS:X09LB-UIND-GAP} # Aqua Blue #9BF6FF + { X10SA-UIND-GAP, AGEOP-STATUS:X10SA-UIND-GAP} # Pale Yellow #FDFFB6 + { X11MA-UIND2-GAP, AGEOP-STATUS:X11MA-UIND2-GAP} # Periwinkle #BDB2FF + { X12SA-UIND-GAP, AGEOP-STATUS:X12SA-UIND-GAP} # Mint Green #B0F2C2 +} + +file AGEBD-CPCL-PLOTS_week.template { + pattern + { NAME, INP } + { CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } + { CURRENT-PCT, ARS07-DPCT-0000:CURR } + { TAU-BPM, AGEBD-TAUBPM:TAU } + { TAU-PCT, AGEBD-TAUPCT:TAU } + { TAU-TOPUP, AGEBD-SCRUBBING:TOPUP-TAU } + { INJRATE-BPM, AGEBD-TAUBPM:INJRATE } + { INJRATE-PCT, AGEBD-TAUPCT:INJRATE } + { MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } + { MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } + { FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } + { FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } +} + diff --git a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_parameters.yaml b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/plots/current/ioc/PLOTS.template b/services/plots/current/ioc/PLOTS.template new file mode 100644 index 0000000..857d84a --- /dev/null +++ b/services/plots/current/ioc/PLOTS.template @@ -0,0 +1,37 @@ +# This is a template for preaparing an IOC providing BD Service specific PVs +# Access Security Groups: +# DEFAULT - logt wenn EGU oder so veraendert werden +# LOG - logt wenn neuer wert geschrieben wird +# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL +# READONLY - verhindert versuchte caputs und aktiviert caputlog +# Input links can specify CA, CP, or CPP. +# If the input link specifies CA, it will be forced to be a Channel Access link. +# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. +# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. +# + +record(ao, "$(DEVICE):AO") { + field(DESC, "Analog Output Record (ao)") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):BO") { + field(DESC, "Binary Output Record (bo)") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# TODO: ok? +record(bo, "$(DEVICE):CALLBACK") { + field(DESC, "Callback PV to listen to for changes") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/plots/current/ioc/startup.script b/services/plots/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/plots/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/plots/current/qt/A_BD_.ui b/services/plots/current/qt/A_BD_.ui new file mode 100644 index 0000000..0fa9278 --- /dev/null +++ b/services/plots/current/qt/A_BD_.ui @@ -0,0 +1,103 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 60 + 100 + 50 + + + + 1 + + + 0 + + + AGEBD-PLOTS-DEV:AO + + + 9.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 0 + 601 + 22 + + + + Toggle AGEBD-ALH-DEV:PLOTS-ONOFF + + + AGEBD-ALH-DEV:PLOTS-ONOFF + + + + + + 6 + 34 + 401 + 21 + + + + + 13 + + + + Value of AGEBD-PLOTS-DEV:AO + + + + + + + 0 + 0 + 800 + 20 + + + + + + + + caNumeric + QFrame +
caNumeric
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+
+ + +
diff --git a/services/plots/current/systemd/AGEBD-SERVICE-PLOTS.service b/services/plots/current/systemd/AGEBD-SERVICE-PLOTS.service new file mode 100644 index 0000000..a1b82cd --- /dev/null +++ b/services/plots/current/systemd/AGEBD-SERVICE-PLOTS.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-PLOTS +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh PLOTS +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-PLOTS.service +# systemctl --user start AGEBD-SERVICE-PLOTS From 9a83b97bc732d197ef5cdf32bb6d8028ea46e1e9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 10:03:38 +0200 Subject: [PATCH 11/42] chore: migrate remaining ui files --- services/plots/current/qt/A_BD_.ui | 103 ----------------------------- 1 file changed, 103 deletions(-) delete mode 100644 services/plots/current/qt/A_BD_.ui diff --git a/services/plots/current/qt/A_BD_.ui b/services/plots/current/qt/A_BD_.ui deleted file mode 100644 index 0fa9278..0000000 --- a/services/plots/current/qt/A_BD_.ui +++ /dev/null @@ -1,103 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - MainWindow - - - - - - 0 - 60 - 100 - 50 - - - - 1 - - - 0 - - - AGEBD-PLOTS-DEV:AO - - - 9.000000000000000 - - - 0.000000000000000 - - - - - - 0 - 0 - 601 - 22 - - - - Toggle AGEBD-ALH-DEV:PLOTS-ONOFF - - - AGEBD-ALH-DEV:PLOTS-ONOFF - - - - - - 6 - 34 - 401 - 21 - - - - - 13 - - - - Value of AGEBD-PLOTS-DEV:AO - - - - - - - 0 - 0 - 800 - 20 - - - - - - - - caNumeric - QFrame -
caNumeric
-
- - caToggleButton - QCheckBox -
caToggleButton
-
-
- - -
From 9baee1b8c5c92fc573227018f611150f7e8900db Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 10:04:10 +0200 Subject: [PATCH 12/42] chore: migrate remaining ui files --- .../current/qt/A_BD_InjectionGuard_inc.ui | 243 ++++ .../current/qt/A_BD_OrbitBump_Expert.ui | 465 ++++++ .../current/qt/A_BD_OrbitBump_ExpertBackUp.ui | 183 +++ .../current/qt/A_BD_OrbitBump_Expert_all.ui | 1273 +++++++++++++++++ .../current/qt/A_BD_OrbitBump_Expert_inc.ui | 627 ++++++++ .../current/qt/A_BD_OrbitBump_Operator.ui | 291 ++++ .../current/qt/A_BD_OrbitBump_Operator_inc.ui | 159 ++ services/plots/current/qt/A_BD_Plots.ui | 103 ++ 8 files changed, 3344 insertions(+) create mode 100644 services/injectionguard/current/qt/A_BD_InjectionGuard_inc.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_Expert.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_ExpertBackUp.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_Expert_all.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_Expert_inc.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_Operator.ui create mode 100644 services/orbitbump/current/qt/A_BD_OrbitBump_Operator_inc.ui create mode 100644 services/plots/current/qt/A_BD_Plots.ui diff --git a/services/injectionguard/current/qt/A_BD_InjectionGuard_inc.ui b/services/injectionguard/current/qt/A_BD_InjectionGuard_inc.ui new file mode 100644 index 0000000..1170830 --- /dev/null +++ b/services/injectionguard/current/qt/A_BD_InjectionGuard_inc.ui @@ -0,0 +1,243 @@ + + + MainWindow + + + + 0 + 0 + 580 + 30 + + + + MainWindow + + + + + + 380 + 6 + 18 + 18 + + + + + 20 + 20 + + + + AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(checknr) + + + + 200 + 200 + 200 + + + + caToggleButton::Default + + + 1 + + + caToggleButton::on_top + + + + + + 220 + 0 + 40 + 30 + + + + false + + + AGEBD-INJECTIONGUARD:CHECK-$(checknr) + + + caLed::Alarm + + + + + + 280 + 0 + 40 + 30 + + + + false + + + AGEBD-INJECTIONGUARD:CHECK-$(checknr)-MD + + + caLed::Alarm + + + + + + 0 + 0 + 200 + 30 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGEBD-INJECTIONGUARD:CHECK-$(checknr).DESC + + + + 160 + 160 + 164 + + + + caLineEdit::Static + + + caLineEdit::None + + + + + + 460 + 0 + 120 + 30 + + + + + 160 + 160 + 164 + + + + caFrame::Outline + + + caFrame::Calc + + + caFrame::All + + + $(latch) + + + + + + + + 40 + 0 + 40 + 30 + + + + false + + + AGEBD-INJECTIONGUARD:CHECK-$(checknr)-LATCH + + + caLed::Alarm + + + + + + + 376 + 4 + 22 + 23 + + + + true + + + false + + + 20 + + + 20 + + + AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(checknr) + + + caLed::Alarm + + + + 0 + 0 + 0 + + + + + + + + caToggleButton + QCheckBox +
caToggleButton
+
+ + caFrame + QFrame +
caFrame
+ 1 +
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+
+ + +
+ diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_Expert.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert.ui new file mode 100644 index 0000000..328eafb --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert.ui @@ -0,0 +1,465 @@ + + + MainWindow + + + + 0 + 0 + 1801 + 196 + + + + MainWindow + + + + + + 10 + 72 + 1790 + 120 + + + + sourcepoint=$(sourcepoint),beamline=$(beamline) + + + A_BD_OrbitBump_Expert_inc.ui + + + 1 + + + 1 + + + + + + 240 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 354 + 42 + 100 + 30 + + + + + 15 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + 462 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 574 + 42 + 100 + 30 + + + + + 15 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 686 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 1 + + + Qt::AlignCenter + + + + + + 966 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 2 + + + Qt::AlignCenter + + + + + + 1246 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 3 + + + Qt::AlignCenter + + + + + + 1526 + 42 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 4 + + + Qt::AlignCenter + + + + + + 791 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 876 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1071 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1156 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1631 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1351 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1716 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1436 + 42 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 0 + 0 + 1909 + 33 + + + + + Sans Serif + 20 + 75 + false + true + + + + $(sourcepoint) $(beamline) + + + Qt::AlignLeading + + + + 255 + 255 + 255 + + + + + 100 + 100 + 100 + + + + caLabel::Static + + + + + + + caLabel + QLabel +
caLabel
+
+ + caInclude + QWidget +
caInclude
+
+
+ + +
diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_ExpertBackUp.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_ExpertBackUp.ui new file mode 100644 index 0000000..780ccbc --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_ExpertBackUp.ui @@ -0,0 +1,183 @@ + + + MainWindow + + + + 0 + 0 + 1178 + 600 + + + + MainWindow + + + + + + 80 + 30 + 460 + 40 + + + + + 16 + 75 + true + + + + AGEBD-ORBITBUMP:BEAMLINE-BEND + + + + + + 650 + 30 + 460 + 40 + + + + + 16 + 75 + true + + + + AGEBD-ORBITBUMP:BEAMLINE-ID + + + + + + 270 + 340 + 501 + 51 + + + + AGEBD-ORBITBUMP:BEAMLINECALC + + + caLineEdit::Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 50 + 110 + 501 + 51 + + + + AGEBD-ORBITBUMP:BEAMLINETYPE-BEND + + + caLineEdit::Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 270 + 230 + 501 + 51 + + + + AGEBD-ORBITBUMP:BEAMLINETYPE + + + caLineEdit::Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 630 + 110 + 501 + 51 + + + + AGEBD-ORBITBUMP:BEAMLINETYPE-ID + + + caLineEdit::Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 260 + 450 + 501 + 51 + + + + AGEBD-ORBITBUMP:BEAMLINE + + + caLineEdit::Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + + caMenu + QComboBox +
caMenu
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+
+ + +
diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_all.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_all.ui new file mode 100644 index 0000000..b5f2dd1 --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_all.ui @@ -0,0 +1,1273 @@ + + + MainWindow + + + + 0 + 0 + 1819 + 1470 + + + + MainWindow + + + + + + 0 + 2 + 1837 + 33 + + + + + Sans Serif + 20 + 75 + false + true + + + + Beamline local Bumps Expert + + + Qt::AlignLeading + + + + 255 + 255 + 255 + + + + + 100 + 100 + 100 + + + + caLabel::Static + + + + + + 0 + 40 + 1819 + 1430 + + + + 0 + + + + Diagnostic Beamlines + + + + + 570 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 1629 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 964 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 2 + + + Qt::AlignCenter + + + + + + 240 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 1524 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 4 + + + Qt::AlignCenter + + + + + + 460 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 10 + 40 + 1790 + 242 + + + + sourcepoint=X01DD,beamline=NEMO;sourcepoint=X08DB,beamline=DISCO + + + A_BD_OrbitBump_Expert_inc.ui + + + 2 + + + 2 + + + + + + 684 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 1 + + + Qt::AlignCenter + + + + + + 1349 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 874 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1069 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 789 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1434 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1154 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1244 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 3 + + + Qt::AlignCenter + + + + + + 1714 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 350 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + Dipole Beamlines + + + + + 1067 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1242 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 3 + + + Qt::AlignCenter + + + + + + 682 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 1 + + + Qt::AlignCenter + + + + + + 1432 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 570 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 1627 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 240 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 350 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + 872 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1522 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 4 + + + Qt::AlignCenter + + + + + + 787 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 962 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 2 + + + Qt::AlignCenter + + + + + + 1347 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1152 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 460 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 1712 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 10 + 40 + 1790 + 1096 + + + + sourcepoint=X01DA,beamline=Debye;sourcepoint=X02DA,beamline=S-TOMCAT;sourcepoint=X03DA,beamline=PEARL;sourcepoint=X04DB,beamline=VUV;sourcepoint=X05DA,beamline=Optics;sourcepoint=X06DA,beamline=PXIII;sourcepoint=X07DB,beamline=nanoXAS;sourcepoint=X07DA,beamline=PolLux;sourcepoint=X10DA,beamline=SuperXAS + + + A_BD_OrbitBump_Expert_inc.ui + + + 9 + + + 2 + + + + + + ID Beamlines + + + + + 10 + 40 + 1790 + 1340 + + + + sourcepoint=X02SA,beamline=I-TOMCAT;sourcepoint=X03MA,beamline=ADRESS;sourcepoint=X04SA,beamline=ADDAMS;sourcepoint=X05LA,beamline=QUEST;sourcepoint=X06SA,beamline=PXI;sourcepoint=X07MA,beamline=Phoenix/XTreme;sourcepoint=X08SA,beamline=micro-XAS;sourcepoint=X09LA,beamline=PEARL/XIL-II;sourcepoint=X10SA,beamline=PXII;sourcepoint=X11MA,beamline=SIM;sourcepoint=X12SA,beamline=cSAXS + + + A_BD_OrbitBump_Expert_inc.ui + + + 11 + + + 2 + + + + + + 872 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1522 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 4 + + + Qt::AlignCenter + + + + + + 1627 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 682 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 1 + + + Qt::AlignCenter + + + + + + 1242 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 3 + + + Qt::AlignCenter + + + + + + 1432 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 240 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 787 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 350 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + 962 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + BPM 2 + + + Qt::AlignCenter + + + + + + 1067 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 1712 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + 1347 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dx + + + Qt::AlignCenter + + + + + + 460 + 6 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 570 + 6 + 100 + 30 + + + + + 15 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 1152 + 6 + 80 + 30 + + + + + 18 + 50 + false + + + + dy + + + Qt::AlignCenter + + + + + + + + + caLabel + QLabel +
caLabel
+
+ + caInclude + QWidget +
caInclude
+
+
+ + +
diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_inc.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_inc.ui new file mode 100644 index 0000000..2aa7420 --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_Expert_inc.ui @@ -0,0 +1,627 @@ + + + MainWindow + + + + 0 + 0 + 1790 + 120 + + + + MainWindow + + + + + + 779 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM1 + + + + + + 864 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM1 + + + + + + 1059 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM2 + + + + + + 1144 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM2 + + + + + + 230 + 1 + 100 + 30 + + + + 3 + + + 0 + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 340 + 1 + 100 + 30 + + + + 3 + + + 0 + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 560 + 1 + 100 + 30 + + + + 3 + + + 0 + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 450 + 1 + 100 + 30 + + + + 3 + + + 0 + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 1619 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM4 + + + + + + 1424 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM3 + + + + + + 1704 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM4 + + + + + + 1339 + 1 + 80 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM3 + + + + + + 674 + 1 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-BPM1 + + + + + + 954 + 1 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-BPM2 + + + + + + 1234 + 1 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-BPM3 + + + + + + 1514 + 1 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-BPM4 + + + + + + 450 + 42 + 100 + 30 + + + + 3 + + + 0 + + + $(sourcepoint)-ORBITBUMP:OFFSET-Y + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 230 + 42 + 100 + 30 + + + + 3 + + + 0 + + + $(sourcepoint)-ORBITBUMP:OFFSET-X + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 560 + 42 + 100 + 30 + + + + 3 + + + 0 + + + $(sourcepoint)-ORBITBUMP:OFFSET-YP + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 340 + 42 + 100 + 30 + + + + 3 + + + 0 + + + $(sourcepoint)-ORBITBUMP:OFFSET-XP + + + caSpinbox::Alarm + + + caSpinbox::User + + + true + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + 0 + 40 + 225 + 30 + + + + Beamline setpoint + + + + + + 0 + 0 + 1790 + 120 + + + + + + + 230 + 80 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL + + + caLineEdit::Alarm_Default + + + false + + + caLineEdit::onBackground + + + + + + 450 + 80 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 560 + 80 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 340 + 80 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 0 + 80 + 225 + 30 + + + + Total Bump + + + + + + 0 + 2 + 225 + 30 + + + + Machine setpoint + + + cagraphics + calineedit + calineedit_2 + calineedit_3 + calineedit_4 + caspinbox_2 + caspinbox_3 + caspinbox_4 + caspinbox_5 + calineedit_5 + calineedit_6 + calineedit_7 + calineedit_8 + calineedit_9 + calineedit_10 + calineedit_11 + calineedit_12 + caspinbox_6 + caspinbox_7 + caspinbox_8 + caspinbox_9 + calabel_3 + calineedit_17 + calineedit_18 + calineedit_19 + calineedit_20 + calabel_5 + calabel_6 + + + + + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caGraphics + QWidget +
caGraphics
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+
+ + +
diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_Operator.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_Operator.ui new file mode 100644 index 0000000..0a66761 --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_Operator.ui @@ -0,0 +1,291 @@ + + + MainWindow + + + + 0 + 0 + 770 + 950 + + + + MainWindow + + + + + + 10 + 190 + 750 + 346 + + + + sourcepoint=X01DA,beamline=Debye;sourcepoint=X02DA,beamline=S-TOMCAT;sourcepoint=X03DA,beamline=PEARL;sourcepoint=X04DB,beamline=VUV;sourcepoint=X05DA,beamline=Optics;sourcepoint=X06DA,beamline=PXIII;sourcepoint=X07DB,beamline=nanoXAS;sourcepoint=X07DA,beamline=PolLux;sourcepoint=X10DA,beamline=SuperXAS + + + A_BD_OrbitBump_Operator_inc.ui + + + 9 + + + 5 + + + + + + 10 + 80 + 750 + 80 + + + + sourcepoint=X01DD,beamline=NEMO;sourcepoint=X08DB,beamline=DISCO + + + A_BD_OrbitBump_Operator_inc.ui + + + 2 + + + 5 + + + + + + 10 + 160 + 261 + 30 + + + + + 18 + 75 + true + + + + Dipole Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 50 + 291 + 30 + + + + + 18 + 75 + true + + + + Diagnostic Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 530 + 261 + 30 + + + + + 18 + 75 + true + + + + ID Beamlines + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 10 + 560 + 750 + 541 + + + + sourcepoint=X02SA,beamline=I-TOMCAT;sourcepoint=X03MA,beamline=ADRESS;sourcepoint=X04SA,beamline=ADDAMS;sourcepoint=X05LA,beamline=QUEST;sourcepoint=X06SA,beamline=PXI;sourcepoint=X07MA,beamline=Phoenix/XTreme;sourcepoint=X08SA,beamline=micro-XAS;sourcepoint=X09LA,beamline=PEARL/XIL-II;sourcepoint=X10SA,beamline=PXII;sourcepoint=X11MA,beamline=SIM;sourcepoint=X12SA,beamline=cSAXS + + + A_BD_OrbitBump_Operator_inc.ui + + + 11 + + + 5 + + + + + + 330 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + X (um) + + + Qt::AlignCenter + + + + + + 440 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + X' (urad) + + + Qt::AlignCenter + + + + + + 550 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + Y (um) + + + Qt::AlignCenter + + + + + + 660 + 50 + 100 + 30 + + + + + 18 + 75 + true + + + + Y' (urad) + + + Qt::AlignCenter + + + + + + 590 + 10 + 170 + 30 + + + + Expert Panel + + + + 183 + 157 + 92 + + + + Expert Panel + + + A_BD_OrbitBump_Expert.ui + + + + + + + caRelatedDisplay + QWidget +
caRelatedDisplay
+
+ + caLabel + QLabel +
caLabel
+
+ + caInclude + QWidget +
caInclude
+
+
+ + +
diff --git a/services/orbitbump/current/qt/A_BD_OrbitBump_Operator_inc.ui b/services/orbitbump/current/qt/A_BD_OrbitBump_Operator_inc.ui new file mode 100644 index 0000000..2845c39 --- /dev/null +++ b/services/orbitbump/current/qt/A_BD_OrbitBump_Operator_inc.ui @@ -0,0 +1,159 @@ + + + MainWindow + + + + 0 + 0 + 750 + 30 + + + + MainWindow + + + + + + 160 + 0 + 150 + 30 + + + + $(beamline) + + + + + + 320 + 0 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL + + + caLineEdit::Alarm_Default + + + false + + + caLineEdit::onBackground + + + + + + 430 + 0 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 540 + 0 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 650 + 0 + 100 + 30 + + + + AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + + + + 0 + 0 + 150 + 30 + + + + -$(sourcepoint) Expert + + + + 183 + 157 + 92 + + + + $(sourcepoint) Expert + + + A_BD_OrbitBump_Expert.ui + + + sourcepoint=$(sourcepoint),beamline=$(beamline) + + + + + + + caRelatedDisplay + QWidget +
caRelatedDisplay
+
+ + caLabel + QLabel +
caLabel
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+
+ + +
diff --git a/services/plots/current/qt/A_BD_Plots.ui b/services/plots/current/qt/A_BD_Plots.ui new file mode 100644 index 0000000..0fa9278 --- /dev/null +++ b/services/plots/current/qt/A_BD_Plots.ui @@ -0,0 +1,103 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 60 + 100 + 50 + + + + 1 + + + 0 + + + AGEBD-PLOTS-DEV:AO + + + 9.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 0 + 601 + 22 + + + + Toggle AGEBD-ALH-DEV:PLOTS-ONOFF + + + AGEBD-ALH-DEV:PLOTS-ONOFF + + + + + + 6 + 34 + 401 + 21 + + + + + 13 + + + + Value of AGEBD-PLOTS-DEV:AO + + + + + + + 0 + 0 + 800 + 20 + + + + + + + + caNumeric + QFrame +
caNumeric
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+
+ + +
From 0771cffbfe28a0f5ffd593c6ef248882c2d8bb54 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 10:16:00 +0200 Subject: [PATCH 13/42] chore: copy missing ioc templates --- .../current/ioc/INJECTIONGUARD.template | 37 -- .../ioc/INJECTIONGUARD_automated.template | 89 ++++ .../ioc/INJECTIONGUARD_individual.template | 304 +++++++++++ .../orbitbump/current/ioc/ORBITBUMP.template | 37 -- .../current/ioc/ORBITBUMP_beamline.template | 87 +++ .../current/ioc/ORBITBUMP_machine.template | 504 ++++++++++++++++++ services/plots/current/ioc/PLOTS.template | 37 -- services/plots/current/ioc/PLOTS_9h.template | 8 + .../plots/current/ioc/PLOTS_timeaxis.template | 23 + .../plots/current/ioc/PLOTS_week.template | 8 + .../ioc/POSTMORTEMLOG_15min10Hz.template | 30 ++ 11 files changed, 1053 insertions(+), 111 deletions(-) delete mode 100644 services/injectionguard/current/ioc/INJECTIONGUARD.template create mode 100644 services/injectionguard/current/ioc/INJECTIONGUARD_automated.template create mode 100644 services/injectionguard/current/ioc/INJECTIONGUARD_individual.template delete mode 100644 services/orbitbump/current/ioc/ORBITBUMP.template create mode 100644 services/orbitbump/current/ioc/ORBITBUMP_beamline.template create mode 100644 services/orbitbump/current/ioc/ORBITBUMP_machine.template delete mode 100644 services/plots/current/ioc/PLOTS.template create mode 100644 services/plots/current/ioc/PLOTS_9h.template create mode 100644 services/plots/current/ioc/PLOTS_timeaxis.template create mode 100644 services/plots/current/ioc/PLOTS_week.template create mode 100644 services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD.template b/services/injectionguard/current/ioc/INJECTIONGUARD.template deleted file mode 100644 index 857d84a..0000000 --- a/services/injectionguard/current/ioc/INJECTIONGUARD.template +++ /dev/null @@ -1,37 +0,0 @@ -# This is a template for preaparing an IOC providing BD Service specific PVs -# Access Security Groups: -# DEFAULT - logt wenn EGU oder so veraendert werden -# LOG - logt wenn neuer wert geschrieben wird -# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL -# READONLY - verhindert versuchte caputs und aktiviert caputlog -# Input links can specify CA, CP, or CPP. -# If the input link specifies CA, it will be forced to be a Channel Access link. -# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. -# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. -# - -record(ao, "$(DEVICE):AO") { - field(DESC, "Analog Output Record (ao)") - field(ASG, "PROTECTED") - field(VAL, "0") - field(PINI, "YES") -} - -record(bo, "$(DEVICE):BO") { - field(DESC, "Binary Output Record (bo)") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} - -# TODO: ok? -record(bo, "$(DEVICE):CALLBACK") { - field(DESC, "Callback PV to listen to for changes") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} \ No newline at end of file diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template b/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template new file mode 100644 index 0000000..ebb7172 --- /dev/null +++ b/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template @@ -0,0 +1,89 @@ +record(bo, "AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(NR)") { + field(DESC, "Only in MD mode: bridge check $(NR)") + field(ASG, "PROTECTED") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(VAL, "0") + field(ZSV, "NO_ALARM") + field(OSV, "MINOR") + field(PINI, "YES") +} + +record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") { + field(DESC, "$(Description)") + field(ASG, "PROTECTED") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(ZSV, "MAJOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") + field(HIGH, "1") # Seconds until automatic switch to Alarm +} + +record(calc, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") { + field(DESC, "Check $(NR) MD, written by IOC") + field(ASG, "READONLY") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHFWD") + field(LOLO, "0.1") + field(LLSV, "MAJOR") + field(CALC, "A ? 1 : B") + field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(NR)") + field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") +} + +# forward only alarm states to latch bo +record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHFWD") { + field(DESC, "Latchfwd for check $(NR)") + field(ASG, "READONLY") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") + field(CALC, "$(Latch)? ( A? C : B ) : 1") + field(PINI, "YES") + field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE CP") + field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR) CP") + field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD CP") + field(OOPT, "When Zero") + field(DOPT, "Use CALC") + field(OUT, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH.VAL") +} + +# forward current state to latch bo on reset event +record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHRST") { + field(DESC, "Latchfwd for check $(NR)") + field(ASG, "READONLY") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") + field(SCAN, "Event") + field(EVNT, "5") + field(CALC, "$(Latch)? ( A? C : B ) : 1") + field(PINI, "YES") + field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE") + field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") + field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(OOPT, "Every Time") + field(DOPT, "Use CALC") + field(OUT, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH.VAL") +} + +record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") { + field(DESC, "$(Description)") + field(ASG, "READONLY") + field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-SUM-OP-A") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# emit event for master rearm when alarm state is left and non latched +record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-REARM-MASTER") { + field(DESC, "Rearm Master for non latched checks") + field(ASG, "NOACCESS") + field(CALC, "!$(Latch)? ( A? C : B ) : 1") + field(PINI, "YES") + field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE CP") + field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR) CP") + field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD CP") + field(OOPT, "Transition To Non-zero") + field(OEVT, "4") + field(ODLY, "0.1") +} + + \ No newline at end of file diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template b/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template new file mode 100644 index 0000000..b7c421f --- /dev/null +++ b/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template @@ -0,0 +1,304 @@ +# HLA Service Control Parameters + +record(mbbo, "$(DEVICE):CONTROL-MODE") { + field(DESC, "Mode of Injection Guard") + field(ASG, "PROTECTED") + field(FLNK, "$(DEVICE):CHECK-SUM") + field(ZRST, "User Operation") + field(ZRVL, "0") + field(ONST, "Machine Development") + field(ONVL, "1") + field(PINI, "YES") +} + +# Local events on this IOC +# 1 - secret master trigger inhibited +# 2 - gun trigger inhibited +# 3 - booster extraction trigger inhibited +# 4 - rearm of master trigger if sum signal ok again +# 5 - request to reset latches + +record(waveform,"$(DEVICE):LOG") { + field(DESC, "Last failed checks") + field(ASG, "PROTECTED") + field(FTVL, "CHAR") + field(NELM, "$(SIZE=60000)") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):LOG-PAUSE") { + field(DESC, "pause/start logging") + field(ASG, "PROTECTED") + field(ZNAM, "Start") + field(ONAM, "Pause") + field(VAL, "1") + field(PINI, "YES") + field(HIGH, "60") # Seconds until automatic switch back to run +} + +record(bo,"$(DEVICE):LOG-CLEAR") { + field(DESC, "Clear log of last failed checks") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bi,"$(DEVICE):STATUS-SECRET-MASTER") { + field(DESC, "Status of secret master trigger") + field(ASG, "READONLY") + field(ZSV, "MAJOR" ) + field(INP, "$(DEVICE):NOACCESS-SECRETMASTER CP") + field(PINI, "YES") +} + +record(bi,"$(DEVICE):NOACCESS-SECRETMASTER") { + field(DESC, "Status of secret master trigger") + field(ASG, "NOACCESS") + field(INP, "AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel-I CP") + field(PINI, "YES") +} + +record(calcout, "$(DEVICE):AUTO-REARM-MASTER-CALCOUT") { + field(DESC, "Automatic rearming of master trigger") + field(ASG, "READONLY") + field(SCAN, "Event") + field(EVNT, "4") + field(CALC, "(A > 0) ? 1 : 0") + field(INPA, "$(DEVICE):CHECK-SUM") + field(OOPT, "When Non-zero") + field(DOPT, "Use CALC") + field(OUT, "AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel") +} + +record(calcout, "$(DEVICE):OUTLINK-2-ONBEAM-FORWARD") { + field(DESC, "activate secret trigger if checks ok") + field(ASG, "READONLY") + field(CALC, "(A > 0) ? 0 : 1") + field(INPA, "$(DEVICE):CHECK-SUM") + field(OOPT, "Transition To Zero") + field(ODLY, "0") + field(DOPT, "Use OCAL") + field(OCAL, "1") + field(OUT, "AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel-I") +} + +record(calcout, "$(DEVICE):OUTLINK-2-ONBEAM-INHIBIT") { + field(DESC, "disable secret trigger if checks nok") + field(ASG, "READONLY") + field(CALC, "!A && B ? 0 : 1") + field(INPA, "$(DEVICE):CHECK-SUM") + field(INPB, "AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel-I CP") + field(OOPT, "When Zero") + field(OEVT, "1") + field(ODLY, "0") + field(DOPT, "Use CALC") + field(OUT, "AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel-I") +} + +# record(calcout, "$(DEVICE):OUTLINK-2-GUNTRI") { +# field(DESC, "disable gun if checks nok") +# field(ASG, "READONLY") +# field(CALC, "!A && B ? 0 : 1") +# field(INPA, "$(DEVICE):CHECK-SUM") +# field(INPB, "ALIRF-VME-A-GUN:CH1-MODE CP") +# field(OOPT, "Transition To Zero") +# field(OEVT, "2") +# field(ODLY, "0") +# field(DOPT, "Use CALC") +# field(OUT, "ALIRF-VME-A-GUN:CH1-MODE") +# } + +# record(calcout, "$(DEVICE):OUTLINK-2-BOOEXT") { +# field(DESC, "disable booster extraction if checks nok") +# field(ASG, "READONLY") +# field(CALC, "!A && B ? 0 : 1") +# field(INPA, "$(DEVICE):CHECK-SUM") +# field(INPB, "AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel CP") +# field(OOPT, "Transition To Zero") +# field(OEVT, "3") +# field(ODLY, "0") +# field(DOPT, "Use CALC") +# field(OUT, "AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel") +# } + +# Overall Check SUM +record(fanout, "$(DEVICE):CHECK-SUM-FANOUT") { + field(DESC, "FANOUT for checksum changes") + field(ASG, "READONLY") + field(SELM, "All") + field(LNK1, "$(DEVICE):OUTLINK-2-ONBEAM-FORWARD") + field(LNK2, "$(DEVICE):OUTLINK-2-ONBEAM-INHIBIT") + # field(LNK3, "$(DEVICE):OUTLINK-2-GUNTRI") + # field(LNK4, "$(DEVICE):OUTLINK-2-BOOEXT") +} + +record(mbbi, "$(DEVICE):CHECK-SUM") { + field(DESC, "Check SUM overall, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-FANOUT") + field(ASG, "READONLY") + field(ZRST, "Injection Inhibit") + field(ZRVL, "0") + field(ZRSV, "MAJOR") + field(ONST, "Injection Enabled") + field(ONVL, "1") + field(ONSV, "NO_ALARM") + field(TWST, "Linac Mode") + field(TWVL, "2") + field(TWSV, "MINOR") +} + +record(calcout, "$(DEVICE):CHECK-SUM-CALC") { + field(DESC, "Check SUM overall, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM") + field(ASG, "READONLY") + field(CALC, "!E & !F ? 2 : (A ? B & D : C & D)") + field(INPA, "$(DEVICE):CONTROL-MODE") + field(INPB, "$(DEVICE):CHECK-SUM-MD") + field(INPC, "$(DEVICE):CHECK-SUM-OP") + field(INPD, "$(DEVICE):CHECK-SUM-LATCH") + field(INPE, "ALI00-SGEN-PSYS:ALBSA-BB-OPEN") # Linac Mode, (0 closed, 1 opened) + field(INPF, "ALI00-SGEN-PSYS:ALBSA-KV-OPEN") # Linac Mode, (0 closed, 1 opened) + field(DOPT, "Use CALC") + field(OUT, "$(DEVICE):CHECK-SUM") +} + +# Check SUMs OP/MD +record(calc, "$(DEVICE):CHECK-SUM-OP-A") { + field(DESC, "Check SUM OP Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-OP") + field(ASG, "READONLY") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-12") + field(INPB, "$(DEVICE):CHECK-13") + field(INPC, "$(DEVICE):CHECK-14") + field(INPD, "$(DEVICE):CHECK-15") + field(INPE, "$(DEVICE):CHECK-16") + field(INPF, "$(DEVICE):CHECK-17") + field(INPG, "$(DEVICE):CHECK-18") + field(INPH, "$(DEVICE):CHECK-19") + field(INPI, "$(DEVICE):CHECK-20") + field(INPJ, "$(DEVICE):CHECK-21") + field(INPK, "$(DEVICE):CHECK-22") + field(INPL, "$(DEVICE):CHECK-23") +} + +record(calc, "$(DEVICE):CHECK-SUM-OP") { + field(DESC, "Check SUM OP Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-MD-A") + field(ASG, "READONLY") + field(LOLO, "0.1") + field(LLSV, "MAJOR") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-01") + field(INPB, "$(DEVICE):CHECK-02") + field(INPC, "$(DEVICE):CHECK-03") + field(INPD, "$(DEVICE):CHECK-04") + field(INPE, "$(DEVICE):CHECK-05") + field(INPF, "$(DEVICE):CHECK-06") + field(INPG, "$(DEVICE):CHECK-07") + field(INPH, "$(DEVICE):CHECK-08") + field(INPI, "$(DEVICE):CHECK-09") + field(INPJ, "$(DEVICE):CHECK-10") + field(INPK, "$(DEVICE):CHECK-11") + field(INPL, "$(DEVICE):CHECK-SUM-OP-A") +} + +record(calc, "$(DEVICE):CHECK-SUM-MD-A") { + field(DESC, "Check SUM MD Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-MD") + field(ASG, "READONLY") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-12-MD") + field(INPB, "$(DEVICE):CHECK-13-MD") + field(INPC, "$(DEVICE):CHECK-14-MD") + field(INPD, "$(DEVICE):CHECK-15-MD") + field(INPE, "$(DEVICE):CHECK-16-MD") + field(INPF, "$(DEVICE):CHECK-17-MD") + field(INPG, "$(DEVICE):CHECK-18-MD") + field(INPH, "$(DEVICE):CHECK-19-MD") + field(INPI, "$(DEVICE):CHECK-20-MD") + field(INPJ, "$(DEVICE):CHECK-21-MD") + field(INPK, "$(DEVICE):CHECK-22-MD") + field(INPL, "$(DEVICE):CHECK-23-MD") +} + +record(calc, "$(DEVICE):CHECK-SUM-MD") { + field(DESC, "Check SUM MD Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-LATCH-A") + field(ASG, "READONLY") + field(LOLO, "0.1") + field(LLSV, "MAJOR") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-01-MD") + field(INPB, "$(DEVICE):CHECK-02-MD") + field(INPC, "$(DEVICE):CHECK-03-MD") + field(INPD, "$(DEVICE):CHECK-04-MD") + field(INPE, "$(DEVICE):CHECK-05-MD") + field(INPF, "$(DEVICE):CHECK-06-MD") + field(INPG, "$(DEVICE):CHECK-07-MD") + field(INPH, "$(DEVICE):CHECK-08-MD") + field(INPI, "$(DEVICE):CHECK-09-MD") + field(INPJ, "$(DEVICE):CHECK-10-MD") + field(INPK, "$(DEVICE):CHECK-11-MD") + field(INPL, "$(DEVICE):CHECK-SUM-MD-A") +} + +record(calc, "$(DEVICE):CHECK-SUM-LATCH-A") { + field(DESC, "Check SUM LATCH Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-LATCH") + field(ASG, "READONLY") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-12-LATCH") + field(INPB, "$(DEVICE):CHECK-13-LATCH") + field(INPC, "$(DEVICE):CHECK-14-LATCH") + field(INPD, "$(DEVICE):CHECK-15-LATCH") + field(INPE, "$(DEVICE):CHECK-16-LATCH") + field(INPF, "$(DEVICE):CHECK-17-LATCH") + field(INPG, "$(DEVICE):CHECK-18-LATCH") + field(INPH, "$(DEVICE):CHECK-19-LATCH") + field(INPI, "$(DEVICE):CHECK-20-LATCH") + field(INPJ, "$(DEVICE):CHECK-21-LATCH") + field(INPK, "$(DEVICE):CHECK-22-LATCH") + field(INPL, "$(DEVICE):CHECK-23-LATCH") +} + +record(calc, "$(DEVICE):CHECK-SUM-LATCH") { + field(DESC, "Check SUM LATCH Mode, written by IOC") + field(FLNK, "$(DEVICE):CHECK-SUM-CALC") + field(ASG, "READONLY") + field(LOLO, "0.1") + field(LLSV, "MINOR") + field(CALC, "A & B & C & D & E & F & G & H & I & J & K & L") + field(INPA, "$(DEVICE):CHECK-01-LATCH") + field(INPB, "$(DEVICE):CHECK-02-LATCH") + field(INPC, "$(DEVICE):CHECK-03-LATCH") + field(INPD, "$(DEVICE):CHECK-04-LATCH") + field(INPE, "$(DEVICE):CHECK-05-LATCH") + field(INPF, "$(DEVICE):CHECK-06-LATCH") + field(INPG, "$(DEVICE):CHECK-07-LATCH") + field(INPH, "$(DEVICE):CHECK-08-LATCH") + field(INPI, "$(DEVICE):CHECK-09-LATCH") + field(INPJ, "$(DEVICE):CHECK-10-LATCH") + field(INPK, "$(DEVICE):CHECK-11-LATCH") + field(INPL, "$(DEVICE):CHECK-SUM-LATCH-A") +} + +record(bo, "AGEBD-INJECTIONGUARD:RESET-LATCHES") { + field(DESC, "Reset all Latches") + field(ASG, "PROTECTED") + field(FLNK, "AGEBD-INJECTIONGUARD:RESET-LATCHES-CALCOUT") + field(VAL, "0") + field(PINI, "YES") + field(HIGH, "1") # Seconds until automatic switch to 0 +} + +record(calcout, "AGEBD-INJECTIONGUARD:RESET-LATCHES-CALCOUT") { + field(DESC, "Reset all Latches") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") + field(CALC, "A") + field(INPA, "AGEBD-INJECTIONGUARD:RESET-LATCHES") + field(OOPT, "Transition To Non-zero") + field(OEVT, "5") +} diff --git a/services/orbitbump/current/ioc/ORBITBUMP.template b/services/orbitbump/current/ioc/ORBITBUMP.template deleted file mode 100644 index 857d84a..0000000 --- a/services/orbitbump/current/ioc/ORBITBUMP.template +++ /dev/null @@ -1,37 +0,0 @@ -# This is a template for preaparing an IOC providing BD Service specific PVs -# Access Security Groups: -# DEFAULT - logt wenn EGU oder so veraendert werden -# LOG - logt wenn neuer wert geschrieben wird -# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL -# READONLY - verhindert versuchte caputs und aktiviert caputlog -# Input links can specify CA, CP, or CPP. -# If the input link specifies CA, it will be forced to be a Channel Access link. -# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. -# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. -# - -record(ao, "$(DEVICE):AO") { - field(DESC, "Analog Output Record (ao)") - field(ASG, "PROTECTED") - field(VAL, "0") - field(PINI, "YES") -} - -record(bo, "$(DEVICE):BO") { - field(DESC, "Binary Output Record (bo)") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} - -# TODO: ok? -record(bo, "$(DEVICE):CALLBACK") { - field(DESC, "Callback PV to listen to for changes") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} \ No newline at end of file diff --git a/services/orbitbump/current/ioc/ORBITBUMP_beamline.template b/services/orbitbump/current/ioc/ORBITBUMP_beamline.template new file mode 100644 index 0000000..14ba98f --- /dev/null +++ b/services/orbitbump/current/ioc/ORBITBUMP_beamline.template @@ -0,0 +1,87 @@ +record(ao, "$(sourcepoint)-ORBITBUMP:OFFSET-X") { + field(DESC, "Beamline x offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "um") + field(PREC, "0") + field(VAL, "$(X)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(DRVH, "$(DRVH)") + field(DRVL, "$(DRVL)") + field(HOPR, "$(DRVH)") + field(LOPR, "$(DRVL)") + field(HIHI, "10") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-10") + field(LLSV, "MAJOR") +} + +record(ao, "$(sourcepoint)-ORBITBUMP:OFFSET-XP") { + field(DESC, "Beamline xp offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "urad") + field(PREC, "0") + field(VAL, "$(XP)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(DRVH, "$(DRVH)") + field(DRVL, "$(DRVL)") + field(HOPR, "$(DRVH)") + field(LOPR, "$(DRVL)") + field(HIHI, "10") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-10") + field(LLSV, "MAJOR") +} + +record(ao, "$(sourcepoint)-ORBITBUMP:OFFSET-Y") { + field(DESC, "Beamline y offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "um") + field(PREC, "0") + field(VAL, "$(Y)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(DRVH, "$(DRVH)") + field(DRVL, "$(DRVL)") + field(HOPR, "$(DRVH)") + field(LOPR, "$(DRVL)") + field(HIHI, "10") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-10") + field(LLSV, "MAJOR") +} + +record(ao, "$(sourcepoint)-ORBITBUMP:OFFSET-YP") { + field(DESC, "Beamline yp offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "urad") + field(PREC, "0") + field(VAL, "$(YP)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(DRVH, "$(DRVH)") + field(DRVL, "$(DRVL)") + field(HOPR, "$(DRVH)") + field(LOPR, "$(DRVL)") + field(HIHI, "10") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-10") + field(LLSV, "MAJOR") +} \ No newline at end of file diff --git a/services/orbitbump/current/ioc/ORBITBUMP_machine.template b/services/orbitbump/current/ioc/ORBITBUMP_machine.template new file mode 100644 index 0000000..31b8ed0 --- /dev/null +++ b/services/orbitbump/current/ioc/ORBITBUMP_machine.template @@ -0,0 +1,504 @@ +# # on request writing total bump values to machine bumps and zero beamline bumps +# record(bo, "AGEBD-ORBITBUMP:$(sourcepoint)-COPYOVER") { +# field(DESC, "Request zeroing of beamline offsets") +# field(ASG, "PROTECTED") +# field(PINI, "YES") +# field(ZNAM, "Idle") +# field(ONAM, "Trigger") +# field(OUT, "myDevice:addAndZero.PROC PP") +# } + +# record(seq, "AGEBD-ORBITBUMP:$(sourcepoint)-COPYOVER") { +# field(DESC, "On trigger: add PV_A to PV_B, zero PV_A") + +# field(DOL1, "myDevice:add_calc NPP NMS") # Value = A + B +# field(LNK1, "myDevice:PV_B PP MS") # Step 1: write sum to PV_B + +# field(DLY1, "0.1") # Wait 0.1s before next step + +# field(DOL2, "0") # Value = 0 +# field(LNK2, "myDevice:PV_A PP MS") # Step 2: zero PV_A +# } + + + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X") { + field(DESC, "Machine x offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "um") + field(PREC, "0") + field(VAL, "$(X)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(DRVH, "$(HIX)") + field(DRVL, "$(LOX)") + field(HOPR, "$(HIX)") + field(LOPR, "$(LOX)") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP") { + field(DESC, "Machine xp offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "urad") + field(PREC, "0") + field(VAL, "$(XP)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(DRVH, "$(HIXP)") + field(DRVL, "$(LOXP)") + field(HOPR, "$(HIXP)") + field(LOPR, "$(LOXP)") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y") { + field(DESC, "Machine y offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "um") + field(PREC, "0") + field(VAL, "$(Y)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(DRVH, "$(HIY)") + field(DRVL, "$(LOY)") + field(HOPR, "$(HIY)") + field(LOPR, "$(LOY)") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP") { + field(DESC, "Machine yp offset for $(beamline)") + field(ASG, "PROTECTED") + field(EGU, "urad") + field(PREC, "0") + field(VAL, "$(YP)") + field(PINI, "YES") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(DRVH, "$(HIYP)") + field(DRVL, "$(LOYP)") + field(HOPR, "$(HIYP)") + field(LOPR, "$(LOYP)") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +# Sum PVs for total desired orbit bumps, i.e., sum of machine and beamline +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") { + field(DESC, "Total x offset for $(beamline)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "0") + field(CALC, "A + B") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X") + field(INPB, "$(sourcepoint)-ORBITBUMP:OFFSET-X") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM1") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") { + field(DESC, "Total xp offset for $(beamline)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "0") + field(CALC, "A + B") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP") + field(INPB, "$(sourcepoint)-ORBITBUMP:OFFSET-XP") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM1") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") { + field(DESC, "Total y offset for $(beamline)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "0") + field(CALC, "A + B") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y") + field(INPB, "$(sourcepoint)-ORBITBUMP:OFFSET-Y") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM1") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") { + field(DESC, "Total y offset for $(beamline)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "0") + field(CALC, "A + B") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP") + field(INPB, "$(sourcepoint)-ORBITBUMP:OFFSET-YP") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM1") + field(HIHI, "100") + field(HHSV, "MAJOR") + field(HIGH, "1") + field(HSV, "MINOR") + field(LOW, "-1") + field(LSV, "MINOR") + field(LOLO, "-100") + field(LLSV, "MAJOR") +} + +# BPM1, C1xx, C1xpx, C1yy, C1ypy, + +record(stringout, "AGEBD-ORBITBUMP:$(sourcepoint)-BPM1") { + field(DESC, "$(BPM1)") + field(ASG, "READONLY") + field(VAL, "$(BPM1)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C1xx") { + field(DESC, "Coefficient dx2dx at $(BPM1)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C1xx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C1xpx") { + field(DESC, "Coefficient dxp2dx at $(BPM1)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C1xpx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C1yy") { + field(DESC, "Coefficient dy2dy at $(BPM1)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C1yy)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C1ypy") { + field(DESC, "Coefficient dyp2dy at $(BPM1)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C1ypy)") + field(PINI, "YES") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM1") { + field(DESC, "Hor. change for $(BPM1)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C1xx") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C1xpx") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM1):X-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM2") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM1") { + field(DESC, "Hor. change for $(BPM1)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C1yy") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C1ypy") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM1):Y-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM2") +} + +# BPM2, C2xx, C2xpx, C2yy, C2ypy, + +record(stringout, "AGEBD-ORBITBUMP:$(sourcepoint)-BPM2") { + field(DESC, "$(BPM2)") + field(ASG, "READONLY") + field(VAL, "$(BPM2)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C2xx") { + field(DESC, "Coefficient dx2dx at $(BPM2)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C2xx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C2xpx") { + field(DESC, "Coefficient dxp2dx at $(BPM2)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C2xpx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C2yy") { + field(DESC, "Coefficient dy2dy at $(BPM2)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C2yy)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C2ypy") { + field(DESC, "Coefficient dyp2dy at $(BPM2)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C2ypy)") + field(PINI, "YES") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM2") { + field(DESC, "Hor. change for $(BPM2)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C2xx") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C2xpx") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(INPE, "$(sourcepoint)-ORBITBUMP:OFFSET-X") + field(INPF, "$(sourcepoint)-ORBITBUMP:OFFSET-XP") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM2):X-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM3") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM2") { + field(DESC, "Hor. change for $(BPM2)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C2yy") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C2ypy") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM2):Y-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM3") +} + +# BPM3, C3xx, C3xpx, C3yy, C3ypy, + +record(stringout, "AGEBD-ORBITBUMP:$(sourcepoint)-BPM3") { + field(DESC, "$(BPM3)") + field(VAL, "$(BPM3)") + field(ASG, "READONLY") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C3xx") { + field(DESC, "Coefficient dx2dx at $(BPM3)") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C3xx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C3xpx") { + field(DESC, "Coefficient dxp2dx at $(BPM3)") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C3xpx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C3yy") { + field(DESC, "Coefficient dy2dy at $(BPM3)") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C3yy)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C3ypy") { + field(DESC, "Coefficient dyp2dy at $(BPM3)") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C3ypy)") + field(PINI, "YES") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM3") { + field(DESC, "Hor. change for $(BPM3)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C3xx") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C3xpx") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(INPE, "$(sourcepoint)-ORBITBUMP:OFFSET-X") + field(INPF, "$(sourcepoint)-ORBITBUMP:OFFSET-XP") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM3):X-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM4") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM3") { + field(DESC, "Hor. change for $(BPM3)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C3yy") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C3ypy") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM3):Y-B-REF-OP") + field(FLNK, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM4") +} + +# BPM4, C4xx, C4xpx, C4yy, C4ypy, + +record(stringout, "AGEBD-ORBITBUMP:$(sourcepoint)-BPM4") { + field(DESC, "$(BPM4)") + field(ASG, "READONLY") + field(VAL, "$(BPM4)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C4xx") { + field(DESC, "Coefficient dx2dx at $(BPM4)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C4xx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C4xpx") { + field(DESC, "Coefficient dxp2dx at $(BPM4)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C4xpx)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C4yy") { + field(DESC, "Coefficient dy2dy at $(BPM4)") + field(ASG, "READONLY") + field(EGU, "mm/mm") + field(PREC, "3") + field(VAL, "$(C4yy)") + field(PINI, "YES") +} + +record(ao, "AGEBD-ORBITBUMP:$(sourcepoint)-C4ypy") { + field(DESC, "Coefficient dyp2dy at $(BPM4)") + field(ASG, "READONLY") + field(EGU, "mm/mrad") + field(PREC, "3") + field(VAL, "$(C4ypy)") + field(PINI, "YES") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAX-BPM4") { + field(DESC, "Hor. change for $(BPM4)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C4xx") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-X-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C4xpx") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-XP-TOTAL") + field(INPE, "$(sourcepoint)-ORBITBUMP:OFFSET-X") + field(INPF, "$(sourcepoint)-ORBITBUMP:OFFSET-XP") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM4):X-B-REF-OP") +} + +record(calcout, "AGEBD-ORBITBUMP:$(sourcepoint)-DELTAY-BPM4") { + field(DESC, "Hor. change for $(BPM4)") + field(ASG, "READONLY") + field(SCAN, "Passive") + field(PREC, "3") + field(CALC, "A*B/1000 + C*D/1000") + field(INPA, "AGEBD-ORBITBUMP:$(sourcepoint)-C4yy") + field(INPB, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-Y-TOTAL") + field(INPC, "AGEBD-ORBITBUMP:$(sourcepoint)-C4ypy") + field(INPD, "AGEBD-ORBITBUMP:$(sourcepoint)-OFFSET-YP-TOTAL") + field(OOPT, "On Change") + field(DOPT, "Use CALC") + field(OUT, "$(BPM4):Y-B-REF-OP") +} \ No newline at end of file diff --git a/services/plots/current/ioc/PLOTS.template b/services/plots/current/ioc/PLOTS.template deleted file mode 100644 index 857d84a..0000000 --- a/services/plots/current/ioc/PLOTS.template +++ /dev/null @@ -1,37 +0,0 @@ -# This is a template for preaparing an IOC providing BD Service specific PVs -# Access Security Groups: -# DEFAULT - logt wenn EGU oder so veraendert werden -# LOG - logt wenn neuer wert geschrieben wird -# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL -# READONLY - verhindert versuchte caputs und aktiviert caputlog -# Input links can specify CA, CP, or CPP. -# If the input link specifies CA, it will be forced to be a Channel Access link. -# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. -# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. -# - -record(ao, "$(DEVICE):AO") { - field(DESC, "Analog Output Record (ao)") - field(ASG, "PROTECTED") - field(VAL, "0") - field(PINI, "YES") -} - -record(bo, "$(DEVICE):BO") { - field(DESC, "Binary Output Record (bo)") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} - -# TODO: ok? -record(bo, "$(DEVICE):CALLBACK") { - field(DESC, "Callback PV to listen to for changes") - field(ASG, "READONLY") - field(ZSV, "MINOR") - field(OSV, "NO_ALARM") - field(VAL, "1") - field(PINI, "YES") -} \ No newline at end of file diff --git a/services/plots/current/ioc/PLOTS_9h.template b/services/plots/current/ioc/PLOTS_9h.template new file mode 100644 index 0000000..9a7c3f6 --- /dev/null +++ b/services/plots/current/ioc/PLOTS_9h.template @@ -0,0 +1,8 @@ +## 9 Hour Plots +record(compress, "AGEBD-PLOTS:$(NAME)-9h-BUFFER") { + field(DESC, "9h Buffer for SLS Status Panel") + field(SCAN, "1 second") + field(INP, "$(INP)") + field(ALG, "Circular Buffer") + field(NSAM, "32400") +} diff --git a/services/plots/current/ioc/PLOTS_timeaxis.template b/services/plots/current/ioc/PLOTS_timeaxis.template new file mode 100644 index 0000000..974d670 --- /dev/null +++ b/services/plots/current/ioc/PLOTS_timeaxis.template @@ -0,0 +1,23 @@ +# 9 Hour Plots +record(waveform, "$(DEVICE):PAST-9-HOURS") { + field(DESC, "Time axis for 9h buffer") + field(EGU, "h") + field(FTVL, "FLOAT") + field(DTYP, "sequence") + field(NELM, "32400") + field(LOPR, "-9.0") + field(HOPR, "0.0") + field(PINI, "YES") +} + +# 1 Week Plot +record(waveform, "$(DEVICE):PAST-168-HOURS") { + field(DESC, "Time axis for 1 week buffer") + field(EGU, "h") + field(FTVL, "FLOAT") + field(DTYP, "sequence") + field(NELM, "604800") + field(LOPR, "-168.0") + field(HOPR, "0.0") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/plots/current/ioc/PLOTS_week.template b/services/plots/current/ioc/PLOTS_week.template new file mode 100644 index 0000000..8cceb13 --- /dev/null +++ b/services/plots/current/ioc/PLOTS_week.template @@ -0,0 +1,8 @@ +## 1 Week Plot +record(compress, "AGEBD-PLOTS:$(NAME)-168h-BUFFER") { + field(DESC, "1 Week Buffer for SLS Status Panel") + field(SCAN, "1 second") + field(INP, "$(INP)") + field(ALG, "Circular Buffer") + field(NSAM, "604800") +} \ No newline at end of file diff --git a/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template b/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template new file mode 100644 index 0000000..9f225f4 --- /dev/null +++ b/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template @@ -0,0 +1,30 @@ +# Circular Buffer Record for Live Copy of desired PVs +record (compress, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)") { + field(DESC, "15min 10Hz buffer for post mortem") + field(ASG, "READONLY") + field(SCAN, ".1 second") + field(INP, "$(INP)") + field(ALG, "Circular Buffer") + field(NSAM, "9000") +} + +# Records for automatically copying EPICS circular buffer Records after beam abort +record (waveform, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)-LAST"){ + field(DESC, "Copy of post mortem buffer") + field(ASG, "READONLY") + field(FTVL, "FLOAT") + field(NELM, "9000") + field(INP, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME) VAL") + field(SCAN, "Event") # Process on event + field(EVNT, "1") # Event number to trigger +} + +# Records for writing to from HLA when viewing beam abort data history +record (waveform, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)-HLA"){ + field(DESC, "Post mortem buffer filled by HLA") + field(ASG, "PROTECTED") + field(FTVL, "FLOAT") + field(NELM, "9000") +} + + From b470fdf0135fca76d82840b1f5b0466daf33e95d Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 10:17:23 +0200 Subject: [PATCH 14/42] fix: Plots template filenames --- services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs index 911e4f2..13c8179 100644 --- a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs +++ b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs @@ -1,11 +1,11 @@ -file AGEBD-CPCL-PLOTS_timeaxis.template { +file PLOTS_timeaxis.template { pattern { DEVICE } { AGEBD-PLOTS } } -file AGEBD-CPCL-PLOTS_9h.template { +file PLOTS_9h.template { pattern { NAME, INP } { CURRENT, AGEBD-PARAMS:CURRENT } @@ -47,7 +47,7 @@ file AGEBD-CPCL-PLOTS_9h.template { { X12SA-UIND-GAP, AGEOP-STATUS:X12SA-UIND-GAP} # Mint Green #B0F2C2 } -file AGEBD-CPCL-PLOTS_week.template { +file PLOTS_week.template { pattern { NAME, INP } { CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } From c660432e7e5d0e7a7b9675e75cca23eb6870ed26 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 10:31:11 +0200 Subject: [PATCH 15/42] chore: copy mission ioc stuff --- .../ioc/cfg/AGEBD-CPCL-DBPM3CURR_set1.req | 1 + .../current/ioc/cfg/AGEBD-CPCL-TIMING_set.req | 48 +++++++++++++++++++ services/plots/current/ioc/README.md | 28 +++++++++++ services/plots/current/ioc/startup.script | 5 +- .../postmortemlog/current/ioc/startup.script | 1 + .../current/ioc/cfg/AGEBD-CPCL-TIMING_set.req | 48 +++++++++++++++++++ services/tunebump/current/ioc/startup.script | 3 ++ 7 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-DBPM3CURR_set1.req create mode 100644 services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req create mode 100644 services/plots/current/ioc/README.md create mode 100644 services/timing/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req diff --git a/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-DBPM3CURR_set1.req b/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-DBPM3CURR_set1.req new file mode 100644 index 0000000..8c8c606 --- /dev/null +++ b/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-DBPM3CURR_set1.req @@ -0,0 +1 @@ +AGEBD-DBPM3CURR:ACCUMULATED-BEAM-DOSE \ No newline at end of file diff --git a/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req b/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req new file mode 100644 index 0000000..4e0f824 --- /dev/null +++ b/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req @@ -0,0 +1,48 @@ +#ENABLE-PASS=2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-GUN +AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-ictone +AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-icts23 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-llemast +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzQdm +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-500-PBU +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzScp +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly1PMU +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly2PMU +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINKI +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXKI +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-BTRICT +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK3 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK4 +AGEBD-TIMING:CONTROL-FLW-BCKT-GUN +AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-ictone +AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-icts23 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-llemast +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp1 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp2 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr1 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr2 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzQdm +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-500-PBU +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzScp +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly1PMU +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly2PMU +AGEBD-TIMING:CONTROL-FLW-BCKT-BOINKI +AGEBD-TIMING:CONTROL-FLW-BCKT-BOINSE +AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXKI +AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXSE +AGEBD-TIMING:CONTROL-FLW-BCKT-BTRICT +AGEBD-TIMING:CONTROL-FLW-BCKT-BTRBPM +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINSE +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK1 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK2 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK3 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK4 \ No newline at end of file diff --git a/services/plots/current/ioc/README.md b/services/plots/current/ioc/README.md new file mode 100644 index 0000000..13b004e --- /dev/null +++ b/services/plots/current/ioc/README.md @@ -0,0 +1,28 @@ +# Contact +:envelope: [Felix Armborst](mailto:felix.armborst@psi.ch) +:envelope: [Stefan Mäder](mailto:stefan.maeder@psi.ch) + +**The relevant panels are:**
+- 9h Plots for Panels (SLS status / Scrubbing) + +:pushpin: + Some useful tools/commands + +``` + ## ssh to you local clone of this repo on sls-lca + # (re-)install this ioc + ioc install -V --ioc AGEBD-CPCL-PLOTS + + # connect to ioc shell of running ioc and resart via ctrl+x to restart with made changes + ioc shell AGEBD-CPCL-PLOTS + + ## useful debugging commands + # get the most important variables,softioc server port etc + ioc boots AGEBD-CPCL-PLOTS + ioc records -f SLS --sort name --ioc AGEBD-CPCL-PLOTS >ioc_records.txt + ioc duplicates -f SLS + + # make a clean test installation + mkdir -p ./TTT; ioc install --instbase ./TTT --clean --ioc AGEBD-CPCL-PLOTS + meld ./TTT/AGEBD-CPCL-PLOTS /ioc/AGEBD-CPCL-PLOTS + ``` diff --git a/services/plots/current/ioc/startup.script b/services/plots/current/ioc/startup.script index 0fa52ff..4da8df1 100644 --- a/services/plots/current/ioc/startup.script +++ b/services/plots/current/ioc/startup.script @@ -1 +1,4 @@ -epicsEnvSet("ENGINEER", "armborst") +epicsEnvSet("ENGINEER", "Operation") +require array +require SynApps +addScan 300 diff --git a/services/postmortemlog/current/ioc/startup.script b/services/postmortemlog/current/ioc/startup.script index 0fa52ff..b62221c 100644 --- a/services/postmortemlog/current/ioc/startup.script +++ b/services/postmortemlog/current/ioc/startup.script @@ -1 +1,2 @@ epicsEnvSet("ENGINEER", "armborst") +require array diff --git a/services/timing/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req b/services/timing/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req new file mode 100644 index 0000000..4e0f824 --- /dev/null +++ b/services/timing/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req @@ -0,0 +1,48 @@ +#ENABLE-PASS=2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-GUN +AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-ictone +AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-icts23 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-llemast +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzQdm +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-500-PBU +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzScp +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly1PMU +AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly2PMU +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINKI +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXKI +AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-BTRICT +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINSE +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK1 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK2 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK3 +AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK4 +AGEBD-TIMING:CONTROL-FLW-BCKT-GUN +AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-ictone +AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-icts23 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-llemast +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp1 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp2 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr1 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr2 +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzQdm +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-500-PBU +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzScp +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly1PMU +AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly2PMU +AGEBD-TIMING:CONTROL-FLW-BCKT-BOINKI +AGEBD-TIMING:CONTROL-FLW-BCKT-BOINSE +AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXKI +AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXSE +AGEBD-TIMING:CONTROL-FLW-BCKT-BTRICT +AGEBD-TIMING:CONTROL-FLW-BCKT-BTRBPM +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINSE +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK1 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK2 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK3 +AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK4 \ No newline at end of file diff --git a/services/tunebump/current/ioc/startup.script b/services/tunebump/current/ioc/startup.script index 0fa52ff..5c6f31b 100644 --- a/services/tunebump/current/ioc/startup.script +++ b/services/tunebump/current/ioc/startup.script @@ -1 +1,4 @@ epicsEnvSet("ENGINEER", "armborst") +require fft +require array +require SynApps From 35a6253451de5b39c85cc2d1cbbb469b3e645668 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:11:08 +0200 Subject: [PATCH 16/42] feat: ioc template inj.guard --- .../ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs | 52 +++++++++---------- .../ioc/INJECTIONGUARD_individual.template | 8 +-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs index 9fe790b..10eab88 100644 --- a/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs +++ b/services/injectionguard/current/ioc/AGEBD-CPCL-INJECTIONGUARD_main.subs @@ -1,31 +1,31 @@ file INJECTIONGUARD_individual.template { pattern { DEVICE } - { AGEBD-INJECTIONGUARD } + { AGEBD-INJECTIONGUARD{{ agebd_env }} } } file INJECTIONGUARD_automated.template { - pattern { NR Latch Description } - { 01 1 "Beam Dump Kicker"} - { 02 1 "Dump Valve"} - { 03 1 "MIS"} - { 04 1 "VCS"} - { 05 1 "Linac KV/BB/BY"} - { 06 1 "RF Linac"} - { 07 1 "RF Booster"} - { 08 1 "RF Ring"} - { 09 1 "Magnets Pulsed"} - { 10 1 "Magnets Booster"} - { 11 1 "Magnets Corrector"} - { 12 1 "Magnets Ring"} - { 13 1 "Current Limit"} - { 14 1 "IDs Ready"} - { 15 1 "Single Bunch Charge"} - { 16 1 "Injection Quality"} - { 17 1 "Dump Quality"} - { 18 1 "Lifetime"} - { 19 1 "Tune"} - { 20 0 "Pingers"} - { 21 1 "Vacuum Pressure"} - { 22 1 "Orbit Deviation"} - { 23 1 "Beam Dump Controller"} -} \ No newline at end of file + pattern { DEVICE NR Latch Description } + { AGEBD-INJECTIONGUARD{{ agebd_env }} 01 1 "Beam Dump Kicker"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 02 1 "Dump Valve"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 03 1 "MIS"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 04 1 "VCS"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 05 1 "Linac KV/BB/BY"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 06 1 "RF Linac"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 07 1 "RF Booster"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 08 1 "RF Ring"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 09 1 "Magnets Pulsed"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 10 1 "Magnets Booster"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 11 1 "Magnets Corrector"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 12 1 "Magnets Ring"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 13 1 "Current Limit"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 14 1 "IDs Ready"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 15 1 "Single Bunch Charge"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 16 1 "Injection Quality"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 17 1 "Dump Quality"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 18 1 "Lifetime"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 19 1 "Tune"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 20 0 "Pingers"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 21 1 "Vacuum Pressure"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 22 1 "Orbit Deviation"} + { AGEBD-INJECTIONGUARD{{ agebd_env }} 23 1 "Beam Dump Controller"} +} diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template b/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template index b7c421f..b6e66d2 100644 --- a/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template +++ b/services/injectionguard/current/ioc/INJECTIONGUARD_individual.template @@ -283,22 +283,22 @@ record(calc, "$(DEVICE):CHECK-SUM-LATCH") { field(INPL, "$(DEVICE):CHECK-SUM-LATCH-A") } -record(bo, "AGEBD-INJECTIONGUARD:RESET-LATCHES") { +record(bo, "$(DEVICE):RESET-LATCHES") { field(DESC, "Reset all Latches") field(ASG, "PROTECTED") - field(FLNK, "AGEBD-INJECTIONGUARD:RESET-LATCHES-CALCOUT") + field(FLNK, "$(DEVICE):RESET-LATCHES-CALCOUT") field(VAL, "0") field(PINI, "YES") field(HIGH, "1") # Seconds until automatic switch to 0 } -record(calcout, "AGEBD-INJECTIONGUARD:RESET-LATCHES-CALCOUT") { +record(calcout, "$(DEVICE):RESET-LATCHES-CALCOUT") { field(DESC, "Reset all Latches") field(ASG, "PROTECTED") field(VAL, "0") field(PINI, "YES") field(CALC, "A") - field(INPA, "AGEBD-INJECTIONGUARD:RESET-LATCHES") + field(INPA, "$(DEVICE):RESET-LATCHES") field(OOPT, "Transition To Non-zero") field(OEVT, "5") } From e13e3d6d7179bc6133359a44e6f12d7370afd991 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:20:23 +0200 Subject: [PATCH 17/42] chore: injguard template --- .../ioc/INJECTIONGUARD_automated.template | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template b/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template index ebb7172..3661b8b 100644 --- a/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template +++ b/services/injectionguard/current/ioc/INJECTIONGUARD_automated.template @@ -1,17 +1,17 @@ -record(bo, "AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(NR)") { +record(bo, "$(DEVICE):CONTROL-BRIDGE-CHECK-$(NR)") { field(DESC, "Only in MD mode: bridge check $(NR)") field(ASG, "PROTECTED") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(FLNK, "$(DEVICE):CHECK-$(NR)-MD") field(VAL, "0") field(ZSV, "NO_ALARM") field(OSV, "MINOR") field(PINI, "YES") } -record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") { +record(bo, "$(DEVICE):CHECK-$(NR)") { field(DESC, "$(Description)") field(ASG, "PROTECTED") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(FLNK, "$(DEVICE):CHECK-$(NR)-MD") field(ZSV, "MAJOR") field(OSV, "NO_ALARM") field(VAL, "1") @@ -19,53 +19,53 @@ record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") { field(HIGH, "1") # Seconds until automatic switch to Alarm } -record(calc, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") { +record(calc, "$(DEVICE):CHECK-$(NR)-MD") { field(DESC, "Check $(NR) MD, written by IOC") field(ASG, "READONLY") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHFWD") + field(FLNK, "$(DEVICE):CHECK-$(NR)-LATCHFWD") field(LOLO, "0.1") field(LLSV, "MAJOR") field(CALC, "A ? 1 : B") - field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-BRIDGE-CHECK-$(NR)") - field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") + field(INPA, "$(DEVICE):CONTROL-BRIDGE-CHECK-$(NR)") + field(INPB, "$(DEVICE):CHECK-$(NR)") } # forward only alarm states to latch bo -record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHFWD") { +record(calcout, "$(DEVICE):CHECK-$(NR)-LATCHFWD") { field(DESC, "Latchfwd for check $(NR)") field(ASG, "READONLY") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") + field(FLNK, "$(DEVICE):CHECK-$(NR)-LATCH") field(CALC, "$(Latch)? ( A? C : B ) : 1") field(PINI, "YES") - field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE CP") - field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR) CP") - field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD CP") + field(INPA, "$(DEVICE):CONTROL-MODE CP") + field(INPB, "$(DEVICE):CHECK-$(NR) CP") + field(INPC, "$(DEVICE):CHECK-$(NR)-MD CP") field(OOPT, "When Zero") field(DOPT, "Use CALC") - field(OUT, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH.VAL") + field(OUT, "$(DEVICE):CHECK-$(NR)-LATCH.VAL") } # forward current state to latch bo on reset event -record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCHRST") { +record(calcout, "$(DEVICE):CHECK-$(NR)-LATCHRST") { field(DESC, "Latchfwd for check $(NR)") field(ASG, "READONLY") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") + field(FLNK, "$(DEVICE):CHECK-$(NR)-LATCH") field(SCAN, "Event") field(EVNT, "5") field(CALC, "$(Latch)? ( A? C : B ) : 1") field(PINI, "YES") - field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE") - field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR)") - field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD") + field(INPA, "$(DEVICE):CONTROL-MODE") + field(INPB, "$(DEVICE):CHECK-$(NR)") + field(INPC, "$(DEVICE):CHECK-$(NR)-MD") field(OOPT, "Every Time") field(DOPT, "Use CALC") - field(OUT, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH.VAL") + field(OUT, "$(DEVICE):CHECK-$(NR)-LATCH.VAL") } -record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") { +record(bo, "$(DEVICE):CHECK-$(NR)-LATCH") { field(DESC, "$(Description)") field(ASG, "READONLY") - field(FLNK, "AGEBD-INJECTIONGUARD:CHECK-SUM-OP-A") + field(FLNK, "$(DEVICE):CHECK-SUM-OP-A") field(ZSV, "MINOR") field(OSV, "NO_ALARM") field(VAL, "1") @@ -73,17 +73,15 @@ record(bo, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-LATCH") { } # emit event for master rearm when alarm state is left and non latched -record(calcout, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-REARM-MASTER") { +record(calcout, "$(DEVICE):CHECK-$(NR)-REARM-MASTER") { field(DESC, "Rearm Master for non latched checks") field(ASG, "NOACCESS") field(CALC, "!$(Latch)? ( A? C : B ) : 1") field(PINI, "YES") - field(INPA, "AGEBD-INJECTIONGUARD:CONTROL-MODE CP") - field(INPB, "AGEBD-INJECTIONGUARD:CHECK-$(NR) CP") - field(INPC, "AGEBD-INJECTIONGUARD:CHECK-$(NR)-MD CP") + field(INPA, "$(DEVICE):CONTROL-MODE CP") + field(INPB, "$(DEVICE):CHECK-$(NR) CP") + field(INPC, "$(DEVICE):CHECK-$(NR)-MD CP") field(OOPT, "Transition To Non-zero") field(OEVT, "4") field(ODLY, "0.1") } - - \ No newline at end of file From a189676c0379b8636e938966f31a92e6adc3576b Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:26:28 +0200 Subject: [PATCH 18/42] docs: orbitbump ioc --- services/orbitbump/current/ioc/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 services/orbitbump/current/ioc/README.md diff --git a/services/orbitbump/current/ioc/README.md b/services/orbitbump/current/ioc/README.md new file mode 100644 index 0000000..9a0741c --- /dev/null +++ b/services/orbitbump/current/ioc/README.md @@ -0,0 +1 @@ +# TODO: dev/prod templating From 5dc16b637515030b90ec1ef87171084a993bd2ab Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:32:02 +0200 Subject: [PATCH 19/42] feat: plots ioc dev/prod templates --- .../current/ioc/AGEBD-CPCL-PLOTS_main.subs | 103 +++++++++--------- services/plots/current/ioc/PLOTS_9h.template | 2 +- .../plots/current/ioc/PLOTS_week.template | 4 +- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs index 13c8179..250d28c 100644 --- a/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs +++ b/services/plots/current/ioc/AGEBD-CPCL-PLOTS_main.subs @@ -1,65 +1,64 @@ file PLOTS_timeaxis.template { pattern { DEVICE } - { AGEBD-PLOTS } + { AGEBD-PLOTS{{ agebd_env }} } } file PLOTS_9h.template { pattern - { NAME, INP } - { CURRENT, AGEBD-PARAMS:CURRENT } - { CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } - { CURRENT-PCT, ARS07-DPCT-0000:CURR } - { INJECTION-RATE, AGEBD-PARAMS:INJECTION-RATE } - { TRANSMISSION, AGEBD-PARAMS:TRANSMISSION } - { LIFETIME, AGEBD-PARAMS:LIFETIME } - { MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } - { MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } - { FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } - { FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } - { ABRTL-DDRM-0670, ABRTL-DDRM-0670:FET1_BIAS_DOSE} - { ABRTL-DDRM-0950, ABRTL-DDRM-0950:FET1_DOSE} - { X05LA-DDRM-0330, X05LA-DDRM-0330:FET1_BIAS_DOSE} - { X05LA-DDRM-0650, X05LA-DDRM-0650:FET1_BIAS_DOSE} - { X09LA-DDRM-0330, X09LA-DDRM-0330:FET1_BIAS_DOSE} - { X09LA-DDRM-0790, X09LA-DDRM-0790:FET1_BIAS_DOSE} - { ARS01-DDRM-0375, ARS01-DDRM-0375:FET1_DOSE} - { ARS01-DDRM-1530, ARS01-DDRM-1530:FET1_BIAS_DOSE} - { ARS05-DDRM-1530, ARS05-DDRM-1530:FET1_BIAS_DOSE} - { ARS05-DDRM-3500, ARS05-DDRM-3500:FET1_BIAS_DOSE} - { ARS09-DDRM-1530, ARS09-DDRM-1530:FET1_BIAS_DOSE} - { ARS09-DDRM-3500, ARS09-DDRM-3500:FET2_BIAS_DOSE} - { ARS12-DDRM-1530, ARS12-DDRM-1530:FET1_BIAS_DOSE} - { ARS12-DDRM-3500, ARS12-DDRM-3500:FET1_BIAS_DOSE} - { ARS12-DDRM-4400, ARS12-DDRM-4400:FET1_BIAS_DOSE} - { ARS12-DDRM-5480, ARS12-DDRM-5480:FET1_BIAS_DOSE} - { X02SA-UIND-GAP, AGEOP-STATUS:X02SA-UIND-GAP} # Soft Blue #A0C4FF - # { X03MA-UIND-GAP, AGEOP-STATUS:X03MA-UIND-GAP} # Warm Orange #FFD6A5 - { X04SA-UIND-GAP, AGEOP-STATUS:X04SA-UIND-GAP} # Light Green #CAFFBF - # { X05LA-UIND-GAP, AGEOP-STATUS:X05LA-UIND-GAP} # Coral Red #FFADAD - { X06SA-UIND-GAP, AGEOP-STATUS:X06SA-UIND-GAP} # Lavender #CDB4DB - # { X07MA-UIND-GAP, AGEOP-STATUS:X07MA-UIND-GAP} # Desert Tan #DDB892 - # { X08SA-UIND-GAP, AGEOP-STATUS:X08SA-UIND-GAP} # Peach Pink #FFB5A7 - { X09LB-UIND-GAP, AGEOP-STATUS:X09LB-UIND-GAP} # Aqua Blue #9BF6FF - { X10SA-UIND-GAP, AGEOP-STATUS:X10SA-UIND-GAP} # Pale Yellow #FDFFB6 - { X11MA-UIND2-GAP, AGEOP-STATUS:X11MA-UIND2-GAP} # Periwinkle #BDB2FF - { X12SA-UIND-GAP, AGEOP-STATUS:X12SA-UIND-GAP} # Mint Green #B0F2C2 + { DEVICE, NAME, INP } + { AGEBD-PLOTS{{ agebd_env }}, CURRENT, AGEBD-PARAMS:CURRENT } + { AGEBD-PLOTS{{ agebd_env }}, CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } + { AGEBD-PLOTS{{ agebd_env }}, CURRENT-PCT, ARS07-DPCT-0000:CURR } + { AGEBD-PLOTS{{ agebd_env }}, INJECTION-RATE, AGEBD-PARAMS:INJECTION-RATE } + { AGEBD-PLOTS{{ agebd_env }}, TRANSMISSION, AGEBD-PARAMS:TRANSMISSION } + { AGEBD-PLOTS{{ agebd_env }}, LIFETIME, AGEBD-PARAMS:LIFETIME } + { AGEBD-PLOTS{{ agebd_env }}, MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } + { AGEBD-PLOTS{{ agebd_env }}, MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } + { AGEBD-PLOTS{{ agebd_env }}, FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } + { AGEBD-PLOTS{{ agebd_env }}, FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } + { AGEBD-PLOTS{{ agebd_env }}, ABRTL-DDRM-0670, ABRTL-DDRM-0670:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ABRTL-DDRM-0950, ABRTL-DDRM-0950:FET1_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, X05LA-DDRM-0330, X05LA-DDRM-0330:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, X05LA-DDRM-0650, X05LA-DDRM-0650:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, X09LA-DDRM-0330, X09LA-DDRM-0330:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, X09LA-DDRM-0790, X09LA-DDRM-0790:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS01-DDRM-0375, ARS01-DDRM-0375:FET1_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS01-DDRM-1530, ARS01-DDRM-1530:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS05-DDRM-1530, ARS05-DDRM-1530:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS05-DDRM-3500, ARS05-DDRM-3500:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS09-DDRM-1530, ARS09-DDRM-1530:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS09-DDRM-3500, ARS09-DDRM-3500:FET2_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS12-DDRM-1530, ARS12-DDRM-1530:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS12-DDRM-3500, ARS12-DDRM-3500:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS12-DDRM-4400, ARS12-DDRM-4400:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, ARS12-DDRM-5480, ARS12-DDRM-5480:FET1_BIAS_DOSE} + { AGEBD-PLOTS{{ agebd_env }}, X02SA-UIND-GAP, AGEOP-STATUS:X02SA-UIND-GAP} # Soft Blue #A0C4FF + # { AGEBD-PLOTS{{ agebd_env }}, X03MA-UIND-GAP, AGEOP-STATUS:X03MA-UIND-GAP} # Warm Orange #FFD6A5 + { AGEBD-PLOTS{{ agebd_env }}, X04SA-UIND-GAP, AGEOP-STATUS:X04SA-UIND-GAP} # Light Green #CAFFBF + # { AGEBD-PLOTS{{ agebd_env }}, X05LA-UIND-GAP, AGEOP-STATUS:X05LA-UIND-GAP} # Coral Red #FFADAD + { AGEBD-PLOTS{{ agebd_env }}, X06SA-UIND-GAP, AGEOP-STATUS:X06SA-UIND-GAP} # Lavender #CDB4DB + # { AGEBD-PLOTS{{ agebd_env }}, X07MA-UIND-GAP, AGEOP-STATUS:X07MA-UIND-GAP} # Desert Tan #DDB892 + # { AGEBD-PLOTS{{ agebd_env }}, X08SA-UIND-GAP, AGEOP-STATUS:X08SA-UIND-GAP} # Peach Pink #FFB5A7 + { AGEBD-PLOTS{{ agebd_env }}, X09LB-UIND-GAP, AGEOP-STATUS:X09LB-UIND-GAP} # Aqua Blue #9BF6FF + { AGEBD-PLOTS{{ agebd_env }}, X10SA-UIND-GAP, AGEOP-STATUS:X10SA-UIND-GAP} # Pale Yellow #FDFFB6 + { AGEBD-PLOTS{{ agebd_env }}, X11MA-UIND2-GAP, AGEOP-STATUS:X11MA-UIND2-GAP} # Periwinkle #BDB2FF + { AGEBD-PLOTS{{ agebd_env }}, X12SA-UIND-GAP, AGEOP-STATUS:X12SA-UIND-GAP} # Mint Green #B0F2C2 } file PLOTS_week.template { pattern - { NAME, INP } - { CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } - { CURRENT-PCT, ARS07-DPCT-0000:CURR } - { TAU-BPM, AGEBD-TAUBPM:TAU } - { TAU-PCT, AGEBD-TAUPCT:TAU } - { TAU-TOPUP, AGEBD-SCRUBBING:TOPUP-TAU } - { INJRATE-BPM, AGEBD-TAUBPM:INJRATE } - { INJRATE-PCT, AGEBD-TAUPCT:INJRATE } - { MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } - { MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } - { FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } - { FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } + { DEVICE, NAME, INP } + { AGEBD-PLOTS{{ agebd_env }}, CURRENT-BPM, AGEBD-DBPM3CURR:CURRENT-AVG } + { AGEBD-PLOTS{{ agebd_env }}, CURRENT-PCT, ARS07-DPCT-0000:CURR } + { AGEBD-PLOTS{{ agebd_env }}, TAU-BPM, AGEBD-TAUBPM:TAU } + { AGEBD-PLOTS{{ agebd_env }}, TAU-PCT, AGEBD-TAUPCT:TAU } + { AGEBD-PLOTS{{ agebd_env }}, TAU-TOPUP, AGEBD-SCRUBBING:TOPUP-TAU } + { AGEBD-PLOTS{{ agebd_env }}, INJRATE-BPM, AGEBD-TAUBPM:INJRATE } + { AGEBD-PLOTS{{ agebd_env }}, INJRATE-PCT, AGEBD-TAUPCT:INJRATE } + { AGEBD-PLOTS{{ agebd_env }}, MAVAC-AVG, ARIVA-VMAVE:PRESS-AVE } + { AGEBD-PLOTS{{ agebd_env }}, MAVAC-MAX, ARIVA-VMAVE:PRESS-MAX } + { AGEBD-PLOTS{{ agebd_env }}, FEVAC-AVG, ARIVA-VMAVE-FE:PRESS-AVE } + { AGEBD-PLOTS{{ agebd_env }}, FEVAC-MAX, ARIVA-VMAVE-FE:PRESS-MAX } } - diff --git a/services/plots/current/ioc/PLOTS_9h.template b/services/plots/current/ioc/PLOTS_9h.template index 9a7c3f6..707d073 100644 --- a/services/plots/current/ioc/PLOTS_9h.template +++ b/services/plots/current/ioc/PLOTS_9h.template @@ -1,5 +1,5 @@ ## 9 Hour Plots -record(compress, "AGEBD-PLOTS:$(NAME)-9h-BUFFER") { +record(compress, "$(DEVICE):$(NAME)-9h-BUFFER") { field(DESC, "9h Buffer for SLS Status Panel") field(SCAN, "1 second") field(INP, "$(INP)") diff --git a/services/plots/current/ioc/PLOTS_week.template b/services/plots/current/ioc/PLOTS_week.template index 8cceb13..cd5e692 100644 --- a/services/plots/current/ioc/PLOTS_week.template +++ b/services/plots/current/ioc/PLOTS_week.template @@ -1,8 +1,8 @@ ## 1 Week Plot -record(compress, "AGEBD-PLOTS:$(NAME)-168h-BUFFER") { +record(compress, "$(DEVICE):$(NAME)-168h-BUFFER") { field(DESC, "1 Week Buffer for SLS Status Panel") field(SCAN, "1 second") field(INP, "$(INP)") field(ALG, "Circular Buffer") field(NSAM, "604800") -} \ No newline at end of file +} From 0e9b5585b8c3eb8feedaa41e5e3a5e59de2e3395 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:38:48 +0200 Subject: [PATCH 20/42] feat: postmortemlog ioc dev/prod templates --- .../ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs | 230 +++++++++--------- .../ioc/POSTMORTEMLOG_15min10Hz.template | 8 +- 2 files changed, 119 insertions(+), 119 deletions(-) diff --git a/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs index ff33687..628ba75 100644 --- a/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs +++ b/services/postmortemlog/current/ioc/AGEBD-CPCL-POSTMORTEMLOG_main.subs @@ -1,129 +1,129 @@ file POSTMORTEMLOG.template { pattern { DEVICE } - { AGEBD-POSTMORTEMLOG } + { AGEBD-POSTMORTEMLOG{{ agebd_env}} } } file POSTMORTEMLOG_15min10Hz.template { pattern - { NAME INP} + { DEVICE NAME INP} # ---------- BEAM CURRENT -------------- - { CURRBPM AGEBD-DBPM3CURR:CURRENT-AVG } - { CURRPCT ARS07-DPCT-0000:CURR } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} CURRBPM AGEBD-DBPM3CURR:CURRENT-AVG } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} CURRPCT ARS07-DPCT-0000:CURR } # ---------- BEAM LIFETIME -------------- - { TAUBPM AGEBD-TAUBPM:TAU } - { TAUPCT AGEBD-TAUPCT:TAU } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} TAUBPM AGEBD-TAUBPM:TAU } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} TAUPCT AGEBD-TAUPCT:TAU } # ---------- TUNES -------------- - { QX AGEBD-TUNEBUMP:QX } - { QY AGEBD-TUNEBUMP:QY } - { QZ AGEBD-TUNEBUMP:QZ } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} QX AGEBD-TUNEBUMP:QX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} QY AGEBD-TUNEBUMP:QY } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} QZ AGEBD-TUNEBUMP:QZ } # ---------- LOSSES -------------- - { ARS01-DDRM-0375 ARS01-DDRM-0375:FET1_DOSE } - { ABRTL-DDRM-0670 ABRTL-DDRM-0670:FET1_BIAS_DOSE } - { ABRTL-DDRM-0950 ABRTL-DDRM-0950:FET1_DOSE } - { ARS01-DDRM-1530 ARS01-DDRM-1530:FET1_BIAS_DOSE } - { X05LA-DDRM-0330 X05LA-DDRM-0330:FET1_BIAS_DOSE } - { ARS05-DDRM-1530 ARS05-DDRM-1530:FET1_BIAS_DOSE } - { ARS05-DDRM-3500 ARS05-DDRM-3500:FET1_BIAS_DOSE } - { X09LA-DDRM-0330 X09LA-DDRM-0330:FET1_BIAS_DOSE } - { ARS09-DDRM-1530 ARS09-DDRM-1530:FET1_BIAS_DOSE } - { ARS09-DDRM-3500 ARS09-DDRM-3500:FET2_BIAS_DOSE } - { ARS12-DDRM-1530 ARS12-DDRM-1530:FET1_BIAS_DOSE } - { ARS12-DDRM-3500 ARS12-DDRM-3500:FET2_BIAS_DOSE } - { ARS12-DDRM-4400 ARS12-DDRM-4400:FET2_BIAS_DOSE } - { ARS12-DDRM-5480 ARS12-DDRM-5480:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-DDRM-0375 ARS01-DDRM-0375:FET1_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ABRTL-DDRM-0670 ABRTL-DDRM-0670:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ABRTL-DDRM-0950 ABRTL-DDRM-0950:FET1_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-DDRM-1530 ARS01-DDRM-1530:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X05LA-DDRM-0330 X05LA-DDRM-0330:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-DDRM-1530 ARS05-DDRM-1530:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-DDRM-3500 ARS05-DDRM-3500:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X09LA-DDRM-0330 X09LA-DDRM-0330:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-DDRM-1530 ARS09-DDRM-1530:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-DDRM-3500 ARS09-DDRM-3500:FET2_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-DDRM-1530 ARS12-DDRM-1530:FET1_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-DDRM-3500 ARS12-DDRM-3500:FET2_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-DDRM-4400 ARS12-DDRM-4400:FET2_BIAS_DOSE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-DDRM-5480 ARS12-DDRM-5480:FET1_BIAS_DOSE } # ---------- RF -------------- - { MASTERFREQ-SET AGERF-MO01:FREQ-SET } - { MASTERFREQ-GET AGERF-MO01:FREQ-GET } - { RFPOW-0140-INP ARS05-RCAV-0140:CO1i-POWER-MAX } - { RFPOW-0060-INP ARS05-RCAV-0060:CO1i-POWER-MAX } - { RFPOW-0230-INP ARS05-RCAV-0230:CO1i-POWER-MAX } - { RFPOW-0310-INP ARS05-RCAV-0310:CO1i-POWER-MAX } - { RFPOW-0060-REF ARS05-RCAV-0060:CO1r-POWER-MAX } - { RFPOW-0140-REF ARS05-RCAV-0140:CO1r-POWER-MAX } - { RFPOW-0230-REF ARS05-RCAV-0230:CO1r-POWER-MAX } - { RFPOW-0310-REF ARS05-RCAV-0310:CO1r-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} MASTERFREQ-SET AGERF-MO01:FREQ-SET } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} MASTERFREQ-GET AGERF-MO01:FREQ-GET } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0140-INP ARS05-RCAV-0140:CO1i-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0060-INP ARS05-RCAV-0060:CO1i-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0230-INP ARS05-RCAV-0230:CO1i-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0310-INP ARS05-RCAV-0310:CO1i-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0060-REF ARS05-RCAV-0060:CO1r-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0140-REF ARS05-RCAV-0140:CO1r-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0230-REF ARS05-RCAV-0230:CO1r-POWER-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} RFPOW-0310-REF ARS05-RCAV-0310:CO1r-POWER-MAX } # ---------- BEAM SIZE -------------- - { X01DD-SIGX X01DD-FE-CAM1:SIG-X } - { X01DD-SIGY X01DD-FE-CAM1:SIG-Y } - { X08DB-SIGX X08DB-FE-CAM1:SIG-X } - { X08DB-SIGY X08DB-FE-CAM1:SIG-Y } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X01DD-SIGX X01DD-FE-CAM1:SIG-X } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X01DD-SIGY X01DD-FE-CAM1:SIG-Y } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X08DB-SIGX X08DB-FE-CAM1:SIG-X } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} X08DB-SIGY X08DB-FE-CAM1:SIG-Y } # ---------- VACUUM -------------- - { VACMAX ARIVA-VMAVE:PRESS-MAX } - { VACMAXFE ARIVA-VMAVE-FE:PRESS-MAX } - { ARS01-VMCC-0110 ARS01-VMCC-0110:PRESSURE } - { ARS01-VMCC-0210 ARS01-VMCC-0210:PRESSURE } - { ARS01-VMCC-0225 ARS01-VMCC-0225:PRESSURE } - { ARS01-VMCC-0310 ARS01-VMCC-0310:PRESSURE } - { ARS01-VMCC-1550 ARS01-VMCC-1550:PRESSURE } - { ARS01-VMCC-3510 ARS01-VMCC-3510:PRESSURE } - { ARS01-VMCC-5460 ARS01-VMCC-5460:PRESSURE } - { ARS02-VMCC-0110 ARS02-VMCC-0110:PRESSURE } - { ARS02-VMCC-0210 ARS02-VMCC-0210:PRESSURE } - { ARS02-VMCC-0310 ARS02-VMCC-0310:PRESSURE } - { ARS02-VMCC-1550 ARS02-VMCC-1550:PRESSURE } - { ARS02-VMCC-3510 ARS02-VMCC-3510:PRESSURE } - { ARS02-VMCC-5460 ARS02-VMCC-5460:PRESSURE } - { ARS03-VMCC-0110 ARS03-VMCC-0110:PRESSURE } - { ARS03-VMCC-0320 ARS03-VMCC-0320:PRESSURE } - { ARS03-VMCC-1550 ARS03-VMCC-1550:PRESSURE } - { ARS03-VMCC-3510 ARS03-VMCC-3510:PRESSURE } - { ARS03-VMCC-5460 ARS03-VMCC-5460:PRESSURE } - { ARS04-VMCC-0110 ARS04-VMCC-0110:PRESSURE } - { ARS04-VMCC-1550 ARS04-VMCC-1550:PRESSURE } - { ARS04-VMCC-3510 ARS04-VMCC-3510:PRESSURE } - { ARS04-VMCC-5460 ARS04-VMCC-5460:PRESSURE } - { ARS05-VMCC-0110 ARS05-VMCC-0110:PRESSURE } - { ARS05-VMCC-0115 ARS05-VMCC-0115:PRESSURE } - { ARS05-VMCC-0210 ARS05-VMCC-0210:PRESSURE } - { ARS05-VMCC-0215 ARS05-VMCC-0215:PRESSURE } - { ARS05-VMCC-0310 ARS05-VMCC-0310:PRESSURE } - { ARS05-VMCC-0315 ARS05-VMCC-0315:PRESSURE } - { ARS05-VMCC-0410 ARS05-VMCC-0410:PRESSURE } - { ARS05-VMCC-0415 ARS05-VMCC-0415:PRESSURE } - { ARS05-VMCC-0510 ARS05-VMCC-0510:PRESSURE } - { ARS05-VMCC-0520 ARS05-VMCC-0520:PRESSURE } - { ARS05-VMCC-0530 ARS05-VMCC-0530:PRESSURE } - { ARS05-VMCC-0810 ARS05-VMCC-0810:PRESSURE } - { ARS05-VMCC-1550 ARS05-VMCC-1550:PRESSURE } - { ARS05-VMCC-3510 ARS05-VMCC-3510:PRESSURE } - { ARS05-VMCC-5460 ARS05-VMCC-5460:PRESSURE } - { ARS06-VMCC-0110 ARS06-VMCC-0110:PRESSURE } - { ARS06-VMCC-1550 ARS06-VMCC-1550:PRESSURE } - { ARS06-VMCC-3510 ARS06-VMCC-3510:PRESSURE } - { ARS06-VMCC-5460 ARS06-VMCC-5460:PRESSURE } - { ARS07-VMCC-0010 ARS07-VMCC-0010:PRESSURE } - { ARS07-VMCC-0120 ARS07-VMCC-0120:PRESSURE } - { ARS07-VMCC-0210 ARS07-VMCC-0210:PRESSURE } - { ARS07-VMCC-1550 ARS07-VMCC-1550:PRESSURE } - { ARS07-VMCC-3510 ARS07-VMCC-3510:PRESSURE } - { ARS07-VMCC-5460 ARS07-VMCC-5460:PRESSURE } - { ARS08-VMCC-0110 ARS08-VMCC-0110:PRESSURE } - { ARS08-VMCC-1550 ARS08-VMCC-1550:PRESSURE } - { ARS08-VMCC-3510 ARS08-VMCC-3510:PRESSURE } - { ARS08-VMCC-5460 ARS08-VMCC-5460:PRESSURE } - { ARS09-VMCC-0110 ARS09-VMCC-0110:PRESSURE } - { ARS09-VMCC-0120 ARS09-VMCC-0120:PRESSURE } - { ARS09-VMCC-0410 ARS09-VMCC-0410:PRESSURE } - { ARS09-VMCC-0510 ARS09-VMCC-0510:PRESSURE } - { ARS09-VMCC-0810 ARS09-VMCC-0810:PRESSURE } - { ARS09-VMCC-1550 ARS09-VMCC-1550:PRESSURE } - { ARS09-VMCC-3510 ARS09-VMCC-3510:PRESSURE } - { ARS09-VMCC-5460 ARS09-VMCC-5460:PRESSURE } - { ARS10-VMCC-0110 ARS10-VMCC-0110:PRESSURE } - { ARS10-VMCC-1550 ARS10-VMCC-1550:PRESSURE } - { ARS10-VMCC-3510 ARS10-VMCC-3510:PRESSURE } - { ARS10-VMCC-5460 ARS10-VMCC-5460:PRESSURE } - { ARS11-VMCC-0110 ARS11-VMCC-0110:PRESSURE } - { ARS11-VMCC-0210 ARS11-VMCC-0210:PRESSURE } - { ARS11-VMCC-0310 ARS11-VMCC-0310:PRESSURE } - { ARS11-VMCC-0410 ARS11-VMCC-0410:PRESSURE } - { ARS11-VMCC-0510 ARS11-VMCC-0510:PRESSURE } - { ARS11-VMCC-1550 ARS11-VMCC-1550:PRESSURE } - { ARS11-VMCC-3510 ARS11-VMCC-3510:PRESSURE } - { ARS11-VMCC-5460 ARS11-VMCC-5460:PRESSURE } - { ARS12-VMCC-0110 ARS12-VMCC-0110:PRESSURE } - { ARS12-VMCC-1550 ARS12-VMCC-1550:PRESSURE } - { ARS12-VMCC-3510 ARS12-VMCC-3510:PRESSURE } - { ARS12-VMCC-5460 ARS12-VMCC-5460:PRESSURE } -} \ No newline at end of file + { AGEBD-POSTMORTEMLOG{{ agebd_env }} VACMAX ARIVA-VMAVE:PRESS-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} VACMAXFE ARIVA-VMAVE-FE:PRESS-MAX } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-0110 ARS01-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-0210 ARS01-VMCC-0210:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-0225 ARS01-VMCC-0225:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-0310 ARS01-VMCC-0310:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-1550 ARS01-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-3510 ARS01-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS01-VMCC-5460 ARS01-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-0110 ARS02-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-0210 ARS02-VMCC-0210:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-0310 ARS02-VMCC-0310:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-1550 ARS02-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-3510 ARS02-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS02-VMCC-5460 ARS02-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS03-VMCC-0110 ARS03-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS03-VMCC-0320 ARS03-VMCC-0320:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS03-VMCC-1550 ARS03-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS03-VMCC-3510 ARS03-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS03-VMCC-5460 ARS03-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS04-VMCC-0110 ARS04-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS04-VMCC-1550 ARS04-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS04-VMCC-3510 ARS04-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS04-VMCC-5460 ARS04-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0110 ARS05-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0115 ARS05-VMCC-0115:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0210 ARS05-VMCC-0210:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0215 ARS05-VMCC-0215:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0310 ARS05-VMCC-0310:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0315 ARS05-VMCC-0315:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0410 ARS05-VMCC-0410:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0415 ARS05-VMCC-0415:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0510 ARS05-VMCC-0510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0520 ARS05-VMCC-0520:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0530 ARS05-VMCC-0530:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-0810 ARS05-VMCC-0810:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-1550 ARS05-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-3510 ARS05-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS05-VMCC-5460 ARS05-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS06-VMCC-0110 ARS06-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS06-VMCC-1550 ARS06-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS06-VMCC-3510 ARS06-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS06-VMCC-5460 ARS06-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-0010 ARS07-VMCC-0010:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-0120 ARS07-VMCC-0120:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-0210 ARS07-VMCC-0210:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-1550 ARS07-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-3510 ARS07-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS07-VMCC-5460 ARS07-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS08-VMCC-0110 ARS08-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS08-VMCC-1550 ARS08-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS08-VMCC-3510 ARS08-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS08-VMCC-5460 ARS08-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-0110 ARS09-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-0120 ARS09-VMCC-0120:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-0410 ARS09-VMCC-0410:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-0510 ARS09-VMCC-0510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-0810 ARS09-VMCC-0810:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-1550 ARS09-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-3510 ARS09-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS09-VMCC-5460 ARS09-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS10-VMCC-0110 ARS10-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS10-VMCC-1550 ARS10-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS10-VMCC-3510 ARS10-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS10-VMCC-5460 ARS10-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-0110 ARS11-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-0210 ARS11-VMCC-0210:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-0310 ARS11-VMCC-0310:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-0410 ARS11-VMCC-0410:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-0510 ARS11-VMCC-0510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-1550 ARS11-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-3510 ARS11-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS11-VMCC-5460 ARS11-VMCC-5460:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-VMCC-0110 ARS12-VMCC-0110:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-VMCC-1550 ARS12-VMCC-1550:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-VMCC-3510 ARS12-VMCC-3510:PRESSURE } + { AGEBD-POSTMORTEMLOG{{ agebd_env }} ARS12-VMCC-5460 ARS12-VMCC-5460:PRESSURE } +} diff --git a/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template b/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template index 9f225f4..c287ae4 100644 --- a/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template +++ b/services/postmortemlog/current/ioc/POSTMORTEMLOG_15min10Hz.template @@ -1,5 +1,5 @@ # Circular Buffer Record for Live Copy of desired PVs -record (compress, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)") { +record (compress, "$(DEVICE):BUFFER-$(NAME)") { field(DESC, "15min 10Hz buffer for post mortem") field(ASG, "READONLY") field(SCAN, ".1 second") @@ -9,18 +9,18 @@ record (compress, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)") { } # Records for automatically copying EPICS circular buffer Records after beam abort -record (waveform, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)-LAST"){ +record (waveform, "$(DEVICE):BUFFER-$(NAME)-LAST"){ field(DESC, "Copy of post mortem buffer") field(ASG, "READONLY") field(FTVL, "FLOAT") field(NELM, "9000") - field(INP, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME) VAL") + field(INP, "$(DEVICE):BUFFER-$(NAME) VAL") field(SCAN, "Event") # Process on event field(EVNT, "1") # Event number to trigger } # Records for writing to from HLA when viewing beam abort data history -record (waveform, "AGEBD-POSTMORTEMLOG:BUFFER-$(NAME)-HLA"){ +record (waveform, "$(DEVICE):BUFFER-$(NAME)-HLA"){ field(DESC, "Post mortem buffer filled by HLA") field(ASG, "PROTECTED") field(FTVL, "FLOAT") From 1c9400bfc4a64c8c3e0be4c9f62ca4dcab66e926 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:42:28 +0200 Subject: [PATCH 21/42] feat: remainigs iocs dev/prod templates --- services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs | 4 ++-- services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs | 4 ++-- services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs | 4 ++-- services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs | 4 ++-- services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs | 4 ++-- services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs index ec5596b..c5f2732 100644 --- a/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs +++ b/services/scrubbing/current/ioc/AGEBD-CPCL-SCRUBBING_main.subs @@ -1,4 +1,4 @@ file SCRUBBING.template { pattern { DEVICE } - { AGEBD-SCRUBBING } -} \ No newline at end of file + { AGEBD-SCRUBBING{{ agebd_env }} } +} diff --git a/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs index f25a3bd..ab45b7c 100644 --- a/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs +++ b/services/taupct/current/ioc/AGEBD-CPCL-TAUPCT_main.subs @@ -1,4 +1,4 @@ file TAUPCT.template { pattern { DEVICE } - { AGEBD-TAUPCT } -} \ No newline at end of file + { AGEBD-TAUPCT{{ agebd_env }} } +} diff --git a/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs b/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs index d880674..1a840a4 100644 --- a/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs +++ b/services/timing/current/ioc/AGEBD-CPCL-TIMING_main.subs @@ -1,4 +1,4 @@ file TIMING.template { pattern { DEVICE } - { AGEBD-TIMING } -} \ No newline at end of file + { AGEBD-TIMING{{ agebd_env }} } +} diff --git a/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs index 8e9d768..cf91d27 100644 --- a/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs +++ b/services/tunebump/current/ioc/AGEBD-CPCL-TUNEBUMP_main.subs @@ -1,4 +1,4 @@ file TUNEBUMP.template { pattern { DEVICE } - { AGEBD-TUNEBUMP } -} \ No newline at end of file + { AGEBD-TUNEBUMP{{ agebd_env }} } +} diff --git a/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs index 3e0664b..eaabe8c 100644 --- a/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs +++ b/services/tunefbx/current/ioc/AGEBD-CPCL-TUNEFBX_main.subs @@ -1,4 +1,4 @@ file TUNEFBX.template { pattern { DEVICE } - { AGEBD-TUNEFBX } -} \ No newline at end of file + { AGEBD-TUNEFBX{{ agebd_env }} } +} diff --git a/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs index 3d9cb1b..8e1d851 100644 --- a/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs +++ b/services/tunefby/current/ioc/AGEBD-CPCL-TUNEFBY_main.subs @@ -1,4 +1,4 @@ file TUNEFBY.template { pattern { DEVICE } - { AGEBD-TUNEFBY } -} \ No newline at end of file + { AGEBD-TUNEFBY{{ agebd_env }} } +} From bb789490f00a0fe9e4dd65f1d7a3cd7e97b772c4 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 11:45:25 +0200 Subject: [PATCH 22/42] fix: ioc cfg dbpm --- .../current/ioc/cfg/AGEBD-CPCL-TIMING_set.req | 48 ------------------- 1 file changed, 48 deletions(-) delete mode 100644 services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req diff --git a/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req b/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req deleted file mode 100644 index 4e0f824..0000000 --- a/services/dbpm3curr/current/ioc/cfg/AGEBD-CPCL-TIMING_set.req +++ /dev/null @@ -1,48 +0,0 @@ -#ENABLE-PASS=2 -AGEBD-TIMING:CONTROL-ZERO-DELAY-GUN -AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-ictone -AGEBD-TIMING:CONTROL-ZERO-DELAY-lindi-icts23 -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-llemast -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp1 -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-preamp2 -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr1 -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-klystr2 -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzQdm -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-500-PBU -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-3GHzScp -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly1PMU -AGEBD-TIMING:CONTROL-ZERO-DELAY-lirf-Kly2PMU -AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINKI -AGEBD-TIMING:CONTROL-ZERO-DELAY-BOINSE -AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXKI -AGEBD-TIMING:CONTROL-ZERO-DELAY-BOEXSE -AGEBD-TIMING:CONTROL-ZERO-DELAY-BTRICT -AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINSE -AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK1 -AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK2 -AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK3 -AGEBD-TIMING:CONTROL-ZERO-DELAY-SRINK4 -AGEBD-TIMING:CONTROL-FLW-BCKT-GUN -AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-ictone -AGEBD-TIMING:CONTROL-FLW-BCKT-lindi-icts23 -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-llemast -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp1 -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-preamp2 -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr1 -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-klystr2 -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzQdm -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-500-PBU -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-3GHzScp -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly1PMU -AGEBD-TIMING:CONTROL-FLW-BCKT-lirf-Kly2PMU -AGEBD-TIMING:CONTROL-FLW-BCKT-BOINKI -AGEBD-TIMING:CONTROL-FLW-BCKT-BOINSE -AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXKI -AGEBD-TIMING:CONTROL-FLW-BCKT-BOEXSE -AGEBD-TIMING:CONTROL-FLW-BCKT-BTRICT -AGEBD-TIMING:CONTROL-FLW-BCKT-BTRBPM -AGEBD-TIMING:CONTROL-FLW-BCKT-SRINSE -AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK1 -AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK2 -AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK3 -AGEBD-TIMING:CONTROL-FLW-BCKT-SRINK4 \ No newline at end of file From 5de570ef3cbbfcbb720c2432645f555d85268977 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 12:22:54 +0200 Subject: [PATCH 23/42] feat: migrate inj guard python --- .../injectionguard/current/app/pyproject.toml | 1 + .../app/src/agebd_injectionguard/service.py | 3999 ++++++++++++++++- services/injectionguard/current/app/uv.lock | 6 +- 3 files changed, 3951 insertions(+), 55 deletions(-) diff --git a/services/injectionguard/current/app/pyproject.toml b/services/injectionguard/current/app/pyproject.toml index 0344692..211a63c 100644 --- a/services/injectionguard/current/app/pyproject.toml +++ b/services/injectionguard/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-INJECTIONGUARD Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.0.2", ] [dependency-groups] diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/service.py b/services/injectionguard/current/app/src/agebd_injectionguard/service.py index dddb14a..c816633 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/service.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/service.py @@ -1,12 +1,12 @@ -import time +import inspect +from datetime import datetime -from epics import dbr +import numpy as np -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +14,3863 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-INJECTIONGUARD:AO") # TODO: is this a good PV to use? + # logging pvs + logbook_pause = PV("AGEBD-INJECTIONGUARD:LOG-PAUSE.VAL") + logbook = PV("AGEBD-INJECTIONGUARD:LOG") + logclear = PV("AGEBD-INJECTIONGUARD:LOG-CLEAR.VAL") - ## Service specific PVs from other IOCs - # ... + # Service Callback PVs + CallbackPV = PV("AGETI-CVME-MASTER-TMA:Evt-Old-BO-SYN.VALA", auto_monitor=True) + + # Service Check Output PVs + checks_output = { + "Beam Dump Kicker": PV("AGEBD-INJECTIONGUARD:CHECK-01.VAL"), + "Dump Valve": PV("AGEBD-INJECTIONGUARD:CHECK-02.VAL"), + "MIS": PV("AGEBD-INJECTIONGUARD:CHECK-03.VAL"), + "VCS": PV("AGEBD-INJECTIONGUARD:CHECK-04.VAL"), + "Linac KV/BB/BY": PV("AGEBD-INJECTIONGUARD:CHECK-05.VAL"), + "RF Linac": PV("AGEBD-INJECTIONGUARD:CHECK-06.VAL"), + "RF Booster": PV("AGEBD-INJECTIONGUARD:CHECK-07.VAL"), + "RF Ring": PV("AGEBD-INJECTIONGUARD:CHECK-08.VAL"), + "Magnets Pulsed": PV("AGEBD-INJECTIONGUARD:CHECK-09.VAL"), + "Magnets Booster": PV("AGEBD-INJECTIONGUARD:CHECK-10.VAL"), + "Magnets Corrector": PV("AGEBD-INJECTIONGUARD:CHECK-11.VAL"), + "Magnets Ring": PV("AGEBD-INJECTIONGUARD:CHECK-12.VAL"), + "Current Limit": PV("AGEBD-INJECTIONGUARD:CHECK-13.VAL"), + "IDs Ready": PV("AGEBD-INJECTIONGUARD:CHECK-14.VAL"), + "Single Bunch Charge": PV("AGEBD-INJECTIONGUARD:CHECK-15.VAL"), + "Injection Quality": PV("AGEBD-INJECTIONGUARD:CHECK-16.VAL"), + "Dump Quality": PV("AGEBD-INJECTIONGUARD:CHECK-17.VAL"), + "Lifetime": PV("AGEBD-INJECTIONGUARD:CHECK-18.VAL"), + "Tune": PV("AGEBD-INJECTIONGUARD:CHECK-19.VAL"), + "Pingers": PV("AGEBD-INJECTIONGUARD:CHECK-20.VAL"), + "Vacuum Pressure": PV("AGEBD-INJECTIONGUARD:CHECK-21.VAL"), + "Orbit Deviation": PV("AGEBD-INJECTIONGUARD:CHECK-22.VAL"), + "Beam Dump Controller": PV("AGEBD-INJECTIONGUARD:CHECK-23.VAL"), + } + + checks_input = { + "Beam Dump Kicker": [ + [ + # prepare list of pv links for the first check group + PV("ARS01-MKIK-BD:STATUS-GROUP.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-EMERGENCY.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-PULSER.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-VCS.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-BREAKERS.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-MIS.VAL"), + PV("ARS01-MKIK-0050-1:CTRL-VAC.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-OVERLOAD.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-POWERAVG.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-RELAY.VAL"), + PV("ARS01-MKIK-0050-1:ILK-GET-ACK.VAL"), + PV("ARS01-MKIK-0050-1:STATUS-GET-OPT-LINK.VAL"), + PV("ARS01-MKIK-0050-1:CTRL-ON-OFF"), + PV("ARS01-MKIK-0050-1:I-SET.VAL"), + PV("ARS01-MKIK-0050-1:HVPS-V-SCALED.VAL"), + PV("ARS01-MKIK-0050-1:HVPS-V-SET.VAL"), + PV("ARS01-MKIK-0050-2:STATUS-GET-OPT-LINK.VAL"), + PV("ARS01-MKIK-0050-3:STATUS-GET-OPT-LINK.VAL"), + PV("ARS01-MKIK-0050-4:STATUS-GET-OPT-LINK.VAL"), + ], + [ + # prepare list of lamda functions doing checks on vals with vals = [pv.get() for pv in links] + lambda vls: vls["ARS01-MKIK-BD:STATUS-GROUP.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-EMERGENCY.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-PULSER.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-VCS.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-BREAKERS.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-MIS.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:CTRL-VAC.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-OVERLOAD.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-POWERAVG.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-RELAY.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:ILK-GET-ACK.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:STATUS-GET-OPT-LINK.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-2:STATUS-GET-OPT-LINK.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-3:STATUS-GET-OPT-LINK.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-4:STATUS-GET-OPT-LINK.VAL"] == 0, + lambda vls: vls["ARS01-MKIK-0050-1:CTRL-ON-OFF"] == 1, + lambda vls: 5900 < vls["ARS01-MKIK-0050-1:I-SET.VAL"] < 7100, + lambda vls: ( + 980 * vls["ARS01-MKIK-0050-1:HVPS-V-SET.VAL"] + < vls["ARS01-MKIK-0050-1:HVPS-V-SCALED.VAL"] + < 1020 * vls["ARS01-MKIK-0050-1:HVPS-V-SET.VAL"] + ), + ], + ], + "Dump Valve": [ + [ + PV("ARS01-VVPG-0210:PLC_OPEN.VAL"), + ], + [ + lambda vls: vls["ARS01-VVPG-0210:PLC_OPEN.VAL"] == 1, + ], + ], + "MIS": [ + [PV("ARS00-MIS-PLC-01:AlarmCnt.VAL")], + [ + lambda vls: vls["ARS00-MIS-PLC-01:AlarmCnt.VAL"] == 0, + ], + ], + "VCS": [ + [PV("ARS00-VCS:PLC_AlarmCnt.VAL")], + [ + lambda vls: vls["ARS00-VCS:PLC_AlarmCnt.VAL"] == 0, + ], + ], + "Linac KV/BB/BY": [ + [ + PV("ALI00-SGEN-PSYS:ALBSA-BB-OPEN.VAL"), + PV("ALI00-SGEN-PSYS:ALBSA-KV-OPEN.VAL"), + PV("ALIMA-BY:I-READ.VAL"), + ], + [ + lambda vls: vls["ALI00-SGEN-PSYS:ALBSA-BB-OPEN.VAL"] == 1, + lambda vls: vls["ALI00-SGEN-PSYS:ALBSA-KV-OPEN.VAL"] == 1, + lambda vls: vls["ALIMA-BY:I-READ.VAL"] < 25, + ], + ], + "RF Linac": [ + [ + PV("ALIRF-GUN:SM-HV-STATUS.VAL"), + PV("ALIRF-SPB:AM-VSWR.VAL"), + PV("ALIRF-A1-MOD:SM-RF-STATUS.VAL"), + PV("ALIRF-A2-MOD:SM-RF-STATUS.VAL"), + PV("ALIRF-A1-MOD:VHVPS-READ.VAL"), + PV("ALIRF-A2-MOD:VHVPS-READ.VAL"), + PV("ALIRF-A1-PBU:PH-SET-PosErr.VAL"), # formerly ALIRF-A1-PBU:PH-COMP + PV("ALIRF-A1-FBU:PH-SET-PosErr.VAL"), # formerly ALIRF-A1-FBU:PH-COMP + PV("ALIRF-AS-1:Ph-COMP.VAL"), + PV("ALIRF-AS-2:Ph-COMP.VAL"), + PV("ALIRF-A1-MOD:VPULSE-READ.VAL"), + PV("ALIRF-A2-MOD:VPULSE-READ.VAL"), + ], + [ + lambda vls: vls["ALIRF-GUN:SM-HV-STATUS.VAL"] == 5, + lambda vls: vls["ALIRF-SPB:AM-VSWR.VAL"] == 1, + lambda vls: vls["ALIRF-A1-MOD:SM-RF-STATUS.VAL"] == 5, + lambda vls: vls["ALIRF-A2-MOD:SM-RF-STATUS.VAL"] == 5, + lambda vls: vls["ALIRF-A1-MOD:VHVPS-READ.VAL"] > 29, + lambda vls: vls["ALIRF-A2-MOD:VHVPS-READ.VAL"] > 32, + lambda vls: np.abs(vls["ALIRF-A1-PBU:PH-SET-PosErr.VAL"]) < 0.1, + lambda vls: np.abs(vls["ALIRF-A1-FBU:PH-SET-PosErr.VAL"]) < 0.1, + lambda vls: vls["ALIRF-AS-1:Ph-COMP.VAL"] < 10, + lambda vls: vls["ALIRF-AS-2:Ph-COMP.VAL"] < 10, + lambda vls: vls["ALIRF-A1-MOD:VPULSE-READ.VAL"] > 200, + lambda vls: vls["ALIRF-A2-MOD:VPULSE-READ.VAL"] > 200, + ], + ], + "RF Booster": [ + [ + PV("ABORF-CAV0:PU-AMPLT-MAX.VAL"), + PV("ABORF-ILK0:PENDINGSUM.VAL"), + PV("ABORF-LLE0:CTRLPHASE-E-STATUS.VAL"), + ], + [ + lambda vls: vls["ABORF-CAV0:PU-AMPLT-MAX.VAL"] > 549.6, + lambda vls: vls["ABORF-ILK0:PENDINGSUM.VAL"] == 1, + lambda vls: vls["ABORF-LLE0:CTRLPHASE-E-STATUS.VAL"] == 1, + ], + ], + "RF Ring": [ + [ + PV("ARS05-RSYS-0060:VOLTAGE-GET.VAL"), + PV("ARS05-RSYS-0140:VOLTAGE-GET.VAL"), + PV("ARS05-RSYS-0230:VOLTAGE-GET.VAL"), + PV("ARS05-RSYS-0310:VOLTAGE-GET.VAL"), + PV("ARS05-RCCS-0060:SumILK.VAL"), + PV("ARS05-RCCS-0140:SumILK.VAL"), + PV("ARS05-RCCS-0230:SumILK.VAL"), + PV("ARS05-RCCS-0310:SumILK.VAL"), + PV("ARS05-RCCS-0060:SumILK.VAL"), + PV("ARS05-RCCS-0140:SumILK.VAL"), + PV("ARS05-RCCS-0230:SumILK.VAL"), + PV("ARS05-RCCS-0310:SumILK.VAL"), + PV("ARS05-RLLE-0060:CTRLPHASE-E-STATUS.VAL"), + PV("ARS05-RLLE-0140:CTRLPHASE-E-STATUS.VAL"), + PV("ARS05-RLLE-0230:CTRLPHASE-E-STATUS.VAL"), + PV("ARS05-RLLE-0310:CTRLPHASE-E-STATUS.VAL"), + ], + [ + lambda vls: vls["ARS05-RSYS-0060:VOLTAGE-GET.VAL"] > 439.5, + lambda vls: vls["ARS05-RSYS-0140:VOLTAGE-GET.VAL"] > 439.5, + lambda vls: vls["ARS05-RSYS-0230:VOLTAGE-GET.VAL"] > 439.5, + lambda vls: vls["ARS05-RSYS-0310:VOLTAGE-GET.VAL"] > 439.5, + lambda vls: vls["ARS05-RCCS-0060:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0140:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0230:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0310:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0060:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0140:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0230:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RCCS-0310:SumILK.VAL"] == 1, + lambda vls: vls["ARS05-RLLE-0060:CTRLPHASE-E-STATUS.VAL"] == 1, + lambda vls: vls["ARS05-RLLE-0140:CTRLPHASE-E-STATUS.VAL"] == 1, + lambda vls: vls["ARS05-RLLE-0230:CTRLPHASE-E-STATUS.VAL"] == 1, + lambda vls: vls["ARS05-RLLE-0310:CTRLPHASE-E-STATUS.VAL"] == 1, + ], + ], + "Magnets Pulsed": [ + [ + # Booster Injection + PV("ABOMA-YIN:CTRL-ON-OFF.VAL"), + PV("ABOMA-KIN:CTRL-ON-OFF.VAL"), + PV("ABOMA-YIN:STATUS-ALL.VAL"), + PV("ABOMA-KIN:STATUS-ALL.VAL"), + PV("ABOMA-YIN:I-SET.VAL"), + PV("ABOMA-KIN:I-SET.VAL"), + PV("ABOMA-YIN:I-READ-POS.VAL"), + PV("ABOMA-KIN:I-READ-POS.VAL"), + PV("ABOMA-YIN:CTRL-CALC-LED.VAL"), + PV("ABOMA-KIN:CTRL-CALC-LED.VAL"), + # Booster Extraction + PV("ABOMA-KEX:CTRL-ON-OFF.VAL"), + PV("ABOMA-YEX:CTRL-ON-OFF.VAL"), + PV("ABOMA-KEX:STATUS-ALL.VAL"), + PV("ABOMA-YEX:STATUS-ALL.VAL"), + PV("ABOMA-KEX:I-SET.VAL"), + PV("ABOMA-YEX:I-SET.VAL"), + PV("ABOMA-KEX:I-READ-POS.VAL"), + PV("ABOMA-YEX:I-READ-POS.VAL"), + PV("ABOMA-KEX:CTRL-CALC-LED.VAL"), + PV("ABOMA-YEX:CTRL-CALC-LED.VAL"), + # Ring Injection + PV("ARS01-MSEP-0670:CTRL-ON-OFF.VAL"), + PV("ARS01-MKIK1-4:AMP-ON-OFF.VAL"), + PV("ARS01-MKIK-0140:CTRL-ON-OFF.VAL"), + PV("ARS01-MKIK-0220:CTRL-ON-OFF.VAL"), + PV("ARS01-MKIK-0850:CTRL-ON-OFF.VAL"), + PV("ARS01-MKIK-0940:CTRL-ON-OFF.VAL"), + PV("ARS01-MSEP-0670:STATUS-ALL.VAL"), + PV("ARS01-MKIK1-4:STATUS-GROUP.VAL"), + PV("ARS01-MKIK-0140:STATUS-ALL.VAL"), + PV("ARS01-MKIK-0220:STATUS-ALL.VAL"), + PV("ARS01-MKIK-0850:STATUS-ALL.VAL"), + PV("ARS01-MKIK-0940:STATUS-ALL.VAL"), + PV("ARS01-MSEP-0670:I-SET.VAL"), + PV("ARS01-MKIK-0140:I-SET.VAL"), + PV("ARS01-MKIK-0220:I-SET.VAL"), + PV("ARS01-MKIK-0850:I-SET.VAL"), + PV("ARS01-MKIK-0940:I-SET.VAL"), + PV("ARS01-MSEP-0670:I-READ-POS.VAL"), + PV("ARS01-MKIK-0140:I-READ-POS.VAL"), + PV("ARS01-MKIK-0220:I-READ-POS.VAL"), + PV("ARS01-MKIK-0850:I-READ-POS.VAL"), + PV("ARS01-MKIK-0940:I-READ-POS.VAL"), + PV("ARS01-MSEP-0670:CTRL-CALC-LED.VAL"), + PV("ARS01-MKIK-0140:CTRL-CALC-LED.VAL"), + PV("ARS01-MKIK-0220:CTRL-CALC-LED.VAL"), + PV("ARS01-MKIK-0850:CTRL-CALC-LED.VAL"), + PV("ARS01-MKIK-0940:CTRL-CALC-LED.VAL"), + ], + [ + # Booster Injection + lambda vls: vls["ABOMA-YIN:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ABOMA-KIN:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ABOMA-YIN:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ABOMA-KIN:STATUS-ALL.VAL"] == 1, + lambda vls: ( + 0.9 * vls["ABOMA-YIN:I-SET.VAL"] + < vls["ABOMA-YIN:I-READ-POS.VAL"] + < 1.1 * vls["ABOMA-YIN:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ABOMA-KIN:I-SET.VAL"] + < vls["ABOMA-KIN:I-READ-POS.VAL"] + < 1.1 * vls["ABOMA-KIN:I-SET.VAL"] + ), + lambda vls: vls["ABOMA-YIN:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ABOMA-KIN:CTRL-CALC-LED.VAL"] == 1, + # Booster Extraction + lambda vls: vls["ABOMA-KEX:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ABOMA-YEX:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ABOMA-KEX:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ABOMA-YEX:STATUS-ALL.VAL"] == 1, + lambda vls: ( + 0.9 * vls["ABOMA-KEX:I-SET.VAL"] + < vls["ABOMA-KEX:I-READ-POS.VAL"] + < 1.1 * vls["ABOMA-KEX:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ABOMA-YEX:I-SET.VAL"] + < vls["ABOMA-YEX:I-READ-POS.VAL"] + < 1.1 * vls["ABOMA-YEX:I-SET.VAL"] + ), + lambda vls: vls["ABOMA-KEX:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ABOMA-YEX:CTRL-CALC-LED.VAL"] == 1, + # Ring Injection + lambda vls: vls["ARS01-MSEP-0670:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MKIK1-4:AMP-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0140:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0220:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0850:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0940:CTRL-ON-OFF.VAL"] == 1, + lambda vls: vls["ARS01-MSEP-0670:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ARS01-MKIK1-4:STATUS-GROUP.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0140:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0220:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0850:STATUS-ALL.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0940:STATUS-ALL.VAL"] == 1, + lambda vls: ( + 0.9 * vls["ARS01-MSEP-0670:I-SET.VAL"] + < vls["ARS01-MSEP-0670:I-READ-POS.VAL"] + < 1.1 * vls["ARS01-MSEP-0670:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ARS01-MKIK-0140:I-SET.VAL"] + < vls["ARS01-MKIK-0140:I-READ-POS.VAL"] + < 1.1 * vls["ARS01-MKIK-0140:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ARS01-MKIK-0220:I-SET.VAL"] + < vls["ARS01-MKIK-0220:I-READ-POS.VAL"] + < 1.1 * vls["ARS01-MKIK-0220:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ARS01-MKIK-0850:I-SET.VAL"] + < vls["ARS01-MKIK-0850:I-READ-POS.VAL"] + < 1.1 * vls["ARS01-MKIK-0850:I-SET.VAL"] + ), + lambda vls: ( + 0.9 * vls["ARS01-MKIK-0940:I-SET.VAL"] + < vls["ARS01-MKIK-0940:I-READ-POS.VAL"] + < 1.1 * vls["ARS01-MKIK-0940:I-SET.VAL"] + ), + lambda vls: vls["ARS01-MSEP-0670:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0140:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0220:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0850:CTRL-CALC-LED.VAL"] == 1, + lambda vls: vls["ARS01-MKIK-0940:CTRL-CALC-LED.VAL"] == 1, + ], + ], + "Magnets Booster": [ + [ + PV("ABOMA-B:PS-MODE.VAL"), + PV("ABOMA-CBF:PS-MODE.VAL"), + PV("ABOMA-QD:PS-MODE.VAL"), + PV("ABOMA-QE:PS-MODE.VAL"), + PV("ABOMA-QF:PS-MODE.VAL"), + PV("ABOMA-SD:PS-MODE.VAL"), + PV("ABOMA-SF:PS-MODE.VAL"), + PV("ABOMA-CH-1A:PS-MODE.VAL"), + PV("ABOMA-CH-1B:PS-MODE.VAL"), + PV("ABOMA-CH-1C:PS-MODE.VAL"), + PV("ABOMA-CH-1D:PS-MODE.VAL"), + PV("ABOMA-CH-1E:PS-MODE.VAL"), + PV("ABOMA-CH-1F:PS-MODE.VAL"), + PV("ABOMA-CH-1G:PS-MODE.VAL"), + PV("ABOMA-CH-1H:PS-MODE.VAL"), + PV("ABOMA-CH-1S:PS-MODE.VAL"), + PV("ABOMA-CH-2A:PS-MODE.VAL"), + PV("ABOMA-CH-2B:PS-MODE.VAL"), + PV("ABOMA-CH-2C:PS-MODE.VAL"), + PV("ABOMA-CH-2D:PS-MODE.VAL"), + PV("ABOMA-CH-2E:PS-MODE.VAL"), + PV("ABOMA-CH-2F:PS-MODE.VAL"), + PV("ABOMA-CH-2G:PS-MODE.VAL"), + PV("ABOMA-CH-2H:PS-MODE.VAL"), + PV("ABOMA-CH-2S:PS-MODE.VAL"), + PV("ABOMA-CH-3A:PS-MODE.VAL"), + PV("ABOMA-CH-3B:PS-MODE.VAL"), + PV("ABOMA-CH-3C:PS-MODE.VAL"), + PV("ABOMA-CH-3D:PS-MODE.VAL"), + PV("ABOMA-CH-3E:PS-MODE.VAL"), + PV("ABOMA-CH-3F:PS-MODE.VAL"), + PV("ABOMA-CH-3G:PS-MODE.VAL"), + PV("ABOMA-CH-3H:PS-MODE.VAL"), + PV("ABOMA-CH-3S:PS-MODE.VAL"), + PV("ABOMA-CH-4A:PS-MODE.VAL"), + PV("ABOMA-CH-4B:PS-MODE.VAL"), + PV("ABOMA-CH-4C:PS-MODE.VAL"), + PV("ABOMA-CH-4D:PS-MODE.VAL"), + PV("ABOMA-CH-4E:PS-MODE.VAL"), + PV("ABOMA-CH-4F:PS-MODE.VAL"), + PV("ABOMA-CH-4G:PS-MODE.VAL"), + PV("ABOMA-CH-4H:PS-MODE.VAL"), + PV("ABOMA-CH-4S:PS-MODE.VAL"), + PV("ABOMA-CH-5A:PS-MODE.VAL"), + PV("ABOMA-CH-5B:PS-MODE.VAL"), + PV("ABOMA-CH-5C:PS-MODE.VAL"), + PV("ABOMA-CH-5D:PS-MODE.VAL"), + PV("ABOMA-CH-5E:PS-MODE.VAL"), + PV("ABOMA-CH-5F:PS-MODE.VAL"), + PV("ABOMA-CH-5G:PS-MODE.VAL"), + PV("ABOMA-CH-5H:PS-MODE.VAL"), + PV("ABOMA-CH-5S:PS-MODE.VAL"), + PV("ABOMA-CH-6A:PS-MODE.VAL"), + PV("ABOMA-CH-6B:PS-MODE.VAL"), + PV("ABOMA-CH-6C:PS-MODE.VAL"), + PV("ABOMA-CH-6D:PS-MODE.VAL"), + PV("ABOMA-CH-6E:PS-MODE.VAL"), + PV("ABOMA-CH-6F:PS-MODE.VAL"), + PV("ABOMA-CH-6G:PS-MODE.VAL"), + PV("ABOMA-CH-6H:PS-MODE.VAL"), + PV("ABOMA-CH-6S:PS-MODE.VAL"), + PV("ABOMA-CV-1A:PS-MODE.VAL"), + PV("ABOMA-CV-1B:PS-MODE.VAL"), + PV("ABOMA-CV-1C:PS-MODE.VAL"), + PV("ABOMA-CV-1D:PS-MODE.VAL"), + PV("ABOMA-CV-1E:PS-MODE.VAL"), + PV("ABOMA-CV-1F:PS-MODE.VAL"), + PV("ABOMA-CV-1G:PS-MODE.VAL"), + PV("ABOMA-CV-1H:PS-MODE.VAL"), + PV("ABOMA-CV-1S:PS-MODE.VAL"), + PV("ABOMA-CV-2A:PS-MODE.VAL"), + PV("ABOMA-CV-2B:PS-MODE.VAL"), + PV("ABOMA-CV-2C:PS-MODE.VAL"), + PV("ABOMA-CV-2D:PS-MODE.VAL"), + PV("ABOMA-CV-2E:PS-MODE.VAL"), + PV("ABOMA-CV-2F:PS-MODE.VAL"), + PV("ABOMA-CV-2G:PS-MODE.VAL"), + PV("ABOMA-CV-2H:PS-MODE.VAL"), + PV("ABOMA-CV-2S:PS-MODE.VAL"), + PV("ABOMA-CV-3A:PS-MODE.VAL"), + PV("ABOMA-CV-3B:PS-MODE.VAL"), + PV("ABOMA-CV-3C:PS-MODE.VAL"), + PV("ABOMA-CV-3D:PS-MODE.VAL"), + PV("ABOMA-CV-3E:PS-MODE.VAL"), + PV("ABOMA-CV-3F:PS-MODE.VAL"), + PV("ABOMA-CV-3G:PS-MODE.VAL"), + PV("ABOMA-CV-3H:PS-MODE.VAL"), + PV("ABOMA-CV-3S:PS-MODE.VAL"), + PV("ABOMA-CV-4A:PS-MODE.VAL"), + PV("ABOMA-CV-4B:PS-MODE.VAL"), + PV("ABOMA-CV-4C:PS-MODE.VAL"), + PV("ABOMA-CV-4D:PS-MODE.VAL"), + PV("ABOMA-CV-4E:PS-MODE.VAL"), + PV("ABOMA-CV-4F:PS-MODE.VAL"), + PV("ABOMA-CV-4G:PS-MODE.VAL"), + PV("ABOMA-CV-4H:PS-MODE.VAL"), + PV("ABOMA-CV-4S:PS-MODE.VAL"), + PV("ABOMA-CV-5A:PS-MODE.VAL"), + PV("ABOMA-CV-5B:PS-MODE.VAL"), + PV("ABOMA-CV-5C:PS-MODE.VAL"), + PV("ABOMA-CV-5D:PS-MODE.VAL"), + PV("ABOMA-CV-5E:PS-MODE.VAL"), + PV("ABOMA-CV-5F:PS-MODE.VAL"), + PV("ABOMA-CV-5G:PS-MODE.VAL"), + PV("ABOMA-CV-5H:PS-MODE.VAL"), + PV("ABOMA-CV-5S:PS-MODE.VAL"), + PV("ABOMA-CV-6A:PS-MODE.VAL"), + PV("ABOMA-CV-6B:PS-MODE.VAL"), + PV("ABOMA-CV-6C:PS-MODE.VAL"), + PV("ABOMA-CV-6D:PS-MODE.VAL"), + PV("ABOMA-CV-6E:PS-MODE.VAL"), + PV("ABOMA-CV-6F:PS-MODE.VAL"), + PV("ABOMA-CV-6G:PS-MODE.VAL"), + PV("ABOMA-CV-6H:PS-MODE.VAL"), + PV("ABOMA-CV-6S:PS-MODE.VAL"), + PV("ABOMA-B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CBF:IW-ACTWF-RB.VAL"), + PV("ABOMA-QD:IW-ACTWF-RB.VAL"), + PV("ABOMA-QE:IW-ACTWF-RB.VAL"), + PV("ABOMA-QF:IW-ACTWF-RB.VAL"), + PV("ABOMA-SD:IW-ACTWF-RB.VAL"), + PV("ABOMA-SF:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-1S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-2S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-3S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-4S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-5S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CH-6S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-1S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-2S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-3S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-4S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-5S:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6A:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6B:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6C:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6D:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6E:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6F:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6G:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6H:IW-ACTWF-RB.VAL"), + PV("ABOMA-CV-6S:IW-ACTWF-RB.VAL"), + ], + [ + lambda vls: vls["ABOMA-B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CBF:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-QD:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-QE:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-QF:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-SD:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-SF:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-1S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-2S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-3S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-4S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-5S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CH-6S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-1S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-2S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-3S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-4S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-5S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6A:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6B:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6C:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6D:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6E:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6F:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6G:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6H:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-CV-6S:PS-MODE.VAL"] == 2, + lambda vls: vls["ABOMA-B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CBF:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-QD:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-QE:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-QF:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-SD:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-SF:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-1S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-2S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-3S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-4S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-5S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CH-6S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-1S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-2S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-3S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-4S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-5S:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6A:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6B:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6C:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6D:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6E:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6F:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6G:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6H:IW-ACTWF-RB.VAL"] == 1, + lambda vls: vls["ABOMA-CV-6S:IW-ACTWF-RB.VAL"] == 1, + ], + ], + "Magnets Corrector": [ + [ + PV("ARS01-MCOX-0410:PS-MODE.VAL"), + PV("ARS01-MCOX-0740:PS-MODE.VAL"), + PV("ARS01-MCOX-1090:PS-MODE.VAL"), + PV("ARS01-MCOX-1470:PS-MODE.VAL"), + PV("ARS01-MCOX-1910:PS-MODE.VAL"), + PV("ARS01-MCOX-2420:PS-MODE.VAL"), + PV("ARS01-MCOX-2920:PS-MODE.VAL"), + PV("ARS01-MCOX-4230:PS-MODE.VAL"), + PV("ARS01-MCOX-4730:PS-MODE.VAL"), + PV("ARS01-MCOX-5260:PS-MODE.VAL"), + PV("ARS01-MCOX-5890:PS-MODE.VAL"), + PV("ARS02-MCOX-1090:PS-MODE.VAL"), + PV("ARS02-MCOX-1470:PS-MODE.VAL"), + PV("ARS02-MCOX-1910:PS-MODE.VAL"), + PV("ARS02-MCOX-2420:PS-MODE.VAL"), + PV("ARS02-MCOX-2920:PS-MODE.VAL"), + PV("ARS02-MCOX-4230:PS-MODE.VAL"), + PV("ARS02-MCOX-4730:PS-MODE.VAL"), + PV("ARS02-MCOX-5260:PS-MODE.VAL"), + PV("ARS02-MCOX-5890:PS-MODE.VAL"), + PV("ARS03-MCOX-0820:PS-MODE.VAL"), + PV("ARS03-MCOX-1090:PS-MODE.VAL"), + PV("ARS03-MCOX-1470:PS-MODE.VAL"), + PV("ARS03-MCOX-1910:PS-MODE.VAL"), + PV("ARS03-MCOX-2420:PS-MODE.VAL"), + PV("ARS03-MCOX-2920:PS-MODE.VAL"), + PV("ARS03-MCOX-4230:PS-MODE.VAL"), + PV("ARS03-MCOX-4730:PS-MODE.VAL"), + PV("ARS03-MCOX-5260:PS-MODE.VAL"), + PV("ARS03-MCOX-5890:PS-MODE.VAL"), + PV("ARS04-MCOX-1090:PS-MODE.VAL"), + PV("ARS04-MCOX-1470:PS-MODE.VAL"), + PV("ARS04-MCOX-1910:PS-MODE.VAL"), + PV("ARS04-MCOX-2420:PS-MODE.VAL"), + PV("ARS04-MCOX-2920:PS-MODE.VAL"), + PV("ARS04-MCOX-4230:PS-MODE.VAL"), + PV("ARS04-MCOX-4730:PS-MODE.VAL"), + PV("ARS04-MCOX-5260:PS-MODE.VAL"), + PV("ARS04-MCOX-5890:PS-MODE.VAL"), + PV("ARS05-MCOX-0420:PS-MODE.VAL"), + PV("ARS05-MCOX-1090:PS-MODE.VAL"), + PV("ARS05-MCOX-1470:PS-MODE.VAL"), + PV("ARS05-MCOX-1910:PS-MODE.VAL"), + PV("ARS05-MCOX-2420:PS-MODE.VAL"), + PV("ARS05-MCOX-2920:PS-MODE.VAL"), + PV("ARS05-MCOX-4230:PS-MODE.VAL"), + PV("ARS05-MCOX-4730:PS-MODE.VAL"), + PV("ARS05-MCOX-5260:PS-MODE.VAL"), + PV("ARS05-MCOX-5890:PS-MODE.VAL"), + PV("ARS06-MCOX-1090:PS-MODE.VAL"), + PV("ARS06-MCOX-1470:PS-MODE.VAL"), + PV("ARS06-MCOX-1910:PS-MODE.VAL"), + PV("ARS06-MCOX-2420:PS-MODE.VAL"), + PV("ARS06-MCOX-2920:PS-MODE.VAL"), + PV("ARS06-MCOX-4230:PS-MODE.VAL"), + PV("ARS06-MCOX-4730:PS-MODE.VAL"), + PV("ARS06-MCOX-5260:PS-MODE.VAL"), + PV("ARS06-MCOX-5890:PS-MODE.VAL"), + PV("ARS07-MCOX-0820:PS-MODE.VAL"), + PV("ARS07-MCOX-1090:PS-MODE.VAL"), + PV("ARS07-MCOX-1470:PS-MODE.VAL"), + PV("ARS07-MCOX-1910:PS-MODE.VAL"), + PV("ARS07-MCOX-2420:PS-MODE.VAL"), + PV("ARS07-MCOX-2920:PS-MODE.VAL"), + PV("ARS07-MCOX-4230:PS-MODE.VAL"), + PV("ARS07-MCOX-4730:PS-MODE.VAL"), + PV("ARS07-MCOX-5260:PS-MODE.VAL"), + PV("ARS07-MCOX-5890:PS-MODE.VAL"), + PV("ARS08-MCOX-1090:PS-MODE.VAL"), + PV("ARS08-MCOX-1470:PS-MODE.VAL"), + PV("ARS08-MCOX-1910:PS-MODE.VAL"), + PV("ARS08-MCOX-2420:PS-MODE.VAL"), + PV("ARS08-MCOX-2920:PS-MODE.VAL"), + PV("ARS08-MCOX-4230:PS-MODE.VAL"), + PV("ARS08-MCOX-4730:PS-MODE.VAL"), + PV("ARS08-MCOX-5260:PS-MODE.VAL"), + PV("ARS08-MCOX-5890:PS-MODE.VAL"), + PV("ARS09-MCOX-0580:PS-MODE.VAL"), + PV("ARS09-MCOX-1090:PS-MODE.VAL"), + PV("ARS09-MCOX-1470:PS-MODE.VAL"), + PV("ARS09-MCOX-1910:PS-MODE.VAL"), + PV("ARS09-MCOX-2420:PS-MODE.VAL"), + PV("ARS09-MCOX-2920:PS-MODE.VAL"), + PV("ARS09-MCOX-4230:PS-MODE.VAL"), + PV("ARS09-MCOX-4730:PS-MODE.VAL"), + PV("ARS09-MCOX-5260:PS-MODE.VAL"), + PV("ARS09-MCOX-5890:PS-MODE.VAL"), + PV("ARS10-MCOX-1090:PS-MODE.VAL"), + PV("ARS10-MCOX-1470:PS-MODE.VAL"), + PV("ARS10-MCOX-1910:PS-MODE.VAL"), + PV("ARS10-MCOX-2420:PS-MODE.VAL"), + PV("ARS10-MCOX-2920:PS-MODE.VAL"), + PV("ARS10-MCOX-4230:PS-MODE.VAL"), + PV("ARS10-MCOX-4730:PS-MODE.VAL"), + PV("ARS10-MCOX-5260:PS-MODE.VAL"), + PV("ARS10-MCOX-5890:PS-MODE.VAL"), + PV("ARS11-MCOX-0860:PS-MODE.VAL"), + PV("ARS11-MCOX-1090:PS-MODE.VAL"), + PV("ARS11-MCOX-1470:PS-MODE.VAL"), + PV("ARS11-MCOX-1910:PS-MODE.VAL"), + PV("ARS11-MCOX-2420:PS-MODE.VAL"), + PV("ARS11-MCOX-2920:PS-MODE.VAL"), + PV("ARS11-MCOX-4230:PS-MODE.VAL"), + PV("ARS11-MCOX-4730:PS-MODE.VAL"), + PV("ARS11-MCOX-5260:PS-MODE.VAL"), + PV("ARS11-MCOX-5890:PS-MODE.VAL"), + PV("ARS12-MCOX-1090:PS-MODE.VAL"), + PV("ARS12-MCOX-1470:PS-MODE.VAL"), + PV("ARS12-MCOX-1910:PS-MODE.VAL"), + PV("ARS12-MCOX-2420:PS-MODE.VAL"), + PV("ARS12-MCOX-2920:PS-MODE.VAL"), + PV("ARS12-MCOX-4230:PS-MODE.VAL"), + PV("ARS12-MCOX-4730:PS-MODE.VAL"), + PV("ARS12-MCOX-5260:PS-MODE.VAL"), + PV("ARS12-MCOX-5890:PS-MODE.VAL"), + PV("ARS01-MCOY-0400:PS-MODE.VAL"), + PV("ARS01-MCOY-0750:PS-MODE.VAL"), + PV("ARS01-MCOY-1110:PS-MODE.VAL"), + PV("ARS01-MCOY-1490:PS-MODE.VAL"), + PV("ARS01-MCOY-1930:PS-MODE.VAL"), + PV("ARS01-MCOY-2430:PS-MODE.VAL"), + PV("ARS01-MCOY-2930:PS-MODE.VAL"), + PV("ARS01-MCOY-4240:PS-MODE.VAL"), + PV("ARS01-MCOY-4740:PS-MODE.VAL"), + PV("ARS01-MCOY-5270:PS-MODE.VAL"), + PV("ARS01-MCOY-5900:PS-MODE.VAL"), + PV("ARS02-MCOY-1110:PS-MODE.VAL"), + PV("ARS02-MCOY-1490:PS-MODE.VAL"), + PV("ARS02-MCOY-1930:PS-MODE.VAL"), + PV("ARS02-MCOY-2430:PS-MODE.VAL"), + PV("ARS02-MCOY-2930:PS-MODE.VAL"), + PV("ARS02-MCOY-4240:PS-MODE.VAL"), + PV("ARS02-MCOY-4740:PS-MODE.VAL"), + PV("ARS02-MCOY-5270:PS-MODE.VAL"), + PV("ARS02-MCOY-5900:PS-MODE.VAL"), + PV("ARS03-MCOY-0830:PS-MODE.VAL"), + PV("ARS03-MCOY-1110:PS-MODE.VAL"), + PV("ARS03-MCOY-1490:PS-MODE.VAL"), + PV("ARS03-MCOY-1930:PS-MODE.VAL"), + PV("ARS03-MCOY-2430:PS-MODE.VAL"), + PV("ARS03-MCOY-2930:PS-MODE.VAL"), + PV("ARS03-MCOY-4240:PS-MODE.VAL"), + PV("ARS03-MCOY-4740:PS-MODE.VAL"), + PV("ARS03-MCOY-5270:PS-MODE.VAL"), + PV("ARS03-MCOY-5900:PS-MODE.VAL"), + PV("ARS04-MCOY-1110:PS-MODE.VAL"), + PV("ARS04-MCOY-1490:PS-MODE.VAL"), + PV("ARS04-MCOY-1930:PS-MODE.VAL"), + PV("ARS04-MCOY-2430:PS-MODE.VAL"), + PV("ARS04-MCOY-2930:PS-MODE.VAL"), + PV("ARS04-MCOY-4240:PS-MODE.VAL"), + PV("ARS04-MCOY-4740:PS-MODE.VAL"), + PV("ARS04-MCOY-5270:PS-MODE.VAL"), + PV("ARS04-MCOY-5900:PS-MODE.VAL"), + PV("ARS05-MCOY-0430:PS-MODE.VAL"), + PV("ARS05-MCOY-1110:PS-MODE.VAL"), + PV("ARS05-MCOY-1490:PS-MODE.VAL"), + PV("ARS05-MCOY-1930:PS-MODE.VAL"), + PV("ARS05-MCOY-2430:PS-MODE.VAL"), + PV("ARS05-MCOY-2930:PS-MODE.VAL"), + PV("ARS05-MCOY-4240:PS-MODE.VAL"), + PV("ARS05-MCOY-4740:PS-MODE.VAL"), + PV("ARS05-MCOY-5270:PS-MODE.VAL"), + PV("ARS05-MCOY-5900:PS-MODE.VAL"), + PV("ARS06-MCOY-1110:PS-MODE.VAL"), + PV("ARS06-MCOY-1490:PS-MODE.VAL"), + PV("ARS06-MCOY-1930:PS-MODE.VAL"), + PV("ARS06-MCOY-2430:PS-MODE.VAL"), + PV("ARS06-MCOY-2930:PS-MODE.VAL"), + PV("ARS06-MCOY-4240:PS-MODE.VAL"), + PV("ARS06-MCOY-4740:PS-MODE.VAL"), + PV("ARS06-MCOY-5270:PS-MODE.VAL"), + PV("ARS06-MCOY-5900:PS-MODE.VAL"), + PV("ARS07-MCOY-0830:PS-MODE.VAL"), + PV("ARS07-MCOY-1110:PS-MODE.VAL"), + PV("ARS07-MCOY-1490:PS-MODE.VAL"), + PV("ARS07-MCOY-1930:PS-MODE.VAL"), + PV("ARS07-MCOY-2430:PS-MODE.VAL"), + PV("ARS07-MCOY-2930:PS-MODE.VAL"), + PV("ARS07-MCOY-4240:PS-MODE.VAL"), + PV("ARS07-MCOY-4740:PS-MODE.VAL"), + PV("ARS07-MCOY-5270:PS-MODE.VAL"), + PV("ARS07-MCOY-5900:PS-MODE.VAL"), + PV("ARS08-MCOY-1110:PS-MODE.VAL"), + PV("ARS08-MCOY-1490:PS-MODE.VAL"), + PV("ARS08-MCOY-1930:PS-MODE.VAL"), + PV("ARS08-MCOY-2430:PS-MODE.VAL"), + PV("ARS08-MCOY-2930:PS-MODE.VAL"), + PV("ARS08-MCOY-4240:PS-MODE.VAL"), + PV("ARS08-MCOY-4740:PS-MODE.VAL"), + PV("ARS08-MCOY-5270:PS-MODE.VAL"), + PV("ARS08-MCOY-5900:PS-MODE.VAL"), + PV("ARS09-MCOY-0590:PS-MODE.VAL"), + PV("ARS09-MCOY-1110:PS-MODE.VAL"), + PV("ARS09-MCOY-1490:PS-MODE.VAL"), + PV("ARS09-MCOY-1930:PS-MODE.VAL"), + PV("ARS09-MCOY-2430:PS-MODE.VAL"), + PV("ARS09-MCOY-2930:PS-MODE.VAL"), + PV("ARS09-MCOY-4240:PS-MODE.VAL"), + PV("ARS09-MCOY-4740:PS-MODE.VAL"), + PV("ARS09-MCOY-5270:PS-MODE.VAL"), + PV("ARS09-MCOY-5900:PS-MODE.VAL"), + PV("ARS10-MCOY-1110:PS-MODE.VAL"), + PV("ARS10-MCOY-1490:PS-MODE.VAL"), + PV("ARS10-MCOY-1930:PS-MODE.VAL"), + PV("ARS10-MCOY-2430:PS-MODE.VAL"), + PV("ARS10-MCOY-2930:PS-MODE.VAL"), + PV("ARS10-MCOY-4240:PS-MODE.VAL"), + PV("ARS10-MCOY-4740:PS-MODE.VAL"), + PV("ARS10-MCOY-5270:PS-MODE.VAL"), + PV("ARS10-MCOY-5900:PS-MODE.VAL"), + PV("ARS11-MCOY-0870:PS-MODE.VAL"), + PV("ARS11-MCOY-1110:PS-MODE.VAL"), + PV("ARS11-MCOY-1490:PS-MODE.VAL"), + PV("ARS11-MCOY-1930:PS-MODE.VAL"), + PV("ARS11-MCOY-2430:PS-MODE.VAL"), + PV("ARS11-MCOY-2930:PS-MODE.VAL"), + PV("ARS11-MCOY-4240:PS-MODE.VAL"), + PV("ARS11-MCOY-4740:PS-MODE.VAL"), + PV("ARS11-MCOY-5270:PS-MODE.VAL"), + PV("ARS11-MCOY-5900:PS-MODE.VAL"), + PV("ARS12-MCOY-1110:PS-MODE.VAL"), + PV("ARS12-MCOY-1490:PS-MODE.VAL"), + PV("ARS12-MCOY-1930:PS-MODE.VAL"), + PV("ARS12-MCOY-2430:PS-MODE.VAL"), + PV("ARS12-MCOY-2930:PS-MODE.VAL"), + PV("ARS12-MCOY-4240:PS-MODE.VAL"), + PV("ARS12-MCOY-4740:PS-MODE.VAL"), + PV("ARS12-MCOY-5270:PS-MODE.VAL"), + PV("ARS12-MCOY-5900:PS-MODE.VAL"), + PV("ARS01-MCOX-0410:I-READ.VAL"), + PV("ARS01-MCOX-0740:I-READ.VAL"), + PV("ARS01-MCOX-1090:I-READ.VAL"), + PV("ARS01-MCOX-1470:I-READ.VAL"), + PV("ARS01-MCOX-1910:I-READ.VAL"), + PV("ARS01-MCOX-2420:I-READ.VAL"), + PV("ARS01-MCOX-2920:I-READ.VAL"), + PV("ARS01-MCOX-4230:I-READ.VAL"), + PV("ARS01-MCOX-4730:I-READ.VAL"), + PV("ARS01-MCOX-5260:I-READ.VAL"), + PV("ARS01-MCOX-5890:I-READ.VAL"), + PV("ARS02-MCOX-1090:I-READ.VAL"), + PV("ARS02-MCOX-1470:I-READ.VAL"), + PV("ARS02-MCOX-1910:I-READ.VAL"), + PV("ARS02-MCOX-2420:I-READ.VAL"), + PV("ARS02-MCOX-2920:I-READ.VAL"), + PV("ARS02-MCOX-4230:I-READ.VAL"), + PV("ARS02-MCOX-4730:I-READ.VAL"), + PV("ARS02-MCOX-5260:I-READ.VAL"), + PV("ARS02-MCOX-5890:I-READ.VAL"), + PV("ARS03-MCOX-0820:I-READ.VAL"), + PV("ARS03-MCOX-1090:I-READ.VAL"), + PV("ARS03-MCOX-1470:I-READ.VAL"), + PV("ARS03-MCOX-1910:I-READ.VAL"), + PV("ARS03-MCOX-2420:I-READ.VAL"), + PV("ARS03-MCOX-2920:I-READ.VAL"), + PV("ARS03-MCOX-4230:I-READ.VAL"), + PV("ARS03-MCOX-4730:I-READ.VAL"), + PV("ARS03-MCOX-5260:I-READ.VAL"), + PV("ARS03-MCOX-5890:I-READ.VAL"), + PV("ARS04-MCOX-1090:I-READ.VAL"), + PV("ARS04-MCOX-1470:I-READ.VAL"), + PV("ARS04-MCOX-1910:I-READ.VAL"), + PV("ARS04-MCOX-2420:I-READ.VAL"), + PV("ARS04-MCOX-2920:I-READ.VAL"), + PV("ARS04-MCOX-4230:I-READ.VAL"), + PV("ARS04-MCOX-4730:I-READ.VAL"), + PV("ARS04-MCOX-5260:I-READ.VAL"), + PV("ARS04-MCOX-5890:I-READ.VAL"), + PV("ARS05-MCOX-0420:I-READ.VAL"), + PV("ARS05-MCOX-1090:I-READ.VAL"), + PV("ARS05-MCOX-1470:I-READ.VAL"), + PV("ARS05-MCOX-1910:I-READ.VAL"), + PV("ARS05-MCOX-2420:I-READ.VAL"), + PV("ARS05-MCOX-2920:I-READ.VAL"), + PV("ARS05-MCOX-4230:I-READ.VAL"), + PV("ARS05-MCOX-4730:I-READ.VAL"), + PV("ARS05-MCOX-5260:I-READ.VAL"), + PV("ARS05-MCOX-5890:I-READ.VAL"), + PV("ARS06-MCOX-1090:I-READ.VAL"), + PV("ARS06-MCOX-1470:I-READ.VAL"), + PV("ARS06-MCOX-1910:I-READ.VAL"), + PV("ARS06-MCOX-2420:I-READ.VAL"), + PV("ARS06-MCOX-2920:I-READ.VAL"), + PV("ARS06-MCOX-4230:I-READ.VAL"), + PV("ARS06-MCOX-4730:I-READ.VAL"), + PV("ARS06-MCOX-5260:I-READ.VAL"), + PV("ARS06-MCOX-5890:I-READ.VAL"), + PV("ARS07-MCOX-0820:I-READ.VAL"), + PV("ARS07-MCOX-1090:I-READ.VAL"), + PV("ARS07-MCOX-1470:I-READ.VAL"), + PV("ARS07-MCOX-1910:I-READ.VAL"), + PV("ARS07-MCOX-2420:I-READ.VAL"), + PV("ARS07-MCOX-2920:I-READ.VAL"), + PV("ARS07-MCOX-4230:I-READ.VAL"), + PV("ARS07-MCOX-4730:I-READ.VAL"), + PV("ARS07-MCOX-5260:I-READ.VAL"), + PV("ARS07-MCOX-5890:I-READ.VAL"), + PV("ARS08-MCOX-1090:I-READ.VAL"), + PV("ARS08-MCOX-1470:I-READ.VAL"), + PV("ARS08-MCOX-1910:I-READ.VAL"), + PV("ARS08-MCOX-2420:I-READ.VAL"), + PV("ARS08-MCOX-2920:I-READ.VAL"), + PV("ARS08-MCOX-4230:I-READ.VAL"), + PV("ARS08-MCOX-4730:I-READ.VAL"), + PV("ARS08-MCOX-5260:I-READ.VAL"), + PV("ARS08-MCOX-5890:I-READ.VAL"), + PV("ARS09-MCOX-0580:I-READ.VAL"), + PV("ARS09-MCOX-1090:I-READ.VAL"), + PV("ARS09-MCOX-1470:I-READ.VAL"), + PV("ARS09-MCOX-1910:I-READ.VAL"), + PV("ARS09-MCOX-2420:I-READ.VAL"), + PV("ARS09-MCOX-2920:I-READ.VAL"), + PV("ARS09-MCOX-4230:I-READ.VAL"), + PV("ARS09-MCOX-4730:I-READ.VAL"), + PV("ARS09-MCOX-5260:I-READ.VAL"), + PV("ARS09-MCOX-5890:I-READ.VAL"), + PV("ARS10-MCOX-1090:I-READ.VAL"), + PV("ARS10-MCOX-1470:I-READ.VAL"), + PV("ARS10-MCOX-1910:I-READ.VAL"), + PV("ARS10-MCOX-2420:I-READ.VAL"), + PV("ARS10-MCOX-2920:I-READ.VAL"), + PV("ARS10-MCOX-4230:I-READ.VAL"), + PV("ARS10-MCOX-4730:I-READ.VAL"), + PV("ARS10-MCOX-5260:I-READ.VAL"), + PV("ARS10-MCOX-5890:I-READ.VAL"), + PV("ARS11-MCOX-0860:I-READ.VAL"), + PV("ARS11-MCOX-1090:I-READ.VAL"), + PV("ARS11-MCOX-1470:I-READ.VAL"), + PV("ARS11-MCOX-1910:I-READ.VAL"), + PV("ARS11-MCOX-2420:I-READ.VAL"), + PV("ARS11-MCOX-2920:I-READ.VAL"), + PV("ARS11-MCOX-4230:I-READ.VAL"), + PV("ARS11-MCOX-4730:I-READ.VAL"), + PV("ARS11-MCOX-5260:I-READ.VAL"), + PV("ARS11-MCOX-5890:I-READ.VAL"), + PV("ARS12-MCOX-1090:I-READ.VAL"), + PV("ARS12-MCOX-1470:I-READ.VAL"), + PV("ARS12-MCOX-1910:I-READ.VAL"), + PV("ARS12-MCOX-2420:I-READ.VAL"), + PV("ARS12-MCOX-2920:I-READ.VAL"), + PV("ARS12-MCOX-4230:I-READ.VAL"), + PV("ARS12-MCOX-4730:I-READ.VAL"), + PV("ARS12-MCOX-5260:I-READ.VAL"), + PV("ARS12-MCOX-5890:I-READ.VAL"), + PV("ARS01-MCOY-0400:I-READ.VAL"), + PV("ARS01-MCOY-0750:I-READ.VAL"), + PV("ARS01-MCOY-1110:I-READ.VAL"), + PV("ARS01-MCOY-1490:I-READ.VAL"), + PV("ARS01-MCOY-1930:I-READ.VAL"), + PV("ARS01-MCOY-2430:I-READ.VAL"), + PV("ARS01-MCOY-2930:I-READ.VAL"), + PV("ARS01-MCOY-4240:I-READ.VAL"), + PV("ARS01-MCOY-4740:I-READ.VAL"), + PV("ARS01-MCOY-5270:I-READ.VAL"), + PV("ARS01-MCOY-5900:I-READ.VAL"), + PV("ARS02-MCOY-1110:I-READ.VAL"), + PV("ARS02-MCOY-1490:I-READ.VAL"), + PV("ARS02-MCOY-1930:I-READ.VAL"), + PV("ARS02-MCOY-2430:I-READ.VAL"), + PV("ARS02-MCOY-2930:I-READ.VAL"), + PV("ARS02-MCOY-4240:I-READ.VAL"), + PV("ARS02-MCOY-4740:I-READ.VAL"), + PV("ARS02-MCOY-5270:I-READ.VAL"), + PV("ARS02-MCOY-5900:I-READ.VAL"), + PV("ARS03-MCOY-0830:I-READ.VAL"), + PV("ARS03-MCOY-1110:I-READ.VAL"), + PV("ARS03-MCOY-1490:I-READ.VAL"), + PV("ARS03-MCOY-1930:I-READ.VAL"), + PV("ARS03-MCOY-2430:I-READ.VAL"), + PV("ARS03-MCOY-2930:I-READ.VAL"), + PV("ARS03-MCOY-4240:I-READ.VAL"), + PV("ARS03-MCOY-4740:I-READ.VAL"), + PV("ARS03-MCOY-5270:I-READ.VAL"), + PV("ARS03-MCOY-5900:I-READ.VAL"), + PV("ARS04-MCOY-1110:I-READ.VAL"), + PV("ARS04-MCOY-1490:I-READ.VAL"), + PV("ARS04-MCOY-1930:I-READ.VAL"), + PV("ARS04-MCOY-2430:I-READ.VAL"), + PV("ARS04-MCOY-2930:I-READ.VAL"), + PV("ARS04-MCOY-4240:I-READ.VAL"), + PV("ARS04-MCOY-4740:I-READ.VAL"), + PV("ARS04-MCOY-5270:I-READ.VAL"), + PV("ARS04-MCOY-5900:I-READ.VAL"), + PV("ARS05-MCOY-0430:I-READ.VAL"), + PV("ARS05-MCOY-1110:I-READ.VAL"), + PV("ARS05-MCOY-1490:I-READ.VAL"), + PV("ARS05-MCOY-1930:I-READ.VAL"), + PV("ARS05-MCOY-2430:I-READ.VAL"), + PV("ARS05-MCOY-2930:I-READ.VAL"), + PV("ARS05-MCOY-4240:I-READ.VAL"), + PV("ARS05-MCOY-4740:I-READ.VAL"), + PV("ARS05-MCOY-5270:I-READ.VAL"), + PV("ARS05-MCOY-5900:I-READ.VAL"), + PV("ARS06-MCOY-1110:I-READ.VAL"), + PV("ARS06-MCOY-1490:I-READ.VAL"), + PV("ARS06-MCOY-1930:I-READ.VAL"), + PV("ARS06-MCOY-2430:I-READ.VAL"), + PV("ARS06-MCOY-2930:I-READ.VAL"), + PV("ARS06-MCOY-4240:I-READ.VAL"), + PV("ARS06-MCOY-4740:I-READ.VAL"), + PV("ARS06-MCOY-5270:I-READ.VAL"), + PV("ARS06-MCOY-5900:I-READ.VAL"), + PV("ARS07-MCOY-0830:I-READ.VAL"), + PV("ARS07-MCOY-1110:I-READ.VAL"), + PV("ARS07-MCOY-1490:I-READ.VAL"), + PV("ARS07-MCOY-1930:I-READ.VAL"), + PV("ARS07-MCOY-2430:I-READ.VAL"), + PV("ARS07-MCOY-2930:I-READ.VAL"), + PV("ARS07-MCOY-4240:I-READ.VAL"), + PV("ARS07-MCOY-4740:I-READ.VAL"), + PV("ARS07-MCOY-5270:I-READ.VAL"), + PV("ARS07-MCOY-5900:I-READ.VAL"), + PV("ARS08-MCOY-1110:I-READ.VAL"), + PV("ARS08-MCOY-1490:I-READ.VAL"), + PV("ARS08-MCOY-1930:I-READ.VAL"), + PV("ARS08-MCOY-2430:I-READ.VAL"), + PV("ARS08-MCOY-2930:I-READ.VAL"), + PV("ARS08-MCOY-4240:I-READ.VAL"), + PV("ARS08-MCOY-4740:I-READ.VAL"), + PV("ARS08-MCOY-5270:I-READ.VAL"), + PV("ARS08-MCOY-5900:I-READ.VAL"), + PV("ARS09-MCOY-0590:I-READ.VAL"), + PV("ARS09-MCOY-1110:I-READ.VAL"), + PV("ARS09-MCOY-1490:I-READ.VAL"), + PV("ARS09-MCOY-1930:I-READ.VAL"), + PV("ARS09-MCOY-2430:I-READ.VAL"), + PV("ARS09-MCOY-2930:I-READ.VAL"), + PV("ARS09-MCOY-4240:I-READ.VAL"), + PV("ARS09-MCOY-4740:I-READ.VAL"), + PV("ARS09-MCOY-5270:I-READ.VAL"), + PV("ARS09-MCOY-5900:I-READ.VAL"), + PV("ARS10-MCOY-1110:I-READ.VAL"), + PV("ARS10-MCOY-1490:I-READ.VAL"), + PV("ARS10-MCOY-1930:I-READ.VAL"), + PV("ARS10-MCOY-2430:I-READ.VAL"), + PV("ARS10-MCOY-2930:I-READ.VAL"), + PV("ARS10-MCOY-4240:I-READ.VAL"), + PV("ARS10-MCOY-4740:I-READ.VAL"), + PV("ARS10-MCOY-5270:I-READ.VAL"), + PV("ARS10-MCOY-5900:I-READ.VAL"), + PV("ARS11-MCOY-0870:I-READ.VAL"), + PV("ARS11-MCOY-1110:I-READ.VAL"), + PV("ARS11-MCOY-1490:I-READ.VAL"), + PV("ARS11-MCOY-1930:I-READ.VAL"), + PV("ARS11-MCOY-2430:I-READ.VAL"), + PV("ARS11-MCOY-2930:I-READ.VAL"), + PV("ARS11-MCOY-4240:I-READ.VAL"), + PV("ARS11-MCOY-4740:I-READ.VAL"), + PV("ARS11-MCOY-5270:I-READ.VAL"), + PV("ARS11-MCOY-5900:I-READ.VAL"), + PV("ARS12-MCOY-1110:I-READ.VAL"), + PV("ARS12-MCOY-1490:I-READ.VAL"), + PV("ARS12-MCOY-1930:I-READ.VAL"), + PV("ARS12-MCOY-2430:I-READ.VAL"), + PV("ARS12-MCOY-2930:I-READ.VAL"), + PV("ARS12-MCOY-4240:I-READ.VAL"), + PV("ARS12-MCOY-4740:I-READ.VAL"), + PV("ARS12-MCOY-5270:I-READ.VAL"), + PV("ARS12-MCOY-5900:I-READ.VAL"), + ], + [ + lambda vls: vls["ARS01-MCOX-0410:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-0740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-0820:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-0420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-0820:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-0580:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-0860:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-1090:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-1470:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-1910:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-2420:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-2920:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-4230:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-4730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-5260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOX-5890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-0400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-0750:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-0830:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-0430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-0830:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-0590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-0870:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-1110:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-1490:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-1930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-2430:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-2930:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-4240:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-4740:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-5270:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MCOY-5900:PS-MODE.VAL"] == 2, + lambda vls: -4.95 < vls["ARS01-MCOX-0410:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-0740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-0820:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-0420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-0820:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-0580:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-0860:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-1090:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-1470:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-1910:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-2420:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-2920:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-4230:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-4730:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-5260:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOX-5890:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-0400:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-0750:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS01-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS02-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-0830:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS03-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS04-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-0430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS05-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS06-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-0830:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS07-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS08-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-0590:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS09-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS10-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-0870:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS11-MCOY-5900:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-1110:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-1490:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-1930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-2430:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-2930:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-4240:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-4740:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-5270:I-READ.VAL"] < 4.95, + lambda vls: -4.95 < vls["ARS12-MCOY-5900:I-READ.VAL"] < 4.95, + ], + ], + "Magnets Ring": [ + [ + PV("ARS01-MQUA-0550:PS-MODE.VAL"), + PV("ARS01-MQUA-0630:PS-MODE.VAL"), + PV("ARS01-MQUA-0710:PS-MODE.VAL"), + PV("ARS01-MQUA-0790:PS-MODE.VAL"), + PV("ARS01-MQUA-1050:PS-MODE.VAL"), + PV("ARS01-MQUA-1150:PS-MODE.VAL"), + PV("ARS01-MQUA-1260:PS-MODE.VAL"), + PV("ARS01-MQUA-1370:PS-MODE.VAL"), + PV("ARS01-MQUA-5620:PS-MODE.VAL"), + PV("ARS01-MQUA-5730:PS-MODE.VAL"), + PV("ARS01-MQUA-5840:PS-MODE.VAL"), + PV("ARS01-MQUA-5940:PS-MODE.VAL"), + PV("ARS02-MQUA-1050:PS-MODE.VAL"), + PV("ARS02-MQUA-1150:PS-MODE.VAL"), + PV("ARS02-MQUA-1260:PS-MODE.VAL"), + PV("ARS02-MQUA-1370:PS-MODE.VAL"), + PV("ARS02-MQUA-5620:PS-MODE.VAL"), + PV("ARS02-MQUA-5730:PS-MODE.VAL"), + PV("ARS02-MQUA-5840:PS-MODE.VAL"), + PV("ARS02-MQUA-5940:PS-MODE.VAL"), + PV("ARS03-MQUA-0790:PS-MODE.VAL"), + PV("ARS03-MQUA-0850:PS-MODE.VAL"), + PV("ARS03-MQUA-1050:PS-MODE.VAL"), + PV("ARS03-MQUA-1150:PS-MODE.VAL"), + PV("ARS03-MQUA-1260:PS-MODE.VAL"), + PV("ARS03-MQUA-1370:PS-MODE.VAL"), + PV("ARS03-MQUA-5620:PS-MODE.VAL"), + PV("ARS03-MQUA-5730:PS-MODE.VAL"), + PV("ARS03-MQUA-5840:PS-MODE.VAL"), + PV("ARS03-MQUA-5940:PS-MODE.VAL"), + PV("ARS04-MQUA-1050:PS-MODE.VAL"), + PV("ARS04-MQUA-1150:PS-MODE.VAL"), + PV("ARS04-MQUA-1260:PS-MODE.VAL"), + PV("ARS04-MQUA-1370:PS-MODE.VAL"), + PV("ARS04-MQUA-5620:PS-MODE.VAL"), + PV("ARS04-MQUA-5730:PS-MODE.VAL"), + PV("ARS04-MQUA-5840:PS-MODE.VAL"), + PV("ARS04-MQUA-5940:PS-MODE.VAL"), + PV("ARS05-MQUA-0400:PS-MODE.VAL"), + PV("ARS05-MQUA-0440:PS-MODE.VAL"), + PV("ARS05-MQUA-0460:PS-MODE.VAL"), + PV("ARS05-MQUA-1050:PS-MODE.VAL"), + PV("ARS05-MQUA-1150:PS-MODE.VAL"), + PV("ARS05-MQUA-1260:PS-MODE.VAL"), + PV("ARS05-MQUA-1370:PS-MODE.VAL"), + PV("ARS05-MQUA-5620:PS-MODE.VAL"), + PV("ARS05-MQUA-5730:PS-MODE.VAL"), + PV("ARS05-MQUA-5840:PS-MODE.VAL"), + PV("ARS05-MQUA-5940:PS-MODE.VAL"), + PV("ARS06-MQUA-1050:PS-MODE.VAL"), + PV("ARS06-MQUA-1150:PS-MODE.VAL"), + PV("ARS06-MQUA-1260:PS-MODE.VAL"), + PV("ARS06-MQUA-1370:PS-MODE.VAL"), + PV("ARS06-MQUA-5620:PS-MODE.VAL"), + PV("ARS06-MQUA-5730:PS-MODE.VAL"), + PV("ARS06-MQUA-5840:PS-MODE.VAL"), + PV("ARS06-MQUA-5940:PS-MODE.VAL"), + PV("ARS07-MQUA-0790:PS-MODE.VAL"), + PV("ARS07-MQUA-0850:PS-MODE.VAL"), + PV("ARS07-MQUA-1050:PS-MODE.VAL"), + PV("ARS07-MQUA-1150:PS-MODE.VAL"), + PV("ARS07-MQUA-1260:PS-MODE.VAL"), + PV("ARS07-MQUA-1370:PS-MODE.VAL"), + PV("ARS07-MQUA-5620:PS-MODE.VAL"), + PV("ARS07-MQUA-5730:PS-MODE.VAL"), + PV("ARS07-MQUA-5840:PS-MODE.VAL"), + PV("ARS07-MQUA-5940:PS-MODE.VAL"), + PV("ARS08-MQUA-1050:PS-MODE.VAL"), + PV("ARS08-MQUA-1150:PS-MODE.VAL"), + PV("ARS08-MQUA-1260:PS-MODE.VAL"), + PV("ARS08-MQUA-1370:PS-MODE.VAL"), + PV("ARS08-MQUA-5620:PS-MODE.VAL"), + PV("ARS08-MQUA-5730:PS-MODE.VAL"), + PV("ARS08-MQUA-5840:PS-MODE.VAL"), + PV("ARS08-MQUA-5940:PS-MODE.VAL"), + PV("ARS09-MQUA-0530:PS-MODE.VAL"), + PV("ARS09-MQUA-0560:PS-MODE.VAL"), + PV("ARS09-MQUA-0600:PS-MODE.VAL"), + PV("ARS09-MQUA-1050:PS-MODE.VAL"), + PV("ARS09-MQUA-1150:PS-MODE.VAL"), + PV("ARS09-MQUA-1260:PS-MODE.VAL"), + PV("ARS09-MQUA-1370:PS-MODE.VAL"), + PV("ARS09-MQUA-5620:PS-MODE.VAL"), + PV("ARS09-MQUA-5730:PS-MODE.VAL"), + PV("ARS09-MQUA-5840:PS-MODE.VAL"), + PV("ARS09-MQUA-5940:PS-MODE.VAL"), + PV("ARS10-MQUA-1050:PS-MODE.VAL"), + PV("ARS10-MQUA-1150:PS-MODE.VAL"), + PV("ARS10-MQUA-1260:PS-MODE.VAL"), + PV("ARS10-MQUA-1370:PS-MODE.VAL"), + PV("ARS10-MQUA-5620:PS-MODE.VAL"), + PV("ARS10-MQUA-5730:PS-MODE.VAL"), + PV("ARS10-MQUA-5840:PS-MODE.VAL"), + PV("ARS10-MQUA-5940:PS-MODE.VAL"), + PV("ARS11-MQUA-0830:PS-MODE.VAL"), + PV("ARS11-MQUA-0890:PS-MODE.VAL"), + PV("ARS11-MQUA-1050:PS-MODE.VAL"), + PV("ARS11-MQUA-1150:PS-MODE.VAL"), + PV("ARS11-MQUA-1260:PS-MODE.VAL"), + PV("ARS11-MQUA-1370:PS-MODE.VAL"), + PV("ARS11-MQUA-5620:PS-MODE.VAL"), + PV("ARS11-MQUA-5730:PS-MODE.VAL"), + PV("ARS11-MQUA-5840:PS-MODE.VAL"), + PV("ARS11-MQUA-5940:PS-MODE.VAL"), + PV("ARS12-MQUA-1050:PS-MODE.VAL"), + PV("ARS12-MQUA-1150:PS-MODE.VAL"), + PV("ARS12-MQUA-1260:PS-MODE.VAL"), + PV("ARS12-MQUA-1370:PS-MODE.VAL"), + PV("ARS12-MQUA-5620:PS-MODE.VAL"), + PV("ARS12-MQUA-5730:PS-MODE.VAL"), + PV("ARS12-MQUA-5840:PS-MODE.VAL"), + PV("ARS12-MQUA-5940:PS-MODE.VAL"), + PV("ARS01-MSXT-1190:PS-MODE.VAL"), + PV("ARS01-MSXT-1300:PS-MODE.VAL"), + PV("ARS01-MSXT-1410:PS-MODE.VAL"), + PV("ARS01-MSXT-1590:PS-MODE.VAL"), + PV("ARS01-MSXT-1810:PS-MODE.VAL"), + PV("ARS01-MSXT-1980:PS-MODE.VAL"), + PV("ARS01-MSXT-2200:PS-MODE.VAL"), + PV("ARS01-MSXT-2330:PS-MODE.VAL"), + PV("ARS01-MSXT-2480:PS-MODE.VAL"), + PV("ARS01-MSXT-2700:PS-MODE.VAL"), + PV("ARS01-MSXT-2830:PS-MODE.VAL"), + PV("ARS01-MSXT-2980:PS-MODE.VAL"), + PV("ARS01-MSXT-4010:PS-MODE.VAL"), + PV("ARS01-MSXT-4160:PS-MODE.VAL"), + PV("ARS01-MSXT-4290:PS-MODE.VAL"), + PV("ARS01-MSXT-4510:PS-MODE.VAL"), + PV("ARS01-MSXT-4660:PS-MODE.VAL"), + PV("ARS01-MSXT-4790:PS-MODE.VAL"), + PV("ARS01-MSXT-5010:PS-MODE.VAL"), + PV("ARS01-MSXT-5180:PS-MODE.VAL"), + PV("ARS01-MSXT-5400:PS-MODE.VAL"), + PV("ARS01-MSXT-5580:PS-MODE.VAL"), + PV("ARS01-MSXT-5690:PS-MODE.VAL"), + PV("ARS01-MSXT-5800:PS-MODE.VAL"), + PV("ARS02-MSXT-2980:PS-MODE.VAL"), + PV("ARS02-MSXT-4010:PS-MODE.VAL"), + PV("ARS03-MSXT-1590:PS-MODE.VAL"), + PV("ARS03-MSXT-2980:PS-MODE.VAL"), + PV("ARS03-MSXT-4010:PS-MODE.VAL"), + PV("ARS03-MSXT-5400:PS-MODE.VAL"), + PV("ARS05-MSXT-1190:PS-MODE.VAL"), + PV("ARS05-MSXT-1300:PS-MODE.VAL"), + PV("ARS05-MSXT-1410:PS-MODE.VAL"), + PV("ARS05-MSXT-1590:PS-MODE.VAL"), + PV("ARS05-MSXT-5400:PS-MODE.VAL"), + PV("ARS05-MSXT-5580:PS-MODE.VAL"), + PV("ARS05-MSXT-5690:PS-MODE.VAL"), + PV("ARS05-MSXT-5800:PS-MODE.VAL"), + PV("ARS07-MSXT-1590:PS-MODE.VAL"), + PV("ARS07-MSXT-1810:PS-MODE.VAL"), + PV("ARS07-MSXT-1980:PS-MODE.VAL"), + PV("ARS07-MSXT-2200:PS-MODE.VAL"), + PV("ARS07-MSXT-2330:PS-MODE.VAL"), + PV("ARS07-MSXT-2480:PS-MODE.VAL"), + PV("ARS07-MSXT-2700:PS-MODE.VAL"), + PV("ARS07-MSXT-2830:PS-MODE.VAL"), + PV("ARS07-MSXT-2980:PS-MODE.VAL"), + PV("ARS07-MSXT-4010:PS-MODE.VAL"), + PV("ARS07-MSXT-4160:PS-MODE.VAL"), + PV("ARS07-MSXT-4290:PS-MODE.VAL"), + PV("ARS07-MSXT-4510:PS-MODE.VAL"), + PV("ARS07-MSXT-4660:PS-MODE.VAL"), + PV("ARS07-MSXT-4790:PS-MODE.VAL"), + PV("ARS07-MSXT-5010:PS-MODE.VAL"), + PV("ARS07-MSXT-5180:PS-MODE.VAL"), + PV("ARS07-MSXT-5400:PS-MODE.VAL"), + PV("ARS09-MSXT-1190:PS-MODE.VAL"), + PV("ARS09-MSXT-1300:PS-MODE.VAL"), + PV("ARS09-MSXT-1410:PS-MODE.VAL"), + PV("ARS09-MSXT-1590:PS-MODE.VAL"), + PV("ARS09-MSXT-5400:PS-MODE.VAL"), + PV("ARS09-MSXT-5580:PS-MODE.VAL"), + PV("ARS09-MSXT-5690:PS-MODE.VAL"), + PV("ARS09-MSXT-5800:PS-MODE.VAL"), + PV("ARS11-MSXT-1590:PS-MODE.VAL"), + PV("ARS11-MSXT-5400:PS-MODE.VAL"), + PV("ARS01-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS02-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS03-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS04-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS05-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS06-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS07-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS08-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS09-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS10-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS11-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-1230-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-1330-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-1440-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-1840-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-1950-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2230-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2360-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2450-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2730-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2860-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-2950-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4040-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4130-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4260-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4540-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4630-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-4760-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-5040-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-5150-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-5550-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-5660-OC:PS-MODE.VAL"), + PV("ARS12-MOCT-5760-OC:PS-MODE.VAL"), + PV("ARS01-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS02-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS03-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS04-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS05-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS06-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS07-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS08-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS09-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS10-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS11-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-1230-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-1330-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-1440-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-1840-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-1950-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2230-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2360-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2450-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2730-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2860-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-2950-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4040-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4130-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4260-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4540-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4630-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-4760-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-5040-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-5150-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-5550-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-5660-QA:PS-MODE.VAL"), + PV("ARS12-MOCT-5760-QA:PS-MODE.VAL"), + PV("ARS01-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS01-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS02-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS03-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS04-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS05-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS06-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS07-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS08-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS09-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS10-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS11-MOCT-5760-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-1230-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-1330-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-1440-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-1840-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-1950-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2230-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2360-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2450-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2730-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2860-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-2950-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4040-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4130-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4260-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4540-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4630-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-4760-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-5040-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-5150-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-5550-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-5660-QS:PS-MODE.VAL"), + PV("ARS12-MOCT-5760-QS:PS-MODE.VAL"), + ], + [ + lambda vls: vls["ARS01-MQUA-0550:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-0630:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-0710:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-0790:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-0790:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-0850:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-0400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-0440:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-0460:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-0790:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-0850:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-0530:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-0560:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-0600:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-0830:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-0890:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-1050:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-1150:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-1260:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-1370:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-5620:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-5730:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-5840:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MQUA-5940:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1190:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1300:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1410:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1810:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-1980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2200:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2330:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2480:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2700:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2830:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-2980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4160:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4290:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4510:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4660:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-4790:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5180:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5580:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5690:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MSXT-5800:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MSXT-2980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MSXT-4010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MSXT-2980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MSXT-4010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-1190:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-1300:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-1410:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-5580:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-5690:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MSXT-5800:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-1810:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-1980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2200:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2330:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2480:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2700:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2830:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-2980:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4160:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4290:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4510:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4660:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-4790:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-5010:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-5180:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-1190:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-1300:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-1410:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-5580:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-5690:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MSXT-5800:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MSXT-1590:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MSXT-5400:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1330-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1440-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1840-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2230-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2360-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2450-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2730-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2860-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2950-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4130-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4260-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4540-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4630-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5040-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5150-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5550-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5660-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5760-OC:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1330-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1440-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1840-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2230-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2360-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2450-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2730-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2860-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2950-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4130-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4260-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4540-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4630-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5040-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5150-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5550-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5660-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5760-QA:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS01-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS02-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS03-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS04-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS05-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS06-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS07-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS08-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS09-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS10-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS11-MOCT-5760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1330-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1440-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1840-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-1950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2230-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2360-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2450-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2730-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2860-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-2950-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4130-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4260-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4540-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4630-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-4760-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5040-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5150-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5550-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5660-QS:PS-MODE.VAL"] == 2, + lambda vls: vls["ARS12-MOCT-5760-QS:PS-MODE.VAL"] == 2, + ], + ], + "Current Limit": [ + [ + PV("ARS07-DPCT-0000:CURR.VAL"), + PV("ARS07-DPCT-0100:CURR.VAL"), + PV("ARS07-DPCT-0200:CURR.VAL"), + PV("AGEBD-PARAMS:CURRENTLIMIT.VAL"), + ], + [ + lambda vls: vls["ARS07-DPCT-0000:CURR.VAL"] < vls["AGEBD-PARAMS:CURRENTLIMIT.VAL"], + lambda vls: vls["ARS07-DPCT-0100:CURR.VAL"] < vls["AGEBD-PARAMS:CURRENTLIMIT.VAL"], + lambda vls: vls["ARS07-DPCT-0200:CURR.VAL"] < vls["AGEBD-PARAMS:CURRENTLIMIT.VAL"], + ], + ], + "IDs Ready": [ + [ + PV("AGEOP-BL:IDS-ARE-OPEN.VAL"), + PV("ARS07-DPCT-0000:CURR.VAL"), + ], + [ + lambda vls: ( + False + if vls["ARS07-DPCT-0000:CURR.VAL"] < 350 + and vls["AGEOP-BL:IDS-ARE-OPEN.VAL"] == 0 + else True + ) + ], + ], + "Single Bunch Charge": [ + [ + PV("ARSGE-CECL-FPFB:BEAM-DUMP-ABS-ADC-DATA.VAL"), + PV("ARSGE-CECL-FPFB:FPFB-BEAM-DUMP-THR.VAL"), + ], + [ + lambda vls: ( + np.max(vls["ARSGE-CECL-FPFB:BEAM-DUMP-ABS-ADC-DATA.VAL"]) + < 0.95 * vls["ARSGE-CECL-FPFB:FPFB-BEAM-DUMP-THR.VAL"] + ) + ], + ], + "Injection Quality": [ + [ + # ... + ], + [ + lambda vls: True, + ], + ], + "Dump Quality": [ + [ + # ... + ], + [ + lambda vls: True, + ], + ], + "Lifetime": [ + [ + # ... + ], + [ + lambda vls: True, + ], + ], + "Tune": [ + [ + # ... + ], + [ + lambda vls: True, + ], + ], + "Pingers": [ + [ + PV("ARS01-MKIK-0290:CTRL-ON-OFF.VAL"), + PV("ARS01-MKIK-0320:CTRL-ON-OFF.VAL"), + PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL"), + PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL"), + ], + [ + lambda vls: ( + not bool( + ( + vls["ARS01-MKIK-0290:CTRL-ON-OFF.VAL"] + or vls["ARS01-MKIK-0320:CTRL-ON-OFF.VAL"] + ) + and vls["AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL"] + ) + ), + lambda vls: ( + not bool( + vls["ARS01-MKIK-0320:CTRL-ON-OFF.VAL"] + and vls["AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL"] + ) + ), + ], + ], + "Vacuum Pressure": [ + [ + PV("ARIVA-VMAVE:PRESS-MAX.VAL"), + ], + [ + lambda vls: vls["ARIVA-VMAVE:PRESS-MAX.VAL"] < 3e-8, + ], + ], + "Orbit Deviation": [ + [ + PV("ARS07-DPCT-0000:CURR.VAL"), + PV("ARSGE-CECL-FOFB1:B-ERR-X-RMS.VAL"), + PV("ARSGE-CECL-FOFB1:B-ERR-Y-RMS.VAL"), + ], + [ + lambda vls: ( + vls["ARSGE-CECL-FOFB1:B-ERR-X-RMS.VAL"] < 0.02 + if vls["ARS07-DPCT-0000:CURR.VAL"] > 22 + else True + ), + lambda vls: ( + vls["ARSGE-CECL-FOFB1:B-ERR-Y-RMS.VAL"] < 0.02 + if vls["ARS07-DPCT-0000:CURR.VAL"] > 22 + else True + ), + ], + ], + "Beam Dump Controller": [ + [ + PV("AGESA-SBDC-0000:SUM_INPUT_NOT_OK_LATCHED.VAL"), + ], + [ + lambda vls: vls["AGESA-SBDC-0000:SUM_INPUT_NOT_OK_LATCHED.VAL"] == 0, + ], + ], + } def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) - PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True + if len(self.checks_input) != len(self.checks_output): + msg = "amount of defined checks and according ouput check PVs do not match" + print(msg) + raise RuntimeError(msg) - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-INJECTIONGUARD:BO" - ) # TODO: is this a good PV to use? - ## Service specific PVs from other IOCs - # ... +""" +Beam Transfer Checks - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-INJECTIONGUARD:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + 1. Check that all EVR counters increment after according event is released + + Beam Dump (here not an event but the BDC is start of chain) + AGESA-SBDC-0000:INT-COUNTER + AGETI-CVME-MASTER-TMA:Evt-Beam-Dump-EVRCount-I + AGETI-CVME-MASTER-EVR0:Event-41-Cnt-I (= AGETI-CVME-MASTER-TMA:Evt-Beam-Dump-EVRCount-I.INPA) + ARS01-MKIK-0050-1:TRIG-CNT + ARS01-MKIK-0050-2:TRIG-CNT + ARS01-MKIK-0050-3:TRIG-CNT + ARS01-MKIK-0050-4:TRIG-CNT + + SR Injection + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I + AGETI-CVME-MASTER-EVR0:Event-32-Cnt-I + ARS01-MKIK-0140:TRIG-CNT + ARS01-MKIK-0220:TRIG-CNT + ARS01-MKIK-0850:TRIG-CNT + ARS01-MKIK-0940:TRIG-CNT + ARS01-MSEP-0670:TRIG-CNT + + Booster Extraction + AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I + AGETI-CVME-MASTER-EVR0:Event-24-Cnt-I + ABOMA-YEX:TRIG-CNT + ABOMA-KEX:TRIG-CNT + + Booster Injection + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I + AGETI-CVME-MASTER-EVR0:Event-23-Cnt-I + ABOMA-YIN:TRIG-CNT + ABOMA-KIN:TRIG-CNT + + 2. Check that the transmission stays above limits, e.g.: + + 60 % per shot + 80 % per 5 shot average + 90 % per 4 h average + + requires: + - reliable injection indicator and reliable transmission calculation + - reliable correleated PCT readings from booster and ring + - limits as pv for flexibility + +""" class Service(BaseService[PVs]): @@ -56,38 +3883,102 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.logs = [] + + # initiate vals and results dicts + self.timestamp = str(datetime.now()) + self.timestamp5 = self.timestamp[:-5] + self.timestamp7 = self.timestamp[:-7] + self.vals = {} + self.results = {} + for check_group in pvs.checks_input: + self.results[check_group] = 0 + + links, _ = pvs.checks_input[check_group] + + for pv in links: + pvname = pv.pvname + self.vals[pvname] = pv.get() def update(self): + pvs = self.pvs + # when callback is fired, this code will be executed if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + self.timestamp = str(datetime.now()) + self.timestamp5 = self.timestamp[:-5] + self.timestamp7 = self.timestamp[:-7] + + if pvs.logclear.get(): + self.logs = [] + pvs.logclear.put(0) + pvs.logbook.put("Injection Guard Alarm Log Cleared, " + self.timestamp5 + "\n") + + for check_group in pvs.checks_input: + links, checks = pvs.checks_input[check_group] + + # update vals dict for all links of this check_group + for pv in links: + pvname = pv.pvname + + if pv.connected: + self.vals[pvname] = pv.get() + else: + self.logs.append( + "{:} {:35} = not connected".format(self.timestamp7, pvname) + ) + self.vals[pvname] = np.nan + + self.results[check_group] = 1 + + # do all checks of this check_group using vals dict + for check in checks: + try: + if not check(self.vals): + self.results[check_group] = 0 + code = ( + inspect.getsource(check) + .split("vls: ")[1] + .strip("\n") + .strip(",") + .replace("vls[", "") + .replace(".VAL']", "") + .replace("'", "") + ) + self.logs.append("{:} failed: {:}".format(self.timestamp7, code)) + # self.logs.append('{:} values: {:}'.format(self.timestamp7, self.vals)) + except: + self.results[check_group] = 0 + code = ( + inspect.getsource(check) + .split("vls: ")[1] + .strip("\n") + .strip(",") + .replace("vls[", "") + .replace(".VAL']", "") + .replace("'", "") + ) + self.logs.append("{:} exception: {:}".format(self.timestamp7, code)) + # self.logs.append('{:} values: {:}'.format(self.timestamp7, self.vals)) + + try: + if pvs.checks_output[check_group].connected: + pvs.checks_output[check_group].put(self.results[check_group]) + else: + self.logs.append( + "{:} {:35} = not connected".format( + self.timestamp7, pvs.checks_output[check_group].pvname + ) + ) + except: + print("Cannot find check group {:}".format(check_group)) + + if len(self.logs) > 100: + self.logs = self.logs[:100] + + if not pvs.logbook_pause.get(): + log_header = ["Injection Guard Alarm Log, " + self.timestamp5 + "\n"] + pvs.logbook.put("\n".join(log_header + self.logs[::-1])) # callback done self.CallbackFired = 0 - - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., - - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() - - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### diff --git a/services/injectionguard/current/app/uv.lock b/services/injectionguard/current/app/uv.lock index 943f9eb..ecb8da5 100644 --- a/services/injectionguard/current/app/uv.lock +++ b/services/injectionguard/current/app/uv.lock @@ -26,6 +26,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -36,7 +37,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.0.2" }, +] [package.metadata.requires-dev] dev = [ From 8ce97e701f8bbd12760c039f335bad995c73a281 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:37:48 +0200 Subject: [PATCH 24/42] feature: add new service tune --- docs/ioc/ioc_overview.md | 2 +- services/tune/current/app/pyproject.toml | 47 + .../current/app/src/agebd_tune/__init__.py | 1 + .../tune/current/app/src/agebd_tune/main.py | 31 + .../current/app/src/agebd_tune/service.py | 93 + services/tune/current/app/tests/test_app.py | 9 + services/tune/current/app/uv.lock | 275 ++ .../current/ioc/AGEBD-CPCL-TUNE_main.subs | 4 + .../ioc/AGEBD-CPCL-TUNE_parameters.yaml | 6 + services/tune/current/ioc/TUNE.template | 439 ++++ services/tune/current/ioc/startup.script | 1 + services/tune/current/qt/A_BD_Tune.ui | 2300 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TUNE.service | 16 + 13 files changed, 3223 insertions(+), 1 deletion(-) create mode 100644 services/tune/current/app/pyproject.toml create mode 100644 services/tune/current/app/src/agebd_tune/__init__.py create mode 100644 services/tune/current/app/src/agebd_tune/main.py create mode 100644 services/tune/current/app/src/agebd_tune/service.py create mode 100644 services/tune/current/app/tests/test_app.py create mode 100644 services/tune/current/app/uv.lock create mode 100644 services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs create mode 100644 services/tune/current/ioc/AGEBD-CPCL-TUNE_parameters.yaml create mode 100644 services/tune/current/ioc/TUNE.template create mode 100644 services/tune/current/ioc/startup.script create mode 100644 services/tune/current/qt/A_BD_Tune.ui create mode 100644 services/tune/current/systemd/AGEBD-SERVICE-TUNE.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 843d604..eb2d865 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-PLOTS | | +| AGEBD-CPCL-TUNE | | diff --git a/services/tune/current/app/pyproject.toml b/services/tune/current/app/pyproject.toml new file mode 100644 index 0000000..0c62707 --- /dev/null +++ b/services/tune/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-tune" +version = "0.1.0" +description = "AGEBD-TUNE Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/tune/current/app/src/agebd_tune/__init__.py b/services/tune/current/app/src/agebd_tune/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/tune/current/app/src/agebd_tune/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py new file mode 100644 index 0000000..f3eaab0 --- /dev/null +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_tune import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TUNE" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/tune/current/app/src/agebd_tune/service.py b/services/tune/current/app/src/agebd_tune/service.py new file mode 100644 index 0000000..be08b40 --- /dev/null +++ b/services/tune/current/app/src/agebd_tune/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TUNE:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TUNE:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TUNE:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/tune/current/app/tests/test_app.py b/services/tune/current/app/tests/test_app.py new file mode 100644 index 0000000..2afcc45 --- /dev/null +++ b/services/tune/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_tune import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/tune/current/app/uv.lock b/services/tune/current/app/uv.lock new file mode 100644 index 0000000..38d5733 --- /dev/null +++ b/services/tune/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-tune" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs b/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs new file mode 100644 index 0000000..16e587d --- /dev/null +++ b/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs @@ -0,0 +1,4 @@ +file TUNE.template { + pattern { DEVICE } + { AGEBD-TUNE } +} \ No newline at end of file diff --git a/services/tune/current/ioc/AGEBD-CPCL-TUNE_parameters.yaml b/services/tune/current/ioc/AGEBD-CPCL-TUNE_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/tune/current/ioc/AGEBD-CPCL-TUNE_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/tune/current/ioc/TUNE.template b/services/tune/current/ioc/TUNE.template new file mode 100644 index 0000000..ad157d3 --- /dev/null +++ b/services/tune/current/ioc/TUNE.template @@ -0,0 +1,439 @@ +# HLA Service Control Parameters + +record(ao, "$(DEVICE):SVD-CLEAN-Neigenvalues") { + field(DESC, "Nr of EV in SVD") + field(VAL, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-TbTFirstIndex") { + field(DESC, "Index of first TbT data point to use") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-TbTLastIndex") { + field(DESC, "Index of last TbT data point to use") + field(VAL, "511") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-NAveraging") { + field(DESC, "Nr. of samples to take for averaging") + field(VAL, "1") + field(PREC, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ZeroPaddingN") { + field(DESC, "Add zeropadding to obtain N datapoints") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Xi") { + field(DESC, "First datapoint for hor. peak search") + field(VAL, "0.1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Xf") { + field(DESC, "Last datapoint for hor. peak search") + field(VAL, "0.5") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Yi") { + field(DESC, "First datapoint for ver. peak search") + field(VAL, "0.1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Yf") { + field(DESC, "Last datapoint for ver. peak search") + field(VAL, "0.5") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Zi") { + field(DESC, "First datapoint for long. peak search") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-ROI-Zf") { + field(DESC, "Last datapoint for long. peak search") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-HOR-PING-ISET") { + field(DESC, "default current value for x pinger") + field(VAL, "20") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-HOR-PING-DELAY") { + field(DESC, "default delay value for x pinger") + field(VAL, "80") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VER-PING-ISET") { + field(DESC, "default current value for y pinger") + field(VAL, "20") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VER-PING-DELAY") { + field(DESC, "default delay value for y pinger") + field(VAL, "80") + field(PINI, "YES") +} + + +# # HLA Service Output/Result Parameters + +record(ao, "$(DEVICE):HORIZONTAL-PEAK1-FREQ") { + field(DESC, "Horizontal tune frequency") +} + +record(ao, "$(DEVICE):HORIZONTAL-PEAK1-AMP") { + field(DESC, "Horizontal tune amplitude") +} + +record(ao, "$(DEVICE):HORIZONTAL-PEAK2-FREQ") { + field(DESC, "Horizontal sideband 1 frequency") +} + +record(ao, "$(DEVICE):HORIZONTAL-PEAK2-AMP") { + field(DESC, "Horizontal sideband 1 amplitude") +} + +record(ao, "$(DEVICE):HORIZONTAL-PEAK3-FREQ") { + field(DESC, "Horizontal sideband 2 frequency") +} + +record(ao, "$(DEVICE):HORIZONTAL-PEAK3-AMP") { + field(DESC, "Horizontal sideband 2 amplitude") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK1-FREQ") { + field(DESC, "Vertical tune frequency") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK1-AMP") { + field(DESC, "Vertical tune amplitude") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK2-FREQ") { + field(DESC, "Vertical sideband 1 frequency") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK2-AMP") { + field(DESC, "Vertical sideband 1 amplitude") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK3-FREQ") { + field(DESC, "Vertical sideband 2 frequency") +} + +record(ao, "$(DEVICE):VERTICAL-PEAK3-AMP") { + field(DESC, "Vertical sideband 2 amplitude") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK1-FREQ") { + field(DESC, "Longitudinal tune frequency") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK1-AMP") { + field(DESC, "Longitudinal tune amplitude") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK2-FREQ") { + field(DESC, "Longitudinal sideband 1 frequency") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK2-AMP") { + field(DESC, "Longitudinal sideband 1 amplitude") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK3-FREQ") { + field(DESC, "Longitudinal sideband 2 frequency") +} + +record(ao, "$(DEVICE):LONGITUDINAL-PEAK3-AMP") { + field(DESC, "Longitudinal sideband 2 amplitude") +} + +record(waveform, "$(DEVICE):HORIZONTAL-SPEC-ALL") { + field(DESC, "Entire measured horizontal spectrum") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):HORIZONTAL-SPEC-ROI") { + field(DESC, "Entire measured horizontal spectrum") + field(NELM, "4096") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):VERTICAL-SPEC-ALL") { + field(DESC, "Entire measured vertical spectrum") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):VERTICAL-SPEC-ROI") { + field(DESC, "Entire measured vertical spectrum") + field(NELM, "4096") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):LONGITUDINAL-SPEC-ALL") { + field(DESC, "Entire measured longitudinal spectrum") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):LONGITUDINAL-SPEC-ROI") { + field(DESC, "Entire measured longitudinal spectrum") + field(NELM, "4096") + field(FTVL, "FLOAT") +} + + +record (ao,"$(DEVICE):Q1_NAFF"){ + field (DESC, "Horizontal tune calculated using NAFF") + field (VAL, 0) + field (EGU, "") +} + +record (ao,"$(DEVICE):Q2_NAFF"){ + field (DESC, "Vertical tune calculated using NAFF") + field (VAL, 0) + field (EGU, "") +} + +record (ao,"$(DEVICE):NPOINTS"){ + field (DESC, "Number of points in pos/fft waveform") + field (VAL, 16384) + field (EGU, "") +} + +record(waveform, "$(DEVICE):SPEC-SAMPLE-ALL") { + field(DESC, "FFT spectrum tune axis") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):OSCILLATION-X-ALL") { + field(DESC, "Entire measured horizontal oscillation") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):OSCILLATION-Y-ALL") { + field(DESC, "Entire measured vertical oscillation") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record(waveform, "$(DEVICE):OSCILLATION-SAMPLE-ALL") { + field(DESC, "Sample index for oscillations") + field(NELM, "16384") + field(FTVL, "FLOAT") +} + +record (ao,"$(DEVICE):CONTROL-NAFF"){ + field (DESC, "Control NAFF calc.") + field (VAL, 1) + field (EGU, "") +} + +record (ao,"$(DEVICE):SINGLE-BPM"){ + field (VAL, 0) +} + +record (ao,"$(DEVICE):SVD-CLEAN"){ + field (VAL, 0) +} + +record (ao,"$(DEVICE):MEAS-TIME"){ + field (DESC, "Time for measurement") + field (VAL, 0) + field (EGU, "ms") +} + +record (ao,"$(DEVICE):DUMMY1"){ + field (DESC, "Dummy PV with value 1") + field (VAL, 1) +} + +record(stringout, "$(DEVICE):BPM-SELECT-SINGLE") { + field(DESC, "String defining selected BPM") + field(VAL, "ARS07-DBPM-0840") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-01") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-01") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-02") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-02") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-03") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-03") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-04") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-04") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-05") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-05") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-06") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-06") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-07") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-07") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-08") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-08") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-09") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-09") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-10") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-10") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-11") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-11") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPM-12") { + field(DESC, "Select BPMs") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo,"$(DEVICE):BPM-SELECT-BPMA-12") { + field(DESC, "Select BPMAs") + field(VAL, "0") + field(PINI, "YES") +} + +record (ao,"$(DEVICE):NAFF-HARMONICS"){ + field(DESC, "Number") + field(VAL, "5") + field(EGU, "") + field(PINI, "YES") + field(DRVH, "20") + field(DRVL, "1") +} diff --git a/services/tune/current/ioc/startup.script b/services/tune/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/tune/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/tune/current/qt/A_BD_Tune.ui b/services/tune/current/qt/A_BD_Tune.ui new file mode 100644 index 0000000..844a7bc --- /dev/null +++ b/services/tune/current/qt/A_BD_Tune.ui @@ -0,0 +1,2300 @@ + + + MainWindow + + + + 0 + 0 + 950 + 780 + + + + + 1600 + 800 + + + + MainWindow + + + + + + 20 + 400 + 911 + 331 + + + + 0 + + + + Oscillation plot + + + + + 10 + 10 + 421 + 271 + + + + Horizontal beam oscillation + + + Turn + + + x [mm] + + + AGEBD-TUNE:OSCILLATION-SAMPLE-ALL;AGEBD-TUNE:OSCILLATION-X-ALL + + + caCartesianPlot::NoSymbol + + + + 0 + 255 + 0 + + + + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0;0 + + + 0;1 + + + + + + 460 + 10 + 431 + 271 + + + + Vertical beam oscillation + + + Turn + + + y [mm] + + + AGEBD-TUNE:OSCILLATION-SAMPLE-ALL;AGEBD-TUNE:OSCILLATION-Y-ALL + + + caCartesianPlot::NoSymbol + + + + 0 + 255 + 0 + + + + + + + caCartesianPlot::Auto + + + caCartesianPlot::Auto + + + 0;0.5 + + + + + + Tune plot + + + + + 10 + 10 + 421 + 271 + + + + Horizontal tune spectrum + + + Tune + + + Amplitude + + + AGEBD-TUNE:SPEC-SAMPLE-ALL;AGEBD-TUNE:HORIZONTAL-SPEC-ALL + + + caCartesianPlot::NoSymbol + + + + 0 + 255 + 0 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;0.5 + + + + + + 460 + 10 + 431 + 271 + + + + Vertical tune spectrum + + + Tune + + + Amplitude + + + AGEBD-TUNE:SPEC-SAMPLE-ALL;AGEBD-TUNE:VERTICAL-SPEC-ALL + + + caCartesianPlot::NoSymbol + + + + 0 + 255 + 0 + + + + + + + caCartesianPlot::Sticks + + + caCartesianPlot::User + + + caCartesianPlot::Auto + + + 0;0.5 + + + + + + + + 20 + 20 + 141 + 171 + + + + Tune loop control + + + + + 10 + 30 + 129 + 132 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + true + + + false + + + 28 + + + 28 + + + true + + + false + + + AGEBD-ALH:TUNE-ALIVE + + + caLed::Alarm + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + true + + + false + + + 28 + + + 28 + + + true + + + false + + + AGEBD-ALH:TUNE-ONOFF-RB + + + caLed::Alarm + + + + + + + Program alive + + + + + + + Measurement +running + + + Qt::AlignCenter + + + + + + + Activate +measurement + + + true + + + AGEBD-ALH:TUNE-ONOFF + + + + + + + + + + 180 + 20 + 281 + 141 + + + + Results + + + + + 10 + 110 + 111 + 20 + + + + + 10 + + + + Meas. time [ms] + + + + + + 130 + 110 + 71 + 20 + + + + AGEBD-TUNE:MEAS-TIME + + + + + + 10 + 30 + 211 + 71 + + + + + + + + 10 + + + + Q1 + + + + + + + AGEBD-TUNE:VERTICAL-PEAK1-FREQ + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 100.000000000000000 + + + -100.000000000000000 + + + + + + + + 10 + + + + Q2 + + + + + + + AGEBD-TUNE:HORIZONTAL-PEAK1-FREQ + + + 4 + + + caLineEdit::User + + + 100.000000000000000 + + + -100.000000000000000 + + + + + + + + 10 + + + + FFT + + + Qt::AlignCenter + + + + + + + + 10 + + + + NAFF + + + Qt::AlignCenter + + + + + + + AGEBD-TUNE:Q1_NAFF + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 100.000000000000000 + + + -100.000000000000000 + + + + + + + AGEBD-TUNE:Q2_NAFF + + + 4 + + + caLineEdit::User + + + caLineEdit::Channel + + + 100.000000000000000 + + + -100.000000000000000 + + + + + + + + + + 20 + 200 + 911 + 191 + + + + 2 + + + + Tune analysis settings + + + + + 190 + 10 + 91 + 141 + + + + SVD cleaning + + + + + 10 + 30 + 71 + 21 + + + + + Arial + 11 + 75 + true + + + + Enable + + + false + + + AGEBD-TUNE:SVD-CLEAN + + + + + + 10 + 90 + 71 + 41 + + + + 2 + + + 0 + + + AGEBD-TUNE:SVD-CLEAN-Neigenvalues + + + false + + + caNumeric::User + + + 115.000000000000000 + + + 1.000000000000000 + + + + + + 10 + 60 + 81 + 31 + + + + + 10 + + + + # Singular +values + + + + + + + 500 + 10 + 211 + 121 + + + + Region of Interest + + + + + 10 + 30 + 191 + 81 + + + + + + + + 45 + 20 + + + + + 9 + + + + 2 + + + AGEBD-TUNE:CONTROL-ROI-Yi + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + + 10 + + + + From + + + Qt::AlignCenter + + + + + + + + 45 + 20 + + + + + 9 + + + + 2 + + + 0.000000000000000 + + + AGEBD-TUNE:CONTROL-ROI-Xf + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + + 45 + 20 + + + + + 9 + + + + 2 + + + AGEBD-TUNE:CONTROL-ROI-Xi + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + + 10 + + + + Q1 + + + Qt::AlignCenter + + + + + + + + 10 + + + + Q2 + + + Qt::AlignCenter + + + + + + + + 10 + + + + To + + + Qt::AlignCenter + + + + + + + + 45 + 20 + + + + + 9 + + + + 2 + + + 0.000000000000000 + + + AGEBD-TUNE:CONTROL-ROI-Yf + + + caSpinbox::User + + + caSpinbox::User + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + + + + 290 + 10 + 191 + 111 + + + + Turn selection + + + + + 10 + 30 + 171 + 71 + + + + + + + + 45 + 20 + + + + + 9 + + + + 4 + + + 0 + + + false + + + AGEBD-TUNE:CONTROL-TbTLastIndex + + + caSpinbox::User + + + 4095.000000000000000 + + + 1.000000000000000 + + + + + + + + 10 + + + + First turn + + + + + + + + 10 + + + + Last turn + + + + + + + + 45 + 20 + + + + + 9 + + + + 4 + + + 0 + + + false + + + AGEBD-TUNE:CONTROL-TbTFirstIndex + + + false + + + caSpinbox::User + + + 4094.000000000000000 + + + 0.000000000000000 + + + + + + + + + + 20 + 10 + 141 + 51 + + + + + + + # samples + + + Qt::AlignCenter + + + + + + + 1 + + + 0 + + + true + + + AGEBD-TUNE:CONTROL-NAveraging + + + caNumeric::Channel + + + true + + + caNumeric::User + + + 99.000000000000000 + + + 1.000000000000000 + + + caNumeric::on_top + + + + + + + + + 20 + 60 + 141 + 91 + + + + + + + + Arial + 16 + 75 + true + + + + Calc. NAFF + + + true + + + AGEBD-TUNE:CONTROL-NAFF + + + + + + + + + + 9 + + + + # NAFF +harmonics + + + Qt::AlignCenter + + + + + + + 1 + + + 0 + + + true + + + AGEBD-TUNE:NAFF-HARMONICS + + + caNumeric::Channel + + + true + + + caNumeric::User + + + 99.000000000000000 + + + 1.000000000000000 + + + caNumeric::on_top + + + + + + + + + + + BPM select + + + + + 350 + 50 + 159 + 29 + + + + Recommended: +ARS07-DBPM-0840 + + + + + + 170 + 20 + 159 + 111 + + + + AGEBD-TUNE:BPM-SELECT-SINGLE + + + + ARS01-DBPM-0390 + + + + + ARS01-DBPM-0760 + + + + + ARS01-DBPM-1080 + + + + + ARS01-DBPM-1460 + + + + + ARS01-DBPM-1900 + + + + + ARS01-DBPM-2410 + + + + + ARS01-DBPM-2910 + + + + + ARS01-DBPM-4220 + + + + + ARS01-DBPM-4720 + + + + + ARS01-DBPM-5250 + + + + + ARS01-DBPM-5530 + + + + + ARS01-DBPM-5880 + + + + + ARS02-DBPM-1080 + + + + + ARS02-DBPM-1460 + + + + + ARS02-DBPM-1900 + + + + + ARS02-DBPM-2410 + + + + + ARS02-DBPM-2910 + + + + + ARS02-DBPM-4220 + + + + + ARS02-DBPM-4720 + + + + + ARS02-DBPM-5250 + + + + + ARS02-DBPM-5530 + + + + + ARS02-DBPM-5880 + + + + + ARS03-DBPM-0810 + + + + + ARS03-DBPM-1080 + + + + + ARS03-DBPM-1460 + + + + + ARS03-DBPM-1900 + + + + + ARS03-DBPM-2410 + + + + + ARS03-DBPM-2910 + + + + + ARS03-DBPM-4220 + + + + + ARS03-DBPM-4720 + + + + + ARS03-DBPM-5250 + + + + + ARS03-DBPM-5530 + + + + + ARS03-DBPM-5880 + + + + + ARS04-DBPM-0090 + + + + + ARS04-DBPM-0900 + + + + + ARS04-DBPM-1080 + + + + + ARS04-DBPM-1460 + + + + + ARS04-DBPM-1900 + + + + + ARS04-DBPM-2410 + + + + + ARS04-DBPM-2910 + + + + + ARS04-DBPM-4220 + + + + + ARS04-DBPM-4720 + + + + + ARS04-DBPM-5250 + + + + + ARS04-DBPM-5530 + + + + + ARS04-DBPM-5880 + + + + + ARS05-DBPM-0410 + + + + + ARS05-DBPM-1080 + + + + + ARS05-DBPM-1460 + + + + + ARS05-DBPM-1900 + + + + + ARS05-DBPM-2410 + + + + + ARS05-DBPM-2910 + + + + + ARS05-DBPM-4220 + + + + + ARS05-DBPM-4720 + + + + + ARS05-DBPM-5250 + + + + + ARS05-DBPM-5530 + + + + + ARS05-DBPM-5880 + + + + + ARS06-DBPM-1080 + + + + + ARS06-DBPM-1460 + + + + + ARS06-DBPM-1900 + + + + + ARS06-DBPM-2410 + + + + + ARS06-DBPM-2910 + + + + + ARS06-DBPM-4220 + + + + + ARS06-DBPM-4720 + + + + + ARS06-DBPM-5250 + + + + + ARS06-DBPM-5530 + + + + + ARS06-DBPM-5880 + + + + + ARS07-DBPM-0810 + + + + + ARS07-DBPM-0840 + + + + + ARS07-DBPM-1080 + + + + + ARS07-DBPM-1460 + + + + + ARS07-DBPM-1900 + + + + + ARS07-DBPM-2410 + + + + + ARS07-DBPM-2910 + + + + + ARS07-DBPM-4220 + + + + + ARS07-DBPM-4720 + + + + + ARS07-DBPM-5250 + + + + + ARS07-DBPM-5530 + + + + + ARS07-DBPM-5880 + + + + + ARS08-DBPM-1080 + + + + + ARS08-DBPM-1460 + + + + + ARS08-DBPM-1900 + + + + + ARS08-DBPM-2410 + + + + + ARS08-DBPM-2910 + + + + + ARS08-DBPM-4220 + + + + + ARS08-DBPM-4720 + + + + + ARS08-DBPM-5250 + + + + + ARS08-DBPM-5530 + + + + + ARS08-DBPM-5880 + + + + + ARS09-DBPM-0570 + + + + + ARS09-DBPM-1080 + + + + + ARS09-DBPM-1460 + + + + + ARS09-DBPM-1900 + + + + + ARS09-DBPM-2410 + + + + + ARS09-DBPM-2910 + + + + + ARS09-DBPM-4220 + + + + + ARS09-DBPM-4720 + + + + + ARS09-DBPM-5250 + + + + + ARS09-DBPM-5530 + + + + + ARS09-DBPM-5880 + + + + + ARS10-DBPM-1080 + + + + + ARS10-DBPM-1460 + + + + + ARS10-DBPM-1900 + + + + + ARS10-DBPM-2410 + + + + + ARS10-DBPM-2910 + + + + + ARS10-DBPM-4220 + + + + + ARS10-DBPM-4720 + + + + + ARS10-DBPM-5250 + + + + + ARS10-DBPM-5530 + + + + + ARS10-DBPM-5880 + + + + + ARS11-DBPM-0850 + + + + + ARS11-DBPM-1080 + + + + + ARS11-DBPM-1460 + + + + + ARS11-DBPM-1900 + + + + + ARS11-DBPM-2410 + + + + + ARS11-DBPM-2910 + + + + + ARS11-DBPM-4220 + + + + + ARS11-DBPM-4720 + + + + + ARS11-DBPM-5250 + + + + + ARS11-DBPM-5530 + + + + + ARS11-DBPM-5880 + + + + + ARS12-DBPM-0970 + + + + + ARS12-DBPM-1080 + + + + + ARS12-DBPM-1460 + + + + + ARS12-DBPM-1900 + + + + + ARS12-DBPM-2410 + + + + + ARS12-DBPM-2910 + + + + + ARS12-DBPM-4220 + + + + + ARS12-DBPM-4720 + + + + + ARS12-DBPM-5250 + + + + + ARS12-DBPM-5530 + + + + + ARS12-DBPM-5880 + + + + + + + 30 + 40 + 104 + 24 + + + + + 0 + 0 + + + + + Arial + 12 + 50 + false + + + + Single BPM + + + false + + + AGEBD-TUNE:SINGLE-BPM + + + + + + Other settings + + + + + 460 + 0 + 151 + 121 + + + + BPM trigger + + + + + 10 + 30 + 131 + 80 + + + + + + + -Trigger on pinger + + + Restart analysis script + + + /opt/gfa/python-3.8/latest/bin/python /sls/diag/bin/s_di_bpm_cmd.py put_trig_on_pinger + + + + + + + + + + + -Trigger on extraction + + + Restart analysis script + + + /opt/gfa/python-3.8/latest/bin/python /sls/diag/bin/s_di_bpm_cmd.py put_trig_on_extraction + + + + + + + + + + + -Trigger on 3 Hz + + + Restart analysis script + + + /opt/gfa/python-3.8/latest/bin/python /sls/diag/bin/s_di_bpm_cmd.py put_trig_on_3hz + + + + + + + + + + + + + 10 + 0 + 441 + 151 + + + + Pinger settings + + + + + 10 + 30 + 421 + 114 + + + + + + + + Lucida Sans Typewriter + 10 + + + + ARS01-MKIK-0320:I-READ-POS + + + + + + + + 20 + 16777215 + + + + + + + ARS01-MKIK-0290:CTRL-ON-OFF + + + + + + + + 10 + + + + Pinger V + + + + + + + + 10 + + + + Set current +[A] + + + Qt::AlignCenter + + + + + + + + 10 + + + + 4 + + + false + + + ABOMA-VME-KY-EVR0:OUT3-Delay-SP + + + + + + + + 150 + 20 + + + + + 10 + + + + 3 + + + false + + + ARS01-MKIK-0320:I-SET + + + + + + + + 10 + + + + Pinger H + + + + + + + + Lucida Sans Typewriter + 10 + + + + ARS01-MKIK-0290:I-READ-POS + + + + + + + + 10 + + + + Timing Delay +[us] + + + Qt::AlignCenter + + + + + + + + 20 + 16777215 + + + + + + + ARS01-MKIK-0320:CTRL-ON-OFF + + + + + + + + 10 + + + + Read current +[A] + + + Qt::AlignCenter + + + + + + + + 10 + + + + 4 + + + false + + + ABOMA-VME-KY-EVR0:OUT2-Delay-SP + + + + + + + + 150 + 20 + + + + + 10 + + + + 3 + + + false + + + ARS01-MKIK-0290:I-SET + + + + + + + + + + 750 + 30 + 71 + 31 + + + + ARS07-CECL-DBPM3-1:EEVR-EVENT0-ID + + + + + + 620 + 30 + 121 + 31 + + + + + 10 + + + + BPM Trigger ID +ARS07-DBPM-0840 + + + Qt::AutoText + + + Qt::AlignCenter + + + + + + + + + 0 + 0 + 950 + 25 + + + + + + + + caNumeric + QFrame +
caNumeric
+
+ + caMenu + QComboBox +
caMenu
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caShellCommand + QWidget +
caShellCommand
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + +
diff --git a/services/tune/current/systemd/AGEBD-SERVICE-TUNE.service b/services/tune/current/systemd/AGEBD-SERVICE-TUNE.service new file mode 100644 index 0000000..f70014a --- /dev/null +++ b/services/tune/current/systemd/AGEBD-SERVICE-TUNE.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TUNE +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TUNE +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TUNE.service +# systemctl --user start AGEBD-SERVICE-TUNE From bbbd68446efe9f3f38a6e8d2765fcd2d0f9e51a5 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:40:29 +0200 Subject: [PATCH 25/42] feature: add new service topuptool --- docs/ioc/ioc_overview.md | 2 +- services/topuptool/current/app/pyproject.toml | 47 + .../app/src/agebd_topuptool/__init__.py | 1 + .../current/app/src/agebd_topuptool/main.py | 31 + .../app/src/agebd_topuptool/service.py | 93 + .../topuptool/current/app/tests/test_app.py | 9 + services/topuptool/current/app/uv.lock | 275 ++ .../ioc/AGEBD-CPCL-TOPUPTOOL_main.subs | 4 + .../ioc/AGEBD-CPCL-TOPUPTOOL_parameters.yaml | 6 + .../topuptool/current/ioc/TOPUPTOOL.template | 121 + services/topuptool/current/ioc/startup.script | 1 + .../topuptool/current/qt/A_BD_TopUpTool.ui | 3533 +++++++++++++++++ .../systemd/AGEBD-SERVICE-TOPUPTOOL.service | 16 + 13 files changed, 4138 insertions(+), 1 deletion(-) create mode 100644 services/topuptool/current/app/pyproject.toml create mode 100644 services/topuptool/current/app/src/agebd_topuptool/__init__.py create mode 100644 services/topuptool/current/app/src/agebd_topuptool/main.py create mode 100644 services/topuptool/current/app/src/agebd_topuptool/service.py create mode 100644 services/topuptool/current/app/tests/test_app.py create mode 100644 services/topuptool/current/app/uv.lock create mode 100644 services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs create mode 100644 services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_parameters.yaml create mode 100644 services/topuptool/current/ioc/TOPUPTOOL.template create mode 100644 services/topuptool/current/ioc/startup.script create mode 100644 services/topuptool/current/qt/A_BD_TopUpTool.ui create mode 100644 services/topuptool/current/systemd/AGEBD-SERVICE-TOPUPTOOL.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index eb2d865..7536977 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TUNE | | +| AGEBD-CPCL-TOPUPTOOL | | diff --git a/services/topuptool/current/app/pyproject.toml b/services/topuptool/current/app/pyproject.toml new file mode 100644 index 0000000..eeaa6db --- /dev/null +++ b/services/topuptool/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-topuptool" +version = "0.1.0" +description = "AGEBD-TOPUPTOOL Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/topuptool/current/app/src/agebd_topuptool/__init__.py b/services/topuptool/current/app/src/agebd_topuptool/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/topuptool/current/app/src/agebd_topuptool/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py new file mode 100644 index 0000000..1537f0c --- /dev/null +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_topuptool import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "TOPUPTOOL" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/topuptool/current/app/src/agebd_topuptool/service.py b/services/topuptool/current/app/src/agebd_topuptool/service.py new file mode 100644 index 0000000..7b8fe2c --- /dev/null +++ b/services/topuptool/current/app/src/agebd_topuptool/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-TOPUPTOOL:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-TOPUPTOOL:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-TOPUPTOOL:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/topuptool/current/app/tests/test_app.py b/services/topuptool/current/app/tests/test_app.py new file mode 100644 index 0000000..74339a1 --- /dev/null +++ b/services/topuptool/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_topuptool import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/topuptool/current/app/uv.lock b/services/topuptool/current/app/uv.lock new file mode 100644 index 0000000..fe504cb --- /dev/null +++ b/services/topuptool/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-topuptool" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs new file mode 100644 index 0000000..a6848aa --- /dev/null +++ b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs @@ -0,0 +1,4 @@ +file TOPUPTOOL.template { + pattern { DEVICE } + { AGEBD-TOPUPTOOL } +} \ No newline at end of file diff --git a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_parameters.yaml b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/topuptool/current/ioc/TOPUPTOOL.template b/services/topuptool/current/ioc/TOPUPTOOL.template new file mode 100644 index 0000000..43540d9 --- /dev/null +++ b/services/topuptool/current/ioc/TOPUPTOOL.template @@ -0,0 +1,121 @@ +# HLA Service Control Parameters + +record(bo, "$(DEVICE):CONTROL-SCRUB") { + field(DESC, "Activate scrubbung during decay") + field(VAL, "0") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-MAX") { + field(DESC, "Stop injection at this vacuum pressure") + field(EGU, "1e-9 mbar") + field(VAL, "30") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-MAX-PLOT") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-DYN") { + field(DESC, "Stop injection at this vacuum pressure") + field(EGU, "1e-9 mbar") + field(VAL, "27") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-DYN-PLOT") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-DYN-FRAC") { + field(DESC, "Fraction defining dynamic pressure ") + field(VAL, "1.05") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-VACUUM-MIN") { + field(DESC, "Start injection at this vacuum pressure") + field(EGU, "1e-9 mbar") + field(VAL, "24") + field(PREC, "3") + field(FLNK, "$(DEVICE):CONTROL-VACUUM-MIN-PLOT") + field(PINI, "YES") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-MAX-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-MAX") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-DYN-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-DYN") +} + +record(calc, "$(DEVICE):CONTROL-VACUUM-MIN-PLOT") { + field(DESC, "Stop injection at this vacuum pressure") + field(ASG, "READONLY") + field(EGU, "mbar") + field(PREC, "-5") + field(CALC, "A/1e9") + field(INPA, "$(DEVICE):CONTROL-VACUUM-MIN") +} + +record(ao, "$(DEVICE):CONTROL-CURRENT-MAX") { + field(DESC, "Stop injection at this current") + field(EGU, "mA") + field(VAL, "400") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-CURRENT-MIN") { + field(DESC, "Start injection at this current") + field(EGU, "mA") + field(VAL, "396") + field(PREC, "3") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):CONTROL-GUNGRID-MAX") { + field(DESC, "Set gun grid to val before injection") + field(EGU, "V") + field(VAL, "170") + field(PREC, "3") + field(PINI, "YES") +} + +# HLA Service Output/Result Parameters + +record(ao, "$(DEVICE):TOPUP-TAU") { + field(DESC, "Average tau since last top up") + field(EGU, "h") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):TOPUP-DELTAT") { + field(DESC, "Time since last top up") + field(EGU, "min") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} + +record(ao, "$(DEVICE):TOPUP-DELTAI") { + field(DESC, "Current change since last top up") + field(EGU, "mA") + field(VAL, "100") + field(PREC, "3") + field(VAL, "-1") + field(PINI, "YES") +} diff --git a/services/topuptool/current/ioc/startup.script b/services/topuptool/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/topuptool/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/topuptool/current/qt/A_BD_TopUpTool.ui b/services/topuptool/current/qt/A_BD_TopUpTool.ui new file mode 100644 index 0000000..9800d32 --- /dev/null +++ b/services/topuptool/current/qt/A_BD_TopUpTool.ui @@ -0,0 +1,3533 @@ + + + MainWindow + + + + 0 + 0 + 1852 + 610 + + + + MainWindow + + + + + + 10 + 10 + 391 + 61 + + + + AGEBD-ALH:TOPUPTOOL-ONOFF + + + caChoice::Column + + + 1 + + + + + + 729 + 0 + 1111 + 601 + + + + + 10 + 75 + true + + + + Strahlstrom + + + + + + mA + + + ARS07-DPCT-0000:CURR + + + caStripPlot::Second + + + 480.000000000000000 + + + caStripPlot::High + + + 8 + + + caStripPlot::linear + + + caStripPlot::fixedScale + + + caStripPlot::off + + + 408.000000000000000 + + + 300.000000000000000 + + + caStripPlot::Channel + + + caStripPlot::Channel + + + + 0 + 255 + 0 + + + + 0.000000100000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 241 + 252 + 122 + + + + 0.000000100000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000100000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + + 239 + 41 + 41 + + + + 0.000000100000000 + + + 0.000000001000000 + + + caStripPlot::User + + + caStripPlot::User + + + 0.000000100000000 + + + 0.000000001000000 + + + 0.000000100000000 + + + 0.000000001000000 + + + + 218 + 218 + 218 + + + + false + + + + + + 280 + 140 + 85 + 40 + + + + 3 + + + 0 + + + AGEBD-TOPUPTOOL:CONTROL-GUNGRID-MAX + + + caSpinbox::User + + + true + + + + + + 160 + 140 + 105 + 40 + + + + + 15 + 75 + true + + + + Gun Grid + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 1990 + 540 + 70 + 20 + + + + + + + 1980 + 360 + 71 + 20 + + + + RELOAD + + + Qt::AlignCenter + + + RELOAD + + + A + + + AGEBD-ALH:SCRUBBING-GUIRELOAD + + + caCalc::TriggerOneToZero + + + + + + 10 + 90 + 391 + 41 + + + + AGEBD-ALH:SCRUBBING-INFO + + + caLineEdit::Alarm_Default + + + caLineEdit::onBackground + + + caLineEdit::User + + + + + + 570 + 190 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAT + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 570 + 310 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-TAU + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 480 + 310 + 50 + 30 + + + + + 18 + 75 + true + + + + Tau + + + Qt::AlignCenter + + + + + + 480 + 230 + 50 + 30 + + + + + 18 + 75 + true + + + + dI + + + Qt::AlignCenter + + + + + + 480 + 190 + 50 + 30 + + + + + 18 + 75 + true + + + + dt + + + Qt::AlignCenter + + + + + + 570 + 230 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAI + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 10 + 330 + 601 + 270 + + + + Top-Up Save Einstellungen + + + + + 133 + 172 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 209 + 56 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=2 + + + ALIRF-VME-A-GUN:CH1-MODE + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 213 + 31 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 9 + 33 + 100 + 22 + + + + + Sans Serif + 13 + + + + true + + + Master + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 137 + 60 + 70 + 20 + + + + true + + + Disable + + + ALIRF-VME-A-GUN:CH1-MODE + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 209 + 172 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 213 + 176 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 133 + 27 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=0 + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 137 + 176 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-10-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 9 + 178 + 100 + 22 + + + + + Sans Serif + 13 + + + + true + + + Booster Ext + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 209 + 27 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 213 + 60 + 70 + 20 + + + + true + + + External + + + ALIRF-VME-A-GUN:CH1-MODE + + + External + + + + 219 + 212 + 157 + + + + 2 + + + + + + 9 + 62 + 100 + 22 + + + + + Sans Serif + 13 + + + + true + + + Gun TX + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 133 + 56 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + ALIRF-VME-A-GUN:CH1-MODE + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 137 + 31 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 137 + 147 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 9 + 149 + 121 + 22 + + + + + Sans Serif + 13 + + + + true + + + Booster Ramp + + + Qt::AlignAbsolute|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::Height + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 133 + 143 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 213 + 147 + 70 + 20 + + + + true + + + External + + + AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel + + + External + + + + 219 + 212 + 157 + + + + 1 + + + + + + 209 + 143 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 137 + 205 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 213 + 205 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 209 + 201 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 9 + 204 + 150 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Ring Inj + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 133 + 201 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 209 + 85 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 213 + 89 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 133 + 85 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 9 + 91 + 91 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Gun Event + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 137 + 89 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 137 + 118 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 213 + 118 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 133 + 114 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 209 + 114 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 9 + 120 + 111 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Booster Inj + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 98 + 27 + 28 + 28 + + + + true + + + false + + + 22 + + + 22 + + + AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER + + + caLed::Alarm + + + + + + 303 + 27 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Event-Seq-Cnt-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 56 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ALIRF-VME-A:SoftEvent-Linac-Gun-Evnt-Count-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 85 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-LI-Gun-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 114 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 143 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 172 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 303 + 201 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 453 + 27 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 304 + 230 + 100 + 28 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + +AGETI-CVME-MASTER-TMA:Evt-14.VALA + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::None + + + + + + 214 + 234 + 70 + 20 + + + + true + + + Enable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-Ena-Sel + + + Enable + + + + 219 + 212 + 157 + + + + 1 + + + + + + 138 + 234 + 70 + 20 + + + + true + + + Disable + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-Ena-Sel + + + Disable + + + + 219 + 212 + 157 + + + + 0 + + + + + + 133 + 230 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::IfZero + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + 0 + + + 90 + + + + + + 10 + 233 + 101 + 22 + + + + + Sans Serif + 13 + + + + true + + + Qt::LeftToRight + + + Pingers + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + QFrame::NoFrame + + + + + + 210 + 230 + 78 + 28 + + + + true + + + + 0 + 0 + 176 + + + + caGraphics::Filled + + + 1 + + + + 0 + 0 + 0 + + + + caGraphics::Calc + + + A=1 + + + AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-Ena-Sel + + + caGraphics::Rectangle + + + 22 + + + 180 + + + + + + 423 + 27 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 56 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 114 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 85 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 201 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 143 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 172 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 423 + 230 + 28 + 28 + + + + + 40 + 40 + + + + caToggleButton::WidthAndHeight + + + caToggleButton::Alarm + + + + + + 453 + 56 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 114 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 85 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 230 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 201 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 172 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 453 + 143 + 140 + 28 + + + + 2 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + BOO_Ext_External_frame_7 + BOO_Ext_Disable_frame_7 + BOO_Ext_Disable_frame_5 + BOO_Ext_External_frame_5 + BOO_Ext_Disable_frame_4 + BOO_Ext_External_frame_4 + Inj_trig_Enable_frame + BOO_Ext_Disable_frame_2 + BOO_Ext_External_frame_2 + Gun_trig_Disable_frame + Gun_trig_External_frame + Inj_trig_Enable + Inj_trig_ + Gun_trig_Diasable + BOO_Ext_External_2 + Inj_trig_Disable_frame + BOO_Ext_Diasable_2 + BOO_Ext + Gun_trig_External + Gun_trig + Inj_trig_Disable + Gun_trig_2 + Gun_trig_Disable_frame_2 + Gun_trig_External_frame_2 + Gun_trig_External_2 + Gun_trig_Diasable_2 + BOO_Ext_Diasable_4 + BOO_Ext_External_4 + BOO_Ext_3 + BOO_Ext_External_frame_6 + BOO_Ext_External_6 + BOO_Ext_Disable_frame_6 + BOO_Ext_5 + BOO_Ext_Diasable_6 + BOO_Ext_Diasable_5 + BOO_Ext_External_5 + BOO_Ext_4 + caled_23 + calineedit + calineedit_2 + calineedit_4 + calineedit_6 + calineedit_7 + calineedit_8 + calineedit_9 + caspinbox_6 + calineedit_10 + BOO_Ext_External_7 + BOO_Ext_Diasable_7 + BOO_Ext_6 + catogglebutton + catogglebutton_2 + catogglebutton_3 + catogglebutton_4 + catogglebutton_5 + catogglebutton_6 + catogglebutton_7 + catogglebutton_8 + caspinbox_8 + caspinbox_9 + caspinbox_10 + caspinbox_11 + caspinbox_12 + caspinbox_13 + caspinbox_14 + + + + + 440 + 20 + 271 + 50 + + + + + Lucida Sans Typewriter + 32 + 75 + true + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + ARS07-DPCT-0000:CURR + + + + 0 + 0 + 0 + + + + + 170 + 255 + 127 + + + + caLineEdit::Static + + + 1 + + + caLineEdit::User + + + caLineEdit::WidthAndHeight + + + true + + + + + + 10 + 170 + 461 + 151 + + + + Top-Up Schwellen + + + + + 160 + 60 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX + + + caSpinbox::User + + + true + + + + + + 310 + 30 + 140 + 30 + + + + + 18 + 75 + true + + + + min + + + Qt::AlignCenter + + + + + + 10 + 30 + 140 + 30 + + + + + 18 + 75 + true + + + + pbar + + + Qt::AlignCenter + + + + + + 310 + 65 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-TIME-FREQ + + + caSpinbox::User + + + true + + + + + + 160 + 30 + 140 + 30 + + + + + 18 + 75 + true + + + + mA + + + Qt::AlignCenter + + + + + + 160 + 105 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-CURRENT-MIN + + + caSpinbox::User + + + true + + + + + + 10 + 60 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-VAC-MAX + + + caSpinbox::User + + + true + + + + + + 10 + 105 + 140 + 40 + + + + 3 + + + 1 + + + AGEBD-TOPUPTOOL:CONTROL-VAC-MIN + + + caSpinbox::User + + + true + + + + + + + 480 + 270 + 71 + 30 + + + + + 18 + 75 + true + + + + dI/dt + + + Qt::AlignCenter + + + + + + 630 + 190 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAT + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 630 + 230 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAI + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 570 + 270 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-TAU + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 630 + 270 + 50 + 30 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAI + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + 550 + 150 + 71 + 30 + + + + + 15 + 75 + true + + + + Decay + + + Qt::AlignCenter + + + + + + 630 + 150 + 71 + 30 + + + + + 15 + 75 + true + + + + Inject + + + Qt::AlignCenter + + + + + + 440 + 90 + 161 + 30 + + + + + 15 + 75 + true + + + + Next Injection + + + Qt::AlignCenter + + + + + + 620 + 90 + 51 + 31 + + + + AGEBD-TOPUPTOOL:TOPUP-DELTAT + + + caLineEdit::Default + + + caLineEdit::onBackground + + + 2 + + + caLineEdit::User + + + + + + + caChoice + QWidget +
caChoice
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caLabel + QLabel +
caLabel
+
+ + caGraphics + QWidget +
caGraphics
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 2020 + 374 + + + 2022 + 545 + + + + +
diff --git a/services/topuptool/current/systemd/AGEBD-SERVICE-TOPUPTOOL.service b/services/topuptool/current/systemd/AGEBD-SERVICE-TOPUPTOOL.service new file mode 100644 index 0000000..beb2436 --- /dev/null +++ b/services/topuptool/current/systemd/AGEBD-SERVICE-TOPUPTOOL.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-TOPUPTOOL +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh TOPUPTOOL +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-TOPUPTOOL.service +# systemctl --user start AGEBD-SERVICE-TOPUPTOOL From f278ad1a9d1b801fde59a4aaceed1904542954a9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:43:25 +0200 Subject: [PATCH 26/42] feature: add new service shifttool --- docs/ioc/ioc_overview.md | 2 +- services/shifttool/current/app/pyproject.toml | 47 +++ .../app/src/agebd_shifttool/__init__.py | 1 + .../current/app/src/agebd_shifttool/main.py | 31 ++ .../app/src/agebd_shifttool/service.py | 93 ++++++ .../shifttool/current/app/tests/test_app.py | 9 + services/shifttool/current/app/uv.lock | 275 ++++++++++++++++++ .../ioc/AGEBD-CPCL-SHIFTTOOL_main.subs | 4 + .../ioc/AGEBD-CPCL-SHIFTTOOL_parameters.yaml | 6 + .../shifttool/current/ioc/SHIFTTOOL.template | 37 +++ services/shifttool/current/ioc/startup.script | 1 + services/shifttool/current/qt/A_BD_.ui | 103 +++++++ .../systemd/AGEBD-SERVICE-SHIFTTOOL.service | 16 + 13 files changed, 624 insertions(+), 1 deletion(-) create mode 100644 services/shifttool/current/app/pyproject.toml create mode 100644 services/shifttool/current/app/src/agebd_shifttool/__init__.py create mode 100644 services/shifttool/current/app/src/agebd_shifttool/main.py create mode 100644 services/shifttool/current/app/src/agebd_shifttool/service.py create mode 100644 services/shifttool/current/app/tests/test_app.py create mode 100644 services/shifttool/current/app/uv.lock create mode 100644 services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_main.subs create mode 100644 services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_parameters.yaml create mode 100644 services/shifttool/current/ioc/SHIFTTOOL.template create mode 100644 services/shifttool/current/ioc/startup.script create mode 100644 services/shifttool/current/qt/A_BD_.ui create mode 100644 services/shifttool/current/systemd/AGEBD-SERVICE-SHIFTTOOL.service diff --git a/docs/ioc/ioc_overview.md b/docs/ioc/ioc_overview.md index 7536977..22a0c6c 100644 --- a/docs/ioc/ioc_overview.md +++ b/docs/ioc/ioc_overview.md @@ -8,4 +8,4 @@ The ports are configured in the [service registry](../../docs/ioc/ioc_overview.m | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | | AGEBD-CPCL-DBPM3CURR | | | AGEBD-CPCL-TAUBPM | | -| AGEBD-CPCL-TOPUPTOOL | | +| AGEBD-CPCL-SHIFTTOOL | | diff --git a/services/shifttool/current/app/pyproject.toml b/services/shifttool/current/app/pyproject.toml new file mode 100644 index 0000000..990a34c --- /dev/null +++ b/services/shifttool/current/app/pyproject.toml @@ -0,0 +1,47 @@ +[project] +name = "agebd-shifttool" +version = "0.1.0" +description = "AGEBD-SHIFTTOOL Service" +requires-python = "==3.10.*" +dependencies = [ + "agebd", +] + +[dependency-groups] +dev = [ + "pyepics>=3.5.8", + "pytest>=8.4.2", + "ruff>=0.15.20", +] + +[tool.uv.sources] +# Path is relative to where agebd package is deployed on hla +# machines (see CI/CD in .gitea/workflows) +agebd = { path = "../../../../packages/agebd", editable = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +package = true + +[tool.pytest.ini_options] +pythonpath = ["src"] +env = [ + "AGEBD_ENV=local", +] + +[tool.ruff] +include = [ + "src/**/*.py", + "tests/**/*.py", +] +line-length = 100 + +[tool.ruff.lint] +# use isort to sort imports +extend-select = ["I"] + +[tool.ruff.lint.isort] +known-first-party = ["agebd"] diff --git a/services/shifttool/current/app/src/agebd_shifttool/__init__.py b/services/shifttool/current/app/src/agebd_shifttool/__init__.py new file mode 100644 index 0000000..1800c27 --- /dev/null +++ b/services/shifttool/current/app/src/agebd_shifttool/__init__.py @@ -0,0 +1 @@ +from .service import PVs, Service diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py new file mode 100644 index 0000000..a96df33 --- /dev/null +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -0,0 +1,31 @@ +import typer + +from agebd.enums import LogLevel +from agebd.runner import CallbackRunner +from agebd.utils import init_logging +from agebd_shifttool import PVs, Service + + +# TODO: remove: cicd test 10 + +def main( + log_level: LogLevel = typer.Option( + LogLevel.INFO, + "--log-level", + "-l", + # Looks at the OS env variable first. If empty, falls back to "INFO" + envvar="AGEBD_LOG_LEVEL", + # help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL", + case_sensitive=False, + ), +): + init_logging(log_level) + service_name = "SHIFTTOOL" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + runner = CallbackRunner(service=service) + runner.start() + + +if __name__ == "__main__": + typer.run(main) diff --git a/services/shifttool/current/app/src/agebd_shifttool/service.py b/services/shifttool/current/app/src/agebd_shifttool/service.py new file mode 100644 index 0000000..a5c4ea0 --- /dev/null +++ b/services/shifttool/current/app/src/agebd_shifttool/service.py @@ -0,0 +1,93 @@ +import time + +from epics import dbr + +from agebd.pv import LocalPVLink +from agebd.service.base import BaseService +from agebd.service.pvs import BasePVs +from agebd.utils import printgetversion +from agebd.pv import get_pv_class + +__version__ = printgetversion(__file__) + +PV = get_pv_class() + + +class PVs(BasePVs): + # Option 1: + ## Service specific PVs from dedicated IOC + my_pv1 = PV("AGEBD-SHIFTTOOL:AO") # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + def __init__(self, service_name: str, pv_factory=PV): + super().__init__(service_name, pv_factory) + PV = pv_factory + + # TODO: can we do this cleaner? Maybe mechanism for + # settings initial values in dev mode (e.g. ini file) + if isinstance(self.onoff, LocalPVLink): + self.onoff.value = True + + # Option 2: + ## Service specific PVs from dedicated IOC + self.my_pv2 = PV( + "AGEBD-SHIFTTOOL:BO" + ) # TODO: is this a good PV to use? + + ## Service specific PVs from other IOCs + # ... + + # TODO: class attribute names usually lowercase + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + self.CallbackPV = PV( + "AGEBD-SHIFTTOOL:CALLBACK", auto_monitor=dbr.DBE_VALUE + ) # TODO: ok? + + +class Service(BaseService[PVs]): + def __init__( + self, + name: str, + pvs: PVs, + version: str = __version__, + sleep_interval: float = 0.1, + ): + super().__init__(name, pvs, version, sleep_interval) + + # TODO: What is this for? + self.path = "sls/bd/bin" + + def update(self): + # when callback is fired, this code will be executed + if self.CallbackFired: + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running when the callback is fired + time.sleep(1) + ####################################################################################### + ####################################################################################### + + # callback done + self.CallbackFired = 0 + + ####################################################################################### + ####################################################################################### + # here goes all the code that your service + # is supposed to be running in any case, e.g., + + # update some pvs/vals + my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] + self.pvs.my_pv1.put(my_pv1_random_val) + # self.pvs.my_pv2.put("MY_PV2 value") + + # get some pvs/vals + self.val1 = self.pvs.my_pv1.get() + self.val2 = self.pvs.my_pv2.get() + + # maybe sleep to limit the update loop execution rate + time.sleep(1) + ####################################################################################### + ####################################################################################### diff --git a/services/shifttool/current/app/tests/test_app.py b/services/shifttool/current/app/tests/test_app.py new file mode 100644 index 0000000..257fc01 --- /dev/null +++ b/services/shifttool/current/app/tests/test_app.py @@ -0,0 +1,9 @@ +from agebd_shifttool import PVs, Service + + +def test_app(): + service_name = "DUMMY" + pvs = PVs(service_name=service_name) + service = Service(name=service_name, pvs=pvs) + service.CallbackFired = 1 + service.update() diff --git a/services/shifttool/current/app/uv.lock b/services/shifttool/current/app/uv.lock new file mode 100644 index 0000000..b6efa83 --- /dev/null +++ b/services/shifttool/current/app/uv.lock @@ -0,0 +1,275 @@ +version = 1 +revision = 3 +requires-python = "==3.10.*" + +[[package]] +name = "agebd" +version = "0.1.0" +source = { editable = "../../../../packages/agebd" } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.410" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.19" }, +] + +[[package]] +name = "agebd-shifttool" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "agebd" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pyepics" }, + { name = "pytest" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] + +[package.metadata.requires-dev] +dev = [ + { name = "pyepics", specifier = ">=3.5.8" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "ruff", specifier = ">=0.15.20" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyepics" +version = "3.5.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/57/29e1e9ef11ba2a3419f489946ae1d8190025a1e4f4e1c1686758bb2b6e0a/pyepics-3.5.10.tar.gz", hash = "sha256:f390cf9be40aba757b9528888114bc14d8db01086d0c93914720b1772460375b", size = 6150481, upload-time = "2026-05-20T18:44:36.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/36/e517fd83bd97d6bfe4105e0c6b322070c5cc36fb56a8fab2866e319f8804/pyepics-3.5.10-py3-none-any.whl", hash = "sha256:c9fac2c54f2b595268e66fc348cf5ec24e63718e7dbd07d73d1b37d4da6bfee1", size = 5332376, upload-time = "2026-05-20T18:44:34.242Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/9d/d825b07ee7ea9e2d61df92a860033c94e06e7300d50a1c2653aac27d24fe/ruff-0.15.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd", size = 11139539, upload-time = "2026-07-09T20:00:57.809Z" }, + { url = "https://files.pythonhosted.org/packages/f5/de/3b107712e642f063c7a9e0887c427b22cb44097de5aab36c05f2e280670c/ruff-0.15.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646", size = 10595437, upload-time = "2026-07-09T20:01:00.006Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3c/37d0ecb729a7cc2d393ea7dce316fc585680f35d93b8d62139d7d0a3700c/ruff-0.15.21-py3-none-win32.whl", hash = "sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd", size = 10896555, upload-time = "2026-07-09T20:01:26.941Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b8/e43466b2a6067ce91e669068f6e28d6c719a920f014b070d5c8731725de3/ruff-0.15.21-py3-none-win_amd64.whl", hash = "sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3", size = 12038772, upload-time = "2026-07-09T20:01:29.497Z" }, + { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] diff --git a/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_main.subs b/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_main.subs new file mode 100644 index 0000000..6141523 --- /dev/null +++ b/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_main.subs @@ -0,0 +1,4 @@ +file SHIFTTOOL.template { + pattern { DEVICE } + { AGEBD-SHIFTTOOL{{ agebd_env }} } +} diff --git a/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_parameters.yaml b/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_parameters.yaml new file mode 100644 index 0000000..ff8e70f --- /dev/null +++ b/services/shifttool/current/ioc/AGEBD-CPCL-SHIFTTOOL_parameters.yaml @@ -0,0 +1,6 @@ +cpu_architecture: x86_64 +epics_version: 7.0.8 +ioc_host: sls-vserv-bd-01{{ agebd_env }} +ioc_port: {{ ioc_port }} +os: RHEL8 +os_id: rhel diff --git a/services/shifttool/current/ioc/SHIFTTOOL.template b/services/shifttool/current/ioc/SHIFTTOOL.template new file mode 100644 index 0000000..857d84a --- /dev/null +++ b/services/shifttool/current/ioc/SHIFTTOOL.template @@ -0,0 +1,37 @@ +# This is a template for preaparing an IOC providing BD Service specific PVs +# Access Security Groups: +# DEFAULT - logt wenn EGU oder so veraendert werden +# LOG - logt wenn neuer wert geschrieben wird +# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL +# READONLY - verhindert versuchte caputs und aktiviert caputlog +# Input links can specify CA, CP, or CPP. +# If the input link specifies CA, it will be forced to be a Channel Access link. +# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies. +# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links. +# + +record(ao, "$(DEVICE):AO") { + field(DESC, "Analog Output Record (ao)") + field(ASG, "PROTECTED") + field(VAL, "0") + field(PINI, "YES") +} + +record(bo, "$(DEVICE):BO") { + field(DESC, "Binary Output Record (bo)") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} + +# TODO: ok? +record(bo, "$(DEVICE):CALLBACK") { + field(DESC, "Callback PV to listen to for changes") + field(ASG, "READONLY") + field(ZSV, "MINOR") + field(OSV, "NO_ALARM") + field(VAL, "1") + field(PINI, "YES") +} \ No newline at end of file diff --git a/services/shifttool/current/ioc/startup.script b/services/shifttool/current/ioc/startup.script new file mode 100644 index 0000000..0fa52ff --- /dev/null +++ b/services/shifttool/current/ioc/startup.script @@ -0,0 +1 @@ +epicsEnvSet("ENGINEER", "armborst") diff --git a/services/shifttool/current/qt/A_BD_.ui b/services/shifttool/current/qt/A_BD_.ui new file mode 100644 index 0000000..472b163 --- /dev/null +++ b/services/shifttool/current/qt/A_BD_.ui @@ -0,0 +1,103 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 60 + 100 + 50 + + + + 1 + + + 0 + + + AGEBD-SHIFTTOOL-DEV:AO + + + 9.000000000000000 + + + 0.000000000000000 + + + + + + 0 + 0 + 601 + 22 + + + + Toggle AGEBD-ALH-DEV:SHIFTTOOL-ONOFF + + + AGEBD-ALH-DEV:SHIFTTOOL-ONOFF + + + + + + 6 + 34 + 401 + 21 + + + + + 13 + + + + Value of AGEBD-SHIFTTOOL-DEV:AO + + + + + + + 0 + 0 + 800 + 20 + + + + + + + + caNumeric + QFrame +
caNumeric
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+
+ + +
diff --git a/services/shifttool/current/systemd/AGEBD-SERVICE-SHIFTTOOL.service b/services/shifttool/current/systemd/AGEBD-SERVICE-SHIFTTOOL.service new file mode 100644 index 0000000..ee945c0 --- /dev/null +++ b/services/shifttool/current/systemd/AGEBD-SERVICE-SHIFTTOOL.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGEBD-SERVICE-SHIFTTOOL +After=network.target + +[Service] +Environment=AGEBD_ENV={{ agebd_env }} +ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh SHIFTTOOL +Restart=no + +[Install] +WantedBy=default.target + +# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html +# systemctl --user daemon-reload +# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-SHIFTTOOL.service +# systemctl --user start AGEBD-SERVICE-SHIFTTOOL From 43abe571acdd2d4e4bc3477ecc20df499c9d8107 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:47:31 +0200 Subject: [PATCH 27/42] docs: todo for shifttool ioc --- services/shifttool/current/ioc/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 services/shifttool/current/ioc/README.md diff --git a/services/shifttool/current/ioc/README.md b/services/shifttool/current/ioc/README.md new file mode 100644 index 0000000..028b87b --- /dev/null +++ b/services/shifttool/current/ioc/README.md @@ -0,0 +1 @@ +# TODO: does it have an ioc? (in A_OP?) From 4da08d2814a7a3b972522382ea6e2624f939f2a6 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:48:36 +0200 Subject: [PATCH 28/42] chore: dev/prod for tune ioc --- services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs index a6848aa..374cb6e 100644 --- a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs +++ b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs @@ -1,4 +1,4 @@ file TOPUPTOOL.template { pattern { DEVICE } - { AGEBD-TOPUPTOOL } -} \ No newline at end of file + { AGEBD-TOPUPTOOL{{ agebd_env }} } +} From 7fe312854341a8664f5192da404b07e6ab3d5d0b Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:48:36 +0200 Subject: [PATCH 29/42] chore: dev/prod for topuptool ioc --- services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs index a6848aa..374cb6e 100644 --- a/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs +++ b/services/topuptool/current/ioc/AGEBD-CPCL-TOPUPTOOL_main.subs @@ -1,4 +1,4 @@ file TOPUPTOOL.template { pattern { DEVICE } - { AGEBD-TOPUPTOOL } -} \ No newline at end of file + { AGEBD-TOPUPTOOL{{ agebd_env }} } +} From a93c91ceb813c7816369f58814fba85d570140b1 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:50:39 +0200 Subject: [PATCH 30/42] chore: dev/prod for tune ioc --- services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs b/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs index 16e587d..378be70 100644 --- a/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs +++ b/services/tune/current/ioc/AGEBD-CPCL-TUNE_main.subs @@ -1,4 +1,4 @@ file TUNE.template { pattern { DEVICE } - { AGEBD-TUNE } -} \ No newline at end of file + { AGEBD-TUNE{{ agebd_env }} } +} From 2f11efcc9d590f0fb7978baead114fbf9c9dfcde Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 13:52:48 +0200 Subject: [PATCH 31/42] docs: todo for shifttool ui --- services/shifttool/current/qt/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 services/shifttool/current/qt/README.md diff --git a/services/shifttool/current/qt/README.md b/services/shifttool/current/qt/README.md new file mode 100644 index 0000000..6e3690d --- /dev/null +++ b/services/shifttool/current/qt/README.md @@ -0,0 +1 @@ +# TODO: ui for this service... From 1eafb726d16e6982050c394286f85c5381bef1be Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 14:37:18 +0200 Subject: [PATCH 32/42] feat: migrate plots python service --- services/dbpm3curr/current/app/uv.lock | 24 +- services/injectionguard/current/app/uv.lock | 24 +- services/master/current/app/uv.lock | 24 +- services/nturns/current/app/uv.lock | 24 +- services/orbitbump/current/app/uv.lock | 24 +- services/plots/current/app/pyproject.toml | 3 + .../plots/current/app/src/agebd_plots/main.py | 6 +- .../current/app/src/agebd_plots/service.py | 309 ++++++++++++++---- services/plots/current/app/uv.lock | 194 ++++++++++- services/postmortemlog/current/app/uv.lock | 24 +- services/scrubbing/current/app/uv.lock | 24 +- services/shifttool/current/app/uv.lock | 24 +- services/taubpm/current/app/uv.lock | 24 +- services/taupct/current/app/uv.lock | 24 +- services/timing/current/app/uv.lock | 24 +- services/topuptool/current/app/uv.lock | 24 +- services/tune/current/app/uv.lock | 24 +- services/tunebump/current/app/uv.lock | 24 +- services/tunefbx/current/app/uv.lock | 24 +- services/tunefby/current/app/uv.lock | 24 +- 20 files changed, 817 insertions(+), 79 deletions(-) diff --git a/services/dbpm3curr/current/app/uv.lock b/services/dbpm3curr/current/app/uv.lock index 3a2bed0..3134b83 100644 --- a/services/dbpm3curr/current/app/uv.lock +++ b/services/dbpm3curr/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -79,6 +83,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/injectionguard/current/app/uv.lock b/services/injectionguard/current/app/uv.lock index ecb8da5..345e744 100644 --- a/services/injectionguard/current/app/uv.lock +++ b/services/injectionguard/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -79,6 +83,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/master/current/app/uv.lock b/services/master/current/app/uv.lock index 61aea7e..f9f6c6e 100644 --- a/services/master/current/app/uv.lock +++ b/services/master/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -79,6 +83,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/nturns/current/app/uv.lock b/services/nturns/current/app/uv.lock index 84c0e5e..891ecdd 100644 --- a/services/nturns/current/app/uv.lock +++ b/services/nturns/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -81,6 +85,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/orbitbump/current/app/uv.lock b/services/orbitbump/current/app/uv.lock index 7f329ec..92d5e41 100644 --- a/services/orbitbump/current/app/uv.lock +++ b/services/orbitbump/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/plots/current/app/pyproject.toml b/services/plots/current/app/pyproject.toml index facd875..40449a1 100644 --- a/services/plots/current/app/pyproject.toml +++ b/services/plots/current/app/pyproject.toml @@ -5,7 +5,10 @@ description = "AGEBD-PLOTS Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "matplotlib>=3.10.9", + "urllib3>=2.7.0", ] +# TODO: elog [dependency-groups] dev = [ diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index a89cd64..317cce2 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -1,13 +1,13 @@ import typer from agebd.enums import LogLevel -from agebd.runner import CallbackRunner +from agebd.runner import PeriodicRunner from agebd.utils import init_logging from agebd_plots import PVs, Service - # TODO: remove: cicd test 10 + def main( log_level: LogLevel = typer.Option( LogLevel.INFO, @@ -23,7 +23,7 @@ def main( service_name = "PLOTS" pvs = PVs(service_name=service_name) service = Service(name=service_name, pvs=pvs) - runner = CallbackRunner(service=service) + runner = PeriodicRunner(service=service) runner.start() diff --git a/services/plots/current/app/src/agebd_plots/service.py b/services/plots/current/app/src/agebd_plots/service.py index cbd8253..5fa7646 100644 --- a/services/plots/current/app/src/agebd_plots/service.py +++ b/services/plots/current/app/src/agebd_plots/service.py @@ -1,49 +1,91 @@ import time -from epics import dbr +import urllib3 -from agebd.pv import LocalPVLink +urllib3.disable_warnings() +from datetime import datetime +from time import sleep, strftime, time + +import elog +import matplotlib.pyplot as plt +import numpy as np +from epics import PV +from matplotlib.dates import DateFormatter, HourLocator + +from agebd.h5 import h5save +from agebd.pv import get_pv_class, get_pv_external_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) PV = get_pv_class() +PV_EXTERNAL = get_pv_external_class() + +plt.switch_backend("agg") +plt.rcParams.update({"font.size": 18}) +plt.rcParams["axes.facecolor"] = "white" +plt.rcParams["figure.facecolor"] = "white" +plt.rcParams["lines.markersize"] = 1 +plt.rcParams["lines.linewidth"] = 0.2 +plt.rcParams["agg.path.chunksize"] = 20000 class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-PLOTS:AO") # TODO: is this a good PV to use? + light_delivery = PV_EXTERNAL("AGEOP-STATUS:LIGHT-DELIVERY.VAL") + shift_type = PV_EXTERNAL("AGEOP-STATUS:DUO-SHIFT-TYPE.VAL") - ## Service specific PVs from other IOCs - # ... + # fmt: off + buffers_shift = { + 'ARS07-DPCT-0000:CURR' : PV('AGEBD-PLOTS:CURRENT-PCT-9h-BUFFER'), + 'AGEBD-DBPM3CURR:CURRENT-AVG' : PV('AGEBD-PLOTS:CURRENT-BPM-9h-BUFFER'), + 'AGEBD-PARAMS:CURRENT' : PV('AGEBD-PLOTS:CURRENT-9h-BUFFER'), + 'AGEBD-PARAMS:INJECTION-RATE' : PV('AGEBD-PLOTS:INJECTION-RATE-9h-BUFFER'), + 'AGEBD-PARAMS:TRANSMISSION' : PV('AGEBD-PLOTS:TRANSMISSION-9h-BUFFER'), + 'AGEBD-PARAMS:LIFETIME' : PV('AGEBD-PLOTS:LIFETIME-9h-BUFFER'), + 'ARIVA-VMAVE:PRESS-AVE' : PV('AGEBD-PLOTS:MAVAC-AVG-9h-BUFFER'), + 'ARIVA-VMAVE:PRESS-MAX' : PV('AGEBD-PLOTS:MAVAC-MAX-9h-BUFFER'), + 'ARIVA-VMAVE-FE:PRESS-AVE' : PV('AGEBD-PLOTS:FEVAC-AVG-9h-BUFFER'), + 'ARIVA-VMAVE-FE:PRESS-MAX' : PV('AGEBD-PLOTS:FEVAC-MAX-9h-BUFFER'), + 'ABRTL-DDRM-0670:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ABRTL-DDRM-0670-9h-BUFFER'), + 'ABRTL-DDRM-0950:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ABRTL-DDRM-0950-9h-BUFFER'), + 'X05LA-DDRM-0330:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:X05LA-DDRM-0330-9h-BUFFER'), + 'X05LA-DDRM-0650:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:X05LA-DDRM-0650-9h-BUFFER'), + 'X09LA-DDRM-0330:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:X09LA-DDRM-0330-9h-BUFFER'), + 'X09LA-DDRM-0790:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:X09LA-DDRM-0790-9h-BUFFER'), + 'ARS01-DDRM-0375:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS01-DDRM-0375-9h-BUFFER'), + 'ARS01-DDRM-1530:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS01-DDRM-1530-9h-BUFFER'), + 'ARS05-DDRM-1530:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS05-DDRM-1530-9h-BUFFER'), + 'ARS05-DDRM-3500:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS05-DDRM-3500-9h-BUFFER'), + 'ARS09-DDRM-1530:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS09-DDRM-1530-9h-BUFFER'), + 'ARS09-DDRM-3500:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS09-DDRM-3500-9h-BUFFER'), + 'ARS12-DDRM-1530:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS12-DDRM-1530-9h-BUFFER'), + 'ARS12-DDRM-3500:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS12-DDRM-3500-9h-BUFFER'), + 'ARS12-DDRM-4400:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS12-DDRM-4400-9h-BUFFER'), + 'ARS12-DDRM-5480:FET1_BIAS_DOSE' : PV('AGEBD-PLOTS:ARS12-DDRM-5480-9h-BUFFER'), + 'X04SA-UIND:GAP-READ' : PV('AGEBD-PLOTS:X04SA-UIND-GAP-9h-BUFFER'), + 'X10SA-UIND:GAP-READ' : PV('AGEBD-PLOTS:X10SA-UIND-GAP-9h-BUFFER'), + 'X12SA-UIND:GAP-READ' : PV('AGEBD-PLOTS:X12SA-UIND-GAP-9h-BUFFER'), + } + + buffers_week = { + 'AGEBD-DBPM3CURR:CURRENT-AVG' : PV('AGEBD-PLOTS:CURRENT-BPM-168h-BUFFER'), + 'ARS07-DPCT-0000:CURR' : PV('AGEBD-PLOTS:CURRENT-PCT-168h-BUFFER'), + 'AGEBD-TAUBPM:TAU' : PV('AGEBD-PLOTS:TAU-BPM-168h-BUFFER'), + 'AGEBD-TAUPCT:TAU' : PV('AGEBD-PLOTS:TAU-PCT-168h-BUFFER'), + 'AGEBD-SCRUBBING:TOPUP-TAU' : PV('AGEBD-PLOTS:TAU-TOPUP-168h-BUFFER'), + 'AGEBD-TAUBPM:INJRATE' : PV('AGEBD-PLOTS:INJRATE-BPM-168h-BUFFER'), + 'AGEBD-TAUPCT:INJRATE' : PV('AGEBD-PLOTS:INJRATE-PCT-168h-BUFFER'), + 'ARIVA-VMAVE:PRESS-AVE' : PV('AGEBD-PLOTS:MAVAC-AVG-168h-BUFFER'), + 'ARIVA-VMAVE:PRESS-MAX' : PV('AGEBD-PLOTS:MAVAC-MAX-168h-BUFFER'), + 'ARIVA-VMAVE-FE:PRESS-AVE' : PV('AGEBD-PLOTS:FEVAC-AVG-168h-BUFFER'), + 'ARIVA-VMAVE-FE:PRESS-MAX' : PV('AGEBD-PLOTS:FEVAC-MAX-168h-BUFFER'), + } + # fmt: on def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) - PV = pv_factory - - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-PLOTS:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-PLOTS:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? class Service(BaseService[PVs]): @@ -52,42 +94,193 @@ class Service(BaseService[PVs]): name: str, pvs: PVs, version: str = __version__, - sleep_interval: float = 0.1, + sleep_interval: float = 0.01, ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.path_shift = "/sls/op/data/applications/plots_shift/" + self.path_weekly = "/sls/op/data/applications/plots_weekly/" + self.lastshiftplot = -1 + self.lastweekplot = -1 + self.logbook = elog.open( + "https://elog-gfa.psi.ch/SLS/", + user="robot", + password="robot", + use_ssl=True, + ) def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs - # callback done - self.CallbackFired = 0 + dtn = datetime.now() + minute = dtn.minute + hour = dtn.hour + weekday = dtn.weekday() + day = dtn.day + shift_type = pvs.shift_type.get() - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + # shift plots + if hour in [6, 14, 22] and minute == 30 and hour != self.lastshiftplot: + self.lastshiftplot = hour - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + print("Preparing shift plots...") + print(" ... fetching data") - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + data = {pv: pvs.buffers_shift[pv].get() for pv in pvs.buffers_shift} + Npts = len(data["ARS07-DPCT-0000:CURR"]) + tf = int(pvs.buffers_shift["ARS07-DPCT-0000:CURR"].timestamp) + timevec = np.array( + [datetime.fromtimestamp(t) for t in np.linspace(tf - Npts - 1, tf, Npts)] + ) + data.update({"time": np.array([np.datetime64(t) for t in timevec], dtype="S30")}) - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + print(" ...saving data") + h5save(self.path_shift + "ShiftPlotSLS", data) + print(" ...data saved") + + print(" ...preparing plots") + Nplots = 1 + fig = plt.figure(figsize=(16, 9 * Nplots), constrained_layout=True) + + ax = fig.add_subplot(Nplots, 1, 1) + ax.plot(timevec, data["ARS07-DPCT-0000:CURR"], "-xg", label="ARS07-DPCT-0000:CURR") + ax.tick_params(axis="y", colors="g", which="both") + lgnd = ax.legend(loc="lower left", bbox_to_anchor=(0.07, 1)) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Beam current / mA", color="g") + ax.set_ylim([-1, 410]) + ax.set_xlim([timevec[0], timevec[-1]]) + + ax = ax.twinx() + ax.plot( + timevec, + data["AGEBD-PARAMS:LIFETIME"], + "-xb", + label="AGEBD-PARAMS:LIFETIME", + alpha=0.5, + ) + ax.tick_params(axis="y", colors="b", which="both") + lgnd = ax.legend(loc="lower right", bbox_to_anchor=(0.93, 1)) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Beam lifetime / hours", color="b") + ax.set_ylim([-0.1, 41]) + ax.set_xlim([timevec[0], timevec[-1]]) + ax.set_xlabel("Time") + # Set major ticks every hour and format as HH:MM + ax.xaxis.set_major_locator(HourLocator()) + ax.xaxis.set_major_formatter(DateFormatter("%H:%M")) + ax.grid(axis="both") + + print(" ...saving plots") + file1 = self.path_shift + strftime("%Y%m%d%H%M%S") + "_ShiftPlotSLS.png" + fig.savefig(file1, dpi=192, bbox_inches="tight") + plt.close(fig) + print(" ...saved") + + if shift_type > 0: + print(" ...preparing elog entry...") + dict_of_attributes = { + "Wann": time(), + "Autor": "Plots Logger", + "Eintrag": "Status", + "Titel": "Plots for last shift", + "Encoding": "html", + } + self.msg_id = self.logbook.post( + "", + attributes=dict_of_attributes, + attachments=[file1], + suppress_email_notification=True, + attribute_as_param="value", + ) + print(" ...elog entry submitted...") + + # weekly plots + if weekday == 2 and hour == 7 and day != self.lastweekplot: + self.lastweekplot = day + + print("Preparing weekly plots...") + print(" ... fetching data") + + data = {pv: pvs.buffers_week[pv].get() for pv in pvs.buffers_week} + Npts = len(data["AGEBD-DBPM3CURR:CURRENT-AVG"]) + tf = int(pvs.buffers_week["AGEBD-DBPM3CURR:CURRENT-AVG"].timestamp) + timevec = np.array( + [datetime.fromtimestamp(t) for t in np.linspace(tf - Npts - 1, tf, Npts)] + ) + data.update({"time": np.array([np.datetime64(t) for t in timevec], dtype="S30")}) + + print(" ...saving data") + h5save(self.path_weekly + "WeeklyPlotSLS", data) + print(" ...data saved") + + print(" ...preparing plots") + Nplots = 1 + fig = plt.figure(figsize=(16, 9 * Nplots), constrained_layout=True) + + ax = fig.add_subplot(Nplots, 1, 1) + ax.plot(timevec, data["ARS07-DPCT-0000:CURR"], "-xg", label="ARS07-DPCT-0000:CURR") + ax.tick_params(axis="y", colors="g", which="both") + lgnd = ax.legend(loc="lower left", bbox_to_anchor=(0.07, 1)) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Beam current / mA", color="g") + ax.set_ylim([-1, 410]) + ax.set_xlim([timevec[0], timevec[-1]]) + + ax = ax.twinx() + ax.plot(timevec, data["AGEBD-TAUBPM:TAU"], "-xb", label="AGEBD-TAUBPM:TAU", alpha=0.5) + ax.tick_params(axis="y", colors="b", which="both") + lgnd = ax.legend(loc="lower right", bbox_to_anchor=(0.93, 1)) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Beam lifetime / hours", color="b") + ax.set_ylim([-0.1, 41]) + ax.set_xlim([timevec[0], timevec[-1]]) + ax.xaxis.set_major_locator(HourLocator(byhour=12)) + ax.xaxis.set_major_formatter(DateFormatter("%a %H:%M")) + ax.set_xlabel("Time") + ax.grid(axis="both") + + print(" ...saving plots") + file2 = self.path_weekly + strftime("%Y%m%d%H%M%S") + "_WeeklyPlotSLS.png" + fig.savefig(file2, dpi=192, bbox_inches="tight") + plt.close(fig) + print(" ...finished") + + if shift_type > 0: + print(" ...preparing elog entry...") + dict_of_attributes = { + "Wann": time(), + "Autor": "Plots Logger", + "Eintrag": "Status", + "Titel": "Plots for last week", + "Encoding": "html", + } + + print(" ...posting elog entry...") + try: + self.msg_id = self.logbook.post( + "", + attributes=dict_of_attributes, + attachments=[file2], + suppress_email_notification=True, + attribute_as_param="value", + ) + print(" ...elog entry submitted...") + except: + print(" ...elog failed...") + + else: + print(" ...no elog entry during shutdown.") + + print(" ...setting all beamlines to offline") + pvs.light_delivery.put(1) + sleep(0.1) + pvs.light_delivery.put(0) diff --git a/services/plots/current/app/uv.lock b/services/plots/current/app/uv.lock index f8e7691..1909c3c 100644 --- a/services/plots/current/app/uv.lock +++ b/services/plots/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -26,6 +30,9 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "elogpy" }, + { name = "matplotlib" }, + { name = "urllib3" }, ] [package.dev-dependencies] @@ -36,7 +43,12 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "elogpy", specifier = ">=1.0.0" }, + { name = "matplotlib", specifier = ">=3.10.9" }, + { name = "urllib3", specifier = ">=2.7.0" }, +] [package.metadata.requires-dev] dev = [ @@ -63,6 +75,48 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "contourpy" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/a3/da4153ec8fe25d263aa48c1a4cbde7f49b59af86f0b6f7862788c60da737/contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934", size = 268551, upload-time = "2025-04-15T17:34:46.581Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6c/330de89ae1087eb622bfca0177d32a7ece50c3ef07b28002de4757d9d875/contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989", size = 253399, upload-time = "2025-04-15T17:34:51.427Z" }, + { url = "https://files.pythonhosted.org/packages/c1/bd/20c6726b1b7f81a8bee5271bed5c165f0a8e1f572578a9d27e2ccb763cb2/contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d", size = 312061, upload-time = "2025-04-15T17:34:55.961Z" }, + { url = "https://files.pythonhosted.org/packages/22/fc/a9665c88f8a2473f823cf1ec601de9e5375050f1958cbb356cdf06ef1ab6/contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9", size = 351956, upload-time = "2025-04-15T17:35:00.992Z" }, + { url = "https://files.pythonhosted.org/packages/25/eb/9f0a0238f305ad8fb7ef42481020d6e20cf15e46be99a1fcf939546a177e/contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512", size = 320872, upload-time = "2025-04-15T17:35:06.177Z" }, + { url = "https://files.pythonhosted.org/packages/32/5c/1ee32d1c7956923202f00cf8d2a14a62ed7517bdc0ee1e55301227fc273c/contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631", size = 325027, upload-time = "2025-04-15T17:35:11.244Z" }, + { url = "https://files.pythonhosted.org/packages/83/bf/9baed89785ba743ef329c2b07fd0611d12bfecbedbdd3eeecf929d8d3b52/contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f", size = 1306641, upload-time = "2025-04-15T17:35:26.701Z" }, + { url = "https://files.pythonhosted.org/packages/d4/cc/74e5e83d1e35de2d28bd97033426b450bc4fd96e092a1f7a63dc7369b55d/contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2", size = 1374075, upload-time = "2025-04-15T17:35:43.204Z" }, + { url = "https://files.pythonhosted.org/packages/0c/42/17f3b798fd5e033b46a16f8d9fcb39f1aba051307f5ebf441bad1ecf78f8/contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0", size = 177534, upload-time = "2025-04-15T17:35:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/54/ec/5162b8582f2c994721018d0c9ece9dc6ff769d298a8ac6b6a652c307e7df/contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a", size = 221188, upload-time = "2025-04-15T17:35:50.064Z" }, + { url = "https://files.pythonhosted.org/packages/33/05/b26e3c6ecc05f349ee0013f0bb850a761016d89cec528a98193a48c34033/contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c", size = 265681, upload-time = "2025-04-15T17:44:59.314Z" }, + { url = "https://files.pythonhosted.org/packages/2b/25/ac07d6ad12affa7d1ffed11b77417d0a6308170f44ff20fa1d5aa6333f03/contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16", size = 315101, upload-time = "2025-04-15T17:45:04.165Z" }, + { url = "https://files.pythonhosted.org/packages/8f/4d/5bb3192bbe9d3f27e3061a6a8e7733c9120e203cb8515767d30973f71030/contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad", size = 220599, upload-time = "2025-04-15T17:45:08.456Z" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "elogpy" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/2d/1ceedb78bc28f9b060879b49c45fcb76f71f7f6ac812d38f2794fc4d5303/elogpy-1.0.0.tar.gz", hash = "sha256:9676c108cccdee7c7ab96f1fa850d9ade291e186f70479883d9414cb64c55438", size = 5289, upload-time = "2025-08-26T05:31:24.986Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/9a/b65bb5f9c3a7fb0fc54b9689cd587228d1cc890f31157e55236987fb9205/elogpy-1.0.0-py3-none-any.whl", hash = "sha256:cec1a8fb0e69ac613f282ba2988fb970063358c78543166f79412b38f2bb77fe", size = 5386, upload-time = "2025-08-26T05:31:23.719Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -75,6 +129,41 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/c9/4141c90a90db20f807c7e10bfd689fe53eb8f7f4caff58ee4d4dfe46919f/fonttools-4.63.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b", size = 2884632, upload-time = "2026-05-14T12:02:38.56Z" }, + { url = "https://files.pythonhosted.org/packages/b8/46/ad12b5c10eae602d7ef814b02afa08aacbf89da917fed5b071282b7eadc2/fonttools-4.63.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94", size = 2429441, upload-time = "2026-05-14T12:02:41.162Z" }, + { url = "https://files.pythonhosted.org/packages/90/8f/bdca24a84c81d56fffed052229cdcff368f6e05882e526f4558891481f65/fonttools-4.63.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579", size = 4946346, upload-time = "2026-05-14T12:02:43.41Z" }, + { url = "https://files.pythonhosted.org/packages/04/59/a639c0e136441ee91a65b56fdf89e5d075927e7a09c559d1b0f5276577db/fonttools-4.63.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22", size = 4903184, upload-time = "2026-05-14T12:02:45.742Z" }, + { url = "https://files.pythonhosted.org/packages/e6/53/91b7e0cb45b536f3da1b29ba8cbab89f27e8b986809e0b1982303a3f4eca/fonttools-4.63.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e", size = 4922967, upload-time = "2026-05-14T12:02:48.386Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b7/87439bf44e6b97c5538cd29d0b7e366a5b8ce2cc132a4134fb67fa3f2fa2/fonttools-4.63.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69", size = 5042799, upload-time = "2026-05-14T12:02:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/ad/7c/8b96c3263b89ef99cded544c0f0636686f85dbd3c211c4dceef0231fca23/fonttools-4.63.0-cp310-cp310-win32.whl", hash = "sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e", size = 1519704, upload-time = "2026-05-14T12:02:52.523Z" }, + { url = "https://files.pythonhosted.org/packages/e5/4d/2c2f0069970b6907de8fb5b05c5c0193cc22f717df151d1c7aef1c738f58/fonttools-4.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac", size = 1568666, upload-time = "2026-05-14T12:02:54.917Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" @@ -84,6 +173,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/f8/06549565caa026e540b7e7bab5c5a90eb7ca986015f4c48dace243cd24d9/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374", size = 122802, upload-time = "2026-03-09T13:12:37.515Z" }, + { url = "https://files.pythonhosted.org/packages/84/eb/8476a0818850c563ff343ea7c9c05dcdcbd689a38e01aa31657df01f91fa/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd", size = 66216, upload-time = "2026-03-09T13:12:38.812Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/f9c8a6b4c21aed4198566e45923512986d6cef530e7263b3a5f823546561/kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476", size = 63917, upload-time = "2026-03-09T13:12:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0e/ba4ae25d03722f64de8b2c13e80d82ab537a06b30fc7065183c6439357e3/kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22", size = 1628776, upload-time = "2026-03-09T13:12:41.976Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e4/3f43a011bc8a0860d1c96f84d32fa87439d3feedf66e672fef03bf5e8bac/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b", size = 1228164, upload-time = "2026-03-09T13:12:44.002Z" }, + { url = "https://files.pythonhosted.org/packages/4b/34/3a901559a1e0c218404f9a61a93be82d45cb8f44453ba43088644980f033/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e", size = 1246656, upload-time = "2026-03-09T13:12:45.557Z" }, + { url = "https://files.pythonhosted.org/packages/87/9e/f78c466ea20527822b95ad38f141f2de1dcd7f23fb8716b002b0d91bbe59/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb", size = 1295562, upload-time = "2026-03-09T13:12:47.562Z" }, + { url = "https://files.pythonhosted.org/packages/0a/66/fd0e4a612e3a286c24e6d6f3a5428d11258ed1909bc530ba3b59807fd980/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537", size = 2178473, upload-time = "2026-03-09T13:12:50.254Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8e/6cac929e0049539e5ee25c1ee937556f379ba5204840d03008363ced662d/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4", size = 2274035, upload-time = "2026-03-09T13:12:51.785Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d3/9d0c18f1b52ea8074b792452cf17f1f5a56bd0302a85191f405cfbf9da16/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c", size = 2443217, upload-time = "2026-03-09T13:12:53.329Z" }, + { url = "https://files.pythonhosted.org/packages/45/2a/6e19368803a038b2a90857bf4ee9e3c7b667216d045866bf22d3439fd75e/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede", size = 2249196, upload-time = "2026-03-09T13:12:55.057Z" }, + { url = "https://files.pythonhosted.org/packages/75/2b/3f641dfcbe72e222175d626bacf2f72c3b34312afec949dd1c50afa400f5/kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2", size = 73389, upload-time = "2026-03-09T13:12:56.496Z" }, + { url = "https://files.pythonhosted.org/packages/da/88/299b137b9e0025d8982e03d2d52c123b0a2b159e84b0ef1501ef446339cf/kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875", size = 64782, upload-time = "2026-03-09T13:12:57.609Z" }, + { url = "https://files.pythonhosted.org/packages/17/6f/6fd4f690a40c2582fa34b97d2678f718acf3706b91d270c65ecb455d0a06/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4", size = 59606, upload-time = "2026-03-09T13:15:40.81Z" }, + { url = "https://files.pythonhosted.org/packages/82/a0/2355d5e3b338f13ce63f361abb181e3b6ea5fffdb73f739b3e80efa76159/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca", size = 57537, upload-time = "2026-03-09T13:15:42.071Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b9/1d50e610ecadebe205b71d6728fd224ce0e0ca6aba7b9cbe1da049203ac5/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f", size = 79888, upload-time = "2026-03-09T13:15:43.317Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ee/b85ffcd75afed0357d74f0e6fc02a4507da441165de1ca4760b9f496390d/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed", size = 77584, upload-time = "2026-03-09T13:15:44.605Z" }, + { url = "https://files.pythonhosted.org/packages/6b/dd/644d0dde6010a8583b4cd66dd41c5f83f5325464d15c4f490b3340ab73b4/kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc", size = 73390, upload-time = "2026-03-09T13:15:45.832Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -96,6 +211,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, ] +[[package]] +name = "matplotlib" +version = "3.10.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/6f/340b04986e67aac6f66c5145ce68bf72c64bed30f92c8913499a6e6b8f99/matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217", size = 8296625, upload-time = "2026-04-24T00:11:43.376Z" }, + { url = "https://files.pythonhosted.org/packages/bb/2f/127081eb83162053ebb9678ceac64220b93a663e0167432566e9c7c82aab/matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b", size = 8188790, upload-time = "2026-04-24T00:11:46.556Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b7/d8bcec2626c35f96972bff656299fef4578113ea6193c8fdad324710410c/matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37", size = 8769389, upload-time = "2026-04-24T00:11:48.959Z" }, + { url = "https://files.pythonhosted.org/packages/12/49/b78e214a527ea732033b7f4d37f7afb504d74ba9d134bd47938230dfb8b1/matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294", size = 9589657, upload-time = "2026-04-24T00:11:51.915Z" }, + { url = "https://files.pythonhosted.org/packages/5f/15/5246f7b43beae19c74dfee651d58d6cc8112e06f77adb4e88cc04f2e3a23/matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65", size = 9651983, upload-time = "2026-04-24T00:11:54.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/77/5acecfe672ba0fa1b8c0454f69ce155d1e6fc5852fa7206bf9afaf767121/matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda", size = 8199701, upload-time = "2026-04-24T00:11:58.389Z" }, + { url = "https://files.pythonhosted.org/packages/2c/2b/0e92ad0ac446633f928a1563db4aa8add407e1924faf0ded5b95b35afb27/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b", size = 8293058, upload-time = "2026-04-24T00:13:56.339Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/74682fd369f5299ceda438fea2a0662e6383b85c9383fb9cdfcf04713e07/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f", size = 8186627, upload-time = "2026-04-24T00:13:58.623Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e8/368aab88f3c4cd8992800f31abfe0670c3e47540ba20a97e9fdbcde594b3/matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585", size = 8764117, upload-time = "2026-04-24T00:14:01.684Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -136,6 +279,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -194,6 +354,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -241,6 +413,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + [[package]] name = "tomli" version = "2.4.1" @@ -273,3 +454,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3 wheels = [ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] + +[[package]] +name = "urllib3" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, +] diff --git a/services/postmortemlog/current/app/uv.lock b/services/postmortemlog/current/app/uv.lock index 4d2e5ff..d9cb60f 100644 --- a/services/postmortemlog/current/app/uv.lock +++ b/services/postmortemlog/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/scrubbing/current/app/uv.lock b/services/scrubbing/current/app/uv.lock index fadbe6f..c2400b2 100644 --- a/services/scrubbing/current/app/uv.lock +++ b/services/scrubbing/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/shifttool/current/app/uv.lock b/services/shifttool/current/app/uv.lock index b6efa83..753115b 100644 --- a/services/shifttool/current/app/uv.lock +++ b/services/shifttool/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/taubpm/current/app/uv.lock b/services/taubpm/current/app/uv.lock index 9f28c51..226f226 100644 --- a/services/taubpm/current/app/uv.lock +++ b/services/taubpm/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -79,6 +83,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/taupct/current/app/uv.lock b/services/taupct/current/app/uv.lock index 5a4fc6b..41c5a2b 100644 --- a/services/taupct/current/app/uv.lock +++ b/services/taupct/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/timing/current/app/uv.lock b/services/timing/current/app/uv.lock index d427488..9cc0322 100644 --- a/services/timing/current/app/uv.lock +++ b/services/timing/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/topuptool/current/app/uv.lock b/services/topuptool/current/app/uv.lock index fe504cb..11636d8 100644 --- a/services/topuptool/current/app/uv.lock +++ b/services/topuptool/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/tune/current/app/uv.lock b/services/tune/current/app/uv.lock index 38d5733..62436c8 100644 --- a/services/tune/current/app/uv.lock +++ b/services/tune/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/tunebump/current/app/uv.lock b/services/tunebump/current/app/uv.lock index e28b4bb..8a45e3e 100644 --- a/services/tunebump/current/app/uv.lock +++ b/services/tunebump/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/tunefbx/current/app/uv.lock b/services/tunefbx/current/app/uv.lock index f4a9ae0..92c43fe 100644 --- a/services/tunefbx/current/app/uv.lock +++ b/services/tunefbx/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" diff --git a/services/tunefby/current/app/uv.lock b/services/tunefby/current/app/uv.lock index c79326d..ee3af41 100644 --- a/services/tunefby/current/app/uv.lock +++ b/services/tunefby/current/app/uv.lock @@ -7,11 +7,15 @@ name = "agebd" version = "0.1.0" source = { editable = "../../../../packages/agebd" } dependencies = [ + { name = "h5py" }, { name = "typer" }, ] [package.metadata] -requires-dist = [{ name = "typer", specifier = ">=0.23.2" }] +requires-dist = [ + { name = "h5py", specifier = ">=3.16.0" }, + { name = "typer", specifier = ">=0.23.2" }, +] [package.metadata.requires-dev] dev = [ @@ -75,6 +79,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/6b/231413e58a787a89b316bb0d1777da3c62257e4797e09afd8d17ad3549dc/h5py-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e06f864bedb2c8e7c1358e6c73af48519e317457c444d6f3d332bb4e8fa6d7d9", size = 3724137, upload-time = "2026-03-06T13:47:35.242Z" }, + { url = "https://files.pythonhosted.org/packages/74/f9/557ce3aad0fe8471fb5279bab0fc56ea473858a022c4ce8a0b8f303d64e9/h5py-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec86d4fffd87a0f4cb3d5796ceb5a50123a2a6d99b43e616e5504e66a953eca3", size = 3090112, upload-time = "2026-03-06T13:47:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f5/e15b3d0dc8a18e56409a839e6468d6fb589bc5207c917399c2e0706eeb44/h5py-3.16.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:86385ea895508220b8a7e45efa428aeafaa586bd737c7af9ee04661d8d84a10d", size = 4844847, upload-time = "2026-03-06T13:47:39.811Z" }, + { url = "https://files.pythonhosted.org/packages/cb/92/a8851d936547efe30cc0ce5245feac01f3ec6171f7899bc3f775c72030b3/h5py-3.16.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8975273c2c5921c25700193b408e28d6bdd0111c37468b2d4e25dcec4cd1d84d", size = 5065352, upload-time = "2026-03-06T13:47:41.489Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ae/f2adc5d0ca9626db3277a3d87516e124cbc5d0eea0bd79bc085702d04f2c/h5py-3.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1677ad48b703f44efc9ea0c3ab284527f81bc4f318386aaaebc5fede6bbae56f", size = 4839173, upload-time = "2026-03-06T13:47:43.586Z" }, + { url = "https://files.pythonhosted.org/packages/64/0b/e0c8c69da1d8838da023a50cd3080eae5d475691f7636b35eff20bb6ef20/h5py-3.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c4dd4cf5f0a4e36083f73172f6cfc25a5710789269547f132a20975bfe2434c", size = 5076216, upload-time = "2026-03-06T13:47:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/66/35/d88fd6718832133c885004c61ceeeb24dbd6397ef877dbed6b3a64d6a286/h5py-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:bdef06507725b455fccba9c16529121a5e1fbf56aa375f7d9713d9e8ff42454d", size = 3183639, upload-time = "2026-03-06T13:47:47.041Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" From 5f9e82bb74a5ab47c8c1a3d7f7a326846d0a5ac6 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 15:19:04 +0200 Subject: [PATCH 33/42] feat: migrate postmortemlog python service --- services/plots/current/app/uv.lock | 11 - .../postmortemlog/current/app/pyproject.toml | 3 + .../app/src/agebd_postmortemlog/service.py | 1748 ++++++++++++++++- services/postmortemlog/current/app/uv.lock | 161 +- 4 files changed, 1860 insertions(+), 63 deletions(-) diff --git a/services/plots/current/app/uv.lock b/services/plots/current/app/uv.lock index 1909c3c..ecd97cf 100644 --- a/services/plots/current/app/uv.lock +++ b/services/plots/current/app/uv.lock @@ -30,7 +30,6 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, - { name = "elogpy" }, { name = "matplotlib" }, { name = "urllib3" }, ] @@ -45,7 +44,6 @@ dev = [ [package.metadata] requires-dist = [ { name = "agebd", editable = "../../../../packages/agebd" }, - { name = "elogpy", specifier = ">=1.0.0" }, { name = "matplotlib", specifier = ">=3.10.9" }, { name = "urllib3", specifier = ">=2.7.0" }, ] @@ -108,15 +106,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, ] -[[package]] -name = "elogpy" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f4/2d/1ceedb78bc28f9b060879b49c45fcb76f71f7f6ac812d38f2794fc4d5303/elogpy-1.0.0.tar.gz", hash = "sha256:9676c108cccdee7c7ab96f1fa850d9ade291e186f70479883d9414cb64c55438", size = 5289, upload-time = "2025-08-26T05:31:24.986Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/9a/b65bb5f9c3a7fb0fc54b9689cd587228d1cc890f31157e55236987fb9205/elogpy-1.0.0-py3-none-any.whl", hash = "sha256:cec1a8fb0e69ac613f282ba2988fb970063358c78543166f79412b38f2bb77fe", size = 5386, upload-time = "2025-08-26T05:31:23.719Z" }, -] - [[package]] name = "exceptiongroup" version = "1.3.1" diff --git a/services/postmortemlog/current/app/pyproject.toml b/services/postmortemlog/current/app/pyproject.toml index dc6c4c3..d2dc249 100644 --- a/services/postmortemlog/current/app/pyproject.toml +++ b/services/postmortemlog/current/app/pyproject.toml @@ -5,6 +5,9 @@ description = "AGEBD-POSTMORTEMLOG Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "matplotlib>=3.10.9", + "numpy>=2.0.2", + "urllib3>=2.7.0", ] [dependency-groups] diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py index f0d50db..5c05f25 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/service.py @@ -1,49 +1,515 @@ import time -from epics import dbr +# https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings +import urllib3 -from agebd.pv import LocalPVLink +urllib3.disable_warnings() +import socket +from datetime import datetime +from time import perf_counter, sleep, time + +import elog +import matplotlib.pyplot as plt +import numpy as np +from epics import poll + +from agebd.h5 import h5save +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) PV = get_pv_class() +plt.switch_backend("agg") +plt.rcParams.update({"font.size": 18}) +plt.rcParams["axes.facecolor"] = "white" +plt.rcParams["figure.facecolor"] = "white" +plt.rcParams["lines.markersize"] = 1 +plt.rcParams["lines.linewidth"] = 0.2 + +EpicsTimestampStr2FileTimestampStr = lambda ts: datetime.strptime( + ts, "%Y-%m-%d %H:%M:%S.%f" +).strftime("%Y%m%d_%H%M%S") + class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-POSTMORTEMLOG:AO") # TODO: is this a good PV to use? + # # Generic Service Control PV + test = PV("AGEBD-POSTMORTEMLOG:TEST") + postdelay = PV("AGEBD-POSTMORTEMLOG:BEAM-ABORT-EVT.ODLY") - ## Service specific PVs from other IOCs - # ... + # Potential Service Callback PVs + bdcinputsum = PV("AGESA-SBDC-0000:SUM_INPUT_NOT_OK.VAL", auto_monitor=True) + bdcinputsum_latched = PV("AGESA-SBDC-0000:SUM_INPUT_NOT_OK_LATCHED.VAL", auto_monitor=True) + + # Minimum current condition + pctmaster = PV("ARS07-DPCT-0000:CURR.VAL") + + # Service Input PVs (Post Mortem Information) + bdc_interlocks = [ + PV("AGESA-SBDC-0000:CH{:02.0f}-INPUT_OK_LATCHED.VAL".format(i)) for i in range(21) + ] + bdc_delays = [PV("AGESA-SBDC-0000:CH{:02.0f}-DELAY.VAL".format(i)) for i in range(21)] + + pmioc_time = PV("ARS01-MKIK-0050-1:TRIG-CNT.VAL") + + vcs_alarmlist = PV("ARS00-VCS:PLC_AlarmList.VAL") + mis_alarmlist = PV("ARS00-MIS-PLC-01:AlarmList.VAL") + misfe_alarmlist = PV("ARS00-MIS-PLC-01:AlarmList_Frontends.VAL") + + # Counters + counter_bdc = PV("AGESA-SBDC-0000:INT-COUNTER.VAL", auto_monitor=True) + counter_dumpkicker = PV("ARS01-MKIK-0050-1:TRIG-CNT.VAL") + counter_tmaster_beamdump = PV("AGETI-CVME-MASTER-TMA:Evt-Beam-Dump-EVRCount-I.VAL") + counter_tmaster_postmortem = PV("AGETI-CVME-MASTER-TMA:Evt-PM-Rec-EVRCount-I.VAL") + + # Post Mortem Data as dict for easier access + PostMortemLinks = [ + ## BLMs + # IOC: ABODI-DFBL + PV("ABODI-DFBL:SigPm.A"), + PV("ABODI-DFBL:SigPm.B"), + PV("ABODI-DFBL:SigPm.C"), + PV("ABODI-DFBL:SigPm.D"), + # IOC: ARS01-DFBL + PV("ARS01-DFBL:SigPm.A"), + PV("ARS01-DFBL:SigPm.B"), + PV("ARS01-DFBL:SigPm.C"), + PV("ARS01-DFBL:SigPm.D"), + # IOC: ARS02-DFBL + PV("ARS02-DFBL:SigPm.A"), + PV("ARS02-DFBL:SigPm.B"), + PV("ARS02-DFBL:SigPm.C"), + PV("ARS02-DFBL:SigPm.D"), + # IOC: ARS06-DFBL + PV("ARS06-DFBL:SigPm.A"), + PV("ARS06-DFBL:SigPm.B"), + PV("ARS06-DFBL:SigPm.C"), + PV("ARS06-DFBL:SigPm.D"), + # IOC: ARS09-DFBL + PV("ARS09-DFBL:SigPm.A"), + PV("ARS09-DFBL:SigPm.B"), + PV("ARS09-DFBL:SigPm.C"), + PV("ARS09-DFBL:SigPm.D"), + ## 4 Kicker Bump + PV("ARS01-MKIK-0140:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0140:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0220:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0220:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0850:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0850:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0940:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0940:CURRENT-WF.VAL"), + ## Beam Dump Kicker + PV("ARS01-MKIK-0050-1:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0050-1:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0050-2:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0050-2:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0050-3:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0050-3:CURRENT-WF.VAL"), + PV("ARS01-MKIK-0050-4:TIME-AXIS.VAL"), + PV("ARS01-MKIK-0050-4:CURRENT-WF.VAL"), + ## Beam Dump Post Mortem Digitizer + PV("ARF-LPD64:X-AXIS-CH1.VAL"), + PV("ARF-LPD64:CH1-DATA.VAL"), + PV("ARF-LPD64:X-AXIS-CH2.VAL"), + PV("ARF-LPD64:CH2-DATA.VAL"), + PV("ARF-LPD64:X-AXIS-CH3.VAL"), + PV("ARF-LPD64:CH3-DATA.VAL"), + PV("ARF-LPD64:X-AXIS-CH4.VAL"), + PV("ARF-LPD64:CH4-DATA.VAL"), + PV("AGESA-SBDC-0000:BUNCH0_MAGNET_RAMP_DELAY.VAL"), + # ---------- FILLING PATTERN -------------- + PV("AGEBD-POSTMORTEMLOG:BUFFER-FILLPATTERN-APD.VAL"), + ] + # ---------- BPM Post Mortem Data -------------- + bpmnames = [ + "ARS01-DBPM-0390:", + "ARS01-DBPM-0760:", + "ARS01-DBPM-1080:", + "ARS01-DBPM-1460:", + "ARS01-DBPM-1900:", + "ARS01-DBPM-2410:", + "ARS01-DBPM-2910:", + "ARS01-DBPM-4220:", + "ARS01-DBPM-4720:", + "ARS01-DBPM-5250:", + "ARS01-DBPM-5530:", + "ARS01-DBPM-5880:", + "ARS02-DBPM-1080:", + "ARS02-DBPM-1460:", + "ARS02-DBPM-1900:", + "ARS02-DBPM-2410:", + "ARS02-DBPM-2910:", + "ARS02-DBPM-4220:", + "ARS02-DBPM-4720:", + "ARS02-DBPM-5250:", + "ARS02-DBPM-5530:", + "ARS02-DBPM-5880:", + "ARS03-DBPM-0810:", + "ARS03-DBPM-1080:", + "ARS03-DBPM-1460:", + "ARS03-DBPM-1900:", + "ARS03-DBPM-2410:", + "ARS03-DBPM-2910:", + "ARS03-DBPM-4220:", + "ARS03-DBPM-4720:", + "ARS03-DBPM-5250:", + "ARS03-DBPM-5530:", + "ARS03-DBPM-5880:", + "ARS04-DBPM-0090:", + "ARS04-DBPM-0900:", + "ARS04-DBPM-1080:", + "ARS04-DBPM-1460:", + "ARS04-DBPM-1900:", + "ARS04-DBPM-2410:", + "ARS04-DBPM-2910:", + "ARS04-DBPM-4220:", + "ARS04-DBPM-4720:", + "ARS04-DBPM-5250:", + "ARS04-DBPM-5530:", + "ARS04-DBPM-5880:", + "ARS05-DBPM-0410:", + "ARS05-DBPM-1080:", + "ARS05-DBPM-1460:", + "ARS05-DBPM-1900:", + "ARS05-DBPM-2410:", + "ARS05-DBPM-2910:", + "ARS05-DBPM-4220:", + "ARS05-DBPM-4720:", + "ARS05-DBPM-5250:", + "ARS05-DBPM-5530:", + "ARS05-DBPM-5880:", + "ARS06-DBPM-1080:", + "ARS06-DBPM-1460:", + "ARS06-DBPM-1900:", + "ARS06-DBPM-2410:", + "ARS06-DBPM-2910:", + "ARS06-DBPM-4220:", + "ARS06-DBPM-4720:", + "ARS06-DBPM-5250:", + "ARS06-DBPM-5530:", + "ARS06-DBPM-5880:", + "ARS07-DBPM-0810:", + "ARS07-DBPM-0840:", + "ARS07-DBPM-1080:", + "ARS07-DBPM-1460:", + "ARS07-DBPM-1900:", + "ARS07-DBPM-2410:", + "ARS07-DBPM-2910:", + "ARS07-DBPM-4220:", + "ARS07-DBPM-4720:", + "ARS07-DBPM-5250:", + "ARS07-DBPM-5530:", + "ARS07-DBPM-5880:", + "ARS08-DBPM-1080:", + "ARS08-DBPM-1460:", + "ARS08-DBPM-1900:", + "ARS08-DBPM-2410:", + "ARS08-DBPM-2910:", + "ARS08-DBPM-4220:", + "ARS08-DBPM-4720:", + "ARS08-DBPM-5250:", + "ARS08-DBPM-5530:", + "ARS08-DBPM-5880:", + "ARS09-DBPM-0570:", + "ARS09-DBPM-1080:", + "ARS09-DBPM-1460:", + "ARS09-DBPM-1900:", + "ARS09-DBPM-2410:", + "ARS09-DBPM-2910:", + "ARS09-DBPM-4220:", + "ARS09-DBPM-4720:", + "ARS09-DBPM-5250:", + "ARS09-DBPM-5530:", + "ARS09-DBPM-5880:", + "ARS10-DBPM-1080:", + "ARS10-DBPM-1460:", + "ARS10-DBPM-1900:", + "ARS10-DBPM-2410:", + "ARS10-DBPM-2910:", + "ARS10-DBPM-4220:", + "ARS10-DBPM-4720:", + "ARS10-DBPM-5250:", + "ARS10-DBPM-5530:", + "ARS10-DBPM-5880:", + "ARS11-DBPM-0850:", + "ARS11-DBPM-1080:", + "ARS11-DBPM-1460:", + "ARS11-DBPM-1900:", + "ARS11-DBPM-2410:", + "ARS11-DBPM-2910:", + "ARS11-DBPM-4220:", + "ARS11-DBPM-4720:", + "ARS11-DBPM-5250:", + "ARS11-DBPM-5530:", + "ARS11-DBPM-5880:", + "ARS12-DBPM-1080:", + "ARS12-DBPM-1460:", + "ARS12-DBPM-1900:", + "ARS12-DBPM-2410:", + "ARS12-DBPM-2910:", + "ARS12-DBPM-4220:", + "ARS12-DBPM-4720:", + "ARS12-DBPM-5250:", + "ARS12-DBPM-5530:", + "ARS12-DBPM-5880:", + ] + for bpm in bpmnames: + for q in ["X", "Y", "Q"]: + bpmpvname = bpm + "PM-DATA-BEAM-" + q + PostMortemLinks.append(PV(bpmpvname)) + + # MBFB modes + # state of injection, state of pulsed magnets + + ## CIRCULAR BUFFER Records from POST MORTEM IOC + names_circ_buffer_ioc = [ + # ---------- BEAM CURRENT -------------- + "CURRPCT", + "CURRBPM", + # ---------- BEAM LIFETIME -------------- + "TAUBPM", + "TAUPCT", + # ---------- TUNES -------------- + "QX", + "QY", + "QZ", + # ---------- BEAM SIZE -------------- + "X01DD-SIGX", + "X01DD-SIGY", + "X08DB-SIGX", + "X08DB-SIGY", + # ---------- RF -------------- + "MASTERFREQ-GET", + "MASTERFREQ-SET", + "RFPOW-0140-INP", + "RFPOW-0060-INP", + "RFPOW-0230-INP", + "RFPOW-0310-INP", + "RFPOW-0060-REF", + "RFPOW-0140-REF", + "RFPOW-0230-REF", + "RFPOW-0310-REF", + # ---------- RADFETS -------------- + "ARS01-DDRM-0375", # Directly downstream of beam dump + "ABRTL-DDRM-0670", # ABRTL upstream of thick septum (also downstream of beam dump) + "ABRTL-DDRM-0950", # ABRTL downstream of thick septum + "ARS01-DDRM-1530", # End of matching section downstream of X01 (injection straight) + "X05LA-DDRM-0330", # Directly downstream of collimators 5 + "ARS05-DDRM-1530", # End of matching section downstream of X05 (main RF and collimators 5) + "ARS05-DDRM-3500", # Center dipole of arc 5 + "X09LA-DDRM-0330", + "ARS05-VMCC-0210", + "ARS05-VMCC-0215", + "ARS05-VMCC-0310", + "ARS05-VMCC-0315", # Directly downstream of collimators 9 + "ARS09-DDRM-1530", # End of matching section downstream of X09 (3HC and collimators 9) + "ARS09-DDRM-3500", # Center dipole of arc 9 + "ARS12-DDRM-1530", # End of matching section downstream of X12 (beginning of last arc) + "ARS12-DDRM-3500", # Center dipole of arc 12 + "ARS12-DDRM-4400", # Fifth dipole of arc 12 + "ARS12-DDRM-5480", # Start of matching section upstream of X01 (end of last arc) + # ---------- VACUUM -------------- + "VACMAX", + "VACMAXFE", + "ARS01-VMCC-0110", + "ARS01-VMCC-0210", + "ARS01-VMCC-0225", + "ARS01-VMCC-0310", + "ARS01-VMCC-1550", + "ARS01-VMCC-3510", + "ARS01-VMCC-5460", + "ARS02-VMCC-0110", + "ARS02-VMCC-0210", + "ARS02-VMCC-0310", + "ARS02-VMCC-1550", + "ARS02-VMCC-3510", + "ARS02-VMCC-5460", + "ARS03-VMCC-0110", + "ARS03-VMCC-0320", + "ARS03-VMCC-1550", + "ARS03-VMCC-3510", + "ARS03-VMCC-5460", + "ARS04-VMCC-0110", + "ARS04-VMCC-1550", + "ARS04-VMCC-3510", + "ARS04-VMCC-5460", + "ARS05-VMCC-0110", + "ARS05-VMCC-0115", + "ARS05-VMCC-0210", + "ARS05-VMCC-0215", + "ARS05-VMCC-0310", + "ARS05-VMCC-0315", + "ARS05-VMCC-0410", + "ARS05-VMCC-0415", + "ARS05-VMCC-0510", + "ARS05-VMCC-0520", + "ARS05-VMCC-0530", + "ARS05-VMCC-0810", + "ARS05-VMCC-1550", + "ARS05-VMCC-3510", + "ARS05-VMCC-5460", + "ARS06-VMCC-0110", + "ARS06-VMCC-1550", + "ARS06-VMCC-3510", + "ARS06-VMCC-5460", + "ARS07-VMCC-0010", + "ARS07-VMCC-0120", + "ARS07-VMCC-0210", + "ARS07-VMCC-1550", + "ARS09-VMCC-0510", + "ARS09-VMCC-0810", + "ARS07-VMCC-3510", + "ARS07-VMCC-5460", + "ARS08-VMCC-0110", + "ARS08-VMCC-1550", + "ARS08-VMCC-3510", + "ARS08-VMCC-5460", + "ARS09-VMCC-0110", + "ARS09-VMCC-0120", + "ARS09-VMCC-0410", + "ARS09-VMCC-0510", + "ARS09-VMCC-0810", + "ARS09-VMCC-1550", + "ARS09-VMCC-3510", + "ARS09-VMCC-5460", + "ARS10-VMCC-0110", + "ARS10-VMCC-1550", + "ARS10-VMCC-3510", + "ARS10-VMCC-5460", + "ARS11-VMCC-0110", + "ARS11-VMCC-0210", + "ARS11-VMCC-0310", + "ARS11-VMCC-0410", + "ARS11-VMCC-0510", + "ARS11-VMCC-1550", + "ARS11-VMCC-3510", + "ARS11-VMCC-5460", + "ARS12-VMCC-0110", + "ARS12-VMCC-1550", + "ARS12-VMCC-3510", + "ARS12-VMCC-5460", + ] + + for pvname in names_circ_buffer_ioc: + pvname = "AGEBD-POSTMORTEMLOG:BUFFER-" + pvname + "-LAST.VAL" + PostMortemLinks.append(PV(pvname)) + + # Prepare machine for accumulation + master_trig = PV("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") + reset_bucket = PV("AGEBD-TIMING:ZERO-TARGET-BUCKET.VAL") + ID_gap_ena = PV("AGEOP-STATUS:LIGHT-DELIVERY.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True + self.CallbackPV = PV("AGESA-SBDC-0000:INT-COUNTER.VAL", auto_monitor=True) - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-POSTMORTEMLOG:BO" - ) # TODO: is this a good PV to use? - ## Service specific PVs from other IOCs - # ... +class vals: + bdc_channels = np.array( + [ # see https://git.psi.ch/epics_iocboot_sls/A_MPS/-/blob/main/AGESA-CECL-BDC/AGESA-CECL-BDC_main.subs + "Manual EPICS Beam Dump", # 00 + "LLRF for Storage Ring Cavity 1", # 01 + "LLRF for Storage Ring Cavity 2", # 02 + "LLRF for Storage Ring Cavity 3", # 03 + "LLRF for Storage Ring Cavity 4", # 04 + "LLRF for Super Conducting 3HC", # 05 + "Orbit Deviation", # 06 + "FOFB", # 07 + "Horizontal Multi Bunch Instability", # 08 + "Vertical Multi Bunch Instability", # 09 + "Longitudinal Multi Bunch Instabil", # 10 + "Filling Patern Deviation", # 11 + "Quench of Super Conducting Super Bend", # 12 + "Quench of High Temperature Super Conducting Undulator", # 13 + "PSYS", # 14 + "Vacuum", # 15 + "Machine Interlock System", # 16 + "Rapid Storage Ring Current Drop", # 17 + "Beam Dump Kicker", # 18 + "SLS A/C Power", # 19 + "Control Room Emergency Dump", # 20 + ] + ) - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-POSTMORTEMLOG:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + +def htmltable(data, header=False): + + table = [] + table.append('') # overall table design + + if header: + header = data[0] + table.append('') # header row design + + for cell in header: + table.append(''.format(cell)) # header cell design + + table.append("") + data = data[1:] + + for i, row in enumerate(data): + if i % 2 == 0: + table.append('') # even row design + else: + table.append('') # odd row design + + for cell in row: + table.append(''.format(cell)) # data cell design + + table.append("") + + table.append("
{:}
{:}
") + + return "".join(table) + + +def mysleep(seconds): + + t0 = perf_counter() + wait = True + + while wait: + wait = perf_counter() - t0 < seconds + + +def get_scopetime(): + + # scope address + scope = "LPD64-B031482.psi.ch" + port = 4000 + + # cmd for timestamp retrieval + cmd = "HORizontal:FASTframe:TIMEStamp:ALL?\n" + + # Create a TCP socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(5) # Timeout in seconds + + try: + sock.connect((scope, port)) + sock.sendall(cmd.encode()) + + # Read the response + response = sock.recv(1024).decode().strip() + + except Exception as e: + response = f"Error: {e:}" + finally: + sock.close() + + # get time string by truncating response from index of fastfframe and quotation marks + date_str = response[4:-1] + # truncate useless nanoseconds to be compaticble with datetime + date_str = date_str[:-6] + # creat datetimeobject + date_obj = datetime.strptime(date_str, "%d.%m.%Y.%H:%M:%S.%f") + return date_obj.strftime("%Y-%m-%d %H:%M:%S.%f") class Service(BaseService[PVs]): @@ -56,38 +522,1218 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.logbook = elog.open( + "https://elog-gfa.psi.ch/SLS/", + user="robot", + password="robot", + use_ssl=True, + ) + + # Counters + self.counter_bdc_last = pvs.counter_bdc.get() + self.counter_dumpkicker_last = pvs.counter_dumpkicker.get() + self.counter_tmaster_beamdump_last = pvs.counter_tmaster_beamdump.get() + self.counter_tmaster_postmortem_last = pvs.counter_tmaster_postmortem.get() + + self.curr = np.zeros(10) + self.Tshift = pvs.postdelay.get() def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs + + curr = pvs.pctmaster.get() + + if curr != self.curr[-1]: + self.curr[:-1] = self.curr[1:] + self.curr[-1] = curr + + if pvs.test.get(): + self.test = True + else: + self.test = False + + # when callback fired and threshold current exceeded, write elog entry + if self.CallbackFired and np.nanmax(self.curr) > 3 or self.test: + # start stop watch + t0 = perf_counter() + + # get timestamps + self.t0_hla = str(datetime.fromtimestamp(time())) + + # prepare elog config and perform some machine actions depending on real or test interlock + if self.test: + self.suppress_email_notification = True + pvs.test.put(0) + print("Post mortem test request detected...") + else: + pvs.master_trig.put(0) + pvs.ID_gap_ena.put(1) + pvs.reset_bucket.put(1) + self.suppress_email_notification = False + print("Interlock beam dump detected...") + + # wait for BDC latch to show interlocks + print(" ...waiting for BDC...") + while not pvs.bdcinputsum_latched.get() > 0 and perf_counter() - t0 < self.Tshift: + self.alive() + poll(evt=1.0e-5, iot=0.1) + + # get BDC data + self.interlocks = np.array([interlock.get() for interlock in pvs.bdc_interlocks]) + self.delays = np.array([delay.get() for delay in pvs.bdc_delays]) + + # get PLC alarm lists + self.vcs_alarmlist = pvs.vcs_alarmlist.get(as_string=True).split("\n") + self.mis_alarmlist = pvs.mis_alarmlist.get(as_string=True).split("\n") + self.misfe_alarmlist = pvs.misfe_alarmlist.get(as_string=True).split("\n") + + # wait for BDC to get reset or posttrigger time tshift to pass + print(" ...waiting for all interlocks...") + while pvs.bdcinputsum_latched.get() > 0 and perf_counter() - t0 < self.Tshift: + self.alive() + + # check for additional interlock requests to BDC + interlocks = np.array([interlock.get() for interlock in pvs.bdc_interlocks]) + delays = np.array([delay.get() for delay in pvs.bdc_delays]) + if len(np.flatnonzero(interlocks)) > len(np.flatnonzero(self.interlocks)): + self.interlocks = interlocks + self.delays = delays + + # check for additional alarms in PLC alarm lists + vcs_alarmlist = pvs.vcs_alarmlist.get(as_string=True).split("\n") + if len(vcs_alarmlist) > len(self.vcs_alarmlist): + self.vcs_alarmlist = vcs_alarmlist + mis_alarmlist = pvs.mis_alarmlist.get(as_string=True).split("\n") + if len(mis_alarmlist) > len(self.mis_alarmlist): + self.mis_alarmlist = mis_alarmlist + misfe_alarmlist = pvs.misfe_alarmlist.get(as_string=True).split("\n") + if len(misfe_alarmlist) > len(self.misfe_alarmlist): + self.misfe_alarmlist = misfe_alarmlist + + sleep(0.1) + + # make sure that post trigger delay time has passed + while perf_counter() - t0 < self.Tshift: + self.alive() + # wait for time to pass + mysleep(0.01) + mysleep(1) + self.alive() + + # get EPICS post mortem data including postdelay data after dump + self.PMD = {} + for pv in pvs.PostMortemLinks: + pvname = pv.pvname.removesuffix(".VAL") + pvname = pvname.removesuffix("-LAST") + if not pv.connected: + self.PMD[pvname] = np.ones(2) * np.nan + print(" pv not connected: {:}".format(pvname)) + else: + if pvname == "AGEBD-POSTMORTEMLOG:BUFFER-FILLPATTERN-APD": + self.PMD[pvname] = np.reshape(pv.get(), (int(432000 / 480), 480)) + else: + self.PMD[pvname] = pv.get() + self.PMD[pvname + ".timestamp"] = str(datetime.fromtimestamp(pv.timestamp)) + self.t0_pmioc = self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-CURRPCT.timestamp"] + self.t0_pmlpd64 = get_scopetime() + + # if PM IOC is running since at least 15 minutes: NSAM = 9000, SCAN = 0.1 + Npts = len(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-CURRPCT"]) + dt = 0.1 + T = Npts * dt + self.t = np.linspace(-T + self.Tshift, -dt + self.Tshift, Npts) + + Npts = len(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-FILLPATTERN-APD"]) + dt = 1 + T = Npts * dt + self.t2 = np.linspace(-T + self.Tshift, -dt + self.Tshift, Npts) + + self.counter_bdc = pvs.counter_bdc.get() + self.t0_bdc = str(datetime.fromtimestamp(pvs.counter_bdc.timestamp)) + self.counter_dumpkicker = pvs.counter_dumpkicker.get() + self.counter_tmaster_beamdump = pvs.counter_tmaster_beamdump.get() + self.counter_tmaster_postmortem = pvs.counter_tmaster_postmortem.get() + + Npost = int(self.Tshift / 0.1) + self.DRMs = { + pvname[27:]: value + for pvname, value in self.PMD.items() + if "-DDRM-" in pvname and not ".timestamp" in pvname + } + self.DRMs_i = { + DRM: np.nanmin(DRMarray[-Npost - 15 : -Npost - 5]) + for DRM, DRMarray in self.DRMs.items() + } + self.DRMs_f = { + DRM: np.nanmax(DRMarray[-Npost - 5 :]) for DRM, DRMarray in self.DRMs.items() + } + self.DRMs_d = { + DRM: np.nanmax(np.array([0, self.DRMs_f[DRM] - self.DRMs_i[DRM]])) + for DRM in self.DRMs + } # difference with negative values mapped to 0 + self.DRMs_sum = np.nansum(np.array([self.DRMs_d[DRM] for DRM in self.DRMs])) + self.DRMs_p = {DRM: 100 * self.DRMs_d[DRM] / self.DRMs_sum for DRM in self.DRMs} + + self.logtxt = [] + + # Beam Dump Controller Log + print("self.interlocks, ", self.interlocks) + print("self.delays, ", self.delays) + self.index1 = np.flatnonzero(self.interlocks) + print("self.index1", self.index1) + self.index2 = np.argsort(self.delays[self.index1]) + print("self.index2", self.index2) + + if self.test: + self.firstinterlock = "Test" + elif len(self.index1) == 0: + self.firstinterlock = "BDC Readout Issue" + else: + self.firstinterlock = vals.bdc_channels[self.index1][ + self.index2[0] + ] # This lines often crashes + + print(" ...interlock triggered by {:}...".format(self.firstinterlock)) + + self.bdc_delays = [ + "{:.2f} µs".format(self.delays[self.index1][i]) for i in self.index2 + ] + self.bdc_channel_description = [ + "{:}".format(vals.bdc_channels[self.index1][i]) for i in self.index2 + ] + self.bdc_channel_nr = ["{:02}".format(self.index1[i]) for i in self.index2] + + self.logtxt.append("

Beam Dump Controller

") + self.logtxt.append( + htmltable( + [["Delay", "Description", "Channel Nr."]] + + [ + [ + "{:.2f} µs".format(self.delays[self.index1][i]), + "{:}".format(vals.bdc_channels[self.index1][i]), + "{:02}".format(self.index1[i]), + ] + for i in self.index2 + ], + header=True, + ) + ) + + self.alive() + + # VCS Alarm List + self.logtxt.append("

VCS

") + self.logtxt.append(self.vcs_alarmlist[0]) + ( + self.vcs_alarmlist_alarmindex, + self.vcs_alarmlist_timestamps, + self.vcs_alarmlist_descriptions, + ) = self.GascheLines2HTMLtable(self.vcs_alarmlist[2:]) + + self.alive() + + # MIS Alarm List + self.logtxt.append("

MIS

") + self.logtxt.append(self.mis_alarmlist[0]) + ( + self.mis_alarmlist_alarmindex, + self.mis_alarmlist_timestamps, + self.mis_alarmlist_descriptions, + ) = self.GascheLines2HTMLtable(self.mis_alarmlist[2:]) + + self.alive() + + # MIS-FE Alarm List + self.logtxt.append("

MIS-FE

") + self.logtxt.append(self.misfe_alarmlist[0]) + ( + self.misfe_alarmlist_alarmindex, + self.misfe_alarmlist_timestamps, + self.misfe_alarmlist_descriptions, + ) = self.GascheLines2HTMLtable(self.misfe_alarmlist[2:]) + + self.alive() + + # RadFETs + drmdat = lambda DRM: [ + "{:.4f}".format(self.DRMs_i[DRM]), + "{:.4f}".format(self.DRMs_f[DRM]), + "{:.4f}".format(self.DRMs_d[DRM]), + "{:.2f}".format(self.DRMs_p[DRM]), + ] + self.logtxt.append("

RadFETs

") + self.logtxt.append( + htmltable( + [ + [ + "PV", + "Description", + "Before Dump / Gy", + "After Dump / Gy", + "Delta / Gy", + "Distribution / %", + ], + ["ARS01-DDRM-0375", "Directly downstream of beam dump"] + + drmdat("ARS01-DDRM-0375"), + [ + "ABRTL-DDRM-0670", + "ABRTL upstream of thick septum (also downstream of beam dump)", + ] + + drmdat("ABRTL-DDRM-0670"), + ["ABRTL-DDRM-0950", "ABRTL downstream of thick septum"] + + drmdat("ABRTL-DDRM-0950"), + [ + "ARS01-DDRM-1530", + "End of matching section downstream of X01 (injection straight)", + ] + + drmdat("ARS01-DDRM-1530"), + ["X05LA-DDRM-0330", "Directly downstream of collimators 5"] + + drmdat("X05LA-DDRM-0330"), + [ + "ARS05-DDRM-1530", + "End of matching section downstream of X05 (main RF and collimators 5)", + ] + + drmdat("ARS05-DDRM-1530"), + ["ARS05-DDRM-3500", "Center dipole of arc 5"] + drmdat("ARS05-DDRM-3500"), + ["X09LA-DDRM-0330", "Directly downstream of collimators 9"] + + drmdat("X09LA-DDRM-0330"), + [ + "ARS09-DDRM-1530", + "End of matching section downstream of X09 (3HC and collimators 9)", + ] + + drmdat("ARS09-DDRM-1530"), + ["ARS09-DDRM-3500", "Center dipole of arc 9 "] + drmdat("ARS09-DDRM-3500"), + [ + "ARS12-DDRM-1530", + "End of matching section downstream of X12 (beginning of last arc)", + ] + + drmdat("ARS12-DDRM-1530"), + ["ARS12-DDRM-3500", "Center dipole of arc 12"] + drmdat("ARS12-DDRM-3500"), + ["ARS12-DDRM-4400", "Fifth dipole of arc 12"] + drmdat("ARS12-DDRM-4400"), + [ + "ARS12-DDRM-5480", + "Start of matching section upstream of X01 (end of last arc)", + ] + + drmdat("ARS12-DDRM-5480"), + ], + header=True, + ) + ) + + self.alive() + + # Timestamps + self.logtxt.append("

Timestamps

") + self.logtxt.append( + htmltable( + [ + ["BDC Timestamp", "{:}".format(str(self.t0_bdc)[:-3])], + ["HLA Timestamp", "{:}".format(str(self.t0_hla)[:-3])], + ["PM IOC Timestamp", "{:}".format(str(self.t0_pmioc)[:-3])], + ["PM Scope LPD64", "{:}".format(str(self.t0_pmlpd64)[:-3])], + ], + header=False, + ) + ) + + # Counters + self.logtxt.append("

Counters

") + self.logtxt.append( + htmltable( + [ + ["Counter", "Value", "Last Value", "Delta"], + [ + "BDC Dump Counter", + "{:.0f}".format(self.counter_bdc), + "{:.0f}".format(self.counter_bdc_last), + "{:.0f}".format(self.counter_bdc - self.counter_bdc_last), + ], + [ + "Beam Dump Kicker Counter", + "{:.0f}".format(self.counter_dumpkicker), + "{:.0f}".format(self.counter_dumpkicker_last), + "{:.0f}".format(self.counter_dumpkicker - self.counter_dumpkicker_last), + ], + [ + "Beam Dump Event Counter", + "{:.0f}".format(self.counter_tmaster_beamdump), + "{:.0f}".format(self.counter_tmaster_beamdump_last), + "{:.0f}".format( + self.counter_tmaster_beamdump - self.counter_tmaster_beamdump_last + ), + ], + [ + "Post Mortem Event Counter", + "{:.0f}".format(self.counter_tmaster_postmortem), + "{:.0f}".format(self.counter_tmaster_postmortem_last), + "{:.0f}".format( + self.counter_tmaster_postmortem + - self.counter_tmaster_postmortem_last + ), + ], + ], + header=True, + ) + ) + + self.counter_bdc_last = self.counter_bdc + self.counter_dumpkicker_last = self.counter_dumpkicker + self.counter_tmaster_beamdump_last = self.counter_tmaster_beamdump + self.counter_tmaster_postmortem_last = self.counter_tmaster_postmortem + + self.alive() + + # assign dump to system + if self.firstinterlock in [ + "LLRF for Storage Ring Cavity 1", + "LLRF for Storage Ring Cavity 2", + "LLRF for Storage Ring Cavity 3", + "LLRF for Storage Ring Cavity 4", + "LLRF for Super Conducting 3HC", + ]: + system = "HF" + elif self.firstinterlock in ["Orbit Deviation"]: + system = "BPMs" + elif self.firstinterlock in [ + "FOFB", + "Horizontal Multi Bunch Instability", + "Vertical Multi Bunch Instability", + "Longitudinal Multi Bunch Instabil", + "Filling Patern Deviation", + ]: + system = "Feedbacks" + elif self.firstinterlock in ["Vacuum"]: + system = "Vakuum" + elif self.firstinterlock in ["PSYS"]: + system = "PSYS" + elif self.firstinterlock in ["Machine Interlock System"]: + system = "MachineInterlockSystem" + elif self.firstinterlock in ["Test"]: + system = "Test" + else: + system = "Unbekannt" + + # prepare plots for attachment + fig1 = self.makeplots() + + self.alive() + + try: + fig2 = self.lpd64plot() + file2 = "/sls/op/data/applications/postmortem/{:}_BeamDumpLPD64.png".format( + EpicsTimestampStr2FileTimestampStr(self.t0_hla) + ) + fig2.savefig(file2, dpi=192, bbox_inches="tight") + file2 = [file2] + plt.close(fig2) + except: + file2 = [] + print("LPD64 plot failed") + + self.alive() + + file1 = "/sls/op/data/applications/postmortem/{:}_PostMortem.png".format( + EpicsTimestampStr2FileTimestampStr(self.t0_hla) + ) + fig1.savefig(file1, dpi=192, bbox_inches="tight") + self.list_of_attachments = file2 + [file1] + plt.close(fig1) + + self.alive() + + # prepare data file + if self.test: + file3 = "/sls/op/data/applications/postmortem/{:}_PostMortem_Test.h5".format( + EpicsTimestampStr2FileTimestampStr(self.t0_hla) + ) + else: + file3 = "/sls/op/data/applications/postmortem/{:}_PostMortem.h5".format( + EpicsTimestampStr2FileTimestampStr(self.t0_hla) + ) + data = { + "t0_hla": self.t0_hla, + "t0_pmioc": self.t0_pmioc, + "t0_bdc": self.t0_bdc, + "t0_lpd64": self.t0_pmlpd64, + "t": self.t, + "t2": self.t2, + "bdc_delays": self.bdc_delays, + "bdc_channel_description": self.bdc_channel_description, + "bdc_channel_nr": self.bdc_channel_nr, + "counter_bdc": self.counter_bdc, + "counter_dumpkicker": self.counter_dumpkicker, + "counter_tmaster_beamdump": self.counter_tmaster_beamdump, + "counter_tmaster_postmortem": self.counter_tmaster_postmortem, + "vcs_alarmlist_infostring": self.vcs_alarmlist[0], + "vcs_alarmlist_alarmindex": self.vcs_alarmlist_alarmindex, + "vcs_alarmlist_timestamps": self.vcs_alarmlist_timestamps, + "vcs_alarmlist_descriptions": self.vcs_alarmlist_descriptions, + "mis_alarmlist_infostring": self.mis_alarmlist[0], + "mis_alarmlist_alarmindex": self.mis_alarmlist_alarmindex, + "mis_alarmlist_timestamps": self.mis_alarmlist_timestamps, + "mis_alarmlist_descriptions": self.mis_alarmlist_descriptions, + "misfe_alarmlist_infostring": self.misfe_alarmlist[0], + "misfe_alarmlist_alarmindex": self.misfe_alarmlist_alarmindex, + "misfe_alarmlist_timestamps": self.misfe_alarmlist_timestamps, + "misfe_alarmlist_descriptions": self.misfe_alarmlist_descriptions, + } + data.update(self.PMD) + + self.alive() + + # Write to elog + self.logtxt = "".join(self.logtxt) + + self.dict_of_attributes = { + "Wann": time(), + "Autor": "Post Mortem Logger", + "Eintrag": "Post Mortem", + "Effekt": "Downtime", + "System": "{:}".format(system), + "Titel": "Interlock Beam Dump {:.0f}, {:.0f} mA".format( + self.counter_bdc, np.nanmax(self.curr) + ), + "Encoding": "html", + } + + self.alive() + + print(" ...elog entry prepared...") + + self.msg_id = self.logbook.post( + self.logtxt, + attributes=self.dict_of_attributes, + attachments=self.list_of_attachments, + suppress_email_notification=self.suppress_email_notification, + attribute_as_param="value", + ) + print(" ...elog entry submitted...") + + self.alive() + + h5save(file3, data, timestamp=False) + print(" {:}".format(file3)) + print(" ...post mortem data saved") - # callback done self.CallbackFired = 0 - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + elif self.CallbackFired: + print("Beam dump below threshold current detected.") + # upate counters for beamdumps from below threshold beam current + self.counter_bdc_last = pvs.counter_bdc.get() + self.counter_dumpkicker_last = pvs.counter_dumpkicker.get() + self.counter_tmaster_beamdump_last = pvs.counter_tmaster_beamdump.get() + self.counter_tmaster_postmortem_last = pvs.counter_tmaster_postmortem.get() + self.CallbackFired = 0 - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + def alive(self): + # inform watchdog(s) for service run/main state + self.pvs.running.put(0) + self.pvs.alive.put(0) - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + def GascheLines2HTMLtable(self, lines): - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + timestamps = [ + ( + datetime.strptime(line[6:30], "%Y-%m-%d %H:%M:%S.%f") - datetime(1970, 1, 1) + ).total_seconds() + for line in lines + ] + sortindex = np.argsort(timestamps) + + alarmindex = [lines[i][1:4] for i in sortindex] + timestamps = [lines[i][6:30] for i in sortindex] + descriptions = [lines[i][33:] for i in sortindex] + + self.logtxt.append( + htmltable( + [["Alarm", "Timestamp", "Description"]] + + [[lines[i][1:4], lines[i][6:30], lines[i][33:]] for i in sortindex], + header=True, + ) + ) + + return alarmindex, timestamps, descriptions + + def makeplots(self): + + # prepare figure + Nplotrows = 14 + Nplotcols = 1 + bbox = (1.1, 1) + fig = plt.figure(figsize=(20, 6 * (Nplotrows + 4)), constrained_layout=True) + height_ratios = np.ones(Nplotrows) + height_ratios[4] = 3 + height_ratios[5] = 3 + GS = fig.add_gridspec(Nplotrows, Nplotcols, height_ratios=list(height_ratios)) + + self.alive() + # Beam Current and Lifetime + index = 0 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-CURRBPM"], + "-xg", + label="AGEBD-DBPM3CURR:CURRENT-AVG", + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-CURRPCT"], + "-x", + color="lawngreen", + label="ARS07-DPCT-0000:CURR", + ) + ax.tick_params(axis="y", colors="g", which="both") + ax.set_ylabel("Beam current / mA", color="g") + ax.set_xlim([self.t[0], self.t[-1]]) + + ax2 = ax.twinx() + ax2.plot(self.t, self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-TAUBPM"], "-xb", label="TAUBPM") + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-TAUPCT"], + "-x", + color="cornflowerblue", + label="TAUPCT", + ) + ax2.tick_params(axis="y", colors="b", which="both") + lines, labels = ax.get_legend_handles_labels() + lines2, labels2 = ax2.get_legend_handles_labels() + lgnd = ax2.legend(lines + lines2, labels + labels2, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax2.set_ylabel("Beam lifetime / hours", color="b") + ax2.set_xlim([self.t[0], self.t[-1]]) + ax2.set_ylim([0, 25]) + + self.alive() + # Tunes + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-QX"], + "-x", + color="#2A63E4", + label="AGEBD-TUNEBUMP:QX", + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-QY"], + "-x", + color="#8B1A96", + label="AGEBD-TUNEBUMP:QY", + ) + ax.set_ylabel("Transverse Tunes") + ax.set_xlim([self.t[0], self.t[-1]]) + ax2 = ax.twinx() + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-QZ"], + "-x", + color="#cd6100", + label="GEBD-TUNEBUMP:QZ", + ) + ax2.set_ylabel("Synchrotron Tune") + lines, labels = ax.get_legend_handles_labels() + lines2, labels2 = ax2.get_legend_handles_labels() + lgnd = ax2.legend(lines + lines2, labels + labels2, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + + self.alive() + # Beam Size X01DD + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGY"], + "-x", + color="#8B1A96", + label="$\langle\sigma_y\\rangle$={:.1f} µm".format( + np.nanmean(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGY"]) + ), + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGX"], + "-x", + color="#2A63E4", + label="$\langle\sigma_x\\rangle$={:.1f} µm".format( + np.nanmean(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X01DD-SIGX"]) + ), + ) + lines, labels = ax.get_legend_handles_labels() + lgnd = ax.legend(lines, labels, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("FZP beam size X01DD / µm") + ax.set_xlim([self.t[0], self.t[-1]]) + ax.set_ylim([0, 30]) + + self.alive() + # Beam Size X08DB + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGY"], + "-x", + color="#8B1A96", + label="$\langle\sigma_y\\rangle$={:.1f} µm".format( + np.nanmean(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGY"]) + ), + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGX"], + "-x", + color="#2A63E4", + label="$\langle\sigma_x\\rangle$={:.1f} µm".format( + np.nanmean(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-X08DB-SIGX"]) + ), + ) + lines, labels = ax.get_legend_handles_labels() + lgnd = ax.legend(lines, labels, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("FZP beam size X08DB / µm") + ax.set_xlim([self.t[0], self.t[-1]]) + ax.set_ylim([0, 30]) + + self.alive() + # Highest Vacuum Pressure for Machine and Frontend + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-VACMAX"], + "-xy", + label="ARIVA-VMAVE:PRESS-MAX", + ) + ax.tick_params(axis="y", colors="y", which="both") + ax.set_ylabel("Vacuum pressure / mbar", color="y") + ax.set_xlim([self.t[0], self.t[-1]]) + + ax2 = ax.twinx() + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-VACMAXFE"], + "-x", + color="orange", + label="ARIVA-VMAVE-FE:PRESS-MAX", + ) + ax2.tick_params(axis="y", colors="orange", which="both") + lines, labels = ax.get_legend_handles_labels() + lines2, labels2 = ax2.get_legend_handles_labels() + lgnd = ax2.legend(lines + lines2, labels + labels2, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax2.set_ylabel("Vacuum pressure / mbar", color="orange") + ax2.set_xlim([self.t[0], self.t[-1]]) + + self.alive() + # Absolute Machine Vacuum Peaks + index += 1 + ax = fig.add_subplot(GS[index]) + + names_macvac = [key for key in self.PMD if "-VMCC-" in key and not ".timestamp" in key] + ranking = np.zeros(len(names_macvac)) + + for i, pvname in enumerate(names_macvac): + ranking[i] = np.nanmax(self.PMD[pvname]) + + for i in np.argsort(ranking)[::-1]: + pvname = names_macvac[i] + ax.semilogy( + self.t, + self.PMD[pvname], + label="{:}, $p_{{max}}=$ {:.1e}".format(pvname[27:], ranking[i]), + ) + + ax.set_ylabel("Sorted machine vacuum pressure") + ax.set_xlim([self.t[0], self.t[-1]]) + ax.legend(loc="upper left", bbox_to_anchor=bbox, ncol=2) + + self.alive() + # Relative Machine Vacuum Peaks + index += 1 + ax = fig.add_subplot(GS[index]) + + datarel = {} + ranking = np.zeros(len(names_macvac)) + + for i, pvname in enumerate(names_macvac): + datarel[pvname] = self.PMD[pvname] / np.nanmin(self.PMD[pvname]) + ranking[i] = np.nanmax(datarel[pvname]) + + for i in np.argsort(ranking)[::-1]: + pvname = names_macvac[i] + ax.plot( + self.t, + datarel[pvname], + label="{:}, $\delta_{{max}}=$ {:.1f}".format(pvname[27:], ranking[i]), + ) + + ax.set_ylabel("Sorted relative vacuum pressure change, $\delta_{{max}}=max(p/p_{{min}})$ ") + ax.set_ylim([1, np.nanmax(ranking)]) + ax.set_xlim([self.t[0], self.t[-1]]) + ax.legend(loc="upper left", bbox_to_anchor=bbox, ncol=2) + + self.alive() + # RF Master Oscillator Frequency + rf_ref = 499652000 + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + rf_ref - self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-MASTERFREQ-SET"], + "-xr", + label="AGERF-MO01:FREQ-SET", + ) + ax.plot( + self.t, + rf_ref - self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-MASTERFREQ-GET"], + "-xm", + label="AGERF-MO01:FREQ-GET", + ) + ax.tick_params(axis="y", colors="m", which="both") + ax.get_yaxis().get_major_formatter().set_scientific(False) + ax.get_yaxis().get_major_formatter().set_useOffset(False) + lgnd = ax.legend(loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel( + "Master oscillator frequency offset to {:.0f} kHz / Hz".format(rf_ref / 1000), color="m" + ) + ax.set_xlim([self.t[0], self.t[-1]]) + + self.alive() + # RF Power In/Reflected + index += 1 + c = "m" + ax = fig.add_subplot(GS[index]) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0060-INP"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0060:CO1i-POWER-MAX", + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0140-INP"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0140:CO1i-POWER-MAX", + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0230-INP"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0230:CO1i-POWER-MAX", + ) + ax.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0310-INP"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0310:CO1i-POWER-MAX", + ) + ax.tick_params(axis="y", colors=c, which="both") + ax.set_ylabel("Total main RF forward power / kW", color=c) + ax.set_xlabel("Time since beam dump / s") + ax.set_xlim([self.t[0], self.t[-1]]) + + ax2, c = ax.twinx(), "r" + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0060-REF"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0060:CO1r-POWER-MAX", + ) + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0140-REF"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0140:CO1r-POWER-MAX", + ) + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0230-REF"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0230:CO1r-POWER-MAX", + ) + ax2.plot( + self.t, + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-RFPOW-0310-REF"], + "-x", + color=c, + label="$\\Sigma$ ARS05-RCAV-0310:CO1r-POWER-MAX", + ) + ax2.tick_params(axis="y", colors=c, which="both") + lines, labels = ax.get_legend_handles_labels() + lines2, labels2 = ax2.get_legend_handles_labels() + lgnd = ax2.legend(lines + lines2, labels + labels2, loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax2.set_ylabel("Total main RF reflected power / kW", color=c) + ax2.set_xlim([self.t[0], self.t[-1]]) + + self.alive() + # 4 Kicker Bump + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.PMD["ARS01-MKIK-0140:TIME-AXIS"], + self.PMD["ARS01-MKIK-0140:CURRENT-WF"], + "-x", + label="Kicker 1, " + self.PMD["ARS01-MKIK-0140:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0220:TIME-AXIS"], + self.PMD["ARS01-MKIK-0220:CURRENT-WF"], + "-x", + label="Kicker 2, " + self.PMD["ARS01-MKIK-0220:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0850:TIME-AXIS"], + self.PMD["ARS01-MKIK-0850:CURRENT-WF"], + "-x", + label="Kicker 3, " + self.PMD["ARS01-MKIK-0850:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0940:TIME-AXIS"], + self.PMD["ARS01-MKIK-0940:CURRENT-WF"], + "-x", + label="Kicker 4, " + self.PMD["ARS01-MKIK-0940:CURRENT-WF.timestamp"][:-5], + ) + lgnd = ax.legend(loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("4-kicker bump kicker current / A") + ax.set_xlabel("Time since trigger / us") + ax.set_xlim( + [self.PMD["ARS01-MKIK-0140:TIME-AXIS"][0], self.PMD["ARS01-MKIK-0140:TIME-AXIS"][-1]] + ) + + self.alive() + # Beam Dump Kicker + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.PMD["ARS01-MKIK-0050-1:TIME-AXIS"], + self.PMD["ARS01-MKIK-0050-1:CURRENT-WF"], + "-x", + label="Stage 1, " + self.PMD["ARS01-MKIK-0050-1:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0050-2:TIME-AXIS"], + self.PMD["ARS01-MKIK-0050-2:CURRENT-WF"], + "-x", + label="Stage 2, " + self.PMD["ARS01-MKIK-0050-2:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0050-3:TIME-AXIS"], + self.PMD["ARS01-MKIK-0050-3:CURRENT-WF"], + "-x", + label="Stage 3, " + self.PMD["ARS01-MKIK-0050-3:CURRENT-WF.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-MKIK-0050-4:TIME-AXIS"], + self.PMD["ARS01-MKIK-0050-4:CURRENT-WF"], + "-x", + label="Stage 4, " + self.PMD["ARS01-MKIK-0050-4:CURRENT-WF.timestamp"][:-5], + ) + lgnd = ax.legend(loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Beam dump kicker current / A") + ax.set_xlabel("Time since trigger / us") + ax.set_xlim( + [ + self.PMD["ARS01-MKIK-0050-1:TIME-AXIS"][0], + self.PMD["ARS01-MKIK-0050-1:TIME-AXIS"][-1], + ] + ) + + self.alive() + # Libera BLMs 1 + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.PMD["ABODI-DFBL:SigPm.A"], + "-x", + label="ABODI-DFBL:SigPm.A, " + self.PMD["ABODI-DFBL:SigPm.A.timestamp"][:-5], + ) + ax.plot( + self.PMD["ABODI-DFBL:SigPm.B"], + "-x", + label="ABODI-DFBL:SigPm.B, " + self.PMD["ABODI-DFBL:SigPm.B.timestamp"][:-5], + ) + ax.plot( + self.PMD["ABODI-DFBL:SigPm.C"], + "-x", + label="ABODI-DFBL:SigPm.C, " + self.PMD["ABODI-DFBL:SigPm.C.timestamp"][:-5], + ) + ax.plot( + self.PMD["ABODI-DFBL:SigPm.D"], + "-x", + label="ABODI-DFBL:SigPm.D, " + self.PMD["ABODI-DFBL:SigPm.D.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-DFBL:SigPm.A"], + "-x", + label="ARS01-DFBL:SigPm.A, " + self.PMD["ARS01-DFBL:SigPm.A.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-DFBL:SigPm.B"], + "-x", + label="ARS01-DFBL:SigPm.B, " + self.PMD["ARS01-DFBL:SigPm.B.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-DFBL:SigPm.C"], + "-x", + label="ARS01-DFBL:SigPm.C, " + self.PMD["ARS01-DFBL:SigPm.C.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS01-DFBL:SigPm.D"], + "-x", + label="ARS01-DFBL:SigPm.D, " + self.PMD["ARS01-DFBL:SigPm.D.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS02-DFBL:SigPm.A"], + "-x", + label="ARS02-DFBL:SigPm.A, " + self.PMD["ARS02-DFBL:SigPm.A.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS02-DFBL:SigPm.B"], + "-x", + label="ARS02-DFBL:SigPm.B, " + self.PMD["ARS02-DFBL:SigPm.B.timestamp"][:-5], + ) + lgnd = ax.legend(loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Libera BLM SUM signal Post Mortem Buffer / (a.u.)") + ax.set_xlabel("Turns") + + self.alive() + # Libera BLMs 2 + index += 1 + ax = fig.add_subplot(GS[index]) + ax.plot( + self.PMD["ARS02-DFBL:SigPm.C"], + "-x", + label="ARS02-DFBL:SigPm.C, " + self.PMD["ARS02-DFBL:SigPm.C.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS02-DFBL:SigPm.D"], + "-x", + label="ARS02-DFBL:SigPm.D, " + self.PMD["ARS02-DFBL:SigPm.D.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS06-DFBL:SigPm.A"], + "-x", + label="ARS06-DFBL:SigPm.A, " + self.PMD["ARS06-DFBL:SigPm.A.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS06-DFBL:SigPm.B"], + "-x", + label="ARS06-DFBL:SigPm.B, " + self.PMD["ARS06-DFBL:SigPm.B.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS06-DFBL:SigPm.C"], + "-x", + label="ARS06-DFBL:SigPm.C, " + self.PMD["ARS06-DFBL:SigPm.C.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS06-DFBL:SigPm.D"], + "-x", + label="ARS06-DFBL:SigPm.D, " + self.PMD["ARS06-DFBL:SigPm.D.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS09-DFBL:SigPm.A"], + "-x", + label="ARS09-DFBL:SigPm.A, " + self.PMD["ARS09-DFBL:SigPm.A.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS09-DFBL:SigPm.B"], + "-x", + label="ARS09-DFBL:SigPm.B, " + self.PMD["ARS09-DFBL:SigPm.B.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS09-DFBL:SigPm.C"], + "-x", + label="ARS09-DFBL:SigPm.C, " + self.PMD["ARS09-DFBL:SigPm.C.timestamp"][:-5], + ) + ax.plot( + self.PMD["ARS09-DFBL:SigPm.D"], + "-x", + label="ARS09-DFBL:SigPm.D, " + self.PMD["ARS09-DFBL:SigPm.D.timestamp"][:-5], + ) + lgnd = ax.legend(loc="upper left", bbox_to_anchor=bbox) + for handle in lgnd.legendHandles: + handle._markersize = 7 + handle._linewidth = 2 + ax.set_ylabel("Libera BLM SUM signal Post Mortem Buffer / (a.u.)") + ax.set_xlabel("Turns") + + self.alive() + # Filling Pattern + index += 1 + ax = fig.add_subplot(GS[index], projection="3d") + # X-AXIS is for the bucket nr. + X_bucket = np.arange(480) + 1 + # Y-AXIS is for the filled charge (the first dataset is the newest) + Ndat = len(self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-FILLPATTERN-APD"]) + # Z-AXIS is for the individual plots, i.e., the time before the dump + Z_Nplots = self.t2 + # Color-AXIS is duplicate of the Z and time axis for easier visual + N = 5 + colors = np.tile(plt.cm.get_cmap("hsv", Ndat / N)(np.linspace(0, 1, int(Ndat / N))), (N, 1)) + + def plot2din3d(x, y, z, c): + ax.plot(x, y, zs=z, zdir="z", color=c) + col_obj = ax.fill_between(x, 0, y, step="pre", color=c, alpha=0.1) + ax.add_collection3d(col_obj, zs=z, zdir="z") + + for y, z, c in zip( + self.PMD["AGEBD-POSTMORTEMLOG:BUFFER-FILLPATTERN-APD"], Z_Nplots, colors + ): + plot2din3d(X_bucket, y, z, c) + + ax.set_xlabel("Bucket nr.") + ax.set_ylabel("Charge / nC") + ax.set_zlabel("Time since beam dump / s") + ax.view_init(elev=40.0, azim=80) + ax.set_box_aspect((16, 9, 5), zoom=1.2) + + return fig + + def lpd64plot(self): + + fig, (axu, axl) = plt.subplots( + 2, + 1, + figsize=(20, 9), + sharex=True, + tight_layout=True, + gridspec_kw={"height_ratios": [1, 3], "hspace": 0}, + ) + + (l4,) = axu.plot( + self.PMD["ARF-LPD64:X-AXIS-CH1"] / 1e3, + self.PMD["ARF-LPD64:CH1-DATA"], + "y+-", + label="Filling Pattern BPM ARS01-DBPM-0530", + lw=1, + ) + axu.set_ylabel("BPM Sum / V") + axu.set_ylim([-80, 80]) + axu.set_xlim( + [ + np.nanmin(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + np.nanmax(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + ] + ) + + (l1,) = axl.plot( + self.PMD["ARF-LPD64:X-AXIS-CH4"] / 1e3, + self.PMD["ARF-LPD64:CH4-DATA"] / 1e3, + "g+-", + label="Beam Dump Kicker Magnet, BDC delay = {:.0f} ns".format( + self.PMD["AGESA-SBDC-0000:BUNCH0_MAGNET_RAMP_DELAY"] + ), + lw=1, + ) + axl.set_ylabel("Beam Dump Kicker Pulse / V") + axl.set_xlabel("Time relative to dump kick / µs") + axl.set_ylim([-0.09, 1.85]) + axl.set_xlim( + [ + np.nanmin(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + np.nanmax(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + ] + ) + axl.xaxis.set_ticks(np.arange(-1400 / 1e3, 1401 / 1e3, 200 / 1e3)) + axl.xaxis.grid() + + axt = axl.twinx() + + i1 = np.where( + np.abs(self.PMD["ARF-LPD64:CH3-DATA"]) > np.nanmax(self.PMD["ARF-LPD64:CH3-DATA"]) / 4 + )[0][0] + i2 = np.where( + np.abs(self.PMD["ARF-LPD64:CH3-DATA"]) > np.nanmax(self.PMD["ARF-LPD64:CH3-DATA"]) / 4 + )[0][-1] + dt1 = self.PMD["ARF-LPD64:X-AXIS-CH3"][i2] - self.PMD["ARF-LPD64:X-AXIS-CH3"][i1] + axt.axvspan( + self.PMD["ARF-LPD64:X-AXIS-CH3"][i1] / 1e3, + self.PMD["ARF-LPD64:X-AXIS-CH3"][i2] / 1e3, + color="red", + alpha=0.1, + ) + (l2,) = axt.plot( + self.PMD["ARF-LPD64:X-AXIS-CH3"] / 1e3, + np.abs(self.PMD["ARF-LPD64:CH3-DATA"]), + "r-", + label="Beam Dump Cherenkov Fiber, Δt={:.1f} ns".format(dt1), + lw=1, + ) + + i1 = np.where( + np.abs(self.PMD["ARF-LPD64:CH2-DATA"]) > np.nanmax(self.PMD["ARF-LPD64:CH2-DATA"]) / 4 + )[0][0] + i2 = np.where( + np.abs(self.PMD["ARF-LPD64:CH2-DATA"]) > np.nanmax(self.PMD["ARF-LPD64:CH2-DATA"]) / 4 + )[0][-1] + dt2 = self.PMD["ARF-LPD64:X-AXIS-CH2"][i2] - self.PMD["ARF-LPD64:X-AXIS-CH2"][i1] + axt.axvspan( + self.PMD["ARF-LPD64:X-AXIS-CH2"][i1] / 1e3, + self.PMD["ARF-LPD64:X-AXIS-CH2"][i2] / 1e3, + color="blue", + alpha=0.1, + ) + (l3,) = axt.plot( + self.PMD["ARF-LPD64:X-AXIS-CH2"] / 1e3, + np.abs(self.PMD["ARF-LPD64:CH2-DATA"]), + "b-", + label="Septa Cherenkov Fiber, Δt={:.1f} ns".format(dt2), + lw=1, + ) + axt.set_ylabel("Photomultiplier / mV") + axt.set_ylim([0, 1500]) + axt.set_xlim( + [ + np.nanmin(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + np.nanmax(self.PMD["ARF-LPD64:X-AXIS-CH4"]) / 1e3, + ] + ) + axt.grid() + + leg = axt.legend( + handles=[l4, l1, l2, l3], + loc="upper left", + frameon=True, + facecolor="white", + framealpha=1, + title="Post Mortem Scope, " + self.t0_pmlpd64, + ) + fig.subplots_adjust(hspace=0) + + return fig diff --git a/services/postmortemlog/current/app/uv.lock b/services/postmortemlog/current/app/uv.lock index d9cb60f..284dc68 100644 --- a/services/postmortemlog/current/app/uv.lock +++ b/services/postmortemlog/current/app/uv.lock @@ -30,6 +30,9 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "urllib3" }, ] [package.dev-dependencies] @@ -40,7 +43,12 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "matplotlib", specifier = ">=3.10.9" }, + { name = "numpy", specifier = ">=2.0.2" }, + { name = "urllib3", specifier = ">=2.7.0" }, +] [package.metadata.requires-dev] dev = [ @@ -67,6 +75,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "contourpy" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/a3/da4153ec8fe25d263aa48c1a4cbde7f49b59af86f0b6f7862788c60da737/contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934", size = 268551, upload-time = "2025-04-15T17:34:46.581Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6c/330de89ae1087eb622bfca0177d32a7ece50c3ef07b28002de4757d9d875/contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989", size = 253399, upload-time = "2025-04-15T17:34:51.427Z" }, + { url = "https://files.pythonhosted.org/packages/c1/bd/20c6726b1b7f81a8bee5271bed5c165f0a8e1f572578a9d27e2ccb763cb2/contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d", size = 312061, upload-time = "2025-04-15T17:34:55.961Z" }, + { url = "https://files.pythonhosted.org/packages/22/fc/a9665c88f8a2473f823cf1ec601de9e5375050f1958cbb356cdf06ef1ab6/contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9", size = 351956, upload-time = "2025-04-15T17:35:00.992Z" }, + { url = "https://files.pythonhosted.org/packages/25/eb/9f0a0238f305ad8fb7ef42481020d6e20cf15e46be99a1fcf939546a177e/contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512", size = 320872, upload-time = "2025-04-15T17:35:06.177Z" }, + { url = "https://files.pythonhosted.org/packages/32/5c/1ee32d1c7956923202f00cf8d2a14a62ed7517bdc0ee1e55301227fc273c/contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631", size = 325027, upload-time = "2025-04-15T17:35:11.244Z" }, + { url = "https://files.pythonhosted.org/packages/83/bf/9baed89785ba743ef329c2b07fd0611d12bfecbedbdd3eeecf929d8d3b52/contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f", size = 1306641, upload-time = "2025-04-15T17:35:26.701Z" }, + { url = "https://files.pythonhosted.org/packages/d4/cc/74e5e83d1e35de2d28bd97033426b450bc4fd96e092a1f7a63dc7369b55d/contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2", size = 1374075, upload-time = "2025-04-15T17:35:43.204Z" }, + { url = "https://files.pythonhosted.org/packages/0c/42/17f3b798fd5e033b46a16f8d9fcb39f1aba051307f5ebf441bad1ecf78f8/contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0", size = 177534, upload-time = "2025-04-15T17:35:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/54/ec/5162b8582f2c994721018d0c9ece9dc6ff769d298a8ac6b6a652c307e7df/contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a", size = 221188, upload-time = "2025-04-15T17:35:50.064Z" }, + { url = "https://files.pythonhosted.org/packages/33/05/b26e3c6ecc05f349ee0013f0bb850a761016d89cec528a98193a48c34033/contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c", size = 265681, upload-time = "2025-04-15T17:44:59.314Z" }, + { url = "https://files.pythonhosted.org/packages/2b/25/ac07d6ad12affa7d1ffed11b77417d0a6308170f44ff20fa1d5aa6333f03/contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16", size = 315101, upload-time = "2025-04-15T17:45:04.165Z" }, + { url = "https://files.pythonhosted.org/packages/8f/4d/5bb3192bbe9d3f27e3061a6a8e7733c9120e203cb8515767d30973f71030/contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad", size = 220599, upload-time = "2025-04-15T17:45:08.456Z" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -79,6 +120,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/c9/4141c90a90db20f807c7e10bfd689fe53eb8f7f4caff58ee4d4dfe46919f/fonttools-4.63.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b", size = 2884632, upload-time = "2026-05-14T12:02:38.56Z" }, + { url = "https://files.pythonhosted.org/packages/b8/46/ad12b5c10eae602d7ef814b02afa08aacbf89da917fed5b071282b7eadc2/fonttools-4.63.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94", size = 2429441, upload-time = "2026-05-14T12:02:41.162Z" }, + { url = "https://files.pythonhosted.org/packages/90/8f/bdca24a84c81d56fffed052229cdcff368f6e05882e526f4558891481f65/fonttools-4.63.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579", size = 4946346, upload-time = "2026-05-14T12:02:43.41Z" }, + { url = "https://files.pythonhosted.org/packages/04/59/a639c0e136441ee91a65b56fdf89e5d075927e7a09c559d1b0f5276577db/fonttools-4.63.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22", size = 4903184, upload-time = "2026-05-14T12:02:45.742Z" }, + { url = "https://files.pythonhosted.org/packages/e6/53/91b7e0cb45b536f3da1b29ba8cbab89f27e8b986809e0b1982303a3f4eca/fonttools-4.63.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e", size = 4922967, upload-time = "2026-05-14T12:02:48.386Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b7/87439bf44e6b97c5538cd29d0b7e366a5b8ce2cc132a4134fb67fa3f2fa2/fonttools-4.63.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69", size = 5042799, upload-time = "2026-05-14T12:02:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/ad/7c/8b96c3263b89ef99cded544c0f0636686f85dbd3c211c4dceef0231fca23/fonttools-4.63.0-cp310-cp310-win32.whl", hash = "sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e", size = 1519704, upload-time = "2026-05-14T12:02:52.523Z" }, + { url = "https://files.pythonhosted.org/packages/e5/4d/2c2f0069970b6907de8fb5b05c5c0193cc22f717df151d1c7aef1c738f58/fonttools-4.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac", size = 1568666, upload-time = "2026-05-14T12:02:54.917Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + [[package]] name = "h5py" version = "3.16.0" @@ -106,6 +164,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/f8/06549565caa026e540b7e7bab5c5a90eb7ca986015f4c48dace243cd24d9/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374", size = 122802, upload-time = "2026-03-09T13:12:37.515Z" }, + { url = "https://files.pythonhosted.org/packages/84/eb/8476a0818850c563ff343ea7c9c05dcdcbd689a38e01aa31657df01f91fa/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd", size = 66216, upload-time = "2026-03-09T13:12:38.812Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/f9c8a6b4c21aed4198566e45923512986d6cef530e7263b3a5f823546561/kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476", size = 63917, upload-time = "2026-03-09T13:12:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0e/ba4ae25d03722f64de8b2c13e80d82ab537a06b30fc7065183c6439357e3/kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22", size = 1628776, upload-time = "2026-03-09T13:12:41.976Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e4/3f43a011bc8a0860d1c96f84d32fa87439d3feedf66e672fef03bf5e8bac/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b", size = 1228164, upload-time = "2026-03-09T13:12:44.002Z" }, + { url = "https://files.pythonhosted.org/packages/4b/34/3a901559a1e0c218404f9a61a93be82d45cb8f44453ba43088644980f033/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e", size = 1246656, upload-time = "2026-03-09T13:12:45.557Z" }, + { url = "https://files.pythonhosted.org/packages/87/9e/f78c466ea20527822b95ad38f141f2de1dcd7f23fb8716b002b0d91bbe59/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb", size = 1295562, upload-time = "2026-03-09T13:12:47.562Z" }, + { url = "https://files.pythonhosted.org/packages/0a/66/fd0e4a612e3a286c24e6d6f3a5428d11258ed1909bc530ba3b59807fd980/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537", size = 2178473, upload-time = "2026-03-09T13:12:50.254Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8e/6cac929e0049539e5ee25c1ee937556f379ba5204840d03008363ced662d/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4", size = 2274035, upload-time = "2026-03-09T13:12:51.785Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d3/9d0c18f1b52ea8074b792452cf17f1f5a56bd0302a85191f405cfbf9da16/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c", size = 2443217, upload-time = "2026-03-09T13:12:53.329Z" }, + { url = "https://files.pythonhosted.org/packages/45/2a/6e19368803a038b2a90857bf4ee9e3c7b667216d045866bf22d3439fd75e/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede", size = 2249196, upload-time = "2026-03-09T13:12:55.057Z" }, + { url = "https://files.pythonhosted.org/packages/75/2b/3f641dfcbe72e222175d626bacf2f72c3b34312afec949dd1c50afa400f5/kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2", size = 73389, upload-time = "2026-03-09T13:12:56.496Z" }, + { url = "https://files.pythonhosted.org/packages/da/88/299b137b9e0025d8982e03d2d52c123b0a2b159e84b0ef1501ef446339cf/kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875", size = 64782, upload-time = "2026-03-09T13:12:57.609Z" }, + { url = "https://files.pythonhosted.org/packages/17/6f/6fd4f690a40c2582fa34b97d2678f718acf3706b91d270c65ecb455d0a06/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4", size = 59606, upload-time = "2026-03-09T13:15:40.81Z" }, + { url = "https://files.pythonhosted.org/packages/82/a0/2355d5e3b338f13ce63f361abb181e3b6ea5fffdb73f739b3e80efa76159/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca", size = 57537, upload-time = "2026-03-09T13:15:42.071Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b9/1d50e610ecadebe205b71d6728fd224ce0e0ca6aba7b9cbe1da049203ac5/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f", size = 79888, upload-time = "2026-03-09T13:15:43.317Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ee/b85ffcd75afed0357d74f0e6fc02a4507da441165de1ca4760b9f496390d/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed", size = 77584, upload-time = "2026-03-09T13:15:44.605Z" }, + { url = "https://files.pythonhosted.org/packages/6b/dd/644d0dde6010a8583b4cd66dd41c5f83f5325464d15c4f490b3340ab73b4/kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc", size = 73390, upload-time = "2026-03-09T13:15:45.832Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -118,6 +202,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, ] +[[package]] +name = "matplotlib" +version = "3.10.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/6f/340b04986e67aac6f66c5145ce68bf72c64bed30f92c8913499a6e6b8f99/matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217", size = 8296625, upload-time = "2026-04-24T00:11:43.376Z" }, + { url = "https://files.pythonhosted.org/packages/bb/2f/127081eb83162053ebb9678ceac64220b93a663e0167432566e9c7c82aab/matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b", size = 8188790, upload-time = "2026-04-24T00:11:46.556Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b7/d8bcec2626c35f96972bff656299fef4578113ea6193c8fdad324710410c/matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37", size = 8769389, upload-time = "2026-04-24T00:11:48.959Z" }, + { url = "https://files.pythonhosted.org/packages/12/49/b78e214a527ea732033b7f4d37f7afb504d74ba9d134bd47938230dfb8b1/matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294", size = 9589657, upload-time = "2026-04-24T00:11:51.915Z" }, + { url = "https://files.pythonhosted.org/packages/5f/15/5246f7b43beae19c74dfee651d58d6cc8112e06f77adb4e88cc04f2e3a23/matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65", size = 9651983, upload-time = "2026-04-24T00:11:54.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/77/5acecfe672ba0fa1b8c0454f69ce155d1e6fc5852fa7206bf9afaf767121/matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda", size = 8199701, upload-time = "2026-04-24T00:11:58.389Z" }, + { url = "https://files.pythonhosted.org/packages/2c/2b/0e92ad0ac446633f928a1563db4aa8add407e1924faf0ded5b95b35afb27/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b", size = 8293058, upload-time = "2026-04-24T00:13:56.339Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/74682fd369f5299ceda438fea2a0662e6383b85c9383fb9cdfcf04713e07/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f", size = 8186627, upload-time = "2026-04-24T00:13:58.623Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e8/368aab88f3c4cd8992800f31abfe0670c3e47540ba20a97e9fdbcde594b3/matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585", size = 8764117, upload-time = "2026-04-24T00:14:01.684Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -158,6 +270,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -216,6 +345,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -263,6 +404,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + [[package]] name = "tomli" version = "2.4.1" @@ -295,3 +445,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3 wheels = [ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] + +[[package]] +name = "urllib3" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, +] From 4e27b6fe7a31464942834756c4810df51ba8b0da Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 16:02:16 +0200 Subject: [PATCH 34/42] feat: migrate scrubbing python service -- as much as possible :D --- services/scrubbing/current/app/pyproject.toml | 1 + .../current/app/src/agebd_scrubbing/main.py | 12 +- .../current/app/src/agebd_scrubbing/runner.py | 280 +++++++++ .../app/src/agebd_scrubbing/service.py | 546 +++++++++++++++--- .../scrubbing/current/app/tests/test_app.py | 3 +- services/scrubbing/current/app/uv.lock | 6 +- 6 files changed, 775 insertions(+), 73 deletions(-) create mode 100644 services/scrubbing/current/app/src/agebd_scrubbing/runner.py diff --git a/services/scrubbing/current/app/pyproject.toml b/services/scrubbing/current/app/pyproject.toml index f984959..b81a822 100644 --- a/services/scrubbing/current/app/pyproject.toml +++ b/services/scrubbing/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-SCRUBBING Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index b92c9fc..73085b9 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -1,13 +1,13 @@ import typer from agebd.enums import LogLevel -from agebd.runner import CallbackRunner from agebd.utils import init_logging from agebd_scrubbing import PVs, Service - +from agebd_scrubbing.runner import Runner # TODO: remove: cicd test 10 + def main( log_level: LogLevel = typer.Option( LogLevel.INFO, @@ -19,11 +19,15 @@ def main( case_sensitive=False, ), ): + """ + Uses custom/old Runner because migrating to the agebd Runner would be quite + complex. + """ init_logging(log_level) service_name = "SCRUBBING" pvs = PVs(service_name=service_name) - service = Service(name=service_name, pvs=pvs) - runner = CallbackRunner(service=service) + service = Service(pvs=pvs) + runner = Runner(svc=service) runner.start() diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/runner.py b/services/scrubbing/current/app/src/agebd_scrubbing/runner.py new file mode 100644 index 0000000..2ad2058 --- /dev/null +++ b/services/scrubbing/current/app/src/agebd_scrubbing/runner.py @@ -0,0 +1,280 @@ +import traceback +from time import perf_counter, sleep + +import numpy as np +from epics import poll + +from agebd_scrubbing.service import Service + + +class Runner: + def __init__(self, svc: Service) -> None: + self.svc = svc + + def start(self): + svc = self.svc + pvs = self.svc.pvs + + while not pvs.abort.get(): + if pvs.onoff.get() == 1: + # add callback for triggering the loop + if not svc.CallbackActive: + pvs.status.put("running") + pvs.CallbackPV.add_callback(callback=svc.InjectionCallback, index=1, svc=svc) + svc.CallbackActive = 1 + + if svc.ChangeTrue or perf_counter() > svc.tl + 0.1: + # start time for next loop firing, if no vacuum changes + svc.tl = perf_counter() + + # reload control PVs + svc.update() + + # check stop/abort conitions if injection is active + if svc.injection: + # ensure disabled scrubbing during injection + svc.pause_scrubbing() + + # ensure correct injector settings + if svc.cur > pvs.current_threshold.get(): + pvs.gun_grid.put(svc.grid_fpfb) + else: + pvs.gun_grid.put(svc.grid_accum) + + # abort injection when limits exceeded + if svc.conditions_abort_injection: + # disable injection when upper limit reached + svc.stop_injection() + print("injection aborted") + + if not svc.abort: + svc.abort = 1 + svc.abort_t0 = perf_counter() + + svc.set_status(svc.states["abort"], wait=60) + + elif svc.conditions_stop_injection: + # disable injection when upper limit reached + svc.stop_injection() + print("injection stopped") + + # start scrubbing if activated + if svc.scrubbi > 0: + sleep(0.1) + svc.start_scrubbing() + + svc.set_status(svc.states["decay + scrub"]) + + else: + svc.set_status(svc.states["decay - scrub"]) + + elif svc.info != svc.states["inject"]: + svc.set_status(svc.states["inject"]) + + # stop injection and info if master trigger missing + elif not svc.trig_master: + svc.stop_injection() + svc.set_status(svc.states["wait 4 master"]) + + # stop injection and info if master mode is not set to manual + elif not svc.master_mode == 2: + svc.stop_injection() + svc.set_status(svc.states["wait 4 manual"]) + + # stop injection and wait for 60s if injection was aborted + elif svc.abort: + svc.stop_injection() + dt = perf_counter() - svc.abort_t0 + + if dt > 60: + svc.abort = 0 + + else: + svc.set_status(svc.states["abort"], wait=60 - dt) + + sleep(0.1) + + # start warmup cycling if conditions for starting injection are fulfilled + elif svc.conditions_start_injection and svc.info not in [ + svc.states["inject"], + svc.states["warmup"], + ]: + svc.set_status(svc.states["warmup"]) + + # disable pingers for injection + svc.pause_scrubbing() + + # make sure that injection bump and pinger not both fired + sleep(0.1) + + # check setpoints for required amount of warmup cycles + svc.cycles_BOIN_sp = pvs.cycles_BOIN_sp.get() + svc.cycles_BOMB_sp = pvs.cycles_BOMB_sp.get() + svc.cycles_BOME_sp = pvs.cycles_BOME_sp.get() + svc.cycles_BOEX_sp = pvs.cycles_BOEX_sp.get() + svc.cycles_SRIN_sp = pvs.cycles_SRIN_sp.get() + + # set readback of warmup cycle counters to setpoint + pvs.cycles_BOIN_rb.put(svc.cycles_BOIN_sp) + pvs.cycles_BOMB_rb.put(svc.cycles_BOMB_sp) + pvs.cycles_BOME_rb.put(svc.cycles_BOME_sp) + pvs.cycles_BOEX_rb.put(svc.cycles_BOEX_sp) + pvs.cycles_SRIN_rb.put(svc.cycles_SRIN_sp) + svc.cycles_BOIN_rb = svc.cycles_BOIN_sp + svc.cycles_BOMB_rb = svc.cycles_BOMB_sp + svc.cycles_BOME_rb = svc.cycles_BOME_sp + svc.cycles_BOEX_rb = svc.cycles_BOEX_sp + svc.cycles_SRIN_rb = svc.cycles_SRIN_sp + + # calculate highest amount of total required warmup cycles + svc.cycles_max = np.nanmax( + [ + svc.cycles_BOIN_sp, + svc.cycles_BOMB_sp, + svc.cycles_BOME_sp, + svc.cycles_BOEX_sp, + svc.cycles_SRIN_sp, + ] + ) + + # calculate highest amount of remaining warmup cycles + svc.cycles_rem = svc.cycles_max + + # remove default callback for warmup (secretly since svc.CallbackActive = 0) + pvs.CallbackPV.remove_callback(index=1) + + # activate warmup callbacks + pvs.cycles_BOIN_cnt.add_callback( + callback=svc.WarmupCallback, index=2, svc=svc + ) + pvs.cycles_BOMB_cnt.add_callback( + callback=svc.WarmupCallback, index=3, svc=svc + ) + pvs.cycles_BOME_cnt.add_callback( + callback=svc.WarmupCallback, index=4, svc=svc + ) + pvs.cycles_BOEX_cnt.add_callback( + callback=svc.WarmupCallback, index=5, svc=svc + ) + pvs.cycles_SRIN_cnt.add_callback( + callback=svc.WarmupCallback, index=6, svc=svc + ) + # pvs.cycles_ALL_cnt.add_callback(callback=InjectionCallback, index=7, svc=svc) + + # set callback warmup cycle counters to 0 + svc.wait4warm = { + "AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL": 0, + } + + svc.tp = perf_counter() + + # do top up analysis + svc.topup_dt = (svc.tp - svc.topup_t0) / 60 + svc.topup_dI = svc.topup_I0 - svc.cur + pvs.topup_dt.put(svc.topup_dt) + pvs.topup_dI.put(svc.topup_dI) + if svc.topup_I0 > 0: + if svc.topup_dI / svc.topup_I0 < 1: + pvs.topup_tau.put( + (-svc.topup_dt / 60) / np.log(1 - svc.topup_dI / svc.topup_I0) + ) + + elif svc.info == svc.states["warmup"]: + if svc.cycles_rem < 1: + # start injection + svc.start_injection() + + # reactivate default callback by notifying mainloop of its deactivation + svc.CallbackActive = 0 + + # disable warmup callbacks + pvs.cycles_BOIN_cnt.remove_callback(index=2) + pvs.cycles_BOMB_cnt.remove_callback(index=3) + pvs.cycles_BOME_cnt.remove_callback(index=4) + pvs.cycles_BOEX_cnt.remove_callback(index=5) + pvs.cycles_SRIN_cnt.remove_callback(index=6) + pvs.cycles_ALL_cnt.remove_callback(index=7) + + svc.set_status(svc.states["inject"]) + + else: + svc.prepare_injection() + + elif svc.info in [svc.states["pause"], svc.states["wait 4 master"]]: + if svc.injection: + svc.set_status(svc.states["inject"]) + else: + if pvs.trig_pinger_h.get() and pvs.trig_pinger_v.get(): + svc.set_status(svc.states["decay + scrub"]) + else: + svc.set_status(svc.states["decay - scrub"]) + + # stop scrubbing when deactivated + elif svc.scrubbi == 0 and svc.scrubbilast > 0: + svc.stop_scrubbing() + svc.set_status(svc.states["decay - scrub"]) + + # if scrubbing activated and lifetime drops below 1 hour --> stop scrubbing + elif svc.scrubbi > 0 and svc.tau < 1: + svc.pause_scrubbing() + svc.set_status(svc.states["decay - scrub"]) + print("Scrubbing aborted, tau < 1") + + svc.ChangeTrue = 0 + + # inform watchdog(s) + pvs.running.put(0) + + # wait for callback to fire + poll(evt=1.0e-5, iot=0.1) + + else: + # WHILE PAUSED REBOOT OF THE SCRUBBING IOC SHOULD NOT DISTURB THE SERVICE + + if svc.CallbackActive: + # remove callback + pvs.CallbackPV.remove_callback(index=1) + svc.CallbackActive = 0 + + # reload control PVs + svc.update() + + # disable injection and pingers when first paused + if svc.info != svc.states["pause"]: + svc.stop_injection() + svc.pause_scrubbing() + + svc.set_status(svc.states["pause"]) + pvs.status.put("paused") + + sleep(0.1) + + # sleep and inform watchdog(s) + pvs.alive.put(0) + + if pvs.abort.get(): + # confirm clean abort + pvs.status.put("killed") + print("Got Killed by Master Service!") + pvs.abortreq.put(0) + + # elif svc.crashed: + + # # confirm crash + # pvs.status.put('crashed') + # print('Service crashed on exception!') + # print('----- svc.exception.__traceback__ -----') + # print(svc.exception.__traceback__) + # print() + # print('----- traceback.format_exc() -----') + # print(traceback.format_exc()) + + else: + # confirm unknown exit + pvs.status.put("unknown crash") + print("Service crashed without exception!") + print(traceback.format_exc()) diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/service.py b/services/scrubbing/current/app/src/agebd_scrubbing/service.py index 06d6f6d..3be0bc5 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/service.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/service.py @@ -1,12 +1,12 @@ -import time +from datetime import datetime +from time import perf_counter, sleep -from epics import dbr +import numpy as np +from epics import PV -from agebd.pv import LocalPVLink -from agebd.service.base import BaseService +from agebd.pv import get_pv_class from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,80 +14,494 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-SCRUBBING:AO") # TODO: is this a good PV to use? + cycles_BOIN_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-SP.VAL") + cycles_BOIN_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-RB.VAL") + cycles_BOIN_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL", auto_monitor=True) + cycles_BOMB_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-SP.VAL") + cycles_BOMB_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-RB.VAL") + cycles_BOMB_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL", auto_monitor=True) + cycles_BOME_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOME-SP.VAL") + cycles_BOME_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOME-RB.VAL") + cycles_BOME_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL", auto_monitor=True) + cycles_BOEX_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-SP.VAL") + cycles_BOEX_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-RB.VAL") + cycles_BOEX_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL", auto_monitor=True) + cycles_SRIN_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-SP.VAL") + cycles_SRIN_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-RB.VAL") + cycles_SRIN_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL", auto_monitor=True) + cycles_ALL_cnt = PV("AGETI-CVME-MASTER-TMA:Event-Seq-Cnt-I.VAL", auto_monitor=True) - ## Service specific PVs from other IOCs - # ... + ## Control PVs + # top-up control mode + # topumod = PV('.VAL') + # top-up mode vacuum limits + vac_max = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-MAX.VAL") + vac_min = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-MIN.VAL") + # top-up mode current limits + cur_max = PV("AGEBD-SCRUBBING:CONTROL-CURRENT-MAX.VAL") + cur_min = PV("AGEBD-SCRUBBING:CONTROL-CURRENT-MIN.VAL") + # top-up mode time limits for injection and decay (periodic refill) + tim_inj = PV("AGEBD-SCRUBBING:CONTROL-TIME-MAX.VAL") + tim_dec = PV("AGEBD-SCRUBBING:CONTROL-TIME-MIN.VAL") + # mbfb gain setpoints for scrubbing + mbfbx_gain_sp = PV("AGEBD-SCRUBBING:MBFBX-GAIN-SP.VAL") + mbfby_gain_sp = PV("AGEBD-SCRUBBING:MBFBY-GAIN-SP.VAL") + mbfbx_gain = PV("ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN.VAL") + mbfby_gain = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN.VAL") + + # RDP Scan + # pause : set gain to 0 as normal, get current sweep freq, stop sweep, set initial freq of sweep to current freq + # start : set gain to sp (i.e., 100) as normal, start sweep + mbfby_freq_sp = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ.VAL") + mbfby_sweep_onoff = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-EN.VAL") + mbfby_sweepfreq_start = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FREQ-START.VAL") + mbfby_sweepfreq_rb = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FRQ-RB-REG.VAL") + + vac_dyn = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-DYN.VAL") + vac_dyn_frac = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-DYN-FRAC.VAL") + + # grd_max = PV('AGEBD-SCRUBBING:CONTROL-GUNGRID-MAX.VAL') + grid_accum = PV("AGEBD-SCRUBBING:CONTROL-GUNGRID-ACCUM.VAL") + grid_fpfb = PV("AGEBD-SCRUBBING:CONTROL-GUNGRID-FPFB.VAL") + # current above which the feedback mode is started + current_threshold = PV("AGEBD-TIMING:CURRENT-THRESHOLD.VAL") + + scrubbing = PV("AGEBD-SCRUBBING:CONTROL-SCRUB.VAL") + + # Input PVs + vacs = [ + # PV('ARIVA-VMAVE:PRESS-MAX.VAL'), # VCS gauges in the Arcs + Straights + # PV('ARIVA-VMAVE-FE:PRESS-MAX.VAL'), # VCS gauges in the ring to always the first one after the FE-Valve + # PV('ARIVA-VMAVE-ALL:PRESS-MAX.VAL'), # Max of the two above + # PV('ARIVA-VMAVE-PSH:PRESS-MAX.VAL'), # VCS gauges in the Photon Shutters/Beam Stoppers of the existing beamlines + PV("ARIVA-VMAVE-ALL:PRESS-MAX.VAL"), # Max of three signals: Ring/FE/PSH + PV("ARS07-VMCC-0120:PRESSURE.VAL"), + ] + vac_all = PV("ARIVA-VMAVE-ALL:PRESS-MAX.VAL") + vac_acc = [ + PV("ARIVA-VMAVE:PRESS-MAX.VAL"), + PV("ARS07-VMCC-0120:PRESSURE.VAL"), + ] + # vac_fe = PV('ARIVA-VMAVE-FE:PRESS-MAX.VAL') + # cur = PV('AGEBD-DBPM3CURR:CURRENT-AVG.VAL') + cur = PV("ARS07-DPCT-0000:CURR.VAL") + # cur1 = PV('ARS07-CECL-DPCT:BDC-DPCT100-SCALED') + # cur2 = PV('ARS07-CECL-DPCT2:BDC-DPCT200-SCALED') + # curuse = PV('ARS07-DPCT-0000:CHOICE-RB') + + injguard = PV("AGEBD-INJECTIONGUARD:CHECK-SUM.VAL") + + injactive = PV("AGEBD-PARAMS:INJECTION-ACTIVE") + + tau = PV("AGEBD-PARAMS:LIFETIME.VAL") + + # Regulated PVs + trig_firego = PV("AGEBD-TIMING:GO.VAL") + trig_master = PV("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") + master_mode = PV("AGETI-CVME-MASTER-TMA:FP-Mode-Sel.VAL") + trig_secret = PV("AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER.VAL") + # trig_guntxb = PV('ALIRF-VME-A-GUN:CH1-MODE.VAL') + # AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel + # trig_gunevt = PV('AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel.VAL') + # AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel + trig_booinj = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel.VAL") + # AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel + # trig_boormp = PV('AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel.VAL') + trig_bormp1 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel.VAL") + # AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel + trig_bormp2 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel.VAL") + trig_booext = PV( + "AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-10 + trig_rininj = PV( + "AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-26 + trig_pinger_h = PV( + "AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-14-Ena-Sel + trig_pinger_v = PV( + "AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-14-Ena-Sel + + # # injection follow bucket workaround for linac (https://elog-gfa.psi.ch/SLS/64299) + # # Before making injection, disable the LLRF phase feedback ... + # linac_llrf_phaseFB1 = PV('ALIRF-A1-LLE-DSP:PHASE-FB-SWITCH.VAL') + # linac_llrf_phaseFB2 = PV('ALIRF-A2-LLE-DSP:PHASE-FB-SWITCH.VAL') + # # ... and disable the phase alarm by setting the phase limits + # linac_llrf_phaseFB_PBU_HIHI = PV('ALIRF-PBU:Ph-COMP.HIHI') + # linac_llrf_phaseFB_FBU_HIHI = PV('ALIRF-FBU:Ph-COMP.HIHI') + # linac_llrf_phaseFB_MOD1_HIHI = PV('ALIRF-AS-1:Ph-COMP.HIHI') + # linac_llrf_phaseFB_MOD2_HIHI = PV('ALIRF-AS-2:Ph-COMP.HIHI') + # linac_llrf_phaseFB_PBU_LOLO = PV('ALIRF-PBU:Ph-COMP.LOLO') + # linac_llrf_phaseFB_FBU_LOLO = PV('ALIRF-FBU:Ph-COMP.LOLO') + # linac_llrf_phaseFB_MOD1_LOLO = PV('ALIRF-AS-1:Ph-COMP.LOLO') + # linac_llrf_phaseFB_MOD2_LOLO = PV('ALIRF-AS-2:Ph-COMP.LOLO') + + gun_grid = PV("ALIRF-GUN-GRID:V-SET.VAL") + # pinger_v = PV('ARS01-MKIK-0320:CTRL-ON-OFF.VAL') + # pinger_h = PV('ARS01-MKIK-0290:CTRL-ON-OFF.VAL') + + topup_dt = PV("AGEBD-SCRUBBING:TOPUP-DELTAT.VAL") + topup_dI = PV("AGEBD-SCRUBBING:TOPUP-DELTAI.VAL") + topup_tau = PV("AGEBD-SCRUBBING:TOPUP-TAU.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-SCRUBBING:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-SCRUBBING:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + # Service Callback PVs + self.CallbackPV = PV("AGETI-CVME-MASTER-TMA:Evt-Old-BO-SYN.VALA", auto_monitor=True) -class Service(BaseService[PVs]): - def __init__( - self, - name: str, - pvs: PVs, - version: str = __version__, - sleep_interval: float = 0.1, - ): - super().__init__(name, pvs, version, sleep_interval) +class Service: + def __init__(self, pvs: PVs): + self.pvs = pvs - # TODO: What is this for? - self.path = "sls/bd/bin" + self.pvs.started.put(str(datetime.now())[:-7]) + self.pvs.version.put(__version__) + self.pvs.info.put("initialized") + + self.cycles_BOIN_sp = pvs.cycles_BOIN_sp.get() + self.cycles_BOIN_rb = pvs.cycles_BOIN_rb.get() + self.cycles_BOIN_cnt = pvs.cycles_BOIN_cnt.get() + self.cycles_BOMB_sp = pvs.cycles_BOMB_sp.get() + self.cycles_BOMB_rb = pvs.cycles_BOMB_rb.get() + self.cycles_BOMB_cnt = pvs.cycles_BOMB_cnt.get() + self.cycles_BOME_sp = pvs.cycles_BOME_sp.get() + self.cycles_BOME_rb = pvs.cycles_BOME_rb.get() + self.cycles_BOME_cnt = pvs.cycles_BOME_cnt.get() + self.cycles_BOEX_sp = pvs.cycles_BOEX_sp.get() + self.cycles_BOEX_rb = pvs.cycles_BOEX_rb.get() + self.cycles_BOEX_cnt = pvs.cycles_BOEX_cnt.get() + self.cycles_SRIN_sp = pvs.cycles_SRIN_sp.get() + self.cycles_SRIN_rb = pvs.cycles_SRIN_rb.get() + self.cycles_SRIN_cnt = pvs.cycles_SRIN_cnt.get() + self.timerthreadready = 1 + + self.cycles_max = np.nanmax( + [ + self.cycles_BOIN_sp, + self.cycles_BOMB_sp, + self.cycles_BOME_sp, + self.cycles_BOEX_sp, + self.cycles_SRIN_sp, + ] + ) + + self.cycles_rem = self.cycles_max + + self.wait4warm = { + "AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL": 0, + "AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL": 0, + } + + self.vac = np.max([pv.get() for pv in pvs.vacs]) + # self.vac_acc = pvs.vac_acc.get() + self.vac_acc = np.max([pv.get() for pv in pvs.vac_acc]) + # self.vac = pvs.vac_fe.get() + self.vac_array = np.repeat(self.vac_acc, 10) + self.vac_dyn = self.vac * pvs.vac_dyn_frac.get() + pvs.vac_dyn.put(self.vac_dyn * 1e9) + self.cur = 420 + self.scrubbi = pvs.scrubbing.get() + self.scrubbilast = self.scrubbi + + self.mbfbx_sp = int(pvs.mbfbx_gain_sp.get()) + self.mbfby_sp = int(pvs.mbfby_gain_sp.get()) + self.mbfby_sweepfreq_rb = np.round(pvs.mbfby_sweepfreq_rb.get()) + + self.topup_t0 = perf_counter() + self.topup_I0 = pvs.cur_min.get() + self.topup_dI = 0.0 + self.topup_dt = 0.0 + + def getcurr(self): + pvs = self.pvs + + self.cur = pvs.cur.get() + + # def start_linac_phasefeedback(self): + + # # injection follow bucket workaround for linac (https://elog-gfa.psi.ch/SLS/64299) + # # Before making injection, disable the LLRF phase alarms and feedback ... + # pvs.linac_llrf_phaseFB1.put(1) + # pvs.linac_llrf_phaseFB2.put(1) + + # pvs.linac_llrf_phaseFB_PBU_HIHI.put(10) + # pvs.linac_llrf_phaseFB_FBU_HIHI.put(10) + # pvs.linac_llrf_phaseFB_MOD1_HIHI.put(10) + # pvs.linac_llrf_phaseFB_MOD2_HIHI.put(10) + # pvs.linac_llrf_phaseFB_PBU_LOLO.put(-10) + # pvs.linac_llrf_phaseFB_FBU_LOLO.put(-10) + # pvs.linac_llrf_phaseFB_MOD1_LOLO.put(-10) + # pvs.linac_llrf_phaseFB_MOD2_LOLO.put(-10) + # print('phaseFB ON') def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs - # callback done - self.CallbackFired = 0 + # (re-)load input PVs + self.injection = pvs.injactive.get() + self.vac = np.max([pv.get() for pv in pvs.vacs]) + self.vac_acc = np.max([pv.get() for pv in pvs.vac_acc]) - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + self.getcurr() - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + self.trig_master = pvs.trig_master.get() and pvs.trig_secret.get() + self.master_mode = pvs.master_mode.get() + self.injguard = pvs.injguard.get() + self.info = pvs.info.get().split(",")[0] + self.tau = pvs.tau.get() - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + # (re-)load control PVs + self.vac_max = pvs.vac_max.get() * 1e-9 + self.vac_dyn = np.max(self.vac_array[:5]) * pvs.vac_dyn_frac.get() + pvs.vac_dyn.put(self.vac_dyn * 1e9) - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + # roll oldest value arr[0] to end, i.e., arr[-1] + self.vac_array = np.roll(self.vac_array, -2) + # replace oldest value with new value + self.vac_array[-2:] = self.vac_acc + + self.mbfbx_sp = int(pvs.mbfbx_gain_sp.get()) + self.mbfby_sp = int(pvs.mbfby_gain_sp.get()) + + self.vac_min = pvs.vac_min.get() * 1e-9 + self.cur_max = pvs.cur_max.get() + self.cur_min = pvs.cur_min.get() + self.grid_accum = pvs.grid_accum.get() + self.grid_fpfb = pvs.grid_fpfb.get() + self.scrubbilast = self.scrubbi + self.scrubbi = pvs.scrubbing.get() + + self.conditions_start_injection = ( # is any lower limit reached? + self.vac <= self.vac_min or self.cur <= self.cur_min + ) and ( # is no upper limit exceeded ? + self.cur <= self.cur_max and self.vac <= self.vac_max and self.vac_acc <= self.vac_dyn + ) + + self.conditions_stop_injection = ( + # is upper current limit reached/exceeded? + self.cur >= self.cur_max or self.vac >= self.vac_max + ) + + self.conditions_abort_injection = ( + # is any upper limit reached/exceeded? + self.vac_acc >= self.vac_dyn or self.cur > self.cur_max * 1.02 + # or self.injguard != 1 + ) + + def stop_injection(self): + pvs = self.pvs + + # disable super duper master fire trigger + pvs.trig_firego.put(0) + + # stop injection events + pvs.trig_booinj.put(0) + pvs.trig_bormp1.put(0) + pvs.trig_bormp2.put(0) + pvs.trig_booext.put(0) + pvs.trig_rininj.put(0) + + self.injection = 0 + + # prepare top-up analysis + self.topup_I0 = self.cur + self.topup_t0 = perf_counter() + + # # create thread that restarts phase feedback after 2 seconds + # if self.timerthreadready: + + # tt = threading.Timer(10, self.start_linac_phasefeedback) + # tt.start() + # print('threadtimer started....') + # self.timerthreadready = 0 + + def start_injection(self): + pvs = self.pvs + + # # injection follow bucket workaround for linac (https://elog-gfa.psi.ch/SLS/64299) + # # Before making injection, disable the LLRF phase alarms and feedback ... + # pvs.linac_llrf_phaseFB_PBU_HIHI.put(360) + # pvs.linac_llrf_phaseFB_FBU_HIHI.put(360) + # pvs.linac_llrf_phaseFB_MOD1_HIHI.put(360) + # pvs.linac_llrf_phaseFB_MOD2_HIHI.put(360) + # pvs.linac_llrf_phaseFB_PBU_LOLO.put(-360) + # pvs.linac_llrf_phaseFB_FBU_LOLO.put(-360) + # pvs.linac_llrf_phaseFB_MOD1_LOLO.put(-360) + # pvs.linac_llrf_phaseFB_MOD2_LOLO.put(-360) + # pvs.linac_llrf_phaseFB1.put(0) + # pvs.linac_llrf_phaseFB2.put(0) + # print('phaseFB OFF') + # self.timerthreadready = 1 + # sleep(0.5) + + # enable super duper master fire trigger + pvs.trig_firego.put(1) + + def prepare_injection(self): + pvs = self.pvs + + # ensure correct injector settings + if self.cur > pvs.current_threshold.get(): + pvs.gun_grid.put(self.grid_fpfb) + else: + pvs.gun_grid.put(self.grid_accum) + + self.cycles_BOIN_rb = ( + self.cycles_BOIN_sp - self.wait4warm["AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL"] + ) + self.cycles_BOMB_rb = ( + self.cycles_BOMB_sp - self.wait4warm["AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL"] + ) + self.cycles_BOME_rb = ( + self.cycles_BOME_sp - self.wait4warm["AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL"] + ) + self.cycles_BOEX_rb = ( + self.cycles_BOEX_sp - self.wait4warm["AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL"] + ) + self.cycles_SRIN_rb = ( + self.cycles_SRIN_sp - self.wait4warm["AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL"] + ) + + self.cycles_rem = np.nanmax( + [ + self.cycles_BOIN_rb, + self.cycles_BOMB_rb, + self.cycles_BOME_rb, + self.cycles_BOEX_rb, + self.cycles_SRIN_rb, + ] + ) + + if self.cycles_rem == self.cycles_BOIN_sp: + pvs.trig_booinj.put(1) + if self.cycles_rem == self.cycles_BOMB_sp: + pvs.trig_bormp1.put(1) + if self.cycles_rem == self.cycles_BOME_sp: + pvs.trig_bormp2.put(1) + if self.cycles_rem == self.cycles_BOEX_sp: + pvs.trig_booext.put(1) + if self.cycles_rem == self.cycles_SRIN_sp: + pvs.trig_rininj.put(1) + + pvs.cycles_BOIN_rb.put(self.cycles_BOIN_rb) + pvs.cycles_BOMB_rb.put(self.cycles_BOMB_rb) + pvs.cycles_BOME_rb.put(self.cycles_BOME_rb) + pvs.cycles_BOEX_rb.put(self.cycles_BOEX_rb) + pvs.cycles_SRIN_rb.put(self.cycles_SRIN_rb) + + def start_scrubbing(self): + pvs = self.pvs + + if self.scrubbi == 1: + pvs.trig_pinger_v.put(1) + elif self.scrubbi == 2: + pvs.trig_pinger_h.put(1) + elif self.scrubbi == 3: + pvs.trig_pinger_v.put(1) + pvs.trig_pinger_h.put(1) + elif self.scrubbi == 4: + for i in range(self.mbfby_sp): + pvs.mbfby_gain.put(i + 1) + sleep(0.05) + elif self.scrubbi == 5: + for i in range(self.mbfbx_sp): + pvs.mbfbx_gain.put(i + 1) + sleep(0.05) + elif self.scrubbi == 6: + for i in range(self.mbfby_sp): + pvs.mbfby_gain.put(i + 1) + sleep(0.05) + for i in range(self.mbfbx_sp): + pvs.mbfbx_gain.put(i + 1) + sleep(0.05) + elif self.scrubbi == 7: + for i in range(self.mbfby_sp): + pvs.mbfby_gain.put(i + 1) + sleep(0.05) + pvs.mbfby_sweep_onoff.put(1) + + print("scrubbing started...") + + def stop_scrubbing(self): + pvs = self.pvs + + pvs.mbfbx_gain.put(0) + pvs.mbfby_gain.put(0) + pvs.trig_pinger_h.put(0) + pvs.trig_pinger_v.put(0) + + if self.scrubbi == 7: + self.mbfby_sweepfreq_rb = np.round(pvs.mbfby_sweepfreq_rb.get()) + pvs.mbfby_sweep_onoff.put(0) + pvs.mbfby_sweepfreq_start.put(self.mbfby_sweepfreq_rb) + pvs.mbfby_freq_sp.put(self.mbfby_sweepfreq_rb) + + def pause_scrubbing(self): + pvs = self.pvs + + if self.scrubbi > 0: + pvs.mbfbx_gain.put(0) + pvs.mbfby_gain.put(0) + pvs.trig_pinger_h.put(0) + pvs.trig_pinger_v.put(0) + + if self.scrubbi == 7: + self.mbfby_sweepfreq_rb = np.round(pvs.mbfby_sweepfreq_rb.get()) + pvs.mbfby_sweep_onoff.put(0) + pvs.mbfby_sweepfreq_start.put(self.mbfby_sweepfreq_rb) + pvs.mbfby_freq_sp.put(self.mbfby_sweepfreq_rb) + + def set_status(self, status, wait=0): + pvs = self.pvs + + if self.info != status: + self.info = status + + if wait == 0: + pvs.info.put(status) + + if wait > 0: + pvs.info.put(status + ", Wait {:.0f}s".format(wait)) + + ## define some "static" class attributes, i.e., persistent over every class call v = vals() + # trigger for execution of loop (controlled by PV callback) + ChangeTrue = 0 + # current state of callback + CallbackActive = 0 + # start time for next loop firing, if no vacuum changes + tl = perf_counter() + # waittime before injection after preparation + tp = perf_counter() + # status for GUI message + status = "Service Restarted" + # injection abort status + abort = 0 + # injection abort timer + abort_t0 = perf_counter() + # states of state machine + states = { + "abort": "Injection Abort", + "decay + scrub": "Decaying Beam, Scrub ON", + "decay - scrub": "Decaying Beam, Scrub OFF", + "inject": "Injecting", + "wait 4 master": "Waiting for Master Trigger", + "wait 4 manual": "Master Manual Mode Required", + "warmup": "Top Up Save Warmup", + "pause": "Service Paused", + } + + # define callback function to trigger loop execution on change of corresponding pv change + def InjectionCallback(self, pvname=None, value=None, char_value=None, **kw): + # trigger execution of loop with actual callback since execution of code here not reliable + self.ChangeTrue += 1 + + def WarmupCallback(self, pvname=None, value=None, char_value=None, **kw): + # trigger execution of loop with actual callback since execution of code here not reliable + self.wait4warm[pvname] += 1 + self.ChangeTrue += 1 diff --git a/services/scrubbing/current/app/tests/test_app.py b/services/scrubbing/current/app/tests/test_app.py index 4e3b1a8..693f7c8 100644 --- a/services/scrubbing/current/app/tests/test_app.py +++ b/services/scrubbing/current/app/tests/test_app.py @@ -4,6 +4,5 @@ from agebd_scrubbing import PVs, Service def test_app(): service_name = "DUMMY" pvs = PVs(service_name=service_name) - service = Service(name=service_name, pvs=pvs) - service.CallbackFired = 1 + service = Service(pvs=pvs) service.update() diff --git a/services/scrubbing/current/app/uv.lock b/services/scrubbing/current/app/uv.lock index c2400b2..457a790 100644 --- a/services/scrubbing/current/app/uv.lock +++ b/services/scrubbing/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [ From 07f68e6634f2b9e71bd0f5a53231aeb29bc94d2a Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 16:09:21 +0200 Subject: [PATCH 35/42] feat: migrate shifttool python service --- services/shifttool/current/app/pyproject.toml | 1 + .../current/app/src/agebd_shifttool/main.py | 2 +- .../app/src/agebd_shifttool/service.py | 288 ++++++++++++++---- 3 files changed, 234 insertions(+), 57 deletions(-) diff --git a/services/shifttool/current/app/pyproject.toml b/services/shifttool/current/app/pyproject.toml index 990a34c..e5be901 100644 --- a/services/shifttool/current/app/pyproject.toml +++ b/services/shifttool/current/app/pyproject.toml @@ -6,6 +6,7 @@ requires-python = "==3.10.*" dependencies = [ "agebd", ] +# TODO: elog [dependency-groups] dev = [ diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index a96df33..01aa2ab 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -5,9 +5,9 @@ from agebd.runner import CallbackRunner from agebd.utils import init_logging from agebd_shifttool import PVs, Service - # TODO: remove: cicd test 10 + def main( log_level: LogLevel = typer.Option( LogLevel.INFO, diff --git a/services/shifttool/current/app/src/agebd_shifttool/service.py b/services/shifttool/current/app/src/agebd_shifttool/service.py index a5c4ea0..78b6503 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/service.py +++ b/services/shifttool/current/app/src/agebd_shifttool/service.py @@ -1,12 +1,17 @@ +import locale import time +from datetime import datetime +from time import time -from epics import dbr +import elog -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class + +# Setze die Locale auf Deutsch (z. B. 'de_DE' oder 'de_CH' für Schweiz) +locale.setlocale(locale.LC_TIME, "de_CH.UTF-8") # oder 'de_CH.UTF-8' __version__ = printgetversion(__file__) @@ -14,36 +19,147 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-SHIFTTOOL:AO") # TODO: is this a good PV to use? + req_MakeElog = PV("AGEOP-SHIFTTOOL:REQ-SHIFT-ENTRY.VAL") + req_UpdateTeam = PV("AGEOP-SHIFTTOOL:REQ-UPDATE-TEAM.VAL") - ## Service specific PVs from other IOCs - # ... + shift = PV("AGEOP-SHIFTTOOL:TXT-SHIFT.VAL") + crew = PV("AGEOP-SHIFTTOOL:TXT-SHIFT-CREW.VAL") + + operators = [ + PV("AGEOP-SHIFTTOOL:TXT-OPERATOR-01.VAL"), + PV("AGEOP-SHIFTTOOL:TXT-OPERATOR-02.VAL"), + PV("AGEOP-SHIFTTOOL:TXT-OPERATOR-03.VAL"), + PV("AGEOP-SHIFTTOOL:TXT-OPERATOR-04.VAL"), + PV("AGEOP-SHIFTTOOL:TXT-OPERATOR-05.VAL"), + ] + links = { + "Problem-01": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-01.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=Downtime", + ], + "Problem-02": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-02.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=Beamdrop", + ], + "Problem-03": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-03.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=Lifetime", + ], + "Problem-04": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-04.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=Beamsize", + ], + "Problem-05": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-05.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=keiner", + ], + "Problem-06": [ + PV("AGEOP-SHIFTTOOL:LINK-Problem-06.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Problem&pAutor=Rast%2C%20Streich%2C%20Weber&pEffekt=anderer", + ], + "Optimierung-01": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-01.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung%20Transfer", + ], + "Optimierung-02": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-02.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung%20Tau%2FYsig", + ], + "Optimierung-03": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-03.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung", + ], + "Optimierung-04": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-04.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung", + ], + "Optimierung-05": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-05.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung", + ], + "Optimierung-06": [ + PV("AGEOP-SHIFTTOOL:LINK-Optimierung-06.VAL"), + "https://elog-gfa.psi.ch/sls/?cmd=Neu&pEintrag=Tuning&pAutor=Rast%2C%20Streich%2C%20Weber&pTitel=Optimierung", + ], + "Piquet": [ + PV("AGEOP-SHIFTTOOL:LINK-Piquet.VAL"), + ], + "Info": [ + PV("AGEOP-SHIFTTOOL:LINK-Info.VAL"), + ], + "AktuellesProtokoll": [ + PV("AGEOP-SHIFTTOOL:LINK-AktuellesProtokoll.VAL"), + ], + "AndereEintraege-01": [ + PV("AGEOP-SHIFTTOOL:LINK-AndereEintraege-01.VAL"), + ], + "AndereEintraege-02": [ + PV("AGEOP-SHIFTTOOL:LINK-AndereEintraege-02.VAL"), + ], + "AndereEintraege-03": [ + PV("AGEOP-SHIFTTOOL:LINK-AndereEintraege-03.VAL"), + ], + "ListenAnzeigen-01": [ + PV("AGEOP-SHIFTTOOL:LINK-ListenAnzeigen-01.VAL"), + ], + "ListenAnzeigen-02": [ + PV("AGEOP-SHIFTTOOL:LINK-ListenAnzeigen-02.VAL"), + ], + "ListenAnzeigen-03": [ + PV("AGEOP-SHIFTTOOL:LINK-ListenAnzeigen-03.VAL"), + ], + "ListenAnzeigen-04": [ + PV("AGEOP-SHIFTTOOL:LINK-ListenAnzeigen-04.VAL"), + ], + "PiquetWoche": [ + PV("AGEOP-SHIFTTOOL:LINK-PiquetWoche.VAL"), + ], + "OffeneAuftraege": [ + PV("AGEOP-SHIFTTOOL:LINK-OffeneAuftraege.VAL"), + ], + } + + minisave = [ + PV("AGEBD-PARAMS:LIFETIME.VAL"), + PV("AGEBD-DBPM3CURR:CURRENT-AVG.VAL"), + PV("AGEBD-PARAMS:INJECTION-RATE.VAL"), + PV("AGEBD-DBPM3CURR:ACCUMULATED-BEAM-DOSE.VAL"), + PV("AGEOP-CPCL-TRANSMISSION:ICT-BRTL_2_BPM-RING.VAL"), + PV("ARSGE-CECL-FOFB1:X-RMS-UM.VAL"), + PV("ARSGE-CECL-FOFB1:Y-RMS-UM.VAL"), + PV("X01DD-FE-ABS1:STATUS.VAL"), + PV("X08DB-FE-ABS1:STATUS.VAL"), + PV("X01DA-FE-ABS1:STATUS.VAL"), + PV("X01DA-OP-PSYS:SH-A-OPEN.VAL"), + PV("X02DA-FE-ABS1:STATUS.VAL"), + PV("X02DA-OP-PSYS:SH-A-OPEN.VAL"), + PV("X06DA-FE-ABS1:STATUS.VAL"), + PV("X06DA-OP-PSYS:SH-A-OPEN.VAL"), + PV("X07DA-FE-ABS1:STATUS.VAL"), + PV("X07D-OP-PSYS:SH-A-OPEN.VAL"), + PV("X07DB-FE-ABS1:STATUS.VAL"), + PV("X07D-OP-PSYS:SH-B-OPEN.VAL"), + PV("X10DA-FE-ABS1:STATUS.VAL"), + PV("X10DA-OP-PSYS:SH-A-OPEN.VAL"), + PV("X04SA-UIND:GAP-READ.VAL"), + PV("X04SA-UIND:SCTRL.VAL"), + PV("X06SA-UIND:GAP-READ.VAL"), + PV("X06SA-UIND:SCTRL.VAL"), + PV("X09LB-UIND:GAP-READ.VAL"), + PV("X09LB-UIND:SCTRL.VAL"), + PV("X10SA-UIND:GAP-READ.VAL"), + PV("X10SA-UIND:SCTRL.VAL"), + PV("X12SA-UIND:GAP-READ.VAL"), + PV("X12SA-UIND:SCTRL.VAL"), + ] + + NShiftTasks = PV("AGEOP-SHIFTTOOL:CNT-TODO.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-SHIFTTOOL:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-SHIFTTOOL:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("AGEOP-SHIFTTOOL:REQ-CALC.VAL") class Service(BaseService[PVs]): @@ -56,38 +172,98 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + # FACILITY = SLS + self.logbook = elog.open( + "https://elog-gfa.psi.ch/SLS/", + user="robot", + password="robot", + use_ssl=True, + ) + self.path = "/sls/op/data/applications/minisave/" + + def minisave(self): + + # table overview of current machine and beamline parameters + + return def update(self): - # when callback is fired, this code will be executed + pvs = self.pvs + if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + self.req_UpdateTeam = pvs.req_UpdateTeam.get() + self.req_MakeElog = pvs.req_MakeElog.get() + print(self.req_UpdateTeam, self.req_MakeElog) + + # if shift crew update request detected update current shift crew + if self.req_UpdateTeam or self.req_MakeElog: + pvs.req_UpdateTeam.put(0) + print("Team aktualisieren") + + self.logtxt = [] + self.logtxt.append("Eingetragene Mannschaft:") + self.date = datetime.now() + self.hour = int(self.date.strftime("%H")) + + # Format the date + self.day_abbr = self.date.strftime( + "%a" + ) # Abbreviated weekday (e.g., "Mi" for Mittwoch) + self.date_str = self.date.strftime( + "%d-%b-%Y" + ) # Day-Month-Year (e.g., "17-Jun-2026") + self.week_num = self.date.isocalendar()[1] # ISO calendar week number (e.g., 25) + self.timestamp = f"{self.day_abbr} {self.date_str} KW{self.week_num}" + + if self.hour > 4 and self.hour < 8: + self.shift = "Früh-Schicht" + elif self.hour > 12 and self.hour < 16: + self.shift = "Spät-Schicht" + elif self.hour > 20: + self.shift = "Nacht-Schicht" + else: + self.shift = "Verschlafen" + + self.shift += ", " + self.timestamp + pvs.shift.put(self.shift) + + self.operators = [] + for op in pvs.operators: + op = op.get(as_string=True) + if len(op) > 1: + self.operators.append(op) + + print(self.operators) + self.crew = ", ".join(self.operators) + pvs.crew.put(self.crew) + self.logtxt.append(self.crew) + print(self.crew) + + # if shift entry request detected and current shift entry not yet made, make it + if self.req_MakeElog: + pvs.req_MakeElog.put(0) + print("Schicht eintragen") + + # Write to elog + self.logtxt = "".join(self.logtxt) + + self.dict_of_attributes = { + "Wann": time(), + "Autor": self.crew, + "Eintrag": "Schicht-Übergabe", + "Titel": self.shift, + "Encoding": "html", + } + + print(" ...elog entry prepared...") + + self.msg_id = self.logbook.post( + self.logtxt, + attributes=self.dict_of_attributes, + suppress_email_notification=True, + attribute_as_param="value", + ) + print(" ...elog entry submitted...") # callback done self.CallbackFired = 0 - - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., - - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() - - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### From 70217d68eff33b96915aab3029e2de8616f84632 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 16:17:17 +0200 Subject: [PATCH 36/42] feat: migrate taupct python service --- services/taupct/current/app/pyproject.toml | 1 + .../current/app/src/agebd_taupct/main.py | 2 +- .../current/app/src/agebd_taupct/service.py | 155 +++++++++++++----- services/taupct/current/app/uv.lock | 6 +- 4 files changed, 124 insertions(+), 40 deletions(-) diff --git a/services/taupct/current/app/pyproject.toml b/services/taupct/current/app/pyproject.toml index cf97407..c5e2511 100644 --- a/services/taupct/current/app/pyproject.toml +++ b/services/taupct/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-TAUPCT Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index 64fb8a6..4559f96 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -5,9 +5,9 @@ from agebd.runner import CallbackRunner from agebd.utils import init_logging from agebd_taupct import PVs, Service - # TODO: remove: cicd test 10 + def main( log_level: LogLevel = typer.Option( LogLevel.INFO, diff --git a/services/taupct/current/app/src/agebd_taupct/service.py b/services/taupct/current/app/src/agebd_taupct/service.py index b1d2135..ec2f515 100644 --- a/services/taupct/current/app/src/agebd_taupct/service.py +++ b/services/taupct/current/app/src/agebd_taupct/service.py @@ -1,12 +1,12 @@ -import time +from time import sleep +import numpy as np from epics import dbr -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +14,29 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TAUPCT:AO") # TODO: is this a good PV to use? + NsamplesTAU = PV("AGEBD-TAUPCT:CONTROL-NSAMPLES-FIT-TAU.VAL") + NsamplesROC = PV("AGEBD-TAUPCT:CONTROL-NSAMPLES-FIT-ROC.VAL") + MinCurr = PV("AGEBD-TAUPCT:CONTROL-MIN-CURR.VAL") + + # Output PVs + inj_tau = PV("AGEBD-TAUPCT:TAU.VAL") + inj_tau_err = PV("AGEBD-TAUPCT:TAU-ERR.VAL") + inj_rate = PV("AGEBD-TAUPCT:INJRATE.VAL") + inj_rate_err = PV("AGEBD-TAUPCT:INJRATE-ERR.VAL") ## Service specific PVs from other IOCs - # ... + inj_active = PV("AGEBD-PARAMS:INJECTION-ACTIVE.VAL") + dump_valve = PV("ARS01-VVPG-0210:PLC_STATUS.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TAUPCT:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TAUPCT:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("ARS07-CECL-DPCT0:CURR.VAL", auto_monitor=dbr.DBE_VALUE) + # CallbackPV = PV('ARS07-DPCT-0000:AVG-CURR.VAL', auto_monitor = dbr.DBE_VALUE) + # ARS07-DPCT-0000:CURR (5 Hz, i.e., dt = 0.2 s) + # ARS07-DPCT-0000:AVG-CURR (5 Hz, i.e., dt = 0.2 s) class Service(BaseService[PVs]): @@ -56,17 +49,105 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.reset() + + def reset(self): + pvs = self.pvs + + self.IterSinceReset = 0 + self.NsamplesTAU = int(pvs.NsamplesTAU.get()) + self.NsamplesROC = int(pvs.NsamplesROC.get()) + NsamplesMAX = int(np.nanmax([self.NsamplesTAU, self.NsamplesROC])) + self.MinCurr = pvs.MinCurr.get() + self.t = np.empty(NsamplesMAX) + self.I = np.empty(NsamplesMAX) + self.inj_active = pvs.inj_active.get() def update(self): + pvs = self.pvs + # when callback is fired, this code will be executed if self.CallbackFired: ####################################################################################### ####################################################################################### # here goes all the code that your service # is supposed to be running when the callback is fired - time.sleep(1) + + conditions_cb_invalid = ( + not self.inj_active == pvs.inj_active.get() # <-- injection status changed + or self.CallbackValue < self.MinCurr # <-- stored beam + or not 0 <= self.CallbackValue <= 500 # <-- measurement realistic + ) + + # set values to zero and wait without beam + if not pvs.dump_valve.get() == 1: + pvs.inj_tau.put(np.nan) + pvs.inj_tau_err.put(0.0) + pvs.inj_rate.put(0.0) + pvs.inj_rate_err.put(0.0) + sleep(0.5) + + elif conditions_cb_invalid: + self.reset() + print("Callback Invalid --> Reset ({:})".format(self.CallbackTimestamp)) + + else: + self.t[:-1] = self.t[1:] + self.I[:-1] = self.I[1:] + self.t[-1] = self.CallbackTimestamp + self.I[-1] = self.CallbackValue + + self.IterSinceReset += 1 + + if ( + self.IterSinceReset > self.NsamplesROC + and self.IterSinceReset > self.NsamplesTAU + ): + t = self.t - self.t[0] + + p, pcov = np.polyfit(t, self.I, 1, cov=True) + perr = np.sqrt(np.diag(pcov)) + + injrate = p[0] * 60 + injrate_err = perr[0] * 60 + + pvs.inj_rate.put(injrate) + pvs.inj_rate_err.put(injrate_err) + + # injection rate in mA/hour to minimize risk of log(x) with x < 0: + injrate = injrate * 60 + injrate_err = injrate_err * 60 + + # if injrate/p[1] < 1: + if not self.inj_active and self.IterSinceReset > self.NsamplesTAU: + tau = 1 / np.log(1 - injrate / p[1]) # (-dt in hours) / ln(1 - dI/I0) + tau_err = injrate_err * (-1) / ( + (injrate - p[1]) * np.log(1 - injrate / p[1]) ** 2 + ) + perr[1] * (injrate_err) / ( + p[1] * (injrate - p[1]) * np.log(1 - injrate / p[1]) ** 2 + ) + + pvs.inj_tau.put(tau) + pvs.inj_tau_err.put(tau_err) + + elif self.IterSinceReset > self.NsamplesROC: + t = self.t[-self.NsamplesROC :] + I = self.I[-self.NsamplesROC :] + + t = t - t[0] + + p, pcov = np.polyfit(t, I, 1, cov=True) + perr = np.sqrt(np.diag(pcov)) + + injrate = p[0] * 60 + injrate_err = perr[0] * 60 + + pvs.inj_rate.put(injrate) + pvs.inj_rate_err.put(injrate_err) + + # injection rate in mA/hour to minimize risk of log(x) with x < 0: + injrate = injrate * 60 + injrate_err = injrate_err * 60 ####################################################################################### ####################################################################################### @@ -77,17 +158,15 @@ class Service(BaseService[PVs]): ####################################################################################### # here goes all the code that your service # is supposed to be running in any case, e.g., - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() - + conditions_reset = ( + not self.NsamplesROC == pvs.NsamplesROC.get() + or not self.NsamplesTAU == pvs.NsamplesTAU.get() + or not self.MinCurr == pvs.MinCurr.get() + ) + if conditions_reset: + self.reset() # maybe sleep to limit the update loop execution rate - time.sleep(1) + # sleep(1) ####################################################################################### ####################################################################################### diff --git a/services/taupct/current/app/uv.lock b/services/taupct/current/app/uv.lock index 41c5a2b..cc8aea1 100644 --- a/services/taupct/current/app/uv.lock +++ b/services/taupct/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [ From 17078d934b85532adf297a83662567c233942407 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 16:25:29 +0200 Subject: [PATCH 37/42] feat: migrate timing python service --- services/timing/current/app/pyproject.toml | 1 + .../current/app/src/agebd_timing/service.py | 302 ++++++++++++++---- services/timing/current/app/uv.lock | 6 +- 3 files changed, 253 insertions(+), 56 deletions(-) diff --git a/services/timing/current/app/pyproject.toml b/services/timing/current/app/pyproject.toml index 7bad054..d1be494 100644 --- a/services/timing/current/app/pyproject.toml +++ b/services/timing/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-TIMING Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/timing/current/app/src/agebd_timing/service.py b/services/timing/current/app/src/agebd_timing/service.py index 3f81c3e..32641ed 100644 --- a/services/timing/current/app/src/agebd_timing/service.py +++ b/services/timing/current/app/src/agebd_timing/service.py @@ -1,12 +1,11 @@ -import time +from time import perf_counter, sleep -from epics import dbr +import numpy as np -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +13,56 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TIMING:AO") # TODO: is this a good PV to use? + ## dedicated timing service pvs + # separate go pv to enable start/stop without interrupting processing of, e.g., fill pattern changes + go = PV("AGEBD-TIMING:GO.VAL") + # fillpattern definition in top up panel + fillpattern_string = PV("AGEBD-TIMING:CONTROL-FILLPATTERN-string.VAL") + # request to reset index to start with zero bucket (e.g., after beam loss) + zero_bucket = PV("AGEBD-TIMING:ZERO-TARGET-BUCKET.VAL") + # waveform to reflect current target bucket in filling pattern plots on console slsw02 + plot_target_bucket = PV("AGEBD-TIMING:TARGET-BUCKET.VAL") + # waveform to reflect current target filling pattern in filling pattern plots on console slsw02 + plot_target_fillpattern = PV("AGEBD-TIMING:TARGET-FILLPATTERN.VAL") + # current above which the feedback mode is started + current_threshold = PV("AGEBD-TIMING:CURRENT-THRESHOLD.VAL") + # choice of filling pattern feedback mode to use (0: BPM, 1: APD, 2: FPFB or 3: every nth bucket) + fpfb_mode = PV("AGEBD-TIMING:FPFB-MODE.VAL") + # choice of n for every nth bucket mode + fpfb_nth = PV("AGEBD-TIMING:FPFB-NTH.VAL") - ## Service specific PVs from other IOCs - # ... + ## other pvs used by this service + # Beam current measured by PCT + pct_beam_current = PV("ARS07-DPCT-0000:CURR.VAL") + # trig_master: enables the storage-ring injection (start sending events) + trig_master = PV("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") + # trig_secret: everything is correct with the "machine" and injection can be done + trig_secret = PV("AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER.VAL") + # filling pattern measurement from BPM + fill_meas_bpm = PV("ARSGE-CECL-FPFB:FPFB-BUNCH-CHARGE.VAL") + # filling pattern measurement from APD + fill_meas_apd = PV("X08DB-DFPM-DI:FW-SIS0DAQ-CH0-FPM-WF.VAL") + # Pedro's filling pattern feedback reference definition + fpfb_ref = PV("ARSGE-CECL-FPFB:FPFB-REF-FILL-PATTERN.VAL") + # Pedro's filling pattern feedback suggested bucket indices + fpfb_indices = PV("ARSGE-CECL-FPFB:BUNCH-IDX-INJECTION-LIST.VAL") + + ## manual injection timing master pvs + # target bucket for injection + bt = PV("AGETI-CVME-MASTER-TMA:FP-Manual-Bucket-SP.VAL") + # fire request for gun + fire = PV("AGETI-CVME-MASTER-TMA:FP-Manual-Trigger-SP.VAL") + + # feedback from linac evr + # lastbucket = PV('ALIRF-VME-A:Last-Bucket-I.VAL') + # nextbucket = PV('ALIRF-VME-A:Bucket-I.VAL') def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TIMING:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TIMING:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + # trigger gun fire followed by bucket update with start of sequence event (3 Hz) + self.CallbackPV = PV("AGETI-CVME-MASTER-TMA:Evt-SOS-EVRCount-I.VAL") class Service(BaseService[PVs]): @@ -56,38 +75,211 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.index = 0 + self.fire = 1 + self.timer = perf_counter() + self.updatefp() + self.master = pvs.trig_master.get() and pvs.trig_secret.get() + self.getmaster() def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs - # callback done + if self.CallbackFired: + # confirm callback function run self.CallbackFired = 0 - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + # get next bucket + self.updatebucket() - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + # check if master trigger state changed + self.getmaster() - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + if self.master and pvs.go.get(): + # update target bucket + # write next bucket to timing master + if -1 < self.bucket < 481: + pvs.bt.put(self.bucket, wait=True) + else: + print(f"invalid bucket: {self.bucket:}") + self.lastbuckets[:-1] = self.lastbuckets[1:] + self.lastbuckets[-1] = self.bucket - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + # request firing of gun + pvs.fire.put(self.fire, wait=True) + self.Nshots += 1 + + # increment target bucket for next shot by 1 + self.index += 1 + + if self.index > self.N - 1: + self.index = 0 + + self.CallbackFired = 0 + + # update fillpattern if pv has changed or zeroing requested + elif self.fps != pvs.fillpattern_string.get() or pvs.zero_bucket.get(): + self.updatefp() + pvs.zero_bucket.put(0) + + if self.master != self.master_old: + # wait for some 3 Hz cycles in case master trigger was just switched on + # --> safety in case it will be switched off again very fast + # --> avoid going into callback loop of last 3 Hz cycle with arbitrary delay, i.e., off sync + self.Nshots = self.NshotsMax + 1 + self.updatebucket() + + if self.master: + sleep(1) + + # stop self if master was switched off + else: + pvs.go.put(0) + + def getmaster(self): + pvs = self.pvs + + self.master_old = self.master + self.master = pvs.trig_master.get() and pvs.trig_secret.get() + + def updatefp(self): + pvs = self.pvs + + self.fps = pvs.fillpattern_string.get() + + try: + check1 = ( + self.fps.replace("-", "").replace(" ", "").isdecimal() + ) # also catches empty string + check2, check3 = 0, 0 + if check1: + fillpattern = [] + for v in [x for x in self.fps.split(" ")]: + if "-" in v and not "" in v.split("-"): + i, f = [int(x) for x in v.split("-")] + fillpattern.append(np.arange(int(i), int(f))) + else: + fillpattern.append([int(v)]) + + self.fillpattern = np.sort(np.concatenate(fillpattern)) + + check2 = np.max(self.fillpattern) < 481 + check3 = np.min(self.fillpattern) > -1 + + if not check2: + pvs.fillpattern_string.put( + "Error: last bucket is > 480".encode(encoding="ascii") + ) + + elif not check3: + pvs.fillpattern_string.put( + "Error: first bucket is < 0".encode(encoding="ascii") + ) + + else: + pvs.fillpattern_string.put( + "Error: allowed chars are [0-9,-, ]".encode(encoding="ascii") + ) + + if not all([check1, check2, check3]): + sleep(1) + pvs.fillpattern_string.put("0-450".encode(encoding="ascii")) + self.fillpattern = np.arange(0, 450, 1) + + except: + pvs.fillpattern_string.put("0-450".encode(encoding="ascii")) + self.fillpattern = np.arange(0, 450, 1) + + # fill pattern as 480 long array + self.fillpattern_480 = np.zeros(480) + self.fillpattern_480[self.fillpattern] = 1 + pvs.plot_target_fillpattern.put(self.fillpattern_480) + pvs.fpfb_ref.put(self.fillpattern_480) + + # fill pattern as 480 long array of bools + self.fillpattern_bool = self.fillpattern_480.astype(bool) + + # length of fill pattern to loop over + self.N = len(self.fillpattern) + + # nr. of shots until new target fillpattern is retrieved + self.NshotsMax = int(self.N / 15 + 1) + self.Nshots = self.NshotsMax + 1 + + # prepare array for list of last buckets that got a shot + self.lastbuckets = np.ones(self.NshotsMax) * -1 + + # reset bucket index + self.index = 0 + + def updatebucket(self): + pvs = self.pvs + + # use selected filling pattern feedback mode above threshold current to update fill pattern before updating bucket + if pvs.pct_beam_current.get() > pvs.current_threshold.get() and ( + self.Nshots > self.NshotsMax or (perf_counter() - self.timer) > 30 + ): + fillpattern_old = self.fillpattern + self.Nshots = 0 + + # update timer to only update every XX seconds + self.timer = perf_counter() + + # (0: BPM, 1: APD, 2: FPFB or 3: every nth bucket) + self.fpfb_mode = pvs.fpfb_mode.get() + + # fpfb based on sorted list of buckets from BPM fill pattern measurement + if self.fpfb_mode == 0: + self.fill_meas_bpm = pvs.fill_meas_bpm.get() + self.fillpattern = np.argsort(self.fill_meas_bpm[self.fillpattern_bool]) + + # fpfb based on sorted list of buckets from APD fill pattern measurement + elif self.fpfb_mode == 1: + self.fill_meas_apd = pvs.fill_meas_apd.get() + self.fillpattern = np.argsort(self.fill_meas_apd[self.fillpattern_bool]) + + # fpfb based on sorted list of buckets given by fpfb from pedro + elif self.fpfb_mode == 2: + self.fillpattern = pvs.fpfb_indices.get()[: self.N] + + # fpfb based on filling every nth bucket + elif self.fpfb_mode == 3: + # calculate interleaved fill pattern array (has same length and reference as before, i.e., these do not need to be updated) + self.fpfb_nth = int(pvs.fpfb_nth.get()) + self.fillpattern = np.concatenate( + [self.fillpattern[n :: self.fpfb_nth] for n in range(self.fpfb_nth)] + ) + + if self.fpfb_mode in [0, 1, 2]: + # reset bucket index + self.index = 0 + + indices = np.sort( + np.concatenate( + [np.where(bucket == self.fillpattern)[0] for bucket in self.lastbuckets] + ) + ) + # print(indices) + + # calculate next bucket + self.bucket = self.fillpattern[self.index] + if (self.bucket in self.lastbuckets) and self.N > 1: + # increment target bucket for next shot by 1 + self.index += 1 + + if self.index > self.N - 1: + self.index = 0 + + self.bucket = self.fillpattern[self.index] + + plot_target_bucket = np.zeros(480) + plot_target_bucket[self.bucket] = 1 + pvs.plot_target_bucket.put(plot_target_bucket) + + # print('self.bucket', self.bucket) + + # # write next bucket to timing master + # if -1 < self.bucket < 481: + # pvs.bt.put(self.bucket, wait=True) + # else: + # print(f'invalid bucket: {self.bucket:}') diff --git a/services/timing/current/app/uv.lock b/services/timing/current/app/uv.lock index 9cc0322..9eca90c 100644 --- a/services/timing/current/app/uv.lock +++ b/services/timing/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [ From f07e2e8a0a8b084bc895ab4f411b31e59f107594 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 16:41:21 +0200 Subject: [PATCH 38/42] feat: migrate topuptool python service -- best effort --- services/topuptool/current/app/pyproject.toml | 1 + .../current/app/src/agebd_topuptool/main.py | 12 +- .../current/app/src/agebd_topuptool/runner.py | 209 ++++++++++++++ .../app/src/agebd_topuptool/service.py | 269 ++++++++++++++---- .../topuptool/current/app/tests/test_app.py | 3 +- services/topuptool/current/app/uv.lock | 6 +- 6 files changed, 440 insertions(+), 60 deletions(-) create mode 100644 services/topuptool/current/app/src/agebd_topuptool/runner.py diff --git a/services/topuptool/current/app/pyproject.toml b/services/topuptool/current/app/pyproject.toml index eeaa6db..9525511 100644 --- a/services/topuptool/current/app/pyproject.toml +++ b/services/topuptool/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-TOPUPTOOL Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index 1537f0c..b23988c 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -1,13 +1,13 @@ import typer from agebd.enums import LogLevel -from agebd.runner import CallbackRunner from agebd.utils import init_logging from agebd_topuptool import PVs, Service - +from agebd_topuptool.runner import Runner # TODO: remove: cicd test 10 + def main( log_level: LogLevel = typer.Option( LogLevel.INFO, @@ -19,11 +19,15 @@ def main( case_sensitive=False, ), ): + """ + Uses custom/old Runner because migrating to the agebd Runner would be quite + complex. + """ init_logging(log_level) service_name = "TOPUPTOOL" pvs = PVs(service_name=service_name) - service = Service(name=service_name, pvs=pvs) - runner = CallbackRunner(service=service) + service = Service(pvs=pvs) + runner = Runner(svc=service) runner.start() diff --git a/services/topuptool/current/app/src/agebd_topuptool/runner.py b/services/topuptool/current/app/src/agebd_topuptool/runner.py new file mode 100644 index 0000000..e1c36e1 --- /dev/null +++ b/services/topuptool/current/app/src/agebd_topuptool/runner.py @@ -0,0 +1,209 @@ +import traceback +from time import perf_counter, sleep + +import numpy as np +from epics import poll + +from agebd_topuptool.service import Service + + +class Runner: + def __init__(self, svc: Service) -> None: + self.svc = svc + + def start(self): + svc = self.svc + pvs = self.svc.pvs + + while not pvs.abort.get(): + if pvs.onoff.get() == 1: + # add callback for triggering the loop + if not svc.CallbackActive: + pvs.status.put("running") + pvs.vac_all.add_callback( + callback=self.svc.PressureChangeCallback, index=1, svc=svc + ) + svc.CallbackActive = 1 + + # reload control PVs + svc.update() + + # check stop/abort conitions if injection is active + if svc.injection: + # ensure disabled scrubbing during injection + svc.stop_scrubbing() + + # abort injection when limits exceeded + if svc.conditions_abort_injection: + # disable injection when upper limit reached + svc.stop_injection() + print("injection aborted") + + if not svc.abort: + svc.abort = 1 + svc.abort_t0 = perf_counter() + + svc.set_status(svc.states["abort"], wait=60) + + elif svc.conditions_stop_injection: + # disable injection when upper limit reached + svc.stop_injection() + print("injection stopped") + + # start scrubbing if activated + if svc.scrubbi: + sleep(0.1) + svc.start_scrubbing() + + svc.set_status(svc.states["decay + scrub"]) + + else: + svc.set_status(svc.states["decay - scrub"]) + + elif svc.info != svc.states["inject"]: + svc.set_status(svc.states["inject"]) + + # do nothing if master trigger missing + elif not svc.trig_master: + svc.set_status(svc.states["wait 4 master"]) + + # do nothing for 60s if injection was aborted + elif svc.abort: + dt = perf_counter() - svc.abort_t0 + + if dt > 60: + svc.abort = 0 + + else: + svc.set_status(svc.states["abort"], wait=60 - dt) + + sleep(0.1) + + # start acting when callback fired or 100 ms passed + elif svc.ChangeTrue or perf_counter() > svc.tl + 0.1: + # start time for next loop firing, if no vacuum changes + svc.tl = perf_counter() + + if svc.conditions_start_injection and svc.info not in [ + svc.states["inject"], + svc.states["warmup"], + ]: + # disable injection to be sure + pvs.trig_guntxb.put(0) + pvs.trig_gunevt.put(0) + pvs.trig_booinj.put(0) + pvs.trig_boormp.put(0) + pvs.trig_booext.put(0) + pvs.trig_rininj.put(0) + + # disable pingers for injection + svc.stop_scrubbing() + + # make sure that injection bump and pinger not both fired + sleep(0.4) + + svc.prepare_injection() + + svc.tp = perf_counter() + + # do top up analysis + svc.topup_dt = (svc.tp - svc.topup_t0) / 60 + svc.topup_dI = svc.topup_I0 - pvs.cur.get() + pvs.topup_dt.put(svc.topup_dt) + pvs.topup_dI.put(svc.topup_dI) + if svc.topup_I0 > 0: + if svc.topup_dI / svc.topup_I0 < 1: + pvs.topup_tau.put( + (-svc.topup_dt / 60) / np.log(1 - svc.topup_dI / svc.topup_I0) + ) + + svc.set_status(svc.states["warmup"], wait=20) + + elif svc.info == svc.states["warmup"]: + waited = perf_counter() - svc.tp + + if waited > 20: + # disable pingers for injection + svc.stop_scrubbing() + + sleep(0.5) + + svc.start_injection() + + svc.set_status(svc.states["inject"]) + + else: + svc.set_status(svc.states["warmup"], wait=20 - waited) + + elif svc.info in [svc.states["pause"], svc.states["wait 4 master"]]: + if svc.injection: + svc.set_status(svc.states["inject"]) + else: + if pvs.pinger_v.get(): + svc.set_status(svc.states["decay + scrub"]) + else: + svc.set_status(svc.states["decay - scrub"]) + + # stop scrubbing when deactivated + elif not svc.scrubbi: + svc.stop_scrubbing() + + # if scrubbing activated and lifetime drops below 1 hour --> stop scrubbing + elif svc.scrubbi and svc.tau < 1: + svc.stop_scrubbing() + print("Scrubbing aborted, tau < 1") + + svc.ChangeTrue = 0 + + # inform watchdog(s) + pvs.running.put(0) + + # wait for callback to fire + poll(evt=1.0e-5, iot=0.1) + + else: + # WHILE PAUSED REBOOT OF THE SCRUBBING IOC SHOULD NOT DISTURB THE SERVICE + + if svc.CallbackActive: + # remove callback + pvs.vac_all.remove_callback(index=1) + svc.CallbackActive = 0 + + # reload control PVs + svc.update() + + # disable injection and pingers when first paused + if svc.info != svc.states["pause"]: + svc.stop_injection() + svc.stop_scrubbing() + + svc.set_status(svc.states["pause"]) + pvs.status.put("paused") + + sleep(0.1) + + # sleep and inform watchdog(s) + pvs.alive.put(0) + + if pvs.abort.get(): + # confirm clean abort + pvs.status.put("killed") + print("Got Killed by Master Service!") + pvs.abortreq.put(0) + + # elif svc.crashed: + + # # confirm crash + # pvs.status.put('crashed') + # print('Service crashed on exception!') + # print('----- svc.exception.__traceback__ -----') + # print(svc.exception.__traceback__) + # print() + # print('----- traceback.format_exc() -----') + # print(traceback.format_exc()) + + else: + # confirm unknown exit + pvs.status.put("unknown crash") + print("Service crashed without exception!") + print(traceback.format_exc()) diff --git a/services/topuptool/current/app/src/agebd_topuptool/service.py b/services/topuptool/current/app/src/agebd_topuptool/service.py index 7b8fe2c..3754214 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/service.py +++ b/services/topuptool/current/app/src/agebd_topuptool/service.py @@ -1,12 +1,12 @@ -import time +from datetime import datetime +from time import perf_counter -from epics import dbr +import numpy as np +from epics import PV, dbr -from agebd.pv import LocalPVLink -from agebd.service.base import BaseService +from agebd.pv import LocalPVLink, get_pv_class from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,12 +14,58 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TOPUPTOOL:AO") # TODO: is this a good PV to use? + ## Control PVs + # top-up control mode + # topumod = PV('.VAL') + # top-up mode vacuum limits + vac_max = PV("AGEBD-TOPUPTOOL:CONTROL-VACUUM-MAX.VAL") + vac_min = PV("AGEBD-TOPUPTOOL:CONTROL-VACUUM-MIN.VAL") + # top-up mode current limits + cur_max = PV("AGEBD-TOPUPTOOL:CONTROL-CURRENT-MAX.VAL") + cur_min = PV("AGEBD-TOPUPTOOL:CONTROL-CURRENT-MIN.VAL") + # top-up mode periodic refill (using cur_max) + # topufrq = PV('.VAL') - ## Service specific PVs from other IOCs - # ... + vac_dyn = PV("AGEBD-TOPUPTOOL:CONTROL-VACUUM-DYN.VAL") + vac_dyn_frac = PV("AGEBD-TOPUPTOOL:CONTROL-VACUUM-DYN-FRAC.VAL") + + grd_max = PV("AGEBD-TOPUPTOOL:CONTROL-GUNGRID-MAX.VAL") + scrubbing = PV("AGEBD-TOPUPTOOL:CONTROL-SCRUB.VAL") + + # Input PVs + vac_all = PV("ARIVA-VMAVE-ALL:PRESS-MAX.VAL") + vac_acc = PV("ARIVA-VMAVE:PRESS-MAX.VAL") + vac_fe = PV("ARIVA-VMAVE-FE:PRESS-MAX.VAL") + # cur = PV('AGEBD-DBPM3CURR:CURRENT-AVG.VAL') + cur = PV("ARS07-DPCT-0000:CURR.VAL") + injguard = PV("AGEBD-INJECTIONGUARD:CHECK-SUM.VAL") + + injactive = PV("AGEBD-PARAMS:INJECTION-ACTIVE") + + tau = PV("AGEBD-PARAMS:LIFETIME.VAL") + + fpfb_adc = PV("ARSGE-CECL-FPFB:BEAM-DUMP-ABS-ADC-DATA") + fpfb_max = PV("ARSGE-CECL-FPFB:FPFB-BEAM-DUMP-THR") + + # Regulated PVs + trig_master = PV("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") + trig_guntxb = PV("ALIRF-VME-A-GUN:CH1-MODE.VAL") + trig_gunevt = PV("AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel.VAL") + trig_booinj = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel.VAL") + trig_boormp = PV("AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel.VAL") + trig_booext = PV( + "AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-10 + trig_rininj = PV( + "AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel.VAL" + ) # Alias AGETI-CVME-MASTER-TMA:Evt-26 + gun_grid = PV("ALIRF-GUN-GRID:V-SET.VAL") + pinger_v = PV("ARS01-MKIK-0320:CTRL-ON-OFF.VAL") + pinger_h = PV("ARS01-MKIK-0290:CTRL-ON-OFF.VAL") + + topup_dt = PV("AGEBD-TOPUPTOOL:TOPUP-DELTAT.VAL") + topup_dI = PV("AGEBD-TOPUPTOOL:TOPUP-DELTAI.VAL") + topup_tau = PV("AGEBD-TOPUPTOOL:TOPUP-TAU.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) @@ -32,62 +78,179 @@ class PVs(BasePVs): # Option 2: ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TOPUPTOOL:BO" - ) # TODO: is this a good PV to use? + self.my_pv2 = PV("AGEBD-TOPUPTOOL:BO") # TODO: is this a good PV to use? ## Service specific PVs from other IOCs # ... # TODO: class attribute names usually lowercase # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TOPUPTOOL:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("AGEBD-TOPUPTOOL:CALLBACK", auto_monitor=dbr.DBE_VALUE) # TODO: ok? -class Service(BaseService[PVs]): - def __init__( - self, - name: str, - pvs: PVs, - version: str = __version__, - sleep_interval: float = 0.1, - ): - super().__init__(name, pvs, version, sleep_interval) +class Service: + ## define some "static" class attributes, i.e., persistent over every class call v = vals() + # trigger for execution of loop (controlled by PV callback) + ChangeTrue = 0 + # current state of callback + CallbackActive = 0 + # start time for next loop firing, if no vacuum changes + tl = perf_counter() + # waittime before injection after preparation + tp = perf_counter() + # status for GUI message + status = "Service Restarted" + # injection abort status + abort = 0 + # injection abort timer + abort_t0 = perf_counter() + # states of state machine + states = { + "abort": "Injection Abort", + "decay + scrub": "Decaying Beam, Scrub ON", + "decay - scrub": "Decaying Beam, Scrub OFF", + "inject": "Injecting", + "wait 4 master": "Waiting for Master Trigger", + "warmup": "Septum Warmup", + "pause": "Service Paused", + } - # TODO: What is this for? - self.path = "sls/bd/bin" + def __init__(self, pvs: PVs): + self.pvs = pvs + + pvs.started.put(str(datetime.now())[:-7]) + pvs.version.put(__version__) + + # self.vac = np.max([pv.get() for pv in pvs.vac]) + self.vac = pvs.vac_all.get() + self.vac_acc = pvs.vac_acc.get() + # self.vac = pvs.vac_fe.get() + self.vac_array = np.repeat(self.vac_acc, 10) + self.vac_dyn = self.vac * pvs.vac_dyn_frac.get() + pvs.vac_dyn.put(self.vac_dyn * 1e9) + + self.topup_t0 = perf_counter() + self.topup_I0 = pvs.cur_min.get() + self.topup_dI = 0 + self.topup_dt = 0 def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs - # callback done - self.CallbackFired = 0 + # (re-)load input PVs + self.injection = pvs.injactive.get() + self.vac = pvs.vac_all.get() + self.vac_acc = pvs.vac_acc.get() + self.cur = pvs.cur.get() + self.trig_master = pvs.trig_master.get() + self.injguard = pvs.injguard.get() + self.info = pvs.info.get().split(",")[0] + self.tau = pvs.tau.get() - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + # (re-)load control PVs + self.vac_max = pvs.vac_max.get() * 1e-9 + self.vac_dyn = np.max(self.vac_array[:5]) * pvs.vac_dyn_frac.get() + pvs.vac_dyn.put(self.vac_dyn * 1e9) - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + # roll oldest value arr[0] to end, i.e., arr[-1] + self.vac_array = np.roll(self.vac_array, -2) + # replace oldest value with new value + self.vac_array[-2:] = self.vac_acc - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + self.vac_min = pvs.vac_min.get() * 1e-9 + self.cur_max = pvs.cur_max.get() + self.cur_min = pvs.cur_min.get() + self.grd_max = pvs.grd_max.get() + self.scrubbi = pvs.scrubbing.get() - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + self.conditions_start_injection = ( # is any lower limit reached? + self.vac <= self.vac_min or self.cur <= self.cur_min + ) and ( # is no upper limit exceeded ? + self.cur <= self.cur_max and self.vac <= self.vac_max and self.vac_acc <= self.vac_dyn + ) + + self.conditions_stop_injection = ( + # is upper current limit reached/exceeded? + self.cur >= self.cur_max or self.vac >= self.vac_max + ) + + self.conditions_abort_injection = ( + # is any upper limit reached/exceeded? + self.vac_acc >= self.vac_dyn + or np.max(pvs.fpfb_adc.get()) >= 0.95 * pvs.fpfb_max.get() + or self.cur > self.cur_max * 1.02 + or self.injguard != 1 + ) + + def stop_injection(self): + pvs = self.pvs + + # disable gun trigger + pvs.trig_guntxb.put(0) + + # stop all injection events + pvs.trig_gunevt.put(0) + pvs.trig_booinj.put(0) + pvs.trig_boormp.put(0) + pvs.trig_booext.put(0) + pvs.trig_rininj.put(0) + + self.injection = 0 + + # prepare top-up analysis + self.topup_I0 = pvs.cur.get() + self.topup_t0 = perf_counter() + + def start_injection(self): + pvs = self.pvs + + # enable gun trigger + pvs.trig_guntxb.put(2) + + def prepare_injection(self): + pvs = self.pvs + + # ensure correct injector settings + pvs.gun_grid.put(self.grd_max) + + # start all injection events + pvs.trig_gunevt.put(1) + pvs.trig_booinj.put(1) + pvs.trig_boormp.put(1) + pvs.trig_booext.put(1) + pvs.trig_rininj.put(1) + + def start_scrubbing(self): + pvs = self.pvs + + pvs.pinger_v.put(1) + pvs.pinger_h.put(1) + print("pingers switched ON") + + def stop_scrubbing(self): + pvs = self.pvs + + if pvs.pinger_v.get(): + pvs.pinger_v.put(0) + print("Vertical pinger switched OFF") + + if pvs.pinger_h.get(): + pvs.pinger_h.put(0) + print("Horizontal pinger switched OFF") + + def set_status(self, status, wait=0): + pvs = self.pvs + + if self.info != status: + self.info = status + + if wait == 0: + pvs.info.put(status) + + if wait > 0: + pvs.info.put(status + ", Wait {:.0f}s".format(wait)) + + # define callback function to trigger loop execution on change of corresponding pv change + def PressureChangeCallback(self, pvname=None, value=None, char_value=None, **kw): + # trigger execution of loop with actual callback since execution of code here not reliable + self.ChangeTrue += 1 diff --git a/services/topuptool/current/app/tests/test_app.py b/services/topuptool/current/app/tests/test_app.py index 74339a1..d639688 100644 --- a/services/topuptool/current/app/tests/test_app.py +++ b/services/topuptool/current/app/tests/test_app.py @@ -4,6 +4,5 @@ from agebd_topuptool import PVs, Service def test_app(): service_name = "DUMMY" pvs = PVs(service_name=service_name) - service = Service(name=service_name, pvs=pvs) - service.CallbackFired = 1 + service = Service(pvs=pvs) service.update() diff --git a/services/topuptool/current/app/uv.lock b/services/topuptool/current/app/uv.lock index 11636d8..a521ef2 100644 --- a/services/topuptool/current/app/uv.lock +++ b/services/topuptool/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [ From 5d038c17fe0986b910a85ca31a3e35f611b2eb7a Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 16 Jul 2026 17:00:27 +0200 Subject: [PATCH 39/42] feat: migrate tune python service --- services/tune/current/app/pyproject.toml | 4 + .../current/app/src/agebd_tune/service.py | 340 +++++++++++++++--- services/tune/current/app/uv.lock | 168 ++++++++- 3 files changed, 457 insertions(+), 55 deletions(-) diff --git a/services/tune/current/app/pyproject.toml b/services/tune/current/app/pyproject.toml index 0c62707..c501328 100644 --- a/services/tune/current/app/pyproject.toml +++ b/services/tune/current/app/pyproject.toml @@ -5,6 +5,10 @@ description = "AGEBD-TUNE Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "nafflib>=2.1.1", + "numpy>=2.2.6", + "scikit-learn>=1.7.2", + "scipy>=1.15.3", ] [dependency-groups] diff --git a/services/tune/current/app/src/agebd_tune/service.py b/services/tune/current/app/src/agebd_tune/service.py index be08b40..2c9945a 100644 --- a/services/tune/current/app/src/agebd_tune/service.py +++ b/services/tune/current/app/src/agebd_tune/service.py @@ -1,12 +1,20 @@ +import pickle # ONLY FOR TESTING import time +from time import sleep, time -from epics import dbr +import nafflib +import numpy as np +from epics import PV -from agebd.pv import LocalPVLink +# TODO: handle how to incorporate this into the framework +from OMFacility import Facility +from scipy.fft import fft +from sklearn.utils.extmath import randomized_svd + +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +22,79 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: - ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TUNE:AO") # TODO: is this a good PV to use? + Q1_fft = PV("AGEBD-TUNE:HORIZONTAL-PEAK1-FREQ") # horizontal tune from FFT + Q2_fft = PV("AGEBD-TUNE:VERTICAL-PEAK1-FREQ") # vertical tune from FFT + Q1_naff = PV("AGEBD-TUNE:Q1_NAFF") # horizontal tune from NAFF + Q2_naff = PV("AGEBD-TUNE:Q2_NAFF") # vertical tune from NAFF - ## Service specific PVs from other IOCs - # ... + roi_Xi = PV("AGEBD-TUNE:CONTROL-ROI-Xi") + roi_Xf = PV("AGEBD-TUNE:CONTROL-ROI-Xf") + roi_Yi = PV("AGEBD-TUNE:CONTROL-ROI-Yi") + roi_Yf = PV("AGEBD-TUNE:CONTROL-ROI-Yf") + + TbT_firstIndex = PV("AGEBD-TUNE:CONTROL-TbTFirstIndex") + TbT_lastIndex = PV("AGEBD-TUNE:CONTROL-TbTLastIndex") + + specx_all = PV("AGEBD-TUNE:HORIZONTAL-SPEC-ALL") + specy_all = PV("AGEBD-TUNE:VERTICAL-SPEC-ALL") + specx_roi = PV("AGEBD-TUNE:HORIZONTAL-SPEC-ROI") + specy_roi = PV("AGEBD-TUNE:VERTICAL-SPEC-ROI") + osc_sample_all = PV("AGEBD-TUNE:OSCILLATION-SAMPLE-ALL") + spec_sample_all = PV("AGEBD-TUNE:SPEC-SAMPLE-ALL") + + # to be implemented by Felix + measTime = PV("AGEBD-TUNE:MEAS-TIME") # time taken for measurement + + NAveraging = PV("AGEBD-TUNE:CONTROL-NAveraging") + naff_compute = PV("AGEBD-TUNE:CONTROL-NAFF") + naff_harmonics = PV("AGEBD-TUNE:NAFF-HARMONICS") + + BPMSelect_single = PV("AGEBD-TUNE:SINGLE-BPM") # select whether only a single BPM is to be used + BPMSelect_single_selected = PV("AGEBD-TUNE:BPM-SELECT-SINGLE") + SVDclean = PV("AGEBD-TUNE:SVD-CLEAN") # select whether to use SVD cleaning + SVDclean_NEig = PV("AGEBD-TUNE:SVD-CLEAN-Neigenvalues") # select whether to use SVD cleaning + + osc_x = PV("AGEBD-TUNE:OSCILLATION-X-ALL") # horizontal TbT to be transmissed + osc_y = PV("AGEBD-TUNE:OSCILLATION-Y-ALL") # vertical TbT to be transmissed + + # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: + BPMTriggerEvent = PV("ARS07-CECL-DBPM3-1:EEVR-EVENT0-ID") + + CallbackPV_24 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I") + CallbackPV_25 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ext-BPM-EVRCount-I") + CallbackPV_31 = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-EVRCount-I") + CallbackPV_32 = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I") + CallbackPV_34 = PV("AGETI-CVME-MASTER-TMA:Evt-SR-FKICK-EVRCount-I") + CallbackPV_40 = PV("AGETI-CVME-MASTER-TMA:Evt-SR-BPM-EVRCount-I") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True + S2 = Facility("/sls/bd/bin/MasterLayout.txt") + S2.Layout("full", -1) - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TUNE:BO" - ) # TODO: is this a good PV to use? + disabledBPMs = ["ARS01-DBPM-0530", "ARS03-DBPM-0840", "ARS10-DBPM-0970", "ARS11-DBPM-0880"] + BPMNames_BPM = S2.listElement_TYPE("BPM") + BPMNames_BPMA = S2.listElement_TYPE("BPMA") + BPMNames = [item for item in BPMNames_BPM if item not in disabledBPMs] + BPMNamesA = [item for item in BPMNames_BPMA if item not in disabledBPMs] - ## Service specific PVs from other IOCs - # ... + BPMNames_x = [name + ":DAQ-BEAM-STG0-X" for name in BPMNames] + BPMNames_y = [name + ":DAQ-BEAM-STG0-Y" for name in BPMNames] + BPMNames_I = [name + ":DAQ-BEAM-STG0-Q" for name in BPMNames] + BPMNamesA_x = [name + ":DAQ-BEAM-STG0-X" for name in BPMNamesA] + BPMNamesA_y = [name + ":DAQ-BEAM-STG0-Y" for name in BPMNamesA] + BPMNamesA_I = [name + ":DAQ-BEAM-STG0-Q" for name in BPMNamesA] - # TODO: class attribute names usually lowercase - # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TUNE:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.BPMx = [PV(name) for name in BPMNames_x] + self.BPMy = [PV(name) for name in BPMNames_y] + self.BPMI = [PV(name) for name in BPMNames_I] + self.BPMxA = [PV(name) for name in BPMNamesA_x] + self.BPMyA = [PV(name) for name in BPMNamesA_y] + self.BPMIA = [PV(name) for name in BPMNamesA_I] + + self.CallbackPV = None class Service(BaseService[PVs]): @@ -56,38 +107,219 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.update_control() + + def update_control(self): + pvs = self.pvs + + BPMTriggerEvent = pvs.BPMTriggerEvent.get() + + if BPMTriggerEvent == 24: # trigger is booster extraction + pvs.CallbackPV = pvs.CallbackPV_24 + elif BPMTriggerEvent == 25: # trigger is booster extraction BPM + pvs.CallbackPV = pvs.CallbackPV_25 + elif BPMTriggerEvent == 31: # trigger is pingerH event + pvs.CallbackPV = pvs.CallbackPV_31 + elif BPMTriggerEvent == 32: # trigger is SR-Inj event + pvs.CallbackPV = pvs.CallbackPV_32 + elif BPMTriggerEvent == 34: # trigger is pingerV event fast kicker event + pvs.CallbackPV = pvs.CallbackPV_34 + elif BPMTriggerEvent == 40: # trigger is SR BPM Sync event + pvs.CallbackPV = pvs.CallbackPV_40 + else: + print("BPM trigger event ID not understood. Value is: " + str(BPMTriggerEvent)) + + samplingRate = 2 # sampling rate of BPMs w.r.t. 1 MHz + TbT_firstIndex = np.int64(pvs.TbT_firstIndex.get()) + TbT_lastIndex = np.int64(pvs.TbT_lastIndex.get()) + + # user was stupid: set first index higher than last index + if TbT_firstIndex >= TbT_lastIndex: + TbT_firstIndex = TbT_lastIndex - 1 + pvs.TbT_firstIndex.put(TbT_firstIndex) + + # user was stupid: set last index lower than first index + if TbT_lastIndex <= TbT_firstIndex: + TbT_lastIndex = TbT_firstIndex + 1 + pvs.TbT_lastIndex.put(TbT_lastIndex) + + self.Index_first = np.int64( + np.arange(TbT_firstIndex * samplingRate, TbT_lastIndex * samplingRate + 1, samplingRate) + ) + self.Index_second = np.int64( + np.arange( + 1 + TbT_firstIndex * samplingRate, + TbT_lastIndex * samplingRate + 1 + 1, + samplingRate, + ) + ) + self.NIndex = len(range(TbT_firstIndex, TbT_lastIndex + 1)) + + # NAFF control parameters + self.naff_onoff = pvs.naff_compute.get() + self.naff_Nharmonics = int(pvs.naff_harmonics.get()) + + pvs.osc_sample_all.put(np.int64(np.arange(self.NIndex))) + pvs.spec_sample_all.put(np.linspace(0, 1, self.NIndex)) + + if pvs.BPMSelect_single.get(): + BPMNames_single = pvs.BPMSelect_single_selected.get() + + index_BPM = next((i for i, s in enumerate(BPMNames) if s == BPMNames_single), None) + index_BPMA = next((i for i, s in enumerate(BPMNamesA) if s == BPMNames_single), None) + + if index_BPM is not None: + pvs.BPMx_selected = [pvs.BPMx[index_BPM]] + pvs.BPMy_selected = [pvs.BPMy[index_BPM]] + pvs.BPMI_selected = [pvs.BPMI[index_BPM]] + else: + pvs.BPMx_selected = [pvs.BPMxA[index_BPMA]] + pvs.BPMy_selected = [pvs.BPMyA[index_BPMA]] + pvs.BPMI_selected = [pvs.BPMIA[index_BPMA]] + + self.NBPMs = 1 + else: + pvs.BPMx_selected = pvs.BPMx + pvs.BPMy_selected = pvs.BPMy + pvs.BPMI_selected = pvs.BPMI + self.NBPMs = len(pvs.BPMx) + self.NSamples = int(pvs.NAveraging.get()) + self.N_SVDeig = int(pvs.SVDclean_NEig.get()) def update(self): - # when callback is fired, this code will be executed + pvs = self.pvs + if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + t_start = time() + self.update_control() + if self.NBPMs == 0: + return + + x = np.zeros((self.NBPMs, self.NIndex, self.NSamples)) + y = np.zeros((self.NBPMs, self.NIndex, self.NSamples)) + for sample in range(self.NSamples): + if sample > 0: + sleep(1 / 3) + + xtmp = np.array([pv.get() for pv in pvs.BPMx_selected]) + ytmp = np.array([pv.get() for pv in pvs.BPMy_selected]) + Itmp = np.array([pv.get() for pv in pvs.BPMI_selected]) + + index_max = np.argmax(Itmp[:, 0:2], axis=1) + for n in range(self.NBPMs): + if index_max[n] == 0: + x[n, :, sample] = xtmp[n, self.Index_first] - np.mean( + xtmp[n, self.Index_first] + ) # subtract mean values + y[n, :, sample] = ytmp[n, self.Index_first] - np.mean( + ytmp[n, self.Index_first] + ) # subtract mean values + else: + x[n, :, sample] = xtmp[n, self.Index_second] - np.mean( + xtmp[n, self.Index_second] + ) # subtract mean values + y[n, :, sample] = ytmp[n, self.Index_second] - np.mean( + ytmp[n, self.Index_second] + ) # subtract mean values + + Ax = np.mean(x, axis=2) # average over NSamples + Ay = np.mean(y, axis=2) + + if pvs.SVDclean.get(): + Ux, Sx, Vx_T = randomized_svd(Ax, n_components=self.N_SVDeig) + Ax = Ux @ np.diag(Sx) @ Vx_T + Uy, Sy, Vy_T = randomized_svd(Ay, n_components=self.N_SVDeig) + Ay = Uy @ np.diag(Sy) @ Vy_T + Fx = fft(Ax[0, :]) # FFT first BPM only + Fy = fft(Ay[0, :]) + + specx = np.abs(Fx) # Take absolute of FFT to obtain amplitude spectra + specy = np.abs(Fy) + specx[: np.int64(np.ceil(self.NIndex * 0.01))] = 0 # remove DC component + specy[: np.int64(np.ceil(self.NIndex * 0.01))] = 0 # remove DC component + + specx_avg = specx / np.max(specx) # normalize spectra of first BPM + specy_avg = specy / np.max(specy) # normalize spectra of first BPM + + window_x_start = round(pvs.roi_Xi.get() * self.NIndex) + window_x_end = round(pvs.roi_Xf.get() * self.NIndex) + window_y_start = round(pvs.roi_Yi.get() * self.NIndex) + window_y_end = round(pvs.roi_Yf.get() * self.NIndex) + window_indices_x = np.arange(window_x_start, window_x_end + 1) + window_indices_y = np.arange(window_y_start, window_y_end + 1) + + index_max_local_x = np.argmax(specx_avg[window_x_start:window_x_end]) + index_max_local_y = np.argmax(specy_avg[window_y_start:window_y_end]) + Q1_FFTval = window_indices_x[index_max_local_x] / self.NIndex + Q2_FFTval = window_indices_y[index_max_local_y] / self.NIndex + + pvs.Q1_fft.put(Q1_FFTval) + pvs.Q2_fft.put(Q2_FFTval) + + Ax_mixed = Ax.transpose() + Ay_mixed = Ay.transpose() + Ax_mixed = Ax_mixed.flatten() + Ay_mixed = Ay_mixed.flatten() + + Q1_naff = np.nan + Q2_naff = np.nan + + if self.naff_onoff: + h1_naff, _, _ = nafflib.get_tunes(Ax_mixed, self.naff_Nharmonics) + h2_naff, _, _ = nafflib.get_tunes(Ay_mixed, self.naff_Nharmonics) + + h1_naff = h1_naff * self.NBPMs + h2_naff = h2_naff * self.NBPMs + + Q1_naff = np.mod(h1_naff, 1) + Q2_naff = np.mod(h2_naff, 1) + + Q1_naff[Q1_naff > 0.5] = ( + 1 - Q1_naff[Q1_naff > 0.5] + ) # above-half integer peak found. Going down. + Q2_naff[Q2_naff > 0.5] = 1 - Q2_naff[Q2_naff > 0.5] + + Q1_naff = Q1_naff[(Q1_naff >= Q1_FFTval - 0.01) & (Q1_naff <= Q1_FFTval + 0.01)] + Q2_naff = Q2_naff[(Q2_naff >= Q2_FFTval - 0.01) & (Q2_naff <= Q2_FFTval + 0.01)] + + if len(Q1_naff) == 0: + Q1_naff = np.nan + else: + Q1_naff = np.mean(Q1_naff) + + if len(Q2_naff) == 0: + Q2_naff = np.nan + else: + Q2_naff = np.mean(Q2_naff) + + # if self.NBPMs == 1: + # integerX = 0 + # integerY = 0 + # else: + # integerX = 39 + # integerY = 15 + # dh1 = h1_naff*self.NBPMs-(integerX+Q1_FFTval) + # dh2 = h2_naff*self.NBPMs-(integerY+Q2_FFTval) + # if min(abs(dh1))>0.5:# correct integer not found. Increasing number of harmonics + # h1_naff, _, _ = nafflib.get_tunes(Ax_mixed,50) + # dh1 = h1_naff*self.NBPMs-(integerX+Q1_FFTval) + # if min(abs(dh2))>0.5:# correct integer not found. Increasing number of harmonics + # h2_naff, _, _ = nafflib.get_tunes(Ay_mixed,25) + # dh2 = h2_naff*self.NBPMs-(integerY+Q2_FFTval) + # Q1_naff = h1_naff[np.argmin(abs(dh1))]*self.NBPMs + # Q2_naff = h2_naff[np.argmin(abs(dh2))]*self.NBPMs + + pvs.Q1_naff.put(Q1_naff) + pvs.Q2_naff.put(Q2_naff) + + pvs.specx_all.put(specx_avg) + pvs.specy_all.put(specy_avg) + pvs.specx_roi.put(specx_avg[window_x_start - 1 : window_x_end]) + pvs.specy_roi.put(specy_avg[window_y_start - 1 : window_y_end]) + + pvs.osc_x.put(Ax[0, :]) + pvs.osc_y.put(Ay[0, :]) + t_end = time() + pvs.measTime.put((t_end - t_start) * 1e3) - # callback done self.CallbackFired = 0 - - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., - - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() - - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### diff --git a/services/tune/current/app/uv.lock b/services/tune/current/app/uv.lock index 62436c8..8ea8b91 100644 --- a/services/tune/current/app/uv.lock +++ b/services/tune/current/app/uv.lock @@ -30,6 +30,10 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "nafflib" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "scipy" }, ] [package.dev-dependencies] @@ -40,7 +44,13 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "nafflib", specifier = ">=2.1.1" }, + { name = "numpy", specifier = ">=2.2.6" }, + { name = "scikit-learn", specifier = ">=1.7.2" }, + { name = "scipy", specifier = ">=1.15.3" }, +] [package.metadata.requires-dev] dev = [ @@ -106,6 +116,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "joblib" +version = "1.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.48.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/a0/acc8ffcd5bdc63df0097e22c719bfcd61b604358343089313a8aebbb24ab/llvmlite-0.48.0.tar.gz", hash = "sha256:543b19f9ef8f3c7c60d1468191e4ee1b1537bf9f8a3d56f64c0ddd98de92edd2", size = 184016, upload-time = "2026-07-02T20:20:05.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/4e/32543c42568fb321b3bdfcf9106e4116ab8f5a7bbcfd9ecf5569b0c07d83/llvmlite-0.48.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:614aad57df707e3172efd5165f2aa7da6a0c6897e40dce590bf756396815ba76", size = 40480650, upload-time = "2026-07-01T18:41:01.945Z" }, + { url = "https://files.pythonhosted.org/packages/a9/0d/6aa48abd423067139a129d1434b77bbcc56080db51d12a88510bb491ca3d/llvmlite-0.48.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13532f248960ba888ad5ab8150494e2f3a3d20e5f59f264e63741ea5b0ba844c", size = 59890118, upload-time = "2026-07-01T18:41:10.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c7/aa917444d871a79608af49149de1b28764e87d2ab41f933c5cd02431d03d/llvmlite-0.48.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ee0c77685a18f5fca994ae21d0763007fca5c5c64b41de37accc78b69079176", size = 58343459, upload-time = "2026-07-01T18:41:06.21Z" }, + { url = "https://files.pythonhosted.org/packages/c5/2b/ceee1cdc263617109d514ac4d1b31f10a282662740ff7d5777baae25b3b5/llvmlite-0.48.0-cp310-cp310-win_amd64.whl", hash = "sha256:02853fe4214acb3780fc920c3fee10564b61d58a35e1b78afcc8a546c2deaba3", size = 41864734, upload-time = "2026-07-01T18:41:14.746Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -127,6 +158,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "nafflib" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numba" }, + { name = "numpy" }, + { name = "pandas" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/0d/3d563dfc173916d5c0cc1fe614cdf312877540b9cea5bcd50a271ba5f6a3/nafflib-2.1.1.tar.gz", hash = "sha256:e4c67224c01db4b694d8f9c73c5b878178d80379ad99ae89adb4cce21ededd9b", size = 22926, upload-time = "2025-11-22T15:47:22.152Z" } + +[[package]] +name = "numba" +version = "0.66.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/a0/570e3dc53e5602b49108f62a13e529f1eec8bfc7ef37d49c825924dcf546/numba-0.66.0.tar.gz", hash = "sha256:b900e63a0e26c05ea9a6d5a3a5a0a177cb64c5011887bf43edb8c3ed2c38d363", size = 2806181, upload-time = "2026-07-01T23:12:46.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/48/d139bde40f2359351bfe26ee1b261937f458ac177ab810d4f045ae1c9d92/numba-0.66.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:27951c47e0def9bf8afe580eb961102902e2fd23cb77924b7d9d7cc0f8b444cb", size = 2727368, upload-time = "2026-07-01T23:12:04.282Z" }, + { url = "https://files.pythonhosted.org/packages/36/e4/b780bfa9191410da50ba249cb3248a75014e17f611e72709cbddcb21f42d/numba-0.66.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc408c54b450f41582f4be1608f8981c1dcc44c7f40355cc150dd93015753407", size = 3803554, upload-time = "2026-07-01T23:12:06.379Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b2/a051b96626bdf5c4d8fa6b8d450605c09638d85dc872ab63ef9a67096dca/numba-0.66.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c14c044c06b453ec3fa7715dfe75425e2ba72c73377a7ffde6d9ec511dfd94c", size = 3510065, upload-time = "2026-07-01T23:12:08.051Z" }, + { url = "https://files.pythonhosted.org/packages/34/01/24dcdc3e919522e2efbd92969c281ff40deb1d5f8a994bcd0057081c158c/numba-0.66.0-cp310-cp310-win_amd64.whl", hash = "sha256:2338cc0d43609fe448930848fd35a5bc688761b986f81b597a6f45cc0f8c9577", size = 2780379, upload-time = "2026-07-01T23:12:09.772Z" }, +] + [[package]] name = "numpy" version = "2.2.6" @@ -158,6 +216,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763, upload-time = "2025-09-29T23:16:53.287Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217, upload-time = "2025-09-29T23:17:04.522Z" }, + { url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791, upload-time = "2025-09-29T23:17:18.444Z" }, + { url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373, upload-time = "2025-09-29T23:17:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444, upload-time = "2025-09-29T23:17:49.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459, upload-time = "2025-09-29T23:18:03.722Z" }, + { url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086, upload-time = "2025-09-29T23:18:18.505Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -216,6 +295,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "pytz" +version = "2026.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -254,6 +354,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, ] +[[package]] +name = "scikit-learn" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/3e/daed796fd69cce768b8788401cc464ea90b306fb196ae1ffed0b98182859/scikit_learn-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b33579c10a3081d076ab403df4a4190da4f4432d443521674637677dc91e61f", size = 9336221, upload-time = "2025-09-09T08:20:19.328Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ce/af9d99533b24c55ff4e18d9b7b4d9919bbc6cd8f22fe7a7be01519a347d5/scikit_learn-1.7.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:36749fb62b3d961b1ce4fedf08fa57a1986cd409eff2d783bca5d4b9b5fce51c", size = 8653834, upload-time = "2025-09-09T08:20:22.073Z" }, + { url = "https://files.pythonhosted.org/packages/58/0e/8c2a03d518fb6bd0b6b0d4b114c63d5f1db01ff0f9925d8eb10960d01c01/scikit_learn-1.7.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7a58814265dfc52b3295b1900cfb5701589d30a8bb026c7540f1e9d3499d5ec8", size = 9660938, upload-time = "2025-09-09T08:20:24.327Z" }, + { url = "https://files.pythonhosted.org/packages/2b/75/4311605069b5d220e7cf5adabb38535bd96f0079313cdbb04b291479b22a/scikit_learn-1.7.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a847fea807e278f821a0406ca01e387f97653e284ecbd9750e3ee7c90347f18", size = 9477818, upload-time = "2025-09-09T08:20:26.845Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9b/87961813c34adbca21a6b3f6b2bea344c43b30217a6d24cc437c6147f3e8/scikit_learn-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:ca250e6836d10e6f402436d6463d6c0e4d8e0234cfb6a9a47835bd392b852ce5", size = 8886969, upload-time = "2025-09-09T08:20:29.329Z" }, +] + +[[package]] +name = "scipy" +version = "1.15.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -263,6 +402,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + [[package]] name = "tomli" version = "2.4.1" @@ -295,3 +452,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3 wheels = [ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] + +[[package]] +name = "tzdata" +version = "2026.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, +] From c102751c6a9560c306b8b827df0a0c73c966f9e0 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Fri, 17 Jul 2026 08:25:00 +0200 Subject: [PATCH 40/42] feat: migrate tunebump python service --- services/tunebump/current/app/pyproject.toml | 2 + .../current/app/src/agebd_tunebump/service.py | 486 ++++++++++++++++-- services/tunebump/current/app/uv.lock | 28 +- 3 files changed, 463 insertions(+), 53 deletions(-) diff --git a/services/tunebump/current/app/pyproject.toml b/services/tunebump/current/app/pyproject.toml index e1009e9..e59c4d6 100644 --- a/services/tunebump/current/app/pyproject.toml +++ b/services/tunebump/current/app/pyproject.toml @@ -5,6 +5,8 @@ description = "AGEBD-TUNEBUMP Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", + "scipy>=1.15.3", ] [dependency-groups] diff --git a/services/tunebump/current/app/src/agebd_tunebump/service.py b/services/tunebump/current/app/src/agebd_tunebump/service.py index f39cf83..66cdcea 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/service.py +++ b/services/tunebump/current/app/src/agebd_tunebump/service.py @@ -1,12 +1,19 @@ -import time +from datetime import datetime -from epics import dbr +import numpy as np +from epics import PV -from agebd.pv import LocalPVLink +# TODO: how to package/deploy this to use it here? +from OMFacility import Facility + +# TODO: how to package/deploy this to use it here? +from OMSLS2Magnet import SLS2Magnet +from scipy import signal + +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +21,265 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TUNEBUMP:AO") # TODO: is this a good PV to use? + # just print new values or write to magnets + Write2Mag = PV("AGEBD-TUNEBUMP:WRITE2MAG.VAL") + + anatune = { + "QX": { + "Spec": PV("AGEBD-TUNEBUMP:SPEC-X.VAL"), + "Freq": PV("AGEBD-TUNEBUMP:SPEC-FREQ-qX.VAL"), + "NormSpec": PV("AGEBD-TUNEBUMP:NORM-QX-AMP.VAL"), + "NormFreq": PV("AGEBD-TUNEBUMP:NORM-QX-FREQ.VAL"), + "Tune": PV("AGEBD-TUNEBUMP:QX.VAL"), + "TuneSB1": PV("AGEBD-TUNEBUMP:QX-SB1.VAL"), + "TuneSB2": PV("AGEBD-TUNEBUMP:QX-SB2.VAL"), + "Peak": PV("AGEBD-TUNEBUMP:QX-PEAKS.VAL"), + "PeakFreq": PV("AGEBD-TUNEBUMP:QX-PEAKS-FREQ.VAL"), + "Ulim": PV("AGEBD-TUNEBUMP:QX-ULIM.VAL"), + "Llim": PV("AGEBD-TUNEBUMP:QX-LLIM.VAL"), + }, + "QY": { + "Spec": PV("AGEBD-TUNEBUMP:SPEC-Y.VAL"), + "Freq": PV("AGEBD-TUNEBUMP:SPEC-FREQ-qY.VAL"), + "NormSpec": PV("AGEBD-TUNEBUMP:NORM-QY-AMP.VAL"), + "NormFreq": PV("AGEBD-TUNEBUMP:NORM-QY-FREQ.VAL"), + "Tune": PV("AGEBD-TUNEBUMP:QY.VAL"), + "TuneSB1": PV("AGEBD-TUNEBUMP:QY-SB1.VAL"), + "TuneSB2": PV("AGEBD-TUNEBUMP:QY-SB2.VAL"), + "Peak": PV("AGEBD-TUNEBUMP:QY-PEAKS.VAL"), + "PeakFreq": PV("AGEBD-TUNEBUMP:QY-PEAKS-FREQ.VAL"), + "Ulim": PV("AGEBD-TUNEBUMP:QY-ULIM.VAL"), + "Llim": PV("AGEBD-TUNEBUMP:QY-LLIM.VAL"), + }, + "QZ": { + "Spec": PV("AGEBD-TUNEBUMP:SPEC-Z.VAL"), + "Freq": PV("AGEBD-TUNEBUMP:SPEC-FREQ-qZ.VAL"), + "NormSpec": PV("AGEBD-TUNEBUMP:NORM-QZ-AMP.VAL"), + "NormFreq": PV("AGEBD-TUNEBUMP:NORM-QZ-FREQ.VAL"), + "Tune": PV("AGEBD-TUNEBUMP:QZ.VAL"), + "Peak": PV("AGEBD-TUNEBUMP:QZ-PEAKS.VAL"), + "PeakFreq": PV("AGEBD-TUNEBUMP:QZ-PEAKS-FREQ.VAL"), + "Ulim": PV("AGEBD-TUNEBUMP:QZ-ULIM.VAL"), + "Llim": PV("AGEBD-TUNEBUMP:QZ-LLIM.VAL"), + }, + } + + Qx_stepsize = PV("AGEBD-TUNEBUMP:QX-STEPSIZE") + Qx_stepup = PV("AGEBD-TUNEBUMP:QX-STEPUP") + Qx_stepdown = PV("AGEBD-TUNEBUMP:QX-STEPDOWN") + Qy_stepsize = PV("AGEBD-TUNEBUMP:QY-STEPSIZE") + Qy_stepup = PV("AGEBD-TUNEBUMP:QY-STEPUP") + Qy_stepdown = PV("AGEBD-TUNEBUMP:QY-STEPDOWN") + + TuneBump_changelog = PV("AGEBD-TUNEBUMP:CHANGELOG") ## Service specific PVs from other IOCs - # ... + # ordered dict of quads (Python > 3.7 required!) + quads = { # Quad PV base | F or D | pv link to ISET | MQCO Name for SLS2 Magnet Library + "ARS01-MOCT-1840-QA": ["F"], + "ARS01-MOCT-2360-QA": ["F"], + "ARS01-MOCT-2860-QA": ["F"], + "ARS01-MOCT-4130-QA": ["F"], + "ARS01-MOCT-4630-QA": ["F"], + "ARS01-MOCT-5150-QA": ["F"], + "ARS02-MOCT-1840-QA": ["F"], + "ARS02-MOCT-2360-QA": ["F"], + "ARS02-MOCT-2860-QA": ["F"], + "ARS02-MOCT-4130-QA": ["F"], + "ARS02-MOCT-4630-QA": ["F"], + "ARS02-MOCT-5150-QA": ["F"], + "ARS03-MOCT-1840-QA": ["F"], + "ARS03-MOCT-2360-QA": ["F"], + "ARS03-MOCT-2860-QA": ["F"], + "ARS03-MOCT-4130-QA": ["F"], + "ARS03-MOCT-4630-QA": ["F"], + "ARS03-MOCT-5150-QA": ["F"], + "ARS04-MOCT-1840-QA": ["F"], + "ARS04-MOCT-2360-QA": ["F"], + "ARS04-MOCT-2860-QA": ["F"], + "ARS04-MOCT-4130-QA": ["F"], + "ARS04-MOCT-4630-QA": ["F"], + "ARS04-MOCT-5150-QA": ["F"], + "ARS05-MOCT-1840-QA": ["F"], + "ARS05-MOCT-2360-QA": ["F"], + "ARS05-MOCT-2860-QA": ["F"], + "ARS05-MOCT-4130-QA": ["F"], + "ARS05-MOCT-4630-QA": ["F"], + "ARS05-MOCT-5150-QA": ["F"], + "ARS06-MOCT-1840-QA": ["F"], + "ARS06-MOCT-2360-QA": ["F"], + "ARS06-MOCT-2860-QA": ["F"], + "ARS06-MOCT-4130-QA": ["F"], + "ARS06-MOCT-4630-QA": ["F"], + "ARS06-MOCT-5150-QA": ["F"], + "ARS07-MOCT-1840-QA": ["F"], + "ARS07-MOCT-2360-QA": ["F"], + "ARS07-MOCT-2860-QA": ["F"], + "ARS07-MOCT-4130-QA": ["F"], + "ARS07-MOCT-4630-QA": ["F"], + "ARS07-MOCT-5150-QA": ["F"], + "ARS08-MOCT-1840-QA": ["F"], + "ARS08-MOCT-2360-QA": ["F"], + "ARS08-MOCT-2860-QA": ["F"], + "ARS08-MOCT-4130-QA": ["F"], + "ARS08-MOCT-4630-QA": ["F"], + "ARS08-MOCT-5150-QA": ["F"], + "ARS09-MOCT-1840-QA": ["F"], + "ARS09-MOCT-2360-QA": ["F"], + "ARS09-MOCT-2860-QA": ["F"], + "ARS09-MOCT-4130-QA": ["F"], + "ARS09-MOCT-4630-QA": ["F"], + "ARS09-MOCT-5150-QA": ["F"], + "ARS10-MOCT-1840-QA": ["F"], + "ARS10-MOCT-2360-QA": ["F"], + "ARS10-MOCT-2860-QA": ["F"], + "ARS10-MOCT-4130-QA": ["F"], + "ARS10-MOCT-4630-QA": ["F"], + "ARS10-MOCT-5150-QA": ["F"], + "ARS11-MOCT-1840-QA": ["F"], + "ARS11-MOCT-2360-QA": ["F"], + "ARS11-MOCT-2860-QA": ["F"], + "ARS11-MOCT-4130-QA": ["F"], + "ARS11-MOCT-4630-QA": ["F"], + "ARS11-MOCT-5150-QA": ["F"], + "ARS12-MOCT-1840-QA": ["F"], + "ARS12-MOCT-2360-QA": ["F"], + "ARS12-MOCT-2860-QA": ["F"], + "ARS12-MOCT-4130-QA": ["F"], + "ARS12-MOCT-4630-QA": ["F"], + "ARS12-MOCT-5150-QA": ["F"], + "ARS01-MOCT-1950-QA": ["D"], + "ARS01-MOCT-2230-QA": ["D"], + "ARS01-MOCT-2450-QA": ["D"], + "ARS01-MOCT-2730-QA": ["D"], + "ARS01-MOCT-2950-QA": ["D"], + "ARS01-MOCT-4040-QA": ["D"], + "ARS01-MOCT-4260-QA": ["D"], + "ARS01-MOCT-4540-QA": ["D"], + "ARS01-MOCT-4760-QA": ["D"], + "ARS01-MOCT-5040-QA": ["D"], + "ARS02-MOCT-1950-QA": ["D"], + "ARS02-MOCT-2230-QA": ["D"], + "ARS02-MOCT-2450-QA": ["D"], + "ARS02-MOCT-2730-QA": ["D"], + "ARS02-MOCT-2950-QA": ["D"], + "ARS02-MOCT-4040-QA": ["D"], + "ARS02-MOCT-4260-QA": ["D"], + "ARS02-MOCT-4540-QA": ["D"], + "ARS02-MOCT-4760-QA": ["D"], + "ARS02-MOCT-5040-QA": ["D"], + "ARS03-MOCT-1950-QA": ["D"], + "ARS03-MOCT-2230-QA": ["D"], + "ARS03-MOCT-2450-QA": ["D"], + "ARS03-MOCT-2730-QA": ["D"], + "ARS03-MOCT-2950-QA": ["D"], + "ARS03-MOCT-4040-QA": ["D"], + "ARS03-MOCT-4260-QA": ["D"], + "ARS03-MOCT-4540-QA": ["D"], + "ARS03-MOCT-4760-QA": ["D"], + "ARS03-MOCT-5040-QA": ["D"], + "ARS04-MOCT-1950-QA": ["D"], + "ARS04-MOCT-2230-QA": ["D"], + "ARS04-MOCT-2450-QA": ["D"], + "ARS04-MOCT-2730-QA": ["D"], + "ARS04-MOCT-2950-QA": ["D"], + "ARS04-MOCT-4040-QA": ["D"], + "ARS04-MOCT-4260-QA": ["D"], + "ARS04-MOCT-4540-QA": ["D"], + "ARS04-MOCT-4760-QA": ["D"], + "ARS04-MOCT-5040-QA": ["D"], + "ARS05-MOCT-1950-QA": ["D"], + "ARS05-MOCT-2230-QA": ["D"], + "ARS05-MOCT-2450-QA": ["D"], + "ARS05-MOCT-2730-QA": ["D"], + "ARS05-MOCT-2950-QA": ["D"], + "ARS05-MOCT-4040-QA": ["D"], + "ARS05-MOCT-4260-QA": ["D"], + "ARS05-MOCT-4540-QA": ["D"], + "ARS05-MOCT-4760-QA": ["D"], + "ARS05-MOCT-5040-QA": ["D"], + "ARS06-MOCT-1950-QA": ["D"], + "ARS06-MOCT-2230-QA": ["D"], + "ARS06-MOCT-2450-QA": ["D"], + "ARS06-MOCT-2730-QA": ["D"], + "ARS06-MOCT-2950-QA": ["D"], + "ARS06-MOCT-4040-QA": ["D"], + "ARS06-MOCT-4260-QA": ["D"], + "ARS06-MOCT-4540-QA": ["D"], + "ARS06-MOCT-4760-QA": ["D"], + "ARS06-MOCT-5040-QA": ["D"], + "ARS07-MOCT-1950-QA": ["D"], + "ARS07-MOCT-2230-QA": ["D"], + "ARS07-MOCT-2450-QA": ["D"], + "ARS07-MOCT-2730-QA": ["D"], + "ARS07-MOCT-2950-QA": ["D"], + "ARS07-MOCT-4040-QA": ["D"], + "ARS07-MOCT-4260-QA": ["D"], + "ARS07-MOCT-4540-QA": ["D"], + "ARS07-MOCT-4760-QA": ["D"], + "ARS07-MOCT-5040-QA": ["D"], + "ARS08-MOCT-1950-QA": ["D"], + "ARS08-MOCT-2230-QA": ["D"], + "ARS08-MOCT-2450-QA": ["D"], + "ARS08-MOCT-2730-QA": ["D"], + "ARS08-MOCT-2950-QA": ["D"], + "ARS08-MOCT-4040-QA": ["D"], + "ARS08-MOCT-4260-QA": ["D"], + "ARS08-MOCT-4540-QA": ["D"], + "ARS08-MOCT-4760-QA": ["D"], + "ARS08-MOCT-5040-QA": ["D"], + "ARS09-MOCT-1950-QA": ["D"], + "ARS09-MOCT-2230-QA": ["D"], + "ARS09-MOCT-2450-QA": ["D"], + "ARS09-MOCT-2730-QA": ["D"], + "ARS09-MOCT-2950-QA": ["D"], + "ARS09-MOCT-4040-QA": ["D"], + "ARS09-MOCT-4260-QA": ["D"], + "ARS09-MOCT-4540-QA": ["D"], + "ARS09-MOCT-4760-QA": ["D"], + "ARS09-MOCT-5040-QA": ["D"], + "ARS10-MOCT-1950-QA": ["D"], + "ARS10-MOCT-2230-QA": ["D"], + "ARS10-MOCT-2450-QA": ["D"], + "ARS10-MOCT-2730-QA": ["D"], + "ARS10-MOCT-2950-QA": ["D"], + "ARS10-MOCT-4040-QA": ["D"], + "ARS10-MOCT-4260-QA": ["D"], + "ARS10-MOCT-4540-QA": ["D"], + "ARS10-MOCT-4760-QA": ["D"], + "ARS10-MOCT-5040-QA": ["D"], + "ARS11-MOCT-1950-QA": ["D"], + "ARS11-MOCT-2230-QA": ["D"], + "ARS11-MOCT-2450-QA": ["D"], + "ARS11-MOCT-2730-QA": ["D"], + "ARS11-MOCT-2950-QA": ["D"], + "ARS11-MOCT-4040-QA": ["D"], + "ARS11-MOCT-4260-QA": ["D"], + "ARS11-MOCT-4540-QA": ["D"], + "ARS11-MOCT-4760-QA": ["D"], + "ARS11-MOCT-5040-QA": ["D"], + "ARS12-MOCT-1950-QA": ["D"], + "ARS12-MOCT-2230-QA": ["D"], + "ARS12-MOCT-2450-QA": ["D"], + "ARS12-MOCT-2730-QA": ["D"], + "ARS12-MOCT-2950-QA": ["D"], + "ARS12-MOCT-4040-QA": ["D"], + "ARS12-MOCT-4260-QA": ["D"], + "ARS12-MOCT-4540-QA": ["D"], + "ARS12-MOCT-4760-QA": ["D"], + "ARS12-MOCT-5040-QA": ["D"], + } + + for key in quads: + quads[key].append(PV(key + ":I-SET.VAL")) def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TUNEBUMP:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TUNEBUMP:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("AGEBD-TUNEBUMP:CALLBACK", auto_monitor=True) class Service(BaseService[PVs]): @@ -56,38 +292,184 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.spects = pvs.anatune["QZ"]["Spec"].timestamp + self.freqvec = {} + for q in ["QX", "QY", "QZ"]: + self.freqvec[q] = pvs.anatune[q]["Freq"].get() + + ## OnlineModel + # SLS 2.0 Machine Definition + self.S2 = Facility("/sls/bd/bin/MasterLayout.txt") + # load fully expanded machine element by element + self.S2.Layout("full") + # get individual short names for MQCO all magnets + # MQCO = S2.getElement_SN('MQCO') + # rather get them from the already sorted (by focus) PVs since sorting MQCOs from S2 by focusing requires MADX Model + for key in pvs.quads: + pvs.quads[key].append(key.replace("MOCT", "MQCO").rstrip("-QA")) + # SLS 2.0 Magnet Measurement Mapping Library + self.SM = SLS2Magnet() + + # Nominal Tunes + self.Qx0 = 39.36999688 + self.Qy0 = 15.21999988 + + self.dk = 0.01 + + # Tunes when dk=0.01 for Focusing knob + self.dQx_f = 39.38800899 - self.Qx0 + self.dQy_f = 15.21560142 - self.Qy0 + + # Tunes when dk=0.01 for Defocusing knob + self.dQx_d = 39.38329945 - self.Qx0 + self.dQy_d = 15.20693031 - self.Qy0 + + # Tune response matrix for dk=0.01 + self.Qmat = np.array([[self.dQx_f, self.dQx_d], [self.dQy_f, self.dQy_d]]) + + # prepare dict of : Iset old and Iset new for all quads + self.quadsetpoints = {q: np.zeros(2) for q in pvs.quads} def update(self): - # when callback is fired, this code will be executed - if self.CallbackFired: - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) - ####################################################################################### - ####################################################################################### + pvs = self.pvs - # callback done + if self.CallbackFired: + self.log = ["Tunebump service log, {:}".format(str(datetime.now())[:-7])] + + self.dQx = 0 + self.dQy = 0 + + for q in self.quadsetpoints: + self.quadsetpoints[q][0] = pvs.quads[q][1].get() + + if pvs.Qx_stepup.get(): + self.dQx = pvs.Qx_stepsize.get() + + pvs.Qx_stepup.put(0) + self.log.append("Qx_stepup") + + elif pvs.Qx_stepdown.get(): + self.dQx = -pvs.Qx_stepsize.get() + + pvs.Qx_stepdown.put(0) + self.log.append("Qx_stepdown") + + if pvs.Qy_stepup.get(): + self.dQy = pvs.Qy_stepsize.get() + + pvs.Qy_stepup.put(0) + self.log.append("Qy_stepup") + + elif pvs.Qy_stepdown.get(): + self.dQy = -pvs.Qy_stepsize.get() + + pvs.Qy_stepdown.put(0) + self.log.append("Qy_stepdown") + + dKLF, dKLD = self.dQ2dKL(self.dQx, self.dQy) + + for q in self.quadsetpoints: + if pvs.quads[q][0] == "F": + self.quadsetpoints[q][1] = self.Ii2If( + self.quadsetpoints[q][0], pvs.quads[q][2], dKLF + ) + + elif pvs.quads[q][0] == "D": + self.quadsetpoints[q][1] = self.Ii2If( + self.quadsetpoints[q][0], pvs.quads[q][2], dKLD + ) + + Isteps = [ + self.quadsetpoints[q][1] - self.quadsetpoints[q][0] for q in self.quadsetpoints + ] + self.log.append(" MAX Istep = {:.6f}".format(np.nanmax(Isteps))) + self.log.append(" MIN Istep = {:.6f}".format(np.nanmin(Isteps))) + + self.foc = "F" + self.log.append("-------------------------------------------") + self.log.append("focusing quads") + self.log.append("{:18} {:10} {:10}".format("Quad", "Iset_i", "Istep")) + + Write2Mag = pvs.Write2Mag.get() + + for q in self.quadsetpoints: + if Write2Mag: + pvs.quads[q][1].put(np.round(self.quadsetpoints[q][1], 6)) + + if pvs.quads[q][0] == "D" and self.foc == "F": + self.foc = "D" + self.log.append("-------------------------------------------") + self.log.append("defocusing quads") + self.log.append("{:18} {:10} {:10}".format("Quad", "Iset_i", "Istep")) + + self.log.append( + "{:18} {:8.4f} {:8.4f}".format( + q, + self.quadsetpoints[q][0], + self.quadsetpoints[q][1] - self.quadsetpoints[q][0], + ) + ) + + pvs.TuneBump_changelog.put("\n".join(self.log)) self.CallbackFired = 0 - ####################################################################################### - ####################################################################################### - # here goes all the code that your service - # is supposed to be running in any case, e.g., + elif self.spects != pvs.anatune["QZ"]["Spec"].timestamp: + try: + for q in ["QX", "QY", "QZ"]: + spec = pvs.anatune[q]["Spec"].get() + self.spects = pvs.anatune[q]["Spec"].timestamp - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") + freq = self.freqvec[q] + ulim = pvs.anatune[q]["Ulim"].get() + llim = pvs.anatune[q]["Llim"].get() + ind = np.where(np.logical_and(llim < freq, freq < ulim))[0] + freq = freq[ind] + spec = spec[ind] + spec = spec / np.max(spec) + peaks_wf = np.zeros(len(freq)) - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() + pvs.anatune[q]["NormSpec"].put(spec) + pvs.anatune[q]["NormFreq"].put(freq) - # maybe sleep to limit the update loop execution rate - time.sleep(1) - ####################################################################################### - ####################################################################################### + peaks, properties = signal.find_peaks(spec, height=0.03, distance=5) + sortind = np.argsort(properties["peak_heights"])[::-1] + peaks = peaks[sortind] + + N = len(peaks) + + if N > 0: + pvs.anatune[q]["Peak"].put(spec[peaks[:3]]) + pvs.anatune[q]["PeakFreq"].put(freq[peaks[:3]]) + + pvs.anatune[q]["Tune"].put(freq[peaks[0]]) + + if q in ["QX", "QY"]: + if N > 1: + pvs.anatune[q]["TuneSB1"].put(freq[peaks[1]]) + if N > 2: + pvs.anatune[q]["TuneSB2"].put(freq[peaks[2]]) + + except: + pass + + # function to translate setcurrent of individual MQCO + def Ii2If(self, Ii, q, dKL): + + qType = self.S2.getElement(q).TYPE + + # Ii = pv.get() + KLi = self.SM.I2KL(qType, Ii) + KLf = KLi + dKL + If = self.SM.KL2I(qType, KLf) + # pv.put(If) + + return If + + def dQ2dKL(self, dQx, dQy): + + dkF, dkD = np.dot(np.linalg.inv(self.Qmat), np.array([dQx, dQy])) * self.dk + + dKLF = dkF * 0.05 # MQCO length is 5 cm + dKLD = dkD * 0.05 # MQCO length is 5 cm + + return dKLF, dKLD diff --git a/services/tunebump/current/app/uv.lock b/services/tunebump/current/app/uv.lock index 8a45e3e..37e64e0 100644 --- a/services/tunebump/current/app/uv.lock +++ b/services/tunebump/current/app/uv.lock @@ -30,6 +30,8 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, + { name = "scipy" }, ] [package.dev-dependencies] @@ -40,7 +42,11 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, + { name = "scipy", specifier = ">=1.15.3" }, +] [package.metadata.requires-dev] dev = [ @@ -254,6 +260,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/75/e90ab9aeece218a9fc5a5bc3ec97d0ee6bb3c4ff95869463c1de58e29a1c/ruff-0.15.21-py3-none-win_arm64.whl", hash = "sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8", size = 11375265, upload-time = "2026-07-09T20:01:31.772Z" }, ] +[[package]] +name = "scipy" +version = "1.15.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" From c303bc19d6e9f0605f37cc4d6c7084d42d8c8d59 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Fri, 17 Jul 2026 08:34:56 +0200 Subject: [PATCH 41/42] feat: migrate tunefbx python service --- services/tunefbx/current/app/pyproject.toml | 1 + .../current/app/src/agebd_tunefbx/service.py | 204 ++++++++++++++---- services/tunefbx/current/app/uv.lock | 6 +- 3 files changed, 172 insertions(+), 39 deletions(-) diff --git a/services/tunefbx/current/app/pyproject.toml b/services/tunefbx/current/app/pyproject.toml index 04d77bf..1d0f61b 100644 --- a/services/tunefbx/current/app/pyproject.toml +++ b/services/tunefbx/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-TUNEFBX Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/service.py b/services/tunefbx/current/app/src/agebd_tunefbx/service.py index 9e58ff5..fda5c79 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/service.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/service.py @@ -1,12 +1,12 @@ -import time +from time import perf_counter +import numpy as np from epics import dbr -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +14,86 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TUNEFBX:AO") # TODO: is this a good PV to use? + kp = PV("AGEBD-TUNEFBX:CONTROL-KP.VAL") + ki = PV("AGEBD-TUNEFBX:CONTROL-KI.VAL") + kd = PV("AGEBD-TUNEFBX:CONTROL-KD.VAL") + qx_ref = PV("AGEBD-TUNEFBX:CONTROL-QX.VAL") + qx_okrng = PV("AGEBD-TUNEFBX:CONTROL-QX-OKRNG.VAL") + qx_drvh = PV("AGEBD-TUNEFBX:CONTROL-QXMAX.VAL") + qx_drvl = PV("AGEBD-TUNEFBX:CONTROL-QXMIN.VAL") + mincur = PV("AGEBD-TUNEFBX:CONTROL-MIN-CURR.VAL") + dq = PV("AGEBD-TUNEFBX:DELTAQ.VAL") + dq_ulim = PV("AGEBD-TUNEFBX:DELTAQ-ULIM.VAL") + dq_llim = PV("AGEBD-TUNEFBX:DELTAQ-LLIM.VAL") + check1 = PV("AGEBD-TUNEFBX:CHECK1.VAL") + check2 = PV("AGEBD-TUNEFBX:CHECK2.VAL") + check3 = PV("AGEBD-TUNEFBX:CHECK3.VAL") + check4 = PV("AGEBD-TUNEFBX:CHECK4.VAL") + check5 = PV("AGEBD-TUNEFBX:CHECK5.VAL") + check6 = PV("AGEBD-TUNEFBX:CHECK6.VAL") + check7 = PV("AGEBD-TUNEFBX:CHECK7.VAL") + check8 = PV("AGEBD-TUNEFBX:CHECK8.VAL") + + # Output PVs + qx_stepdec = PV("AGEBD-TUNEBUMP:QX-STEPDOWN.VAL") + qx_stepinc = PV("AGEBD-TUNEBUMP:QX-STEPUP.VAL") + qx_stepsiz = PV("AGEBD-TUNEBUMP:QX-STEPSIZE.VAL") ## Service specific PVs from other IOCs - # ... + inj_active = PV("AGEBD-PARAMS:INJECTION-ACTIVE.VAL") + dump_valve = PV("ARS01-VVPG-0210:PLC_STATUS.VAL") + hor_pinger_trig = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL") + ver_pinger_trig = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL") + bpm_qx_pilot_int = PV("ARS07-DBPM-0840:PILOT-INT-SWITCH.VAL") # must be: 0 No Pilot + bpm_qx_pilot_ext = PV("ARS07-DBPM-0840:PILOT-EXT-SWITCH.VAL") # must be: 0 No Pilot + bpm_qx_chopper = PV("ARS07-DBPM-0840:CHOPPER-MODE.VAL") # must be: 0 Periodic + cur = PV("ARS07-DPCT-0000:CURR.VAL") def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TUNEFBX:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TUNEFBX:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("AGEBD-TUNEBUMP:QX.VAL", auto_monitor=dbr.DBE_VALUE) + + +class PID: + # Proportional-Integral-Derivative (PID) controller class + # PID setup procedure: + # 1. set integral and derivative gains ki, kd to 0 + # 2. set proportional gain kp to low, stable value + # 3. increase kp and create a disturbance, e.g., by changing the setpoint + # 4. increase kp until feedback parameter oscillates + # 5. set kp to 40 % of the critical value triggering oscillation + # 6. slowly increase ki to eliminate the steady state error + # 7. adjust it until setpoint is reached accurately without overshoot + # 8. tune kd to minimize oscillations and overshoots (caution: high kd can amplify noise) + + def __init__(self, kp, ki, kd, setpoint): + + # Proportional Gain >> The "present" term. It provides a response proportional to the current error. Increasing kp makes the system respond faster, but if pushed too high, it will cause violent overshoot and oscillation. + self.kp = kp + # Integral Gain >> The "past" term. It accumulates the errors over time to eliminate steady-state error. However, high ki values can cause sluggishness or instability (e.g., integral windup). + self.ki = ki + # Derivative Gain >> The "future" term. It measures the rate of change of the error, acting as a damping factor to reduce overshoot and smooth out rapid, unwanted movements + self.kd = kd + self.setpoint = setpoint + self.integral = 0 + self.prev_error = 0 + + def update(self, measurement, dt): + + error = self.setpoint - measurement + self.integral += error * dt + derivative = (error - self.prev_error) / dt if dt > 0 else 0 + + self.prev_error = error + + # Calculate the final output using Kp, Ki, and Kd which is written to actuator + output = (self.kp * error) + (self.ki * self.integral) + (self.kd * derivative) + + return output class Service(BaseService[PVs]): @@ -56,17 +106,103 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.control = 0.0 + self.dq_llim = 0.0 + self.dq_ulim = 0.0 + + self.qx_okrng = pvs.qx_okrng.get() + + self.PID = PID(pvs.kp.get(), pvs.ki.get(), pvs.kd.get(), pvs.qx_ref.get()) + # start stop watch + self.t0 = perf_counter() def update(self): + pvs = self.pvs # when callback is fired, this code will be executed if self.CallbackFired: ####################################################################################### ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) + # here goes all the code that your service is supposed to be + # running every time when the callback is fired + + # update PID settings + self.PID.setpoint = pvs.qx_ref.get() + self.PID.kp = pvs.kp.get() + self.PID.ki = pvs.ki.get() + self.PID.kd = pvs.kd.get() + + self.qx_okrng = pvs.qx_okrng.get() + + ############ + ## CHECKS ## + ############ + # 1. measured tune within drivelimits + self.check1 = ( + pvs.qx_drvl.get() < self.CallbackValue and self.CallbackValue < pvs.qx_drvh.get() + ) + pvs.check1.put(self.check1) + + # 2. measured tune outside ok range limits + self.check2 = self.CallbackValue < ( + self.PID.setpoint - self.qx_okrng + ) or self.CallbackValue > (self.PID.setpoint + self.qx_okrng) + pvs.check2.put(self.check2) + + # 3. injection not active + self.check3 = not pvs.inj_active.get() + pvs.check3.put(self.check3) + + # 4. stored beam current above threshold + self.check4 = pvs.cur.get() > pvs.mincur.get() + pvs.check4.put(self.check4) + + # 5. bpm setup correctly for tune measurement + self.check5 = ( + pvs.bpm_qx_pilot_int.get() == 0 + and pvs.bpm_qx_pilot_ext.get() == 0 + and pvs.bpm_qx_chopper.get() == 1 + ) + pvs.check5.put(self.check5) + + # 6. pingers are on + self.check6 = pvs.hor_pinger_trig.get() and pvs.ver_pinger_trig.get() + pvs.check6.put(self.check6) + + # 7. dt corresponds to 3.125 Hz, i.e., min. 2 consecutive valid measurements + t1 = perf_counter() + self.dt = t1 - self.t0 + self.t0 = t1 + self.check7 = self.dt < 1.1 / 3.125 + pvs.check7.put(self.check7) + + # check all checks before PID call + self.checkall = ( + self.check1 + and self.check2 + and self.check3 + and self.check4 + and self.check5 + and self.check6 + and self.check7 + ) + + if self.checkall: + # 8. PID calculated step within limits + self.control = self.PID.update(self.CallbackValue, self.dt) + self.dq_llim = pvs.dq_llim.get() + self.dq_ulim = pvs.dq_ulim.get() + + self.check8 = self.control > self.dq_llim and self.control < self.dq_ulim + pvs.check8.put(self.check8) + + if self.check8: + pvs.dq.put(self.control) + pvs.qx_stepsiz.put(np.abs(self.control)) + if self.control < 0: + pvs.qx_stepdec.put(1) + else: + pvs.qx_stepinc.put(1) + ####################################################################################### ####################################################################################### @@ -77,17 +213,9 @@ class Service(BaseService[PVs]): ####################################################################################### # here goes all the code that your service # is supposed to be running in any case, e.g., - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() # maybe sleep to limit the update loop execution rate - time.sleep(1) + # sleep(1) ####################################################################################### ####################################################################################### diff --git a/services/tunefbx/current/app/uv.lock b/services/tunefbx/current/app/uv.lock index 92c43fe..d4cd5b5 100644 --- a/services/tunefbx/current/app/uv.lock +++ b/services/tunefbx/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [ From f904e7909580a63ea3b7d5db5ab938344d2c63a9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Fri, 17 Jul 2026 08:40:51 +0200 Subject: [PATCH 42/42] feat: migrate tunefby python service --- services/tunefby/current/app/pyproject.toml | 1 + .../current/app/src/agebd_tunefby/service.py | 201 ++++++++++++++---- services/tunefby/current/app/uv.lock | 6 +- 3 files changed, 169 insertions(+), 39 deletions(-) diff --git a/services/tunefby/current/app/pyproject.toml b/services/tunefby/current/app/pyproject.toml index b3dd565..cdd7fc7 100644 --- a/services/tunefby/current/app/pyproject.toml +++ b/services/tunefby/current/app/pyproject.toml @@ -5,6 +5,7 @@ description = "AGEBD-TUNEFBY Service" requires-python = "==3.10.*" dependencies = [ "agebd", + "numpy>=2.2.6", ] [dependency-groups] diff --git a/services/tunefby/current/app/src/agebd_tunefby/service.py b/services/tunefby/current/app/src/agebd_tunefby/service.py index 736310e..160777d 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/service.py +++ b/services/tunefby/current/app/src/agebd_tunefby/service.py @@ -1,12 +1,12 @@ -import time +from time import perf_counter +import numpy as np from epics import dbr -from agebd.pv import LocalPVLink +from agebd.pv import get_pv_class from agebd.service.base import BaseService from agebd.service.pvs import BasePVs from agebd.utils import printgetversion -from agebd.pv import get_pv_class __version__ = printgetversion(__file__) @@ -14,36 +14,86 @@ PV = get_pv_class() class PVs(BasePVs): - # Option 1: ## Service specific PVs from dedicated IOC - my_pv1 = PV("AGEBD-TUNEFBY:AO") # TODO: is this a good PV to use? + kp = PV("AGEBD-TUNEFBY:CONTROL-KP.VAL") + ki = PV("AGEBD-TUNEFBY:CONTROL-KI.VAL") + kd = PV("AGEBD-TUNEFBY:CONTROL-KD.VAL") + qy_ref = PV("AGEBD-TUNEFBY:CONTROL-QY.VAL") + qy_okrng = PV("AGEBD-TUNEFBY:CONTROL-QY-OKRNG.VAL") + qy_drvh = PV("AGEBD-TUNEFBY:CONTROL-QYMAX.VAL") + qy_drvl = PV("AGEBD-TUNEFBY:CONTROL-QYMIN.VAL") + mincur = PV("AGEBD-TUNEFBY:CONTROL-MIN-CURR.VAL") + dq = PV("AGEBD-TUNEFBY:DELTAQ.VAL") + dq_ulim = PV("AGEBD-TUNEFBY:DELTAQ-ULIM.VAL") + dq_llim = PV("AGEBD-TUNEFBY:DELTAQ-LLIM.VAL") + check1 = PV("AGEBD-TUNEFBY:CHECK1.VAL") + check2 = PV("AGEBD-TUNEFBY:CHECK2.VAL") + check3 = PV("AGEBD-TUNEFBY:CHECK3.VAL") + check4 = PV("AGEBD-TUNEFBY:CHECK4.VAL") + check5 = PV("AGEBD-TUNEFBY:CHECK5.VAL") + check6 = PV("AGEBD-TUNEFBY:CHECK6.VAL") + check7 = PV("AGEBD-TUNEFBY:CHECK7.VAL") + check8 = PV("AGEBD-TUNEFBY:CHECK8.VAL") + + # Output PVs + qy_stepdec = PV("AGEBD-TUNEBUMP:QY-STEPDOWN.VAL") + qy_stepinc = PV("AGEBD-TUNEBUMP:QY-STEPUP.VAL") + qy_stepsiz = PV("AGEBD-TUNEBUMP:QY-STEPSIZE.VAL") ## Service specific PVs from other IOCs - # ... + inj_active = PV("AGEBD-PARAMS:INJECTION-ACTIVE.VAL") + dump_valve = PV("ARS01-VVPG-0210:PLC_STATUS.VAL") + hor_pinger_trig = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL") + ver_pinger_trig = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL") + cur = PV("ARS07-DPCT-0000:CURR.VAL") + bpm_qy_pilot_int = PV("ARS07-DBPM-5530:PILOT-INT-SWITCH.VAL") # must be: 0 No Pilot + bpm_qy_pilot_ext = PV("ARS07-DBPM-5530:PILOT-EXT-SWITCH.VAL") # must be: 0 No Pilot + bpm_qy_chopper = PV("ARS07-DBPM-5530:CHOPPER-MODE.VAL") # must be: 0 Periodic def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory - # TODO: can we do this cleaner? Maybe mechanism for - # settings initial values in dev mode (e.g. ini file) - if isinstance(self.onoff, LocalPVLink): - self.onoff.value = True - - # Option 2: - ## Service specific PVs from dedicated IOC - self.my_pv2 = PV( - "AGEBD-TUNEFBY:BO" - ) # TODO: is this a good PV to use? - - ## Service specific PVs from other IOCs - # ... - - # TODO: class attribute names usually lowercase # usually it is advisable to trigger the mainloop of a service on changes of certain PVs: - self.CallbackPV = PV( - "AGEBD-TUNEFBY:CALLBACK", auto_monitor=dbr.DBE_VALUE - ) # TODO: ok? + self.CallbackPV = PV("AGEBD-TUNEBUMP:QY.VAL", auto_monitor=dbr.DBE_VALUE) + + +class PID: + # Proportional-Integral-Derivative (PID) controller class + # PID setup procedure: + # 1. set integral and derivative gains ki, kd to 0 + # 2. set proportional gain kp to low, stable value + # 3. increase kp and create a disturbance, e.g., by changing the setpoint + # 4. increase kp until feedback parameter oscillates + # 5. set kp to 40 % of the critical value triggering oscillation + # 6. slowly increase ki to eliminate the steady state error + # 7. adjust it until setpoint is reached accurately without overshoot + # 8. tune kd to minimize oscillations and overshoots (caution: high kd can amplify noise) + + def __init__(self, kp, ki, kd, setpoint): + + # Proportional Gain >> The "present" term. It provides a response proportional to the current error. Increasing kp makes the system respond faster, but if pushed too high, it will cause violent overshoot and oscillation. + self.kp = kp + # Integral Gain >> The "past" term. It accumulates the errors over time to eliminate steady-state error. However, high ki values can cause sluggishness or instability (e.g., integral windup). + self.ki = ki + # Derivative Gain >> The "future" term. It measures the rate of change of the error, acting as a damping factor to reduce overshoot and smooth out rapid, unwanted movements + self.kd = kd + self.setpoint = setpoint + self.integral = 0 + self.prev_error = 0 + + def update(self, measurement, dt): + + error = self.setpoint - measurement + self.integral += error * dt + derivative = (error - self.prev_error) / dt if dt > 0 else 0 + + self.prev_error = error + + # Calculate the final output using Kp, Ki, and Kd which is written to actuator + output = (self.kp * error) + (self.ki * self.integral) + (self.kd * derivative) + + return output class Service(BaseService[PVs]): @@ -56,17 +106,100 @@ class Service(BaseService[PVs]): ): super().__init__(name, pvs, version, sleep_interval) - # TODO: What is this for? - self.path = "sls/bd/bin" + self.qy_okrng = pvs.qy_okrng.get() + + self.PID = PID(pvs.kp.get(), pvs.ki.get(), pvs.kd.get(), pvs.qy_ref.get()) + # start stop watch + self.t0 = perf_counter() def update(self): + pvs = self.pvs + # when callback is fired, this code will be executed if self.CallbackFired: ####################################################################################### ####################################################################################### - # here goes all the code that your service - # is supposed to be running when the callback is fired - time.sleep(1) + # here goes all the code that your service is supposed to be + # running every time when the callback is fired + + # update PID settings + self.PID.setpoint = pvs.qy_ref.get() + self.PID.kp = pvs.kp.get() + self.PID.ki = pvs.ki.get() + self.PID.kd = pvs.kd.get() + + self.qy_okrng = pvs.qy_okrng.get() + + ############ + ## CHECKS ## + ############ + # 1. measured tune within drivelimits + self.check1 = ( + pvs.qy_drvl.get() < self.CallbackValue and self.CallbackValue < pvs.qy_drvh.get() + ) + pvs.check1.put(self.check1) + + # 2. measured tune outside ok range limits + self.check2 = self.CallbackValue < ( + self.PID.setpoint - self.qy_okrng + ) or self.CallbackValue > (self.PID.setpoint + self.qy_okrng) + pvs.check2.put(self.check2) + + # 3. injection not active + self.check3 = not pvs.inj_active.get() + pvs.check3.put(self.check3) + + # 4. stored beam current above threshold + self.check4 = pvs.cur.get() > pvs.mincur.get() + pvs.check4.put(self.check4) + + # 5. bpm setup correctly for tune measurement + self.check5 = ( + pvs.bpm_qy_pilot_int.get() == 0 + and pvs.bpm_qy_pilot_ext.get() == 0 + and pvs.bpm_qy_chopper.get() == 1 + ) + pvs.check5.put(self.check5) + + # 6. pingers are on + self.check6 = pvs.hor_pinger_trig.get() and pvs.ver_pinger_trig.get() + pvs.check6.put(self.check6) + + # 7. dt corresponds to 3.125 Hz, i.e., min. 2 consecutive valid measurements + t1 = perf_counter() + self.dt = t1 - self.t0 + self.t0 = t1 + self.check7 = self.dt < 1.1 / 3.125 + pvs.check7.put(self.check7) + + # check all checks before PID call + self.checkall = ( + self.check1 + and self.check2 + and self.check3 + and self.check4 + and self.check5 + and self.check6 + and self.check7 + ) + + if self.checkall: + # 8. PID calculated step within limits + self.control = self.PID.update(self.CallbackValue, self.dt) + self.dq_llim = pvs.dq_llim.get() + self.dq_ulim = pvs.dq_ulim.get() + + self.check8 = self.control > self.dq_llim and self.control < self.dq_ulim + pvs.check8.put(self.check8) + + if self.check8: + pvs.dq.put(self.control) + pvs.qy_stepsiz.put(np.abs(self.control)) + if self.control < 0: + pvs.qy_stepdec.put(1) + else: + pvs.qy_stepinc.put(1) + ####################################################################################### ####################################################################################### @@ -77,17 +210,9 @@ class Service(BaseService[PVs]): ####################################################################################### # here goes all the code that your service # is supposed to be running in any case, e.g., - # update some pvs/vals - my_pv1_random_val = str(time.clock_gettime_ns(0))[-1] - self.pvs.my_pv1.put(my_pv1_random_val) - # self.pvs.my_pv2.put("MY_PV2 value") - - # get some pvs/vals - self.val1 = self.pvs.my_pv1.get() - self.val2 = self.pvs.my_pv2.get() # maybe sleep to limit the update loop execution rate - time.sleep(1) + # sleep(1) ####################################################################################### ####################################################################################### diff --git a/services/tunefby/current/app/uv.lock b/services/tunefby/current/app/uv.lock index ee3af41..c4be5c0 100644 --- a/services/tunefby/current/app/uv.lock +++ b/services/tunefby/current/app/uv.lock @@ -30,6 +30,7 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, + { name = "numpy" }, ] [package.dev-dependencies] @@ -40,7 +41,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "agebd", editable = "../../../../packages/agebd" }] +requires-dist = [ + { name = "agebd", editable = "../../../../packages/agebd" }, + { name = "numpy", specifier = ">=2.2.6" }, +] [package.metadata.requires-dev] dev = [