Skip to content

Commit

Permalink
Merge pull request #13 from NSLS-II-SRX/axis-caproto-ioc
Browse files Browse the repository at this point in the history
Axis Caproto IOC
  • Loading branch information
dmgav authored May 23, 2024
2 parents b0d143e + fde62d5 commit 0db99ec
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 14 deletions.
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
additional_dependencies: [black==23.*]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v4.5.0"
rev: "v4.6.0"
hooks:
- id: check-added-large-files
- id: check-case-conflict
Expand Down Expand Up @@ -40,7 +40,7 @@ repos:
args: [--prose-wrap=always]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.2.1"
rev: "v0.4.5"
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand All @@ -56,12 +56,12 @@ repos:
# - pytest

- repo: https://github.com/codespell-project/codespell
rev: "v2.2.6"
rev: "v2.3.0"
hooks:
- id: codespell

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: "v0.9.0.6"
rev: "v0.10.0.1"
hooks:
- id: shellcheck

Expand All @@ -74,13 +74,13 @@ repos:
exclude: .pre-commit-config.yaml

- repo: https://github.com/abravalheri/validate-pyproject
rev: "v0.16"
rev: "v0.18"
hooks:
- id: validate-pyproject
additional_dependencies: ["validate-pyproject-schema-store[all]"]

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: "0.28.0"
rev: "0.28.4"
hooks:
- id: check-dependabot
- id: check-github-workflows
Expand Down
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: 0 additions & 1 deletion src/srx_caproto_iocs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
srx-caproto-iocs: Caproto IOCs for the NSLS-II SRX beamline
"""


from __future__ import annotations

from ._version import version as __version__
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."""
94 changes: 94 additions & 0 deletions src/srx_caproto_iocs/axis/caproto_ioc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# pylint: disable=duplicate-code
from __future__ import annotations

import textwrap
from io import BytesIO

import requests
from caproto import ChannelType
from caproto.server import pvproperty, run, template_arg_parser
from PIL import Image

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."""

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): # pylint: disable=unused-argument
url = f"http://{self._camera_host}/axis-cgi/jpg/image.cgi"
resp = requests.get(url, timeout=10)
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.
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)
6 changes: 6 additions & 0 deletions src/srx_caproto_iocs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ async def _stage(self, instance, value):

@stage.putter
async def stage(self, *args, **kwargs):
"""The stage method."""
return await self._stage(*args, **kwargs)

async def _get_current_dataset(self, frame):
Expand Down Expand Up @@ -244,6 +245,11 @@ class OphydDeviceWithCaprotoIOC(Device):
def set(self, command):
"""The set method with values for staging and acquiring."""

expected_old_value = None
expected_new_value = None
obj = None
cmd = None

# print(f"{now()}: {command = }")
if command in [StageStates.STAGED.value, "stage"]:
expected_old_value = StageStates.UNSTAGED.value
Expand Down
2 changes: 1 addition & 1 deletion src/srx_caproto_iocs/example/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
""""Example Caproto IOC code."""
"""Example Caproto IOC code."""
1 change: 0 additions & 1 deletion src/srx_caproto_iocs/sis_scaler/__init__.py

This file was deleted.

5 changes: 5 additions & 0 deletions src/srx_caproto_iocs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ def now(as_object=False):
return _now.isoformat()


def save_image(fname, data, file_format="jpeg", mode="x"): # pylint: disable=unused-argument
"""The function to export the image data (e.g., to a JPEG file."""
data.save(fname, file_format=file_format)


def save_hdf5_zebra(
fname,
data,
Expand Down
2 changes: 1 addition & 1 deletion src/srx_caproto_iocs/zebra/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
""""Zebra Caproto IOC code."""
"""Zebra Caproto IOC code."""
7 changes: 3 additions & 4 deletions src/srx_caproto_iocs/zebra/caproto_ioc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=duplicate-code
from __future__ import annotations

import textwrap
Expand Down Expand Up @@ -162,9 +163,8 @@ class ZebraSaveIOC(CaprotoSaveIOC):
# super().__init__(*args, **kwargs)
# self._external_pvs = external_pvs

async def _get_current_dataset(
self, *args, **kwargs
): # , frame, external_pv="enc1"):
async def _get_current_dataset(self, *args, **kwargs): # pylint: disable=unused-argument
# , frame, external_pv="enc1"):
# client_context = Context()
# (pvobject,) = await client_context.get_pvs(self._external_pvs[external_pv])
# print(f"{pvobject = }")
Expand Down Expand Up @@ -192,7 +192,6 @@ def saver(request_queue, response_queue):
filename = received["filename"]
data = received["data"]
# 'frame_number' is not used for this exporter.
frame_number = received["frame_number"] # noqa: F841
try:
save_hdf5_zebra(fname=filename, data=data, mode="x")
print(f"{now()}: saved data into:\n {filename}")
Expand Down

0 comments on commit 0db99ec

Please sign in to comment.