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

Update my dev branch #133

Merged
merged 34 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
04c9e04
Bump tksheet from 6.2.9 to 6.3.0
dependabot[bot] Nov 27, 2023
c321ced
Bump photutils from 1.9.0 to 1.10.0
dependabot[bot] Nov 27, 2023
92775e4
Merge pull request #107 from WWGolay/dependabot/pip/photutils-1.10.0
WWGolay Nov 28, 2023
26284e7
Merge pull request #106 from WWGolay/dependabot/pip/tksheet-6.3.0
WWGolay Nov 28, 2023
5d02227
Bump tksheet from 6.3.0 to 6.3.4
dependabot[bot] Dec 4, 2023
59238bd
Bump astropy from 5.3.4 to 6.0.0
dependabot[bot] Dec 4, 2023
ecc281b
Bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11
dependabot[bot] Dec 4, 2023
ad3a0c1
Bump actions/setup-python from 4 to 5
dependabot[bot] Dec 11, 2023
8f2d3ce
Merge pull request #119 from WWGolay/dependabot/github_actions/action…
WWGolay Dec 19, 2023
362559d
Merge pull request #116 from WWGolay/dependabot/github_actions/pypa/g…
WWGolay Dec 19, 2023
1025c5c
Merge pull request #115 from WWGolay/dependabot/pip/astropy-6.0.0
WWGolay Dec 19, 2023
f0a2f4c
Merge pull request #114 from WWGolay/dependabot/pip/tksheet-6.3.4
WWGolay Dec 19, 2023
8a08345
Merge branch 'main' into schedtel-dev
WWGolay Dec 19, 2023
3bfb7d2
Merge pull request #92 from WWGolay/schedtel-dev
WWGolay Dec 19, 2023
27e0427
Bump paramiko from 3.3.1 to 3.4.0
dependabot[bot] Dec 19, 2023
bf41f91
Merge pull request #120 from WWGolay/dependabot/pip/paramiko-3.4.0
WWGolay Dec 19, 2023
d0d3bcd
Bump tksheet from 6.3.4 to 6.3.5
dependabot[bot] Dec 25, 2023
4036f22
Merge pull request #123 from WWGolay/dependabot/pip/tksheet-6.3.5
WWGolay Dec 26, 2023
d66ae45
Working on real hardware
pgriffin17 Jan 7, 2024
3519fb4
Remove unneeded print statements
pgriffin17 Jan 7, 2024
856824a
Fix issue 125 add ASCOM EXPTIME
pgriffin17 Jan 7, 2024
76f8117
working exposure time on ZWO ASI290, added CAMTIME flag
pgriffin17 Jan 7, 2024
4aa4021
Use datetime to get backup exposure start time
pgriffin17 Jan 7, 2024
cdd0a04
run black and isort
pgriffin17 Jan 7, 2024
75f6525
Remove unneeded win32com
pgriffin17 Jan 8, 2024
5731619
Add SetImageDataType to ascom_camera
pgriffin17 Jan 8, 2024
41d7fa7
Bump numpy from 1.26.2 to 1.26.3
dependabot[bot] Jan 8, 2024
1628ecd
Moved image transpose to ASCOM Camera driver, improved obs.save_last_…
pgriffin17 Jan 8, 2024
404e03d
Run black formatter
pgriffin17 Jan 8, 2024
2bf796d
Moved camera EXPTIME check from observatory to ASCOM driver
pgriffin17 Jan 8, 2024
6e2d5dc
Merge pull request #131 from WWGolay/dependabot/pip/numpy-1.26.3
WWGolay Jan 9, 2024
614a7bd
Change datetime to astropy.time
pgriffin17 Jan 9, 2024
0f92d03
Merge branch 'main' into exptime
pgriffin17 Jan 9, 2024
a9d9dc9
Merge pull request #127 from pgriffin17/exptime
WWGolay Jan 9, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
Expand All @@ -34,4 +34,4 @@ jobs:
- name: Build package
run: python -m build
- name: pypi-publish
uses: pypa/gh-action-pypi-publish@v1.8.10
uses: pypa/gh-action-pypi-publish@v1.8.11
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ dmypy.json
*OmniSim*
!coverage.xml
docs/source/api/auto_api/
pgHardware
80 changes: 77 additions & 3 deletions pyscope/observatory/ascom_camera.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import logging

import numpy as np
from astropy.time import Time

from .ascom_device import ASCOMDevice
from .camera import Camera

Expand All @@ -15,17 +18,54 @@ def __init__(self, identifier, alpaca=False, device_number=0, protocol="http"):
device_number=device_number,
protocol=protocol,
)
self._last_exposure_duration = None
self._last_exposure_start_time = None
self._image_data_type = None
self._DoTranspose = True
self._camera_time = True

def AbortExposure(self):
logger.debug(f"ASCOMCamera.AbortExposure() called")
self._device.AbortExposure()

