Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
// For format details, see https://containers.dev/implementors/json_reference/
{
    "name": "Native IOC development container",
    "image": "baltig.infn.it:4567/epics-containers/infn-epics-ioc:devel",
    "remoteEnv": {
        // allows X11 apps to run inside the container
        "DISPLAY": "${localEnv:DISPLAY}",
        // provides a name for epics-containers to use in bash prompt etc.
        "EC_PROJECT": "${localWorkspaceFolderBasename}"
    },
    "features": {
        
    },
    // IMPORTANT for this devcontainer to work with docker EC_REMOTE_USER must be
    // set to vscode. For podman it should be left blank.
    "remoteUser": "${localEnv:EC_REMOTE_USER}",
    "customizations": {
        "vscode": {
            // Add the IDs of extensions you want installed when the container is created.
             "extensions": [
                "ms-python.python",
                "ms-python.vscode-pylance",
                "tamasfe.even-better-toml",
                "redhat.vscode-yaml",
                "ryanluker.vscode-coverage-gutters",
                "epicsdeb.vscode-epics",
                "ms-python.black-formatter"
            ]
        }
    },
    // Make sure the files we are mapping into the container exist on the host
    // You can place any other outside of the container before-launch commands here
    //"initializeCommand": "bash .devcontainer/initializeCommand ${devcontainerId}",
    // Hooks the global .bashprofile_dev_container but also can add any other commands
    // to run in the container at creation in here
    //"postCreateCommand": "bash .devcontainer/postCreateCommand ${devcontainerId}",
	// forward ports to clients
     "appPort": [5064,"5064:5064/udp","5065:5065/udp"],

    "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
        "--security-opt=label=disable"
    ],
    "workspaceMount": "source=${localWorkspaceFolder},target=/app/${localWorkspaceFolderBasename},type=bind",
    "workspaceFolder": "/app/${localWorkspaceFolderBasename}",
    "mounts": [
        // Mount some useful local files from the user's home directory
        // By mounting the parent of the workspace we can work on multiple peer projects
        "source=${localWorkspaceFolder}/../,target=/repos,type=bind",
        
        
    ]
}

GIGE Camera

Gigavision cameras that support GIGE protocol can be acquired by ADAravis support that is already included in production/development infn-epics-ioc container, remember this container must be launched with the  --network=host to access GIGE cameras.


Devel example

Example development the arv-tool command inside the container can be used to explore cameras that can be accessed:


Code Block
languagebash
titleCamera development start
docker run --network=host -v .:/epics/ioc/config -it baltig.infn.it:4567/epics-containers/infn-epics-ioc:devel bash
..

root@chaost-camera01:/epics/generic-source/ioc/config# arv-tool-0.8 
Basler-a2A1920-51gmBAS-40426579 (192.168.115.49)
Basler-a2A2600-20gmBAS-40437925 (192.168.115.48)
Basler-scA640-70gm-24159532 (192.168.115.50)


Production example

The configuration and pipelining of plugin can be very difficult and error prone, so the IBEK + templating support is highly recommended.

Create a directory <test> and create a camera_template.j2 file like that:

camera template

Code Block
languageyaml
titleCamera template.j2
# yaml-language-server: $schema=../schemas/ibek.support.schema.json
ioc_name: {{name}}
description: Camera SIM model with plugins

