diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 91aeace9..8ee96899 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,4 +1,10 @@ -v1.10.0 (2023-12-23) +v1.11.0 (2023-12-25) +******************* +* Acquisition and AutoFocus both got a `broadcast` option to disable broadcast of images. +* AutoFocus got a `final_image` parameter to take a final image at optimal focus. + + +v1.10.0 (2023-12-24) ******************* * Added CallModule script. * Changed ScriptRunner module so that it can run a script multiple times. diff --git a/pyobs/modules/focus/focusseries.py b/pyobs/modules/focus/focusseries.py index de7c0cf5..abcb8c22 100644 --- a/pyobs/modules/focus/focusseries.py +++ b/pyobs/modules/focus/focusseries.py @@ -31,6 +31,8 @@ def __init__( filters: Optional[Union[str, IFilters]] = None, filter_name: Optional[str] = None, binning: Optional[int] = None, + broadcast: bool = False, + final_image: bool = True, **kwargs: Any, ): """Initialize a new auto focus system. @@ -41,6 +43,8 @@ def __init__( filters: Name of IFilters, if any. filter_name: Name of filter to set. offset: If True, offsets are used instead of absolute focus values. + broadcast: Whether to broadcast focus series images. + final_image: Whether to take final image with optimal focus, which is always broadcasted. """ Module.__init__(self, **kwargs) @@ -51,6 +55,8 @@ def __init__( self._offset = offset self._abort = threading.Event() self._running = False + self._broadcast = broadcast + self._final_image = final_image # create focus series self._series: FocusSeries = get_object(series, FocusSeries) @@ -122,6 +128,8 @@ async def _auto_focus(self, count: int, step: float, exposure_time: float, **kwa # do camera settings await self._do_camera_settings(camera) + if isinstance(camera, IImageType): + await camera.set_image_type(ImageType.FOCUS) # get filter wheel and current filter filter_name = "unknown" @@ -173,11 +181,7 @@ async def _auto_focus(self, count: int, step: float, exposure_time: float, **kwa if self._abort.is_set(): raise exceptions.AbortedError() try: - if isinstance(camera, IExposureTime): - await camera.set_exposure_time(exposure_time) - if isinstance(camera, IImageType): - await camera.set_image_type(ImageType.FOCUS) - filename = await camera.grab_data() + filename = await self._take_image(camera, exposure_time) except exc.RemoteError: log.error("Could not take image.") continue @@ -231,9 +235,21 @@ async def _auto_focus(self, count: int, step: float, exposure_time: float, **kwa # send event await self.comm.send_event(FocusFoundEvent(absolute, focus[1], filter_name)) + # take final image? + if self._final_image: + await self._take_image(camera, exposure_time) + # return result return focus[0], focus[1] + async def _take_image(self, camera, exposure_time): + if isinstance(camera, IExposureTime): + await camera.set_exposure_time(exposure_time) + if isinstance(camera, IData): + return await camera.grab_data(broadcast=self._broadcast) + else: + raise exc.GeneralError("Cannot grab data from camera.") + async def auto_focus_status(self, **kwargs: Any) -> Dict[str, Any]: """Returns current status of auto focus. diff --git a/pyobs/modules/pointing/acquisition.py b/pyobs/modules/pointing/acquisition.py index c0c9bb85..1c02abf3 100644 --- a/pyobs/modules/pointing/acquisition.py +++ b/pyobs/modules/pointing/acquisition.py @@ -33,6 +33,7 @@ def __init__( tolerance: float = 1, max_offset: float = 120, log_file: Optional[str] = None, + broadcast: bool = False, **kwargs: Any, ): """Create a new acquisition. @@ -44,6 +45,7 @@ def __init__( tolerance: Tolerance in position to reach in arcsec. max_offset: Maximum offset to move in arcsec. log_file: Name of file to write log to. + broadcast: Whether to broadcast acquisition images. """ BasePointing.__init__(self, **kwargs) @@ -55,6 +57,7 @@ def __init__( self._tolerance = tolerance * u.arcsec self._max_offset = max_offset * u.arcsec self._abort_event = asyncio.Event() + self._broadcast = broadcast # init log file self._publisher = CsvPublisher(log_file) if log_file is not None else None @@ -111,6 +114,8 @@ async def _acquire(self, exposure_time: float) -> Dict[str, Any]: # do camera settings await self._do_camera_settings(camera) + if isinstance(camera, IImageType): + await camera.set_image_type(ImageType.ACQUISITION) # try given number of attempts for a in range(self._attempts): @@ -124,9 +129,10 @@ async def _acquire(self, exposure_time: float) -> Dict[str, Any]: await camera.set_exposure_time(exposure_time) else: log.info("Exposing image...") - if isinstance(camera, IImageType): - await camera.set_image_type(ImageType.ACQUISITION) - filename = await camera.grab_data() + if isinstance(camera, IData): + filename = await camera.grab_data(broadcast=self._broadcast) + else: + raise exc.GeneralError("Cannot grab data from camera.") # download image log.info("Downloading image...") diff --git a/pyproject.toml b/pyproject.toml index 624cd2d8..e66076e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "pyobs-core" packages = [{ include = "pyobs" }] -version = "1.10.1" +version = "1.11.0" description = "robotic telescope software" authors = ["Tim-Oliver Husser "] license = "MIT"