def SetImageDataType(self):
"""Determine the data type of the image array based on the MaxADU property.

This method is called automatically when the ImageArray property is called
if it has not already been set (initializes to `None`).
It will choose from the following data types based on the MaxADU property:

- numpy.uint8 : (if MaxADU <= 255)
- numpy.uint16 : (default if MaxADU is not defined, or if MaxADU <= 65535)
- numpy.uint32 : (if MaxADU > 65535)

See Also
--------
numpy.uint8
numpy.uint16
numpy.uint32
MaxADU : ASCOM Camera interface property `ASCOM Documentation <https://ascom-standards.org/Help/Developer/html/P_ASCOM_DriverAccess_Camera_MaxADU.htm>`_
"""
logger.debug(f"ASCOMCamera.SetImageDataType() called")
try:
max_adu = self.MaxADU
if max_adu <= 255:
self._image_data_type = np.uint8
elif max_adu <= 65535:
self._image_data_type = np.uint16
else:
self._image_data_type = np.uint32
except:
self._image_data_type = np.uint16

def PulseGuide(self, Direction, Duration):
logger.debug(f"ASCOMCamera.PulseGuide({Direction}, {Duration}) called")
self._device.PulseGuide(Direction, Duration)

def StartExposure(self, Duration, Light):
logger.debug(f"ASCOMCamera.StartExposure({Duration}, {Light}) called")
self._last_exposure_duration = Duration
self._last_exposure_start_time = str(Time.now())
self._device.StartExposure(Duration, Light)

def StopExposure(self):
Expand Down Expand Up @@ -85,6 +125,11 @@ def CameraYSize(self):
logger.debug(f"ASCOMCamera.CameraYSize property called")
return self._device.CameraYSize

@property
def CameraTime(self):
logger.debug(f"ASCOMCamera.CameraTime property called")
return self._camera_time

@property
def CanAbortExposure(self):
logger.debug(f"ASCOMCamera.CanAbortExposure property called")
Expand Down Expand Up @@ -213,7 +258,14 @@ def HeatSinkTemperature(self):
@property
def ImageArray(self):
logger.debug(f"ASCOMCamera.ImageArray property called")
return self._device.ImageArray
img_array = self._device.ImageArray
# Convert to numpy array and check if it is the correct data type
if self._image_data_type is None:
self.SetImageDataType()
img_array = np.array(img_array, dtype=self._image_data_type)
if self._DoTranspose:
img_array = np.transpose(img_array)
return img_array

@property
def ImageReady(self):
Expand All @@ -228,12 +280,34 @@ def IsPulseGuiding(self):
@property
def LastExposureDuration(self):
logger.debug(f"ASCOMCamera.LastExposureDuration property called")
return self._device.LastExposureDuration
last_exposure_duration = self._device.LastExposureDuration
if last_exposure_duration is None or last_exposure_duration == 0:
last_exposure_duration = self.LastInputExposureDuration
self._camera_time = False
return last_exposure_duration

@property
def LastExposureStartTime(self):
logger.debug(f"ASCOMCamera.LastExposureStartTime property called")
return self._device.LastExposureStartTime
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
else self._last_exposure_start_time
)

@property
def LastInputExposureDuration(self):
logger.debug(f"ASCOMCamera.LastInputExposureDuration property called")
return self._last_exposure_duration

@LastInputExposureDuration.setter
def LastInputExposureDuration(self, value):
logger.debug(f"ASCOMCamera.LastInputExposureDuration property set to {value}")
self._last_exposure_duration = value

@property
def MaxADU(self):
Expand Down
4 changes: 3 additions & 1 deletion pyscope/observatory/maxim.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import platform
import time

from astropy.time import Time

from .autofocus import Autofocus
from .camera import Camera
from .device import Device
Expand Down Expand Up @@ -124,7 +126,7 @@ def PulseGuide(self, Direction, Duration):
def StartExposure(self, Duration, Light):
logger.debug(f"StartExposure called with Duration={Duration}, Light={Light}")
self._last_exposure_duration = Duration
self._last_exposure_start_time = time.time()
self._last_exposure_start_time = str(Time.now())
self._com_object.Expose(Duration, Light)