entities:
  {%- if devtype == "camerasim" %}
  - type: ADSimDetector.simDetector
  {% else %}
  - type: ADAravis.aravisCamera
    ID: {{CAMERA_ID}}
    CLASS: {{CAMERA_CLASS}}
  {% endif %}
    PORT: {{iocroot}}
    P: "{{iocprefix}}:"
    R: "{{iocroot}}:"

    

  - type: ADCore.NDROI
    PORT: {{iocroot}}.ROI1
    NDARRAY_PORT: {{iocroot}}
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Roi1:"
    ENABLED: 1

  - type: ADCore.NDProcess
    PORT: {{iocroot}}.PROC
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Proc1:"
    NDARRAY_PORT: {{iocroot}}.ROI1
    ENABLED: 1

  - type: ADCore.NDOverlay
    PORT: {{iocroot}}.OVERLAY1
    NDARRAY_PORT: {{iocroot}}
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Overlay1:"
    NAME: "Reference"
    NOverlays: 8
    SHAPE: "3"
    XPOS: ""
    YPOS: ""
    XCENT: ""
    YCENT: ""
    XSIZE: ""
    YSIZE: ""
    XWIDTH: ""
    YWIDTH: ""
    O: "1:"

  # Want to have also high throuput PVA protocol
  - type: ADCore.NDPvaPlugin
    PORT: {{iocroot}}.PVA
    PVNAME: "{{iocprefix}}:{{iocroot}}:PVA:OUTPUT"
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Pva1:"
    NDARRAY_PORT: {{iocroot}}
    ENABLED: 1
  
  - type: ADCore.NDPvaPlugin
    PORT: {{iocroot}}.PVA2
    PVNAME: "{{iocprefix}}:{{iocroot}}:PROC:OUTPUT"
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Proc1:Pva1:"
    NDARRAY_PORT: {{iocroot}}.PROC
    ENABLED: 1

  
  - type: ADCore.NDPvaPlugin
    PORT: {{iocroot}}.PVA3
    PVNAME: "{{iocprefix}}:{{iocroot}}:ROI1:OUTPUT"
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Roi1:Pva1:"
    NDARRAY_PORT: {{iocroot}}.ROI1
    ENABLED: 1

  

  - type: ADCore.NDStdArrays
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":image1:"
    PORT: {{iocroot}}.NTD
    NDARRAY_PORT: {{iocroot}}
    TYPE: {{CAMERA_TYPE}}
    FTVL: {{CAMERA_FTVL}}
    NELEMENTS: {{CAMERA_ELEMS}}
    ENABLED: 1

  
  - type: ADCore.NDPvaPlugin
    PORT: {{iocroot}}.PVA4
    PVNAME: "{{iocprefix}}:{{iocroot}}:OVERLAY1:OUTPUT"
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Overlay1:Pva1:"
    NDARRAY_PORT: {{iocroot}}.OVERLAY1
    ENABLED: 1

  - type: ADCore.NDStdArrays
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":image2:"
    PORT: {{iocroot}}.NTD2
    NDARRAY_PORT: {{iocroot}}.PROC
    TYPE: {{CAMERA_TYPE}}
    FTVL: {{CAMERA_FTVL}}
    NELEMENTS: {{CAMERA_ELEMS}}
    ENABLED: 1

  - type: ADCore.NDStats
    PORT: {{iocroot}}.STATS
    NDARRAY_PORT: {{iocroot}}
    HIST_SIZE: 50
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Stats1:"
    XSIZE: {{CAMERA_STATS_XSIZE}}
    YSIZE: {{CAMERA_STATS_YSIZE}}
    ENABLED: 1

  - type: ADCore.NDStats
    PORT: {{iocroot}}.STATS2
    NDARRAY_PORT: {{iocroot}}.PROC
    HIST_SIZE: 50
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Proc1:Stats1:"
    XSIZE: {{CAMERA_STATS_XSIZE}}
    YSIZE: {{CAMERA_STATS_YSIZE}}
    ENABLED: 1
  
  - type: ADCore.NDStats
    PORT: {{iocroot}}.STATS3
    NDARRAY_PORT: {{iocroot}}.ROI1
    HIST_SIZE: 50
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Roi1:Stats1:"
    XSIZE: {{CAMERA_STATS_XSIZE}}
    YSIZE: {{CAMERA_STATS_YSIZE}}
    ENABLED: 1



  - type: ADCore.NDFileTIFF
    PORT: {{iocroot}}.TIFF
    NDARRAY_PORT: {{iocroot}}
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":TIFF1:"
    ENABLED: 1

  - type: ADCore.NDFileTIFF
    PORT: {{iocroot}}.TIFF2
    NDARRAY_PORT: {{iocroot}}.PROC
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Proc1:TIFF1:"
    ENABLED: 1

  - type: ADCore.NDFileTIFF
    PORT: {{iocroot}}.TIFF3
    NDARRAY_PORT: {{iocroot}}.ROI1
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Roi1:TIFF1:"
    ENABLED: 1

  - type: ADCore.NDFileTIFF
    PORT: {{iocroot}}.TIFF4
    NDARRAY_PORT: {{iocroot}}.OVERLAY1
    P: "{{iocprefix}}:{{iocroot}}"
    R: ":Overlay1:TIFF1:"
    ENABLED: 1

  - type: epics.PostStartupCommand 
    command: dbl              ## dumps PV NAMES

  - type: epics.PostStartupCommand 
    command: |
      dbl("*") > {{data_config}}/pvlist.txt
      dbpf("{{iocprefix}}:{{iocroot}}:TIFF1:FilePath", "{{data_dir}}")
      dbpf("{{iocprefix}}:{{iocroot}}:TIFF1:FileWriteMode",2)
      dbpf("{{iocprefix}}:{{iocroot}}:TIFF1:FileName","camera")
      dbpf("{{iocprefix}}:{{iocroot}}:TIFF1:AutoIncrement",1)

      dbpf("{{iocprefix}}:{{iocroot}}:TIFF1:FileTemplate","%s%s_%3.3d.tiff")
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF1:FilePath", "{{data_dir}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF1:FileWriteMode",2)
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF1:FileName","{{iocroot}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF1:AutoIncrement",1)
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF1:FileTemplate","%s%s_proc_%3.3d.tiff")

      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF:FilePath", "{{data_dir}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF:FileWriteMode",2)
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF:FileName","{{iocroot}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF:AutoIncrement",1)
      dbpf("{{iocprefix}}:{{iocroot}}:Proc1:TIFF:FileTemplate","%s%s_proc_%3.3d.tiff")

      dbpf("{{iocprefix}}:{{iocroot}}:Roi1:TIFF1:FilePath", "{{data_dir}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Roi1:TIFF1:FileWriteMode",2)
      dbpf("{{iocprefix}}:{{iocroot}}:Roi1:TIFF1:FileName","{{iocroot}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Roi1:TIFF1:AutoIncrement",1)
      dbpf("{{iocprefix}}:{{iocroot}}:Roi1:TIFF1:FileTemplate","%s%s_roi_%3.3d.tiff")
      dbpf("{{iocprefix}}:{{iocroot}}:Overlay1:TIFF1:FilePath", "{{data_dir}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Overlay1:TIFF1:FileWriteMode",2)
      dbpf("{{iocprefix}}:{{iocroot}}:Overlay1:TIFF1:FileTemplate","%s%s_overlay_%3.3d.tiff")
      dbpf("{{iocprefix}}:{{iocroot}}:Overlay1:TIFF1:FileName","{{iocroot}}")
      dbpf("{{iocprefix}}:{{iocroot}}:Overlay1:EnableCallbacks","1")
      {%- for param in iocinit %}
        dbpf("{{iocprefix}}:{{iocroot}}:{{param.name}}","{{param.value}}")
      {%- endfor %}

  - type: epics.EpicsCaMaxArrayBytes 
    max_bytes: 10000000


camera ibek specific rendering

And a camerainit.yml that produce the ibek yaml for the given camera:

Code Block
languageyaml
titlecamera ini
name: "SCOUT640"
asset: "https://confluence.infn.it/x/nYD8DQ"
charturl: 'https://baltig.infn.it/epics-containers/ioc-launcher-chart.git'
host: "192.168.197.24"
user: "root"
iocdir: "camera"
ca_server_port: 5264
pva_server_port: 5275
docker:
  enable: true
  image: baltig.infn.it:4567/epics-containers/infn-epics-ioc:latest
devtype: camera
devgroup: diag
iocprefix: "EUAPS:CAM"
iocroot: "SCOUT64"
autosync: false ## restart automatically on changes
opi:
  url: https://baltig.infn.it/infn-epics/camera-opi.git
  main: Camera_Main.bob
  macro:
    - name: "DEVICE"
      value: EUAPS:CAM
    - name: "CAM"
      value: "SCOUT64"

CAMERA_ID: "Basler-scA640-70gm-24159532"
CAMERA_CLASS: "Basler-scA640-70gm"
CAMERA_TYPE: "Int8"
CAMERA_FTVL: "USHORT"
CAMERA_ELEMS: 5616000
CAMERA_STATS_XSIZE: 1024
CAMERA_STATS_YSIZE: 768

The application jnjrender (pip install jnjrender) will render a valid ibek yaml  camera_template.yaml


Code Block
languageyaml
titlecamera ini
jnjrender camera_template.j2  camerainit.yml  --output camera_template.yaml


camera run

Now launch the docker mounting the directory that contains the camera_template.yaml in/epics/ioc/config

Code Block
languagebash
titleCamera development start
docker run --network=host -v .:/epics/ioc/config -it baltig.infn.it:4567/epics-containers/infn-epics-ioc

Deploy on the target EPIK8S 

...