From e3248cfbe2264e0beb3a26297685e5761ff36b8f Mon Sep 17 00:00:00 2001 From: Gary Yendell Date: Wed, 26 Jul 2023 16:41:55 +0100 Subject: [PATCH] Add container runtime and dev environment Publish runtime container Update devcontainer to build and run C++ applictions Create full local eiger deployment Add development quickstart guide to README --- .devcontainer/devcontainer.json | 51 +++++++----- .devcontainer/initializeCommand | 6 ++ .devcontainer/postCreateCommand | 28 +++++++ .dockerignore | 5 ++ .github/workflows/container.yml | 76 +++++++++++++++++ .vscode/settings.json | 20 +++++ Dockerfile | 58 +++++++------ README.md | 40 +++++++-- deploy/fp1.json | 140 ++++++++++++++++++++++++++++++++ deploy/fp2.json | 140 ++++++++++++++++++++++++++++++++ deploy/fp3.json | 140 ++++++++++++++++++++++++++++++++ deploy/fp4.json | 140 ++++++++++++++++++++++++++++++++ deploy/fr1.json | 18 ++++ deploy/fr2.json | 18 ++++ deploy/fr3.json | 18 ++++ deploy/fr4.json | 18 ++++ deploy/log4cxx.xml | 46 +++++++++++ deploy/odin_server.cfg | 28 +++++++ deploy/stEigerFan.sh | 5 ++ deploy/stFrameProcessor1.sh | 7 ++ deploy/stFrameProcessor2.sh | 7 ++ deploy/stFrameProcessor3.sh | 7 ++ deploy/stFrameProcessor4.sh | 7 ++ deploy/stFrameReceiver1.sh | 5 ++ deploy/stFrameReceiver2.sh | 5 ++ deploy/stFrameReceiver3.sh | 5 ++ deploy/stFrameReceiver4.sh | 5 ++ deploy/stMetaWriter.sh | 3 + deploy/stOdinServer.sh | 8 ++ deploy/startAll.kdl | 29 +++++++ 30 files changed, 1028 insertions(+), 55 deletions(-) create mode 100644 .devcontainer/initializeCommand create mode 100644 .devcontainer/postCreateCommand create mode 100644 .dockerignore create mode 100644 .github/workflows/container.yml create mode 100644 .vscode/settings.json create mode 100644 deploy/fp1.json create mode 100644 deploy/fp2.json create mode 100644 deploy/fp3.json create mode 100644 deploy/fp4.json create mode 100644 deploy/fr1.json create mode 100644 deploy/fr2.json create mode 100644 deploy/fr3.json create mode 100644 deploy/fr4.json create mode 100644 deploy/log4cxx.xml create mode 100644 deploy/odin_server.cfg create mode 100755 deploy/stEigerFan.sh create mode 100755 deploy/stFrameProcessor1.sh create mode 100755 deploy/stFrameProcessor2.sh create mode 100755 deploy/stFrameProcessor3.sh create mode 100755 deploy/stFrameProcessor4.sh create mode 100755 deploy/stFrameReceiver1.sh create mode 100755 deploy/stFrameReceiver2.sh create mode 100755 deploy/stFrameReceiver3.sh create mode 100755 deploy/stFrameReceiver4.sh create mode 100755 deploy/stMetaWriter.sh create mode 100755 deploy/stOdinServer.sh create mode 100644 deploy/startAll.kdl diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f609365..f7e3c25 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,46 +1,55 @@ // For format details, see https://containers.dev/implementors/json_reference/ { - "name": "Python 3 Developer Container", + "name": "eiger-detector devcontainer", "build": { "dockerfile": "../Dockerfile", + "context": "..", "target": "developer" }, - "remoteEnv": { - // Allow X11 apps to run inside the container - "DISPLAY": "${localEnv:DISPLAY}" + "features": { + // add quality of life features for developers including git config integration + // note this is slow for the odin-data container - leaving out for now + "ghcr.io/devcontainers/features/common-utils:2": { + // don't upgrade to make this similar to the runtime container + "upgradePackages": false + } }, + // IMPORTANT for this devcontainer to work with docker VSCODE_REMOTE_USER must be + // set to vscode. You will run as vscode with full sudo rights. + // For podman it should be left blank. You will run as root but host mounts + // will be owned by your user. + "remoteUser": "${localEnv:VSCODE_REMOTE_USER}", "customizations": { "vscode": { - // Set *default* container specific settings.json values on container create. - "settings": { - "python.defaultInterpreterPath": "/venv/bin/python" - }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "ms-python.python", - "github.vscode-github-actions", + "ms-python.vscode-pylance", "tamasfe.even-better-toml", "redhat.vscode-yaml", "ryanluker.vscode-coverage-gutters", + "epicsdeb.vscode-epics", "charliermarsh.ruff", - "ms-azuretools.vscode-docker" + "ms-vscode.cmake-tools", + "ms-vscode.cpptools" ] } }, - "features": { - // Some default things like git config - "ghcr.io/devcontainers/features/common-utils:2": { - "upgradePackages": false - } - }, + // You can place any outside of the container before-launch commands here + "initializeCommand": "bash .devcontainer/initializeCommand ${devcontainerId}", + // One time global setup commands inside the container + "postCreateCommand": "bash .devcontainer/postCreateCommand ${devcontainerId}", "runArgs": [ // Allow the container to access the host X11 display and EPICS CA "--net=host", - // Make sure SELinux does not disable with access to host filesystems like tmp + // Make sure SELinux does not disable write access to host filesystems like tmp "--security-opt=label=disable" ], - // Mount the parent as /workspaces so we can pip install peers as editable + // Mount the parent of the project folder so we can access peer projects "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind", - // After the container is created, install the python project in editable form - "postCreateCommand": "pip install $([ -f dev-requirements.txt ] && echo '-c dev-requirements.txt') -e './python[dev]' && pre-commit install" + // mount in other useful files from the host + "mounts": [ + // add extra mounts below + // "source=${localWorkspaceFolder},target=/odin-data,type=bind" + "source=/dev/shm,target=/dev/shm,type=bind" + ] } diff --git a/.devcontainer/initializeCommand b/.devcontainer/initializeCommand new file mode 100644 index 0000000..732ec1f --- /dev/null +++ b/.devcontainer/initializeCommand @@ -0,0 +1,6 @@ +#!/bin/bash + +# custom initialization goes here - runs outside of the dev container +# just before the container is launched but after the container is created + +echo "devcontainerID ${1}" diff --git a/.devcontainer/postCreateCommand b/.devcontainer/postCreateCommand new file mode 100644 index 0000000..156a8f5 --- /dev/null +++ b/.devcontainer/postCreateCommand @@ -0,0 +1,28 @@ +#!/bin/bash + +# Custom initialization goes here if needed. +# Runs inside the dev container after the container is created + +################################################################################ +# When using docker we will not be root inside the container +# You may wish to change ownership of files you want the user to modify +################################################################################ + +# if [[ $USER != "root" ]] ; then +# # make sure the non-root user can build iocs and (mounted in) support modules +# # sudo chown -R ${USER}:${USER} add_folders_here_if needed +# fi + +################################################################################ +# Shell customizations for Generic IOC devcontainers +################################################################################ + +# pick a zsh theme that does not cause completion corruption in zsh vscode terminals +sed -i $HOME/.zshrc -e 's/ZSH_THEME="devcontainers"/ZSH_THEME="dst"/' + +# allow personalization of all devcontainers in this subdirectory +# by placing a .devcontainer_rc file in the workspace root +if [[ -f /workspaces/.devcontainer_rc ]] ; then + source /workspaces/.devcontainer_rc +fi + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2e8f597 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.dockerignore +Dockerfile + +*build* +*prefix* diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 0000000..67bbd3b --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,76 @@ +name: Container CI + +on: + push: + # Build for main, tags and PRs + # Builds from PRs are not pushed to the registry because of rules in the steps + branches: + - dev + tags: + - "*" + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 # All history + + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Log in to GitHub Docker Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=raw,value=latest + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + + - name: Docker meta config runtime + id: meta-runtime + uses: docker/metadata-action@v4 + with: + images: ghcr.io/${{ github.repository }}-runtime + tags: | + type=ref,event=branch + type=ref,event=tag + type=raw,value=latest + + - name: Docker build runtime image + uses: docker/build-push-action@v4 + with: + context: . + file: Dockerfile + target: runtime + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta-runtime.outputs.tags }} + labels: ${{ steps.meta-runtime.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c8ba787 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "cmake.generator": "Unix Makefiles", + "cmake.sourceDirectory": "${workspaceFolder}/cpp", + "cmake.buildDirectory": "${workspaceFolder}/vscode_build", + "cmake.installPrefix": "/odin", + "cmake.configureArgs": [ + "-DODINDATA_ROOT_DIR=/odin" + ], + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "editor.formatOnSave": true, + "[python]": { + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.rulers": [ + 88 + ] + }, +} diff --git a/Dockerfile b/Dockerfile index 6309e7c..c2c3287 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,31 @@ -# The devcontainer should use the developer target and run as root with podman -# or docker with user namespaces. -ARG PYTHON_VERSION=3.11 -FROM python:${PYTHON_VERSION} as developer - -# Add any system dependencies for the developer/build environment here -RUN apt-get update && apt-get install -y --no-install-recommends \ - graphviz \ - && rm -rf /var/lib/apt/lists/* - -# Set up a virtual environment and put it in PATH -RUN python -m venv /venv -ENV PATH=/venv/bin:$PATH - -# The build stage installs the context into the venv -FROM developer as build -COPY . /context -WORKDIR /context -RUN pip install ./python - -# The runtime stage copies the built venv into a slim runtime container -FROM python:${PYTHON_VERSION}-slim as runtime -# Add apt-get system dependecies for runtime here if needed -COPY --from=build /venv/ /venv/ -ENV PATH=/venv/bin:$PATH - -ENTRYPOINT ["bash"] +FROM ghcr.io/odin-detector/odin-data-developer:latest AS common + +FROM common as developer + +FROM common as build + +# Root of eiger-detector +COPY . /tmp/eiger-detector + +# C++ +WORKDIR /tmp/eiger-detector +RUN mkdir -p build && cd build && \ + cmake -DCMAKE_INSTALL_PREFIX=/odin -DODINDATA_ROOT_DIR=/odin ../cpp && \ + make -j8 VERBOSE=1 && \ + make install + +COPY deploy /odin/eiger-deploy + +# Python +WORKDIR /tmp/eiger-detector/python +RUN python -m pip install . + +# Final image +FROM ghcr.io/odin-detector/odin-data-runtime:latest as runtime +COPY --from=build /odin /odin +ENV PATH=/odin/bin:/odin/venv/bin:$PATH +WORKDIR /odin + +COPY deploy /odin/eiger-deploy + +CMD ["sh", "-c", "cd /odin/eiger-deploy && zellij --layout ./startAll.kdl"] diff --git a/README.md b/README.md index 228b377..ed8e8ba 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,39 @@ -eiger-detector -========= +# eiger-detector -Data Acquisition from the Eiger detector. +Data acquisition framework for the Eiger detector consisting of: -eigerfan: a fan-out of the Eiger zeromq push/pull stream. +- eigerfan: a fan-out of the Eiger zeromq push/pull stream +- EigerMetaWriter: A plugin for the odin-data meta_writer application +- EigerProcessPlugin: A plugin for the odin-data FrameProcessor +- EigerFrameDecoder: A plugin for the odin-data FrameReceiver -metalistener: A python application that listens for odin-data meta messages and writes data to a meta file +# Development -EigerProcessPlugin: Plugin for the odin-data FrameProcessor +A devcontainer is provided for simpler local development. To get started: -EigerFrameDecoder: Plugin for the odin-data FrameReceiver +1. Open the project in VSCode and re-open in devcontainer when prompted, or + open manually with `Dev Containers: Reopen in Container` +2. Add odin-data to with `Workspaces: Add Folder to Workspace...` +3. Build both odin-data and then eiger-detector by selecting a file in each project and: + i. `CMake: Delete Cache and Reconfigure` + ii. `CMake: Install` +4. Install the python dependencies + i. `pip install -e ./odin-data/python[meta_writer]` + ii. `pip install -e ./eiger-detector/python` +5. Run the dev deployment from the `deploy` directory with `zellij -l startAll.kdl` +It is then possible to edit the python applications and restart, or edit the C++ +applications, rebuild and restart. + +To run the tickit simulation, add tickit-devices to the workspace, pip install, and then +run the `Eiger` launch config. + +To run the IOC, add eiger-fastcs to the workspace, pip install and run the `Eiger IOC` +launch config, which talks to the tickit sim by default. The generated output.bob can +then be opened in Phoebus for GUI control. + +Currently in development is odin-fastcs, which creates an EPICS IOC to control the odin +processes. To run this, add odin-fastcs to the workspace, pip install, and then run the +`Odin IOC` launch config, which by default talks to a control server at 127.0.0.1:8888. +At the time of writing, this will not produce any PVs, but at the time of following this +guide it may be functional. diff --git a/deploy/fp1.json b/deploy/fp1.json new file mode 100644 index 0000000..735cedd --- /dev/null +++ b/deploy/fp1.json @@ -0,0 +1,140 @@ +[ + { + "fr_setup": { + "fr_ready_cnxn": "tcp://127.0.0.1:10001", + "fr_release_cnxn": "tcp://127.0.0.1:10002" + }, + "meta_endpoint": "tcp://*:10008" + }, + { + "plugin": { + "load": { + "index": "eiger", + "name": "EigerProcessPlugin", + "library": "/odin/lib/libEigerProcessPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "offset", + "name": "OffsetAdjustmentPlugin", + "library": "/odin/lib/libOffsetAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "param", + "name": "ParameterAdjustmentPlugin", + "library": "/odin/lib/libParameterAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "hdf", + "name": "FileWriterPlugin", + "library": "/odin/lib/libHdf5Plugin.so" + } + } + }, + { + "plugin": { + "connect": { + "index": "eiger", + "connection": "frame_receiver" + } + } + }, + { + "plugin": { + "connect": { + "index": "offset", + "connection": "eiger" + } + } + }, + { + "plugin": { + "connect": { + "index": "param", + "connection": "offset" + } + } + }, + { + "plugin": { + "connect": { + "index": "hdf", + "connection": "param" + } + } + }, + { + "hdf": { + "dataset": { + "compressed_size": { + "datatype": "uint32", + "chunks": [1000] + } + } + } + }, + { + "hdf": { + "dataset": { + "uid": { + "datatype": "uint64", + "chunks": [1000] + } + } + } + }, + { + "param": { + "parameter": { + "uid": { + "adjustment": 1 + } + } + } + }, + { + "hdf": { + "process": { + "number": 4, + "rank": 0 + } + } + }, + { + "hdf": { + "file": { + "flush_error_duration": 10000, + "write_error_duration": 10000, + "close_error_duration": 10000, + "create_error_duration": 10000 + } + } + }, + { + "hdf": { + "file": { + "first_number": 1 + } + } + }, + { + "hdf": { + "dataset": { + "data": { + "indexes": true + } + } + } + } +] diff --git a/deploy/fp2.json b/deploy/fp2.json new file mode 100644 index 0000000..978c1e8 --- /dev/null +++ b/deploy/fp2.json @@ -0,0 +1,140 @@ +[ + { + "fr_setup": { + "fr_ready_cnxn": "tcp://127.0.0.1:10011", + "fr_release_cnxn": "tcp://127.0.0.1:10012" + }, + "meta_endpoint": "tcp://*:10018" + }, + { + "plugin": { + "load": { + "index": "eiger", + "name": "EigerProcessPlugin", + "library": "/odin/lib/libEigerProcessPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "offset", + "name": "OffsetAdjustmentPlugin", + "library": "/odin/lib/libOffsetAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "param", + "name": "ParameterAdjustmentPlugin", + "library": "/odin/lib/libParameterAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "hdf", + "name": "FileWriterPlugin", + "library": "/odin/lib/libHdf5Plugin.so" + } + } + }, + { + "plugin": { + "connect": { + "index": "eiger", + "connection": "frame_receiver" + } + } + }, + { + "plugin": { + "connect": { + "index": "offset", + "connection": "eiger" + } + } + }, + { + "plugin": { + "connect": { + "index": "param", + "connection": "offset" + } + } + }, + { + "plugin": { + "connect": { + "index": "hdf", + "connection": "param" + } + } + }, + { + "hdf": { + "dataset": { + "compressed_size": { + "datatype": "uint32", + "chunks": [1000] + } + } + } + }, + { + "hdf": { + "dataset": { + "uid": { + "datatype": "uint64", + "chunks": [1000] + } + } + } + }, + { + "param": { + "parameter": { + "uid": { + "adjustment": 1 + } + } + } + }, + { + "hdf": { + "process": { + "number": 4, + "rank": 1 + } + } + }, + { + "hdf": { + "file": { + "flush_error_duration": 10000, + "write_error_duration": 10000, + "close_error_duration": 10000, + "create_error_duration": 10000 + } + } + }, + { + "hdf": { + "file": { + "first_number": 1 + } + } + }, + { + "hdf": { + "dataset": { + "data": { + "indexes": true + } + } + } + } +] diff --git a/deploy/fp3.json b/deploy/fp3.json new file mode 100644 index 0000000..4455ba2 --- /dev/null +++ b/deploy/fp3.json @@ -0,0 +1,140 @@ +[ + { + "fr_setup": { + "fr_ready_cnxn": "tcp://127.0.0.1:10021", + "fr_release_cnxn": "tcp://127.0.0.1:10022" + }, + "meta_endpoint": "tcp://*:10028" + }, + { + "plugin": { + "load": { + "index": "eiger", + "name": "EigerProcessPlugin", + "library": "/odin/lib/libEigerProcessPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "offset", + "name": "OffsetAdjustmentPlugin", + "library": "/odin/lib/libOffsetAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "param", + "name": "ParameterAdjustmentPlugin", + "library": "/odin/lib/libParameterAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "hdf", + "name": "FileWriterPlugin", + "library": "/odin/lib/libHdf5Plugin.so" + } + } + }, + { + "plugin": { + "connect": { + "index": "eiger", + "connection": "frame_receiver" + } + } + }, + { + "plugin": { + "connect": { + "index": "offset", + "connection": "eiger" + } + } + }, + { + "plugin": { + "connect": { + "index": "param", + "connection": "offset" + } + } + }, + { + "plugin": { + "connect": { + "index": "hdf", + "connection": "param" + } + } + }, + { + "hdf": { + "dataset": { + "compressed_size": { + "datatype": "uint32", + "chunks": [1000] + } + } + } + }, + { + "hdf": { + "dataset": { + "uid": { + "datatype": "uint64", + "chunks": [1000] + } + } + } + }, + { + "param": { + "parameter": { + "uid": { + "adjustment": 1 + } + } + } + }, + { + "hdf": { + "process": { + "number": 4, + "rank": 2 + } + } + }, + { + "hdf": { + "file": { + "flush_error_duration": 10000, + "write_error_duration": 10000, + "close_error_duration": 10000, + "create_error_duration": 10000 + } + } + }, + { + "hdf": { + "file": { + "first_number": 1 + } + } + }, + { + "hdf": { + "dataset": { + "data": { + "indexes": true + } + } + } + } +] diff --git a/deploy/fp4.json b/deploy/fp4.json new file mode 100644 index 0000000..4a36502 --- /dev/null +++ b/deploy/fp4.json @@ -0,0 +1,140 @@ +[ + { + "fr_setup": { + "fr_ready_cnxn": "tcp://127.0.0.1:10031", + "fr_release_cnxn": "tcp://127.0.0.1:10032" + }, + "meta_endpoint": "tcp://*:10038" + }, + { + "plugin": { + "load": { + "index": "eiger", + "name": "EigerProcessPlugin", + "library": "/odin/lib/libEigerProcessPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "offset", + "name": "OffsetAdjustmentPlugin", + "library": "/odin/lib/libOffsetAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "param", + "name": "ParameterAdjustmentPlugin", + "library": "/odin/lib/libParameterAdjustmentPlugin.so" + } + } + }, + { + "plugin": { + "load": { + "index": "hdf", + "name": "FileWriterPlugin", + "library": "/odin/lib/libHdf5Plugin.so" + } + } + }, + { + "plugin": { + "connect": { + "index": "eiger", + "connection": "frame_receiver" + } + } + }, + { + "plugin": { + "connect": { + "index": "offset", + "connection": "eiger" + } + } + }, + { + "plugin": { + "connect": { + "index": "param", + "connection": "offset" + } + } + }, + { + "plugin": { + "connect": { + "index": "hdf", + "connection": "param" + } + } + }, + { + "hdf": { + "dataset": { + "compressed_size": { + "datatype": "uint32", + "chunks": [1000] + } + } + } + }, + { + "hdf": { + "dataset": { + "uid": { + "datatype": "uint64", + "chunks": [1000] + } + } + } + }, + { + "param": { + "parameter": { + "uid": { + "adjustment": 1 + } + } + } + }, + { + "hdf": { + "process": { + "number": 4, + "rank": 3 + } + } + }, + { + "hdf": { + "file": { + "flush_error_duration": 10000, + "write_error_duration": 10000, + "close_error_duration": 10000, + "create_error_duration": 10000 + } + } + }, + { + "hdf": { + "file": { + "first_number": 1 + } + } + }, + { + "hdf": { + "dataset": { + "data": { + "indexes": true + } + } + } + } +] diff --git a/deploy/fr1.json b/deploy/fr1.json new file mode 100644 index 0000000..ac7d6e4 --- /dev/null +++ b/deploy/fr1.json @@ -0,0 +1,18 @@ +[ + { + "decoder_type": "Eiger", + "decoder_path": "/odin/lib", + "rx_type": "zmq", + "rx_address": "127.0.0.1", + "rx_ports": "31600,", + "shared_buffer_name": "odin_buf_1", + "max_buffer_mem": 1600000000, + "frame_ready_endpoint": "tcp://127.0.0.1:10001", + "frame_release_endpoint": "tcp://127.0.0.1:10002", + "decoder_config": { + "enable_packet_logging": false, + "frame_timeout_ms": 1000, + "detector_model": "16M" + } + } +] \ No newline at end of file diff --git a/deploy/fr2.json b/deploy/fr2.json new file mode 100644 index 0000000..f7f8983 --- /dev/null +++ b/deploy/fr2.json @@ -0,0 +1,18 @@ +[ + { + "decoder_type": "Eiger", + "decoder_path": "/odin/lib", + "rx_type": "zmq", + "rx_address": "127.0.0.1", + "rx_ports": "31601,", + "shared_buffer_name": "odin_buf_2", + "max_buffer_mem": 1600000000, + "frame_ready_endpoint": "tcp://127.0.0.1:10011", + "frame_release_endpoint": "tcp://127.0.0.1:10012", + "decoder_config": { + "enable_packet_logging": false, + "frame_timeout_ms": 1000, + "detector_model": "16M" + } + } +] \ No newline at end of file diff --git a/deploy/fr3.json b/deploy/fr3.json new file mode 100644 index 0000000..9de200f --- /dev/null +++ b/deploy/fr3.json @@ -0,0 +1,18 @@ +[ + { + "decoder_type": "Eiger", + "decoder_path": "/odin/lib", + "rx_type": "zmq", + "rx_address": "127.0.0.1", + "rx_ports": "31602,", + "shared_buffer_name": "odin_buf_3", + "max_buffer_mem": 1600000000, + "frame_ready_endpoint": "tcp://127.0.0.1:10021", + "frame_release_endpoint": "tcp://127.0.0.1:10022", + "decoder_config": { + "enable_packet_logging": false, + "frame_timeout_ms": 1000, + "detector_model": "16M" + } + } +] \ No newline at end of file diff --git a/deploy/fr4.json b/deploy/fr4.json new file mode 100644 index 0000000..dc293f0 --- /dev/null +++ b/deploy/fr4.json @@ -0,0 +1,18 @@ +[ + { + "decoder_type": "Eiger", + "decoder_path": "/odin/lib", + "rx_type": "zmq", + "rx_address": "127.0.0.1", + "rx_ports": "31603,", + "shared_buffer_name": "odin_buf_4", + "max_buffer_mem": 1600000000, + "frame_ready_endpoint": "tcp://127.0.0.1:10031", + "frame_release_endpoint": "tcp://127.0.0.1:10032", + "decoder_config": { + "enable_packet_logging": false, + "frame_timeout_ms": 1000, + "detector_model": "16M" + } + } +] \ No newline at end of file diff --git a/deploy/log4cxx.xml b/deploy/log4cxx.xml new file mode 100644 index 0000000..42e726b --- /dev/null +++ b/deploy/log4cxx.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/deploy/odin_server.cfg b/deploy/odin_server.cfg new file mode 100644 index 0000000..509d3d9 --- /dev/null +++ b/deploy/odin_server.cfg @@ -0,0 +1,28 @@ +[server] +debug_mode = 0 +http_port = 8888 +http_addr = 0.0.0.0 +adapters = fp, fr, meta_listener, eiger_fan + +[tornado] +logging = error + +[adapter.fp] +module = odin_data.control.frame_processor_adapter.FrameProcessorAdapter +endpoints = 127.0.0.1:10004, 127.0.0.1:10014, 127.0.0.1:10024, 127.0.0.1:10034 +update_interval = 0.2 + +[adapter.fr] +module = odin_data.control.frame_receiver_adapter.FrameReceiverAdapter +endpoints = 127.0.0.1:10000, 127.0.0.1:10010, 127.0.0.1:10020, 127.0.0.1:10030 +update_interval = 0.2 + +[adapter.meta_listener] +module = odin_data.control.meta_listener_adapter.MetaListenerAdapter +endpoints = 127.0.0.1:5659 +update_interval = 0.5 + +[adapter.eiger_fan] +module = eiger_detector.control.eiger_fan_adapter.EigerFanAdapter +endpoints = 127.0.0.1:5559 +update_interval = 0.5 diff --git a/deploy/stEigerFan.sh b/deploy/stEigerFan.sh new file mode 100755 index 0000000..4ee9a41 --- /dev/null +++ b/deploy/stEigerFan.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +/odin/bin/eigerfan -s 127.0.0.1 -n 4 -z 4 -b 1000 -t 2 --logconfig $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameProcessor1.sh b/deploy/stFrameProcessor1.sh new file mode 100755 index 0000000..85e3c2b --- /dev/null +++ b/deploy/stFrameProcessor1.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +export HDF5_PLUGIN_PATH=/dls_sw/prod/tools/RHEL7-x86_64/hdf5filters/0-7-0/prefix/hdf5_1.10/h5plugin + +/odin/bin/frameProcessor --ctrl=tcp://0.0.0.0:10004 --config=$SCRIPT_DIR/fp1.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameProcessor2.sh b/deploy/stFrameProcessor2.sh new file mode 100755 index 0000000..0703877 --- /dev/null +++ b/deploy/stFrameProcessor2.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +export HDF5_PLUGIN_PATH=/dls_sw/prod/tools/RHEL7-x86_64/hdf5filters/0-7-0/prefix/hdf5_1.10/h5plugin + +/odin/bin/frameProcessor --ctrl=tcp://0.0.0.0:10014 --config=$SCRIPT_DIR/fp2.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameProcessor3.sh b/deploy/stFrameProcessor3.sh new file mode 100755 index 0000000..b4d6356 --- /dev/null +++ b/deploy/stFrameProcessor3.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +export HDF5_PLUGIN_PATH=/dls_sw/prod/tools/RHEL7-x86_64/hdf5filters/0-7-0/prefix/hdf5_1.10/h5plugin + +/odin/bin/frameProcessor --ctrl=tcp://0.0.0.0:10024 --config=$SCRIPT_DIR/fp3.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameProcessor4.sh b/deploy/stFrameProcessor4.sh new file mode 100755 index 0000000..766f902 --- /dev/null +++ b/deploy/stFrameProcessor4.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +export HDF5_PLUGIN_PATH=/dls_sw/prod/tools/RHEL7-x86_64/hdf5filters/0-7-0/prefix/hdf5_1.10/h5plugin + +/odin/bin/frameProcessor --ctrl=tcp://0.0.0.0:10034 --config=$SCRIPT_DIR/fp4.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameReceiver1.sh b/deploy/stFrameReceiver1.sh new file mode 100755 index 0000000..f1fc003 --- /dev/null +++ b/deploy/stFrameReceiver1.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +/odin/bin/frameReceiver --io-threads 2 --ctrl=tcp://0.0.0.0:10000 --config=$SCRIPT_DIR/fr1.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameReceiver2.sh b/deploy/stFrameReceiver2.sh new file mode 100755 index 0000000..ff06ffd --- /dev/null +++ b/deploy/stFrameReceiver2.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +/odin/bin/frameReceiver --io-threads 2 --ctrl=tcp://0.0.0.0:10010 --config=$SCRIPT_DIR/fr2.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameReceiver3.sh b/deploy/stFrameReceiver3.sh new file mode 100755 index 0000000..8f4971e --- /dev/null +++ b/deploy/stFrameReceiver3.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +/odin/bin/frameReceiver --io-threads 2 --ctrl=tcp://0.0.0.0:10020 --config=$SCRIPT_DIR/fr3.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stFrameReceiver4.sh b/deploy/stFrameReceiver4.sh new file mode 100755 index 0000000..0aedc90 --- /dev/null +++ b/deploy/stFrameReceiver4.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +/odin/bin/frameReceiver --io-threads 2 --ctrl=tcp://0.0.0.0:10030 --config=$SCRIPT_DIR/fr4.json --log-config $SCRIPT_DIR/log4cxx.xml diff --git a/deploy/stMetaWriter.sh b/deploy/stMetaWriter.sh new file mode 100755 index 0000000..5f7d462 --- /dev/null +++ b/deploy/stMetaWriter.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +/venv/bin/eiger_meta_writer -w eiger_detector.EigerMetaWriter --sensor-shape 4362 4148 --data-endpoints tcp://127.0.0.1:10008,tcp://127.0.0.1:10018,tcp://127.0.0.1:10028,tcp://127.0.0.1:10038 diff --git a/deploy/stOdinServer.sh b/deploy/stOdinServer.sh new file mode 100755 index 0000000..8572800 --- /dev/null +++ b/deploy/stOdinServer.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" + +# Increase maximum fds available for ZeroMQ sockets +ulimit -n 2048 + +/venv/bin/eiger_control --config=$SCRIPT_DIR/odin_server.cfg --logging=info --access_logging=ERROR diff --git a/deploy/startAll.kdl b/deploy/startAll.kdl new file mode 100644 index 0000000..f57b2ae --- /dev/null +++ b/deploy/startAll.kdl @@ -0,0 +1,29 @@ +layout { + pane size=1 borderless=true { + plugin location="zellij:tab-bar" + } + pane split_direction="vertical" { + pane split_direction="horizontal" { + pane command="./stFrameReceiver1.sh" + pane command="./stFrameProcessor1.sh" + pane command="./stFrameReceiver2.sh" + pane command="./stFrameProcessor2.sh" + pane command="./stFrameReceiver3.sh" + pane command="./stFrameProcessor3.sh" + pane command="./stFrameReceiver4.sh" + pane command="./stFrameProcessor4.sh" + } + pane split_direction="horizontal" { + pane command="./stEigerFan.sh" + pane command="./stMetaWriter.sh" + pane command="bash" { + args "-c" "sleep 3; ./stOdinServer.sh" + } + } + } + pane size=2 borderless=true { + plugin location="zellij:status-bar" + } +} +session_name "EIGER" +attach_to_session true