def StopExposure(self):
Expand Down
56 changes: 35 additions & 21 deletions pyscope/observatory/observatory.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,11 +1169,10 @@ def save_last_image(
logger.exception("Image is not ready, cannot be saved")
return False

if (
self.camera.ImageArray is None
or len(self.camera.ImageArray) == 0
or len(self.camera.ImageArray[0]) == 0
):
# Read out the image array
img_array = self.camera.ImageArray

if 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

Expand All @@ -1182,9 +1181,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")
Expand Down Expand Up @@ -1224,7 +1223,7 @@ def save_last_image(
for hist in history:
hdr["HISTORY"] = hist

hdu = fits.PrimaryHDU(self.camera.ImageArray, header=hdr)
hdu = fits.PrimaryHDU(img_array, header=hdr)
hdu.writeto(filename, overwrite=overwrite)

if do_fwhm:
Expand Down Expand Up @@ -2375,13 +2374,17 @@ def _read_out_kwargs(self, dictionary):
"filter_focus_offsets", self.filter_focus_offsets
)

self.rotator_reverse = dictionary.get("rotator_reverse", self.rotator_reverse)
self.rotator_min_angle = dictionary.get(
"rotator_min_angle", self.rotator_min_angle
)
self.rotator_max_angle = dictionary.get(
"rotator_max_angle", self.rotator_max_angle
)
# Not sure if this if statement is a good idea here...
if dictionary.get("rotator_driver", self.rotator_driver) is not None:
self.rotator_reverse = dictionary.get(
"rotator_reverse", self.rotator_reverse
)
self.rotator_min_angle = dictionary.get(
"rotator_min_angle", self.rotator_min_angle
)
self.rotator_max_angle = dictionary.get(
"rotator_max_angle", self.rotator_max_angle
)

self.min_altitude = dictionary.get("min_altitude", self.min_altitude)
self.settle_time = dictionary.get("settle_time", self.settle_time)
Expand Down Expand Up @@ -2422,6 +2425,7 @@ def camera_info(self):
"JD": (None, "Julian date"),
"MJD": (None, "Modified Julian date"),
"MJD-OBS": (None, "Modified Julian date"),
"CAMTIME": (None, "Exposure time from camera (T) or user (F)"),
"EXPTIME": (None, "Exposure time [seconds]"),
"EXPOSURE": (None, "Exposure time [seconds]"),
"SUBEXP": (None, "Subexposure time [seconds]"),
Expand Down Expand Up @@ -2518,8 +2522,13 @@ def camera_info(self):
except:
pass
try:
info["EXPTIME"] = (self.camera.ExposureTime, info["EXPTIME"][1])
info["EXPOSURE"] = (self.camera.ExposureTime, info["EXPOSURE"][1])
last_exposure_duration = self.camera.LastExposureDuration
info["EXPTIME"] = (last_exposure_duration, info["EXPTIME"][1])
info["EXPOSURE"] = (last_exposure_duration, info["EXPOSURE"][1])
except:
pass
try:
info["CAMTIME"] = (self.camera.CameraTime, info["CAMTIME"][1])
except:
pass
try:
Expand Down Expand Up @@ -3684,7 +3693,9 @@ def latitude(self, value):
self._latitude = (
coord.Latitude(value) if value is not None or value != "" else None
)
self.telescope.SiteLatitude = self._latitude.deg
# If connected, set the telescope site latitude
if self.telescope.Connected:
self.telescope.SiteLatitude = self._latitude.deg
self._config["site"]["latitude"] = (
self._latitude.to_string(unit=u.degree, sep="dms", precision=5)
if self._latitude is not None
Expand All @@ -3704,7 +3715,8 @@ def longitude(self, value):
if value is not None or value != ""
else None
)
self.telescope.SiteLongitude = self._longitude.deg
if self.telescope.Connected:
self.telescope.SiteLongitude = self._longitude.deg
self._config["site"]["longitude"] = (
self._longitude.to_string(unit=u.degree, sep="dms", precision=5)
if self._longitude is not None
Expand Down Expand Up @@ -3855,7 +3867,7 @@ def cover_calibrator_alt(self):
def cover_calibrator_alt(self, value):
logger.debug(f"Observatory.cover_calibrator_alt = {value} called")
self._cover_calibrator_alt = (
min(max(float(value), 0), 90) if value is not None or value != "" else None
min(max(float(value), 0), 90) if value is not None and value != "" else None
)
self._config["cover_calibrator"]["cover_calibrator_alt"] = (
str(self._cover_calibrator_alt)
Expand All @@ -3872,7 +3884,9 @@ def cover_calibrator_az(self):
def cover_calibrator_az(self, value):
logger.debug(f"Observatory.cover_calibrator_az = {value} called")
self._cover_calibrator_az = (
min(max(float(value), 0), 360) if value is not None or value != "" else None
min(max(float(value), 0), 360)
if value is not None and value != ""
else None
)
self._config["cover_calibrator"]["cover_calibrator_az"] = (
str(self._cover_calibrator_az)
Expand Down
10 changes: 5 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
alpyca == 2.0.4
astroplan == 0.9.1
astropy == 5.3.4
astropy == 6.0.0
astroquery == 0.4.6
astroscrappy == 1.1.0
click == 8.1.7
cmcrameri == 1.7.0
markdown == 3.5.1
matplotlib == 3.8.2
numpy == 1.26.2
paramiko == 3.3.1
photutils == 1.9.0
numpy == 1.26.3
paramiko == 3.4.0
photutils == 1.10.0
prettytable == 3.9.0
pywin32 == 306;platform_system=='Windows'
scikit-image == 0.22.0
scipy == 1.11.4
smplotlib == 0.0.9
timezonefinder == 6.2.0
tksheet == 6.2.9
tksheet == 6.3.5
tqdm == 4.66.1