Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Axis Caproto IOC #13

Merged
merged 3 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading