Skip to content

Commit

Permalink
Implement Axis Caproto IOC
Browse files Browse the repository at this point in the history
  • Loading branch information
mrakitin committed May 23, 2024
1 parent 135d93c commit a2fc5db
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies = [
"h5py",
"numpy",
"ophyd",
"pillow",
"pyepics", # does not work with 'setuptools' version higher than v66.1.1
"scikit-image[data]",
]
Expand Down
1 change: 1 addition & 0 deletions src/srx_caproto_iocs/axis/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
""""Axis Cameras Caproto IOC code."""
99 changes: 99 additions & 0 deletions src/srx_caproto_iocs/axis/caproto_ioc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from __future__ import annotations

import requests
from PIL import Image, ImageFont, ImageDraw
from io import BytesIO

import textwrap
from enum import Enum

from caproto import ChannelType
from caproto.server import pvproperty, run, template_arg_parser

from ..base import CaprotoSaveIOC, check_args
from ..utils import now, save_image

DEFAULT_MAX_LENGTH = 10_000_000


class AxisSaveIOC(CaprotoSaveIOC):
"""Axis caproto save IOC."""

common_kwargs = {"max_length": 255, "string_encoding": "utf-8"}

key1 = pvproperty(
value="",
string_encoding="utf-8",
dtype=ChannelType.CHAR,
doc="key 1 for data 1",
max_length=255,
)
data1 = pvproperty(
value=0,
dtype=ChannelType.DOUBLE,
doc="data 1",
max_length=DEFAULT_MAX_LENGTH,
)

def __init__(self, *args, camera_host=None, **kwargs):
self._camera_host = camera_host
print(f"{camera_host = }")
super().__init__(*args, **kwargs)

async def _get_current_dataset(
self, *args, **kwargs
):
url = f"http://{self._camera_host}/axis-cgi/jpg/image.cgi"
resp = requests.get(url)
img = Image.open(BytesIO(resp.content))

dataset = img
print(f"{now()}:\n{dataset.size}")

return dataset

@staticmethod
def saver(request_queue, response_queue):
"""The saver callback for threading-based queueing."""
while True:
received = request_queue.get()
filename = received["filename"]
data = received["data"]
# 'frame_number' is not used for this exporter.
frame_number = received["frame_number"] # noqa: F841
try:
save_image(fname=filename, data=data, file_format="jpeg", mode="x")
print(f"{now()}: saved data into:\n {filename}")

success = True
error_message = ""
except Exception as exc: # pylint: disable=broad-exception-caught
success = False
error_message = exc
print(
f"Cannot save file {filename!r} due to the following exception:\n{exc}"
)

response = {"success": success, "error_message": error_message}
response_queue.put(response)


if __name__ == "__main__":
parser, split_args = template_arg_parser(
default_prefix="", desc=textwrap.dedent(AxisSaveIOC.__doc__)
)

parser.add_argument(
"-c", "--camera-host",
help="The camera hostname, e.g., 'xf06bm-cam5'",
required=True,
type=str,
)

ioc_options, run_options = check_args(parser, split_args)

print(f"{ioc_options = }")
print(f"{run_options = }")

ioc = AxisSaveIOC(camera_host=parser.parse_args().camera_host, **ioc_options)
run(ioc.pvdb, **run_options)
4 changes: 4 additions & 0 deletions src/srx_caproto_iocs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def now(as_object=False):
return _now.isoformat()


def save_image(fname, data, file_format="jpeg", mode="x"):
data.save(fname, file_format=file_format)


def save_hdf5_zebra(
fname,
data,
Expand Down

0 comments on commit a2fc5db

Please sign in to comment.