From 1628ecd00b9831dc36c919a3af804625f5c9b700 Mon Sep 17 00:00:00 2001 From: pgriffin17 <31374077+pgriffin17@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:07:09 -0600 Subject: [PATCH] Moved image transpose to ASCOM Camera driver, improved obs.save_last_image --- pyscope/observatory/ascom_camera.py | 9 ++++++++- pyscope/observatory/observatory.py | 20 ++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/pyscope/observatory/ascom_camera.py b/pyscope/observatory/ascom_camera.py index b0307b25..b39265a8 100644 --- a/pyscope/observatory/ascom_camera.py +++ b/pyscope/observatory/ascom_camera.py @@ -1,5 +1,6 @@ import logging from datetime import datetime as dt + import numpy as np from .ascom_device import ASCOMDevice @@ -20,6 +21,7 @@ def __init__(self, identifier, alpaca=False, device_number=0, protocol="http"): self._last_exposure_duration = None self._last_exposure_start_time = None self._image_data_type = None + self._DoTranspose = True def AbortExposure(self): logger.debug(f"ASCOMCamera.AbortExposure() called") @@ -255,7 +257,9 @@ def ImageArray(self): if self._image_data_type is None: self.SetImageDataType() img_array = np.array(img_array, dtype=self._image_data_type) - return self._device.ImageArray + if self._DoTranspose: + img_array = np.transpose(img_array) + return img_array @property def ImageReady(self): @@ -276,6 +280,9 @@ def LastExposureDuration(self): def LastExposureStartTime(self): logger.debug(f"ASCOMCamera.LastExposureStartTime property called") last_time = self._device.LastExposureStartTime + """ This code is needed to handle the case of the ASCOM ZWO driver + which returns an empty string instead of None if the camera does not + support the property """ return ( last_time if last_time != "" and last_time != None diff --git a/pyscope/observatory/observatory.py b/pyscope/observatory/observatory.py index a89e9039..c34600ca 100644 --- a/pyscope/observatory/observatory.py +++ b/pyscope/observatory/observatory.py @@ -1168,11 +1168,14 @@ def save_last_image( if not self.camera.ImageReady: logger.exception("Image is not ready, cannot be saved") return False + + # Read out the image array + img_array = self.camera.ImageArray if ( - self.camera.ImageArray is None - or len(self.camera.ImageArray) == 0 - or len(self.camera.ImageArray[0]) == 0 + img_array is None + or len(img_array) == 0 + or len(img_array) == 0 ): logger.exception("Image array is empty, cannot be saved") return False @@ -1182,9 +1185,9 @@ def save_last_image( hdr["SIMPLE"] = True hdr["BITPIX"] = (16, "8 unsigned int, 16 & 32 int, -32 & -64 real") hdr["NAXIS"] = (2, "number of axes") - hdr["NAXIS1"] = (len(self.camera.ImageArray), "fastest changing axis") + hdr["NAXIS1"] = (len(img_array), "fastest changing axis") hdr["NAXIS2"] = ( - len(self.camera.ImageArray[0]), + len(img_array[0]), "next to fastest changing axis", ) hdr["BSCALE"] = (1, "physical=BZERO + BSCALE*array_value") @@ -1224,13 +1227,6 @@ def save_last_image( for hist in history: hdr["HISTORY"] = hist - # By default, the ImageArray is 32 bit int, at least on my system - # of a ZWO 290MM Mini - we need to convert it to 16 bit unsigned int - img_array = np.array(self.camera.ImageArray).astype(np.uint16) - # Transpose the image array to match the FITS standard - # as well as the axis order defined above - img_array = np.transpose(img_array) - hdu = fits.PrimaryHDU(img_array, header=hdr) hdu.writeto(filename, overwrite=overwrite)