From 8d28664b4292e729dae5793d62b037a93db9a1e4 Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Wed, 1 Dec 2021 16:47:33 +0900 Subject: [PATCH 1/9] just for check --- python/lvmagp/actor/commands/guide.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index d5c6c14..e427d77 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -8,6 +8,8 @@ from . import parser +question = "Is this develop branch?" + KHU_inner_test = True @parser.group() From e6ad85837e4d75b46593869dedc325edaca81d4c Mon Sep 17 00:00:00 2001 From: mgjeon Date: Thu, 2 Dec 2021 00:55:48 +0900 Subject: [PATCH 2/9] slew command debug --- python/lvmagp/actor/actor.py | 15 +++++++ python/lvmagp/actor/astrometry_result.txt | 25 +++++++++++ python/lvmagp/actor/commands/guide.py | 8 ++-- python/lvmagp/actor/commands/slew.py | 39 ++++++++--------- python/lvmagp/actor/commands/test.py | 53 +++++++++++++++++++++++ python/lvmagp/actor/commfunc.py | 22 ++++++---- python/lvmagp/actor/internalfunc.py | 9 ++-- python/lvmagp/actor/user_parameters.py | 2 +- 8 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 python/lvmagp/actor/astrometry_result.txt create mode 100644 python/lvmagp/actor/commands/test.py diff --git a/python/lvmagp/actor/actor.py b/python/lvmagp/actor/actor.py index 9ece314..437d0b7 100644 --- a/python/lvmagp/actor/actor.py +++ b/python/lvmagp/actor/actor.py @@ -36,6 +36,21 @@ def __init__( **kwargs, ): super().__init__(*args, **kwargs) + + self.schema = { + "type": "object", + "properties": { + "fail" : {"type": "string"}, + "Img_ra2000": {"type": "string"}, + "Img_dec2000": {"type": "string"}, + "Img_pa": {"type": "string"}, + "offset_ra": {"type": "string"}, + "offset_dec": {"type": "string"}, + }, + "additionalProperties": False, + } + self.load_schema(self.schema, is_file=False) + self.telescopes = {s.name: s for s in telescopes} self.eastcameras = {s.name: s for s in eastcameras} self.westcameras = {s.name: s for s in westcameras} diff --git a/python/lvmagp/actor/astrometry_result.txt b/python/lvmagp/actor/astrometry_result.txt new file mode 100644 index 0000000..ddcdc60 --- /dev/null +++ b/python/lvmagp/actor/astrometry_result.txt @@ -0,0 +1,25 @@ +Reading input file 1 of 1: "/home/sumin/lvmcam/python/lvmcam/assets/test.fits"... +Extracting sources... +Downsampling by 2... +simplexy: found 197 sources. +Solving... +Reading file "/home/sumin/lvmcam/python/lvmcam/assets/test.axy"... +Only searching for solutions within 1 degrees of RA,Dec (83.85,-5.45) +Field 1 did not solve (index index-4211.fits, field objects 1-10). +Field 1 did not solve (index index-4210.fits, field objects 1-10). +Field 1 did not solve (index index-4209.fits, field objects 1-10). +Field 1 did not solve (index index-4208.fits, field objects 1-10). +Field 1 did not solve (index index-4207-05.fits, field objects 1-10). + log-odds ratio 439.518 (7.58935e+190), 87 match, 0 conflict, 105 distractors, 127 index. + RA,Dec = (83.8516,-5.44941), pixel scale 2.59094 arcsec/pix. + Hit/miss: Hit/miss: ++++++-+++++++++++++++++-++++-++++++-++++---+++--++-++-+++--+++-+-+-+++-+++-+-+-+---+---+--+----+--+ +Field 1: solved with index index-4206-05.fits. +Field 1 solved: writing to file /home/sumin/lvmcam/python/lvmcam/assets/test.solved to indicate this. +Field: /home/sumin/lvmcam/python/lvmcam/assets/test.fits +Field center: (RA,Dec) = (83.851870, -5.449307) deg. +Field center: (RA H:M:S, Dec D:M:S) = (05:35:24.449, -05:26:57.505). +Field size: 69.2306 x 47.6209 arcminutes +Field rotation angle: up is 171.703 degrees E of N +Field parity: pos +Creating new FITS file "/home/sumin/lvmcam/python/lvmcam/assets/test.new"... + diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index e427d77..8842c42 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -39,6 +39,8 @@ async def start(command: Command, else: return command.fail(text="Telescope '%s' does not exist" % tel) + return command.finish() + @guide.command() @click.argument("TEL", type=str) @@ -52,7 +54,7 @@ async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcamera else: return command.fail(text="Telescope '%s' does not exist" % tel) - return True + return command.finish('Guide stopped') async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], @@ -78,7 +80,7 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas telescopes[tel].ag_break = False break - command.info('Guide stopped') + return True ''' Here is old version using task.cancle @@ -166,7 +168,7 @@ async def autoguide_supervisor(command, tel): ''' async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel, positionguess=None) + tel, positionguess=None): global KHU_inner_test command.info("Taking image...") # take an image for astrometry diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 80159a3..8451594 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -41,11 +41,7 @@ async def slew(command: Command, # Calculate position angle and rotate K-mirror :: should be changed to traj method. target_pa_d = cal_pa(target_ra_h, target_dec_d, long_d, lat_d) command.info("Rotate K-mirror to pa = %.3f deg" % target_pa_d) - - try: - cmd.append(kmirrors[tel].moveabs(command, target_pa_d, "DEG")) - except Exception as e: - return command.fail(fail="Kmirror error") + cmd.append(kmirrors[tel].moveabs(command, target_pa_d, "DEG")) # send slew command to lvmpwi try: @@ -64,9 +60,10 @@ async def slew(command: Command, # take an image for astrometry try: imgcmd = [] - imgcmd.append(westcameras[tel].single_exposure(command, usrpars.aqu_exptime)) - if test_KHU is not True: - imgcmd.append(eastcameras[tel].single_exposure(command, usrpars.aqu_exptime)) + imgcmd.append(westcameras[tel].test_exposure(command, usrpars.aqu_exptime)) + #imgcmd.append(westcameras[tel].single_exposure(command, usrpars.aqu_exptime)) + if not test_KHU: + imgcmd.append(eastcameras[tel].test_exposure(command, usrpars.aqu_exptime)) guideimgpath = await asyncio.gather(*imgcmd) except Exception as e: @@ -86,23 +83,22 @@ async def slew(command: Command, westguideimg = GuideImage(guideimgpath[0]) eastguideimg = westguideimg - if test_KHU is not True: + if not test_KHU: eastguideimg = GuideImage(guideimgpath[1]) try: # await guideimg.astrometry(ra_h=13, dec_d=-55) - astcmd = [] astcmd.append(westguideimg.astrometry(ra_h=target_ra_h, dec_d=target_dec_d)) - if test_KHU is not True: + if not test_KHU: astcmd.append(eastguideimg.astrometry(ra_h=target_ra_h, dec_d=target_dec_d)) - await asyncio.gather(*astcmd) + cmd = await asyncio.gather(*astcmd) except Exception as e: return command.fail(text="Astrometry timeout") - ra2000_d = 0.5*(eastguideimg.ra2000 + westguideimg.dec2000) + ra2000_d = 0.5*(eastguideimg.ra2000 + westguideimg.ra2000) dec2000_d = 0.5*(eastguideimg.dec2000 + westguideimg.dec2000) pa_d = 0.5*(eastguideimg.pa + westguideimg.pa) @@ -123,15 +119,18 @@ async def slew(command: Command, ) # Compensation // Compensation for K-mirror based on astrometry result? may be by offset method.. - if iter >= usrpars.aqu_max_iter: - return command.fail(fail="Compensation failed.") + if (np.sqrt(comp_ra_arcsec**2+comp_dec_arcsec**2) > usrpars.aqu_tolerance_arcsec): - command.info(text="Compensating ...") - cmd = [] - cmd.append(kmirrors[tel].moverel(command, -pa_d, "DEG")) - cmd.append(telescopes[tel].offset_radec(command, comp_ra_arcsec, comp_dec_arcsec)) - await asyncio.gather(*cmd) + if iter >= usrpars.aqu_max_iter: + return command.fail(fail="Compensation failed.") + else: + command.info(text="Compensating ...") + cmd = [] + if not test_KHU: + cmd.append(kmirrors[tel].moverel(command, -pa_d, "DEG")) + cmd.append(telescopes[tel].offset_radec(command, comp_ra_arcsec, comp_dec_arcsec)) + await asyncio.gather(*cmd) else: break diff --git a/python/lvmagp/actor/commands/test.py b/python/lvmagp/actor/commands/test.py new file mode 100644 index 0000000..1d9902b --- /dev/null +++ b/python/lvmagp/actor/commands/test.py @@ -0,0 +1,53 @@ +import os +import click +from clu.command import Command + +from lvmagp.actor.commfunc import * # noqa: F403 +from lvmagp.actor.internalfunc import * # noqa: F403 +from lvmagp.actor.user_parameters import usrpars + +from . import parser + +test_KHU = True + +@parser.command() +#@click.argument("TEL", type=str) +async def test(command: Command, + telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], + ): + global test_KHU + resultpath = "/home/sumin/lvmagp/python/lvmagp/actor/astrometry_result.txt" + + ospassword = "0000" + resultpath = os.path.dirname(os.path.abspath(__file__)) + "/../astrometry_result.txt" + timeout = 30 + scalelow = 2 + scalehigh = 3 + radius = 1 + filepath = "/home/sumin/lvmcam/python/lvmcam/assets/2459550/sci.agw-00000075.fits" + ra_h = 0.7 + dec_d = 41.3 + + + + cmd = "echo %s | sudo -S /usr/local/astrometry/bin/solve-field %s --cpulimit %f --overwrite \ + --downsample 2 --scale-units arcsecperpix --scale-low %f --scale-high %f --ra %f --dec %f \ + --radius %f --no-plots > %s" % ( # noqa: E501 + ospassword, + filepath, + timeout, + scalelow, + scalehigh, + ra_h * 15, + dec_d, + radius, + resultpath, + ) + + proc = await asyncio.create_subprocess_shell( + cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + await proc.communicate() + + print("end") diff --git a/python/lvmagp/actor/commfunc.py b/python/lvmagp/actor/commfunc.py index 6dd683d..dde8002 100644 --- a/python/lvmagp/actor/commfunc.py +++ b/python/lvmagp/actor/commfunc.py @@ -18,7 +18,7 @@ async def getposition(self, command, unit="STEPS"): cmd = await send_message( command, self.lvmtan, - "getposition %s" % unit, + "getPosition %s" % unit, returnval=True, body="Position", ) @@ -26,11 +26,11 @@ async def getposition(self, command, unit="STEPS"): async def moveabs(self, command, position, unit='STEPS'): - cmd = await send_message(command, self.lvmtan, "moveabsolute %d %s" % (position, unit)) + cmd = await send_message(command, self.lvmtan, "moveAbsolute %d %s" % (position, unit)) return cmd async def moverel(self, command, position, unit='STEPS'): - cmd = await send_message(command, self.lvmtan, "moverelative %d %s" % (position, unit)) + cmd = await send_message(command, self.lvmtan, "moveRelative %d %s" % (position, unit)) return cmd ''' @@ -94,15 +94,15 @@ def __init__(self, tel): self.ag_break = False async def slew_radec2000(self, command, target_ra_h, target_dec_d): - cmd = await send_message(command,self.lvmpwi,"gotoradecj2000 %f %f" % (target_ra_h, target_dec_d)) + cmd = await send_message(command,self.lvmpwi,"gotoRaDecJ2000 %f %f" % (target_ra_h, target_dec_d)) return cmd async def reset_offset_radec(self, command): await send_message( - command, self.lvmpwi, "offset --ra_reset 0" + command, self.lvmpwi, "offset --ra_reset" ) await send_message( - command, self.lvmpwi, "offset --dec_reset 0" + command, self.lvmpwi, "offset --dec_reset" ) return True @@ -132,9 +132,15 @@ def __init__(self): async def single_exposure(self, command, exptime): path = await send_message( - command, self.lvmcam, "expose %f 1 %s" % (exptime, self.cam), returnval=True, body="0" + command, self.lvmcam, "expose %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" ) - return path + return path["0"] + + async def test_exposure(self, command, exptime): + path = await send_message( + command, self.lvmcam, "expose -t %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" + ) + return path["0"] class LVMEastCamera(LVMCamera): def __init__(self, tel): diff --git a/python/lvmagp/actor/internalfunc.py b/python/lvmagp/actor/internalfunc.py index caa01ba..a03a0c3 100644 --- a/python/lvmagp/actor/internalfunc.py +++ b/python/lvmagp/actor/internalfunc.py @@ -1,6 +1,7 @@ import asyncio import warnings from datetime import datetime +import os import numpy as np # import matplotlib.pyplot as plt @@ -115,10 +116,10 @@ def update_guidestar_properties(self): async def astrometry(self, ra_h=-999, dec_d=-999): ospassword = "0000" - resultpath = "/home/hojae/Desktop/lvmagp/testimg/astrometry_result/result.txt" - timeout = 5 - scalelow = 0.9 - scalehigh = 1.1 + resultpath = os.path.dirname(os.path.abspath(__file__)) + "/astrometry_result.txt" + timeout = 10 + scalelow = 2 + scalehigh = 3 radius = 1 if ra_h == -999: diff --git a/python/lvmagp/actor/user_parameters.py b/python/lvmagp/actor/user_parameters.py index b0fe3d5..0b8166e 100644 --- a/python/lvmagp/actor/user_parameters.py +++ b/python/lvmagp/actor/user_parameters.py @@ -9,7 +9,7 @@ class usrpars(): # aquisition parameters aqu_exptime = 5 #in seconds - aqu_max_iter = 1 + aqu_max_iter = 2 aqu_tolerance_arcsec = 30.0 # autoguide paramters From c25e83b002b1bd72d1754191b9a4237c35ba2284 Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 3 Dec 2021 16:30:02 +0900 Subject: [PATCH 3/9] v.0.2.0a slew/guide command update --- pyproject.toml | 7 ++- python/lvmagp/actor/actor.py | 6 ++ python/lvmagp/actor/commands/guide.py | 85 +++++++++++++++++++++++--- python/lvmagp/actor/commands/slew.py | 3 +- python/lvmagp/actor/commands/test.py | 16 +++++ python/lvmagp/actor/commfunc.py | 13 +++- python/lvmagp/actor/user_parameters.py | 3 + python/lvmagp/etc/lvmagp.yml | 14 ++++- 8 files changed, 130 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b499255..bd86c9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [tool.poetry] name = "sdss-lvmagp" -version = "0.1.0-alpha.0" -description = "Simple Template package for creating SDSS Python projects" -authors = ["sumin lee "] +version = "0.2.0-alpha" +description = "Aquisition and guiding package for SDSS-V LVM" +authors = ["Hojae Ahn "] license = "BSD-3-Clause" readme = "README.md" homepage = "https://github.com/sdss/lvmagp" @@ -16,6 +16,7 @@ classifiers = [ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Documentation :: Sphinx", "Topic :: Software Development :: Libraries :: Python Modules" ] diff --git a/python/lvmagp/actor/actor.py b/python/lvmagp/actor/actor.py index 437d0b7..01bae09 100644 --- a/python/lvmagp/actor/actor.py +++ b/python/lvmagp/actor/actor.py @@ -46,6 +46,10 @@ def __init__( "Img_pa": {"type": "string"}, "offset_ra": {"type": "string"}, "offset_dec": {"type": "string"}, + "xscale_ra": {"type": "float"}, + "yscale_ra": {"type": "float"}, + "xscale_dec": {"type": "float"}, + "yscale_dec": {"type": "float"} }, "additionalProperties": False, } @@ -74,11 +78,13 @@ def from_config(cls, config, *args, **kwargs): instance.eastcameras[ctrname].pixelscale = ctr['age']['pixelscale'] instance.eastcameras[ctrname].offset_x = ctr['age']['offset_x'] instance.eastcameras[ctrname].offset_y = ctr['age']['offset_y'] + instance.eastcameras[ctrname].rotationangle = ctr['age']['rotationangle'] instance.westcameras.update({ctrname: LVMWestCamera(ctrname)}) instance.westcameras[ctrname].pixelscale = ctr['agw']['pixelscale'] instance.westcameras[ctrname].offset_x = ctr['agw']['offset_x'] instance.westcameras[ctrname].offset_y = ctr['agw']['offset_y'] + instance.westcameras[ctrname].rotationangle = ctr['agw']['rotationangle'] instance.focusers.update({ctrname: LVMFocuser(ctrname)}) diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 8842c42..9389511 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -19,16 +19,17 @@ def guide(*args): @guide.command() @click.argument("TEL", type=str) +@click.option("--useteldata", type=float, is_flag=True) async def start(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel: str): + tel: str, useteldata: bool): if tel in telescopes: try: telescopes[tel].ag_task = asyncio.wait_for(autoguide_supervisor(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel), timeout=3600) + westcameras, focusers, kmirrors, tel, useteldata), timeout=3600) await telescopes[tel].ag_task except asyncio.TimeoutError: @@ -39,7 +40,7 @@ async def start(command: Command, else: return command.fail(text="Telescope '%s' does not exist" % tel) - return command.finish() + return command.finish('Guide stopped') @guide.command() @@ -54,18 +55,76 @@ async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcamera else: return command.fail(text="Telescope '%s' does not exist" % tel) - return command.finish('Guide stopped') + return command.finish() + + +@guide.command() +@click.argument("TEL", type=str) +async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], + tel: str): + global KHU_inner_test + offset_per_step = usrpars.ag_cal_offset_per_step + num_step = usrpars.ag_cal_num_step + + if tel not in telescopes: + return command.fail(text="Telescope '%s' does not exist" % tel) + + xpositions, ypositions = [], [] + + initposition, initflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel) + xpositions.append(initposition[:, 0]) + ypositions.append(initposition[:, 1]) + + # dec axis calibration + for step in range(1,num_step+1): + await telescopes[tel].offset_radec(command, 0, offset_per_step) + position, flux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, + kmirrors, tel) + xpositions.append(position[:, 0]) + ypositions.append(position[:, 1]) + + await telescopes[tel].offset_radec(command, 0, -num_step*offset_per_step) + + xpositions = np.array(xpositions) - xpositions[0] + ypositions = np.array(ypositions) - ypositions[0] + xscale_dec = np.sum(xpositions/np.arange(num_step+1))/(num_step) # displacement along x-axis by ra offset in pixel per arcsecond. exclude the first index (0,0) + yscale_dec = np.sum(ypositions/np.arange(num_step+1))/(num_step) # exclude the first index (0,0) + + # ra axis calibration + xpositions = [initposition[:, 0]] + ypositions = [initposition[:, 1]] + + for step in range(1,num_step+1): + await telescopes[tel].offset_radec(command, offset_per_step, 0) + position, flux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, + kmirrors, tel) + xpositions.append(position[:, 0]) + ypositions.append(position[:, 1]) + + await telescopes[tel].offset_radec(command, -num_step*offset_per_step, 0) + + decj2000_deg = telescopes[tel].get_dec2000_deg() + + xpositions = np.array(xpositions) - xpositions[0] + ypositions = np.array(ypositions) - ypositions[0] + xscale_ra = np.sum(xpositions*np.arange(num_step+1))/(num_step)/np.cos(decj2000_deg) # exclude the first index (0,0) + yscale_ra = np.sum(ypositions*np.arange(num_step+1))/(num_step)/np.cos(decj2000_deg) # exclude the first index (0,0) + + telescopes[tel].scale_matrix = np.matrix([[xscale_ra, yscale_ra],[xscale_dec, yscale_dec]]) + return command.finish(xscale_ra="%.3f pixel/arcsec"%xscale_ra, yscale_ra="%.3f pixel/arcsec"%yscale_ra, + xscale_dec="%.3f pixel/arcsec"%xscale_dec, ysclae_dec="%.3f pixel/arcsec"%yscale_dec) async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel): + westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel, useteldata): global KHU_inner_test if KHU_inner_test: i = 0 else: initposition, initflux = await find_guide_stars(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel, register=True) + westcameras, focusers, kmirrors, tel) while 1: if KHU_inner_test: @@ -74,7 +133,7 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas await asyncio.sleep(8) else: await autoguiding(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel, initposition, initflux) + westcameras, focusers, kmirrors, tel, initposition, initflux, useteldata) if telescopes[tel].ag_break is True: telescopes[tel].ag_break = False @@ -203,7 +262,7 @@ async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcam async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel, initposition, initflux): + tel, initposition, initflux, useteldata): starposition, starflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel, positionguess=initposition) @@ -212,7 +271,15 @@ async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: return command.error("Star flux variation is too large.") offset = np.mean(starposition - initposition, axis=0) # in x,y [pixel] - offset_arcsec = offset*eastcameras[tel].pixelscale # in x,y(=ra,dec) [arcsec] + + if useteldata: + offset_arcsec = np.matmul(telescopes[tel].scale_matrix.I, offset.T) # in x,y(=ra,dec) [arcsec] + offset_arcsec = np.array(offset_arcsec) + else: + offset_arcsec = offset * westcameras[tel].pixelscale # in x,y(=ra,dec) [arcsec] + + decj2000_deg = telescopes[tel].get_dec2000_deg() + offset_arcsec[0] = offset_arcsec[0]/np.cos(decj2000_deg) if (np.sqrt(offset[0]**2+offset[1]**2)) > usrpars.ag_min_offset: await telescopes[tel].offset_radec(command, *offset_arcsec) diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 8451594..2157d7f 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -8,7 +8,6 @@ from . import parser - async def deg_to_dms(deg): absdeg = np.abs(deg) d = np.floor(absdeg) @@ -56,6 +55,7 @@ async def slew(command: Command, command.info("Initial slew completed.") for iter in range(usrpars.aqu_max_iter + 1): + log.info("Taking image...") command.info("Taking image...") # take an image for astrometry try: @@ -95,6 +95,7 @@ async def slew(command: Command, cmd = await asyncio.gather(*astcmd) except Exception as e: + log.error("Astrometry timeout") return command.fail(text="Astrometry timeout") diff --git a/python/lvmagp/actor/commands/test.py b/python/lvmagp/actor/commands/test.py index 1d9902b..aeaff54 100644 --- a/python/lvmagp/actor/commands/test.py +++ b/python/lvmagp/actor/commands/test.py @@ -2,6 +2,9 @@ import click from clu.command import Command +#import logging +#from sdsstools import get_logger + from lvmagp.actor.commfunc import * # noqa: F403 from lvmagp.actor.internalfunc import * # noqa: F403 from lvmagp.actor.user_parameters import usrpars @@ -10,12 +13,24 @@ test_KHU = True +#log = get_logger("sdss-lvmagp") +#log.sh.setLevel(logging.DEBUG) + @parser.command() #@click.argument("TEL", type=str) async def test(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], ): + ''' + log.info("Img_ra2000='%02dh %02dm %06.3fs' Img_dec2000='%02dd %02dm %06.3fs'" % (1,2,3,4,5,6), + ) + command.info(Img_ra2000="%02dh %02dm %06.3fs" + % (1,2,3), + Img_dec2000="%02dd %02dm %06.3fs" + % (6,5,4)) + ''' + ''' global test_KHU resultpath = "/home/sumin/lvmagp/python/lvmagp/actor/astrometry_result.txt" @@ -51,3 +66,4 @@ async def test(command: Command, await proc.communicate() print("end") + ''' \ No newline at end of file diff --git a/python/lvmagp/actor/commfunc.py b/python/lvmagp/actor/commfunc.py index dde8002..7c14ea4 100644 --- a/python/lvmagp/actor/commfunc.py +++ b/python/lvmagp/actor/commfunc.py @@ -3,6 +3,7 @@ from lvmagp.actor.internalfunc import send_message import datetime +import numpy as np import asyncio @@ -90,6 +91,10 @@ def __init__(self, tel): self.latitude = -999 self.longitude = -999 self.rotationangle = -999 + + self.scale_matrix = np.matrix([[1,1], #[x_ra , y_ra ] + [1,1]]) #[x_dec, y_dec] + self.ag_task = None self.ag_break = False @@ -107,7 +112,6 @@ async def reset_offset_radec(self, command): return True - async def offset_radec(self, command, ra_arcsec, dec_arcsec): await send_message( @@ -119,6 +123,12 @@ async def offset_radec(self, command, ra_arcsec, dec_arcsec): return True + async def get_dec2000_deg(self, command): + dec2000 = await send_message( + command, self.lvmpwi, "status", returnval=True, body="dec_j2000_degs" + ) + return dec2000 + # Functions for camera class LVMCamera: @@ -128,6 +138,7 @@ def __init__(self): self.offset_x = -999 self.offset_y = -999 self.pixelscale = -999 + self.rotationangle = -999 self.lvmcampath = '' async def single_exposure(self, command, exptime): diff --git a/python/lvmagp/actor/user_parameters.py b/python/lvmagp/actor/user_parameters.py index 0b8166e..b848058 100644 --- a/python/lvmagp/actor/user_parameters.py +++ b/python/lvmagp/actor/user_parameters.py @@ -19,5 +19,8 @@ class usrpars(): ag_min_offset = 0.3 # minimum offset to do correction in pixel ag_flux_tolerance = 0.2 # maximum variability of flux due to seeing to identify the guide star + ag_cal_offset_per_step = 4.0 + ag_cal_num_step = 2 + diff --git a/python/lvmagp/etc/lvmagp.yml b/python/lvmagp/etc/lvmagp.yml index 8eafe70..82b8c9c 100644 --- a/python/lvmagp/etc/lvmagp.yml +++ b/python/lvmagp/etc/lvmagp.yml @@ -9,10 +9,10 @@ sci: offset_y: null rotationangle: null agw: - pixelscale: 2.6 + pixelscale: 2.60 offset_x: 0.0 offset_y: 0.0 - rotationangle: null + rotationangle: 0.0 foc: varA: null km: @@ -26,10 +26,12 @@ skye: pixelscale: null offset_x: null offset_y: null + rotationangle: null agw: pixelscale: null offset_x: null offset_y: null + rotationangle: null foc: varA: null km: @@ -43,10 +45,12 @@ skyw: pixelscale: null offset_x: null offset_y: null + rotationangle: null agw: pixelscale: null offset_x: null offset_y: null + rotationangle: null foc: varA: null km: @@ -60,10 +64,12 @@ spec: pixelscale: null offset_x: null offset_y: null + rotationangle: null agw: pixelscale: null offset_x: null offset_y: null + rotationangle: null foc: varA: null km: @@ -74,4 +80,6 @@ spec: actor: name: lvmagp host: localhost - port: 5672 \ No newline at end of file + port: 5672 + version: '0.2.0-alpha' + log_dir: '../../logs' \ No newline at end of file From 40ff35f67eaadfa78fd44cb47e74483dcd4d78d4 Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 3 Dec 2021 16:33:22 +0900 Subject: [PATCH 4/9] v.0.2.0a slew/guide command update --- python/lvmagp/actor/commands/guide.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 9389511..61c3bd5 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -282,6 +282,8 @@ async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: offset_arcsec[0] = offset_arcsec[0]/np.cos(decj2000_deg) if (np.sqrt(offset[0]**2+offset[1]**2)) > usrpars.ag_min_offset: + print("compensate: ra %.2f arcsec dec %.2f arcsec x %.2f pixel y %.2f pixel" % + (offset_arcsec[0], offset_arcsec[1], offset[0], offset[1])) await telescopes[tel].offset_radec(command, *offset_arcsec) return offset_arcsec From 6b175defe874207a7311b936b094796bf5f73a73 Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 3 Dec 2021 17:45:20 +0900 Subject: [PATCH 5/9] v.0.2.1a docstring --- poetry.lock | 126 ++++++++++---------- python/lvmagp/actor/commands/autofocus.py | 16 +++ python/lvmagp/actor/commands/guide.py | 69 ++++++++++- python/lvmagp/actor/commands/slew.py | 21 ++++ python/lvmagp/actor/commfunc.py | 139 +++++++++++++++++++++- python/lvmagp/actor/internalfunc.py | 109 +++++++++++++++++ python/lvmagp/actor/user_parameters.py | 18 +-- python/lvmagp/etc/lvmagp.yml | 2 +- 8 files changed, 419 insertions(+), 81 deletions(-) diff --git a/poetry.lock b/poetry.lock index c496aaa..d3fe76f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -177,7 +177,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [[package]] name = "coverage" -version = "6.1.2" +version = "6.2" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -341,7 +341,7 @@ toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] name = "ipython" -version = "7.29.0" +version = "7.30.1" description = "IPython: Productive Interactive Computing" category = "dev" optional = false @@ -498,7 +498,7 @@ pyparsing = ">=2.0.2" [[package]] name = "parso" -version = "0.8.2" +version = "0.8.3" description = "A Python Parser" category = "dev" optional = false @@ -597,7 +597,7 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.22" +version = "3.0.23" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false @@ -901,7 +901,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "setuptools" -version = "59.2.0" +version = "59.4.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false @@ -1119,7 +1119,7 @@ python-versions = ">=3.6" [[package]] name = "typing-extensions" -version = "4.0.0" +version = "4.0.1" description = "Backported and Experimental Type Hints for Python 3.6+" category = "main" optional = false @@ -1239,53 +1239,53 @@ configparser = [ {file = "configparser-5.1.0.tar.gz", hash = "sha256:202b9679a809b703720afa2eacaad4c6c2d63196070e5d9edc953c0489dfd536"}, ] coverage = [ - {file = "coverage-6.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:675adb3b3380967806b3cbb9c5b00ceb29b1c472692100a338730c1d3e59c8b9"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95a58336aa111af54baa451c33266a8774780242cab3704b7698d5e514840758"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0a595a781f8e186580ff8e3352dd4953b1944289bec7705377c80c7e36c4d6c"}, - {file = "coverage-6.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d3c5f49ce6af61154060640ad3b3281dbc46e2e0ef2fe78414d7f8a324f0b649"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:310c40bed6b626fd1f463e5a83dba19a61c4eb74e1ac0d07d454ebbdf9047e9d"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a4d48e42e17d3de212f9af44f81ab73b9378a4b2b8413fd708d0d9023f2bbde4"}, - {file = "coverage-6.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ffa545230ca2ad921ad066bf8fd627e7be43716b6e0fcf8e32af1b8188ccb0ab"}, - {file = "coverage-6.1.2-cp310-cp310-win32.whl", hash = "sha256:cd2d11a59afa5001ff28073ceca24ae4c506da4355aba30d1e7dd2bd0d2206dc"}, - {file = "coverage-6.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:96129e41405887a53a9cc564f960d7f853cc63d178f3a182fdd302e4cab2745b"}, - {file = "coverage-6.1.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1de9c6f5039ee2b1860b7bad2c7bc3651fbeb9368e4c4d93e98a76358cdcb052"}, - {file = "coverage-6.1.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:80cb70264e9a1d04b519cdba3cd0dc42847bf8e982a4d55c769b9b0ee7cdce1e"}, - {file = "coverage-6.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:ba6125d4e55c0b8e913dad27b22722eac7abdcb1f3eab1bd090eee9105660266"}, - {file = "coverage-6.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8492d37acdc07a6eac6489f6c1954026f2260a85a4c2bb1e343fe3d35f5ee21a"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66af99c7f7b64d050d37e795baadf515b4561124f25aae6e1baa482438ecc388"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebcc03e1acef4ff44f37f3c61df478d6e469a573aa688e5a162f85d7e4c3860d"}, - {file = "coverage-6.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98d44a8136eebbf544ad91fef5bd2b20ef0c9b459c65a833c923d9aa4546b204"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c18725f3cffe96732ef96f3de1939d81215fd6d7d64900dcc4acfe514ea4fcbf"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c8e9c4bcaaaa932be581b3d8b88b677489975f845f7714efc8cce77568b6711c"}, - {file = "coverage-6.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:06d009e8a29483cbc0520665bc46035ffe9ae0e7484a49f9782c2a716e37d0a0"}, - {file = "coverage-6.1.2-cp36-cp36m-win32.whl", hash = "sha256:e5432d9c329b11c27be45ee5f62cf20a33065d482c8dec1941d6670622a6fb8f"}, - {file = "coverage-6.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:82fdcb64bf08aa5db881db061d96db102c77397a570fbc112e21c48a4d9cb31b"}, - {file = "coverage-6.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:94f558f8555e79c48c422045f252ef41eb43becdd945e9c775b45ebfc0cbd78f"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046647b96969fda1ae0605f61288635209dd69dcd27ba3ec0bf5148bc157f954"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cc799916b618ec9fd00135e576424165691fec4f70d7dc12cfaef09268a2478c"}, - {file = "coverage-6.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62646d98cf0381ffda301a816d6ac6c35fc97aa81b09c4c52d66a15c4bef9d7c"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:27a3df08a855522dfef8b8635f58bab81341b2fb5f447819bc252da3aa4cf44c"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:610c0ba11da8de3a753dc4b1f71894f9f9debfdde6559599f303286e70aeb0c2"}, - {file = "coverage-6.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:35b246ae3a2c042dc8f410c94bcb9754b18179cdb81ff9477a9089dbc9ecc186"}, - {file = "coverage-6.1.2-cp37-cp37m-win32.whl", hash = "sha256:0cde7d9fe2fb55ff68ebe7fb319ef188e9b88e0a3d1c9c5db7dd829cd93d2193"}, - {file = "coverage-6.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:958ac66272ff20e63d818627216e3d7412fdf68a2d25787b89a5c6f1eb7fdd93"}, - {file = "coverage-6.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a300b39c3d5905686c75a369d2a66e68fd01472ea42e16b38c948bd02b29e5bd"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d3855d5d26292539861f5ced2ed042fc2aa33a12f80e487053aed3bcb6ced13"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:586d38dfc7da4a87f5816b203ff06dd7c1bb5b16211ccaa0e9788a8da2b93696"}, - {file = "coverage-6.1.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a34fccb45f7b2d890183a263578d60a392a1a218fdc12f5bce1477a6a68d4373"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bc1ee1318f703bc6c971da700d74466e9b86e0c443eb85983fb2a1bd20447263"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3f546f48d5d80a90a266769aa613bc0719cb3e9c2ef3529d53f463996dd15a9d"}, - {file = "coverage-6.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd92ece726055e80d4e3f01fff3b91f54b18c9c357c48fcf6119e87e2461a091"}, - {file = "coverage-6.1.2-cp38-cp38-win32.whl", hash = "sha256:24ed38ec86754c4d5a706fbd5b52b057c3df87901a8610d7e5642a08ec07087e"}, - {file = "coverage-6.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:97ef6e9119bd39d60ef7b9cd5deea2b34869c9f0b9777450a7e3759c1ab09b9b"}, - {file = "coverage-6.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e5a8c947a2a89c56655ecbb789458a3a8e3b0cbf4c04250331df8f647b3de59"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a39590d1e6acf6a3c435c5d233f72f5d43b585f5be834cff1f21fec4afda225"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9d2c2e3ce7b8cc932a2f918186964bd44de8c84e2f9ef72dc616f5bb8be22e71"}, - {file = "coverage-6.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3348865798c077c695cae00da0924136bb5cc501f236cfd6b6d9f7a3c94e0ec4"}, - {file = "coverage-6.1.2-cp39-cp39-win32.whl", hash = "sha256:fae3fe111670e51f1ebbc475823899524e3459ea2db2cb88279bbfb2a0b8a3de"}, - {file = "coverage-6.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:af45eea024c0e3a25462fade161afab4f0d9d9e0d5a5d53e86149f74f0a35ecc"}, - {file = "coverage-6.1.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:eab14fdd410500dae50fd14ccc332e65543e7b39f6fc076fe90603a0e5d2f929"}, - {file = "coverage-6.1.2.tar.gz", hash = "sha256:d9a635114b88c0ab462e0355472d00a180a5fbfd8511e7f18e4ac32652e7d972"}, + {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, + {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, + {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, + {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, + {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, + {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, + {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, + {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, + {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, + {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, + {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, + {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, + {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, + {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, + {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, + {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, + {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, + {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, + {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, + {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, ] cycler = [ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, @@ -1339,8 +1339,8 @@ ipdb = [ {file = "ipdb-0.13.9.tar.gz", hash = "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"}, ] ipython = [ - {file = "ipython-7.29.0-py3-none-any.whl", hash = "sha256:a658beaf856ce46bc453366d5dc6b2ddc6c481efd3540cb28aa3943819caac9f"}, - {file = "ipython-7.29.0.tar.gz", hash = "sha256:4f69d7423a5a1972f6347ff233e38bbf4df6a150ef20fbb00c635442ac3060aa"}, + {file = "ipython-7.30.1-py3-none-any.whl", hash = "sha256:fc60ef843e0863dd4e24ab2bb5698f071031332801ecf8d1aeb4fb622056545c"}, + {file = "ipython-7.30.1.tar.gz", hash = "sha256:cb6aef731bf708a7727ab6cde8df87f0281b1427d41e65d62d4b68934fa54e97"}, ] isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, @@ -1520,8 +1520,8 @@ packaging = [ {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] parso = [ - {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, - {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, @@ -1611,8 +1611,8 @@ pluggy = [ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.22-py3-none-any.whl", hash = "sha256:48d85cdca8b6c4f16480c7ce03fd193666b62b0a21667ca56b4bb5ad679d1170"}, - {file = "prompt_toolkit-3.0.22.tar.gz", hash = "sha256:449f333dd120bd01f5d296a8ce1452114ba3a71fae7288d2f0ae2c918764fa72"}, + {file = "prompt_toolkit-3.0.23-py3-none-any.whl", hash = "sha256:5f29d62cb7a0ecacfa3d8ceea05a63cd22500543472d64298fc06ddda906b25d"}, + {file = "prompt_toolkit-3.0.23.tar.gz", hash = "sha256:7053aba00895473cb357819358ef33f11aa97e4ac83d38efb123e5649ceeecaf"}, ] psutil = [ {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"}, @@ -1864,8 +1864,8 @@ semantic-version = [ {file = "semantic_version-2.8.5.tar.gz", hash = "sha256:d2cb2de0558762934679b9a104e82eca7af448c9f4974d1f3eeccff651df8a54"}, ] setuptools = [ - {file = "setuptools-59.2.0-py3-none-any.whl", hash = "sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d"}, - {file = "setuptools-59.2.0.tar.gz", hash = "sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576"}, + {file = "setuptools-59.4.0-py3-none-any.whl", hash = "sha256:feb5ff19b354cde9efd2344ef6d5e79880ce4be643037641b49508bbb850d060"}, + {file = "setuptools-59.4.0.tar.gz", hash = "sha256:b4c634615a0cf5b02cf83c7bedffc8da0ca439f00e79452699454da6fbd4153d"}, ] setuptools-scm = [ {file = "setuptools_scm-6.3.2-py3-none-any.whl", hash = "sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119"}, @@ -1952,8 +1952,8 @@ typed-ast = [ {file = "typed_ast-1.5.0.tar.gz", hash = "sha256:ff4ad88271aa7a55f19b6a161ed44e088c393846d954729549e3cde8257747bb"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"}, - {file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"}, + {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, + {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, ] urllib3 = [ {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, diff --git a/python/lvmagp/actor/commands/autofocus.py b/python/lvmagp/actor/commands/autofocus.py index 2c80337..803a4fb 100644 --- a/python/lvmagp/actor/commands/autofocus.py +++ b/python/lvmagp/actor/commands/autofocus.py @@ -17,12 +17,28 @@ def autofocus(*args): @autofocus.command() @click.argument("TEL", type=str) async def coarse(command: Command, tel: str): + """ + Find the focus coarsely by scanning whole reachable position. + + Parameters + ---------- + tel + The telescope to be focused + """ pass @autofocus.command() @click.argument("TEL", type=str) async def fine(command: Command, tel: str): + """ + Find the optimal focus position which is near the current position. + + Parameters + ---------- + tel + The telescope to be focused + """ position, fwhm = [], [] incremental = 100 repeat = 5 diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 61c3bd5..6298b86 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -25,6 +25,17 @@ async def start(command: Command, westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel: str, useteldata: bool): + """ + Start the autoguide sequence. + + Parameters + ---------- + tel + Telescope to autoguide + useteldata + If ``useteldata`` is flagged, the sequence will use the pixel scale and rotation angle from LVMTelescope. + Otherwise, the sequence will get pixel scale from LVMCamera and it assumes that the camera is north-oriented. + """ if tel in telescopes: try: @@ -47,6 +58,14 @@ async def start(command: Command, @click.argument("TEL", type=str) async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel: str): + """ + Stop the autoguide sequence. + + Parameters + ---------- + tel + Telescope to stop autoguide + """ if tel in telescopes: if telescopes[tel].ag_task is not None: telescopes[tel].ag_break = True @@ -63,6 +82,14 @@ async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcamera async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel: str): + """ + Run calibration sequence to calculate the transformation from the equatorial coordinates to the xy coordinates of the image. + + Parameters + ---------- + tel + Telescope to be calibrated + """ global KHU_inner_test offset_per_step = usrpars.ag_cal_offset_per_step num_step = usrpars.ag_cal_num_step @@ -118,7 +145,18 @@ async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eas async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel, useteldata): - + """ + Manage the autoguide sequence. + It starts real autoguide loop and keeps it until the break signal comes. + + Parameters + ---------- + tel + Telescope to autoguide + useteldata + If ``useteldata`` is flagged, the sequence will use the pixel scale and rotation angle from LVMTelescope. + Otherwise, the sequence will get pixel scale from LVMCamera and it assumes that the camera is north-oriented. + """ global KHU_inner_test if KHU_inner_test: i = 0 @@ -228,6 +266,18 @@ async def autoguide_supervisor(command, tel): async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel, positionguess=None): + """ + Expose an image, and find three guide stars from the image. + Also calculate the center coordinates and flux of found stars. + + Parameters + ---------- + tel + Telescope to autoguide + positionguess + Initial guess of guidestar position. It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] + If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding based on ``positionguess`` without finding new stars. + """ global KHU_inner_test command.info("Taking image...") # take an image for astrometry @@ -263,7 +313,22 @@ async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcam async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel, initposition, initflux, useteldata): - + """ + Expose an image, and calculate offset from the image and initial values. + Compensate the offset. + + Parameters + ---------- + tel + Telescope to autoguide + initposition + Position of guide stars when the autoguide is started + initflux + Flux of guide stars when the autoguide is started + positionguess + Initial guess of guidestar position. It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] + If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding based on ``positionguess`` without finding new stars. + """ starposition, starflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel, positionguess=initposition) diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 2157d7f..3ec21fd 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -9,6 +9,15 @@ from . import parser async def deg_to_dms(deg): + """ + Convert the number in degree unit into a tuple consists of degree, minutes, and seconds. + Degree and minutes is integer, and seconds is float. + + Parameters + ---------- + exptime + Exposure time + """ absdeg = np.abs(deg) d = np.floor(absdeg) m = np.floor((absdeg - d) * 60) @@ -26,6 +35,18 @@ async def slew(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel: str, target_ra_h: float, target_dec_d: float): + """ + Slew the telescope to the given equatorial coordinate (J2000). + + Parameters + ---------- + tel + Telescope to slew + target_ra_h + The right ascension (J2000) of the target in hours + target_dec_d + The declination (J2000) of the target in degrees + """ test_KHU = True long_d = telescopes[tel].longitude diff --git a/python/lvmagp/actor/commfunc.py b/python/lvmagp/actor/commfunc.py index 7c14ea4..48c5922 100644 --- a/python/lvmagp/actor/commfunc.py +++ b/python/lvmagp/actor/commfunc.py @@ -7,8 +7,17 @@ import asyncio -# Functions for focuser class LVMTANInstrument: + """ + Class for the instruments using TAN. + + Parameters + ---------- + tel + Telescope to which the instrument belongs + inst + Type of the instrument + """ def __init__(self, tel, inst): if tel == "test" or inst == "test": self.lvmtan = "test.first.focus_stage" @@ -16,6 +25,14 @@ def __init__(self, tel, inst): self.lvmtan = "lvm." + tel + "." + inst async def getposition(self, command, unit="STEPS"): + """ + Get current position of device in given unit. + + Parameters + ---------- + unit + Unit of position + """ cmd = await send_message( command, self.lvmtan, @@ -25,12 +42,31 @@ async def getposition(self, command, unit="STEPS"): ) return cmd - async def moveabs(self, command, position, unit='STEPS'): + """ + Move the device at given absolute position. + + Parameters + ---------- + position + Position for the device to be located + unit + Unit of position + """ cmd = await send_message(command, self.lvmtan, "moveAbsolute %d %s" % (position, unit)) return cmd async def moverel(self, command, position, unit='STEPS'): + """ + Move the device at given relative position. + + Parameters + ---------- + position + Position for the device to be located + unit + Unit of position + """ cmd = await send_message(command, self.lvmtan, "moveRelative %d %s" % (position, unit)) return cmd ''' @@ -53,20 +89,36 @@ async def moverel(self, command, position, unit="STEPS"): ''' class LVMFocuser(LVMTANInstrument): + """ + Class for the focusers + + Parameters + ---------- + tel + Telescope to which the focuser belongs + """ def __init__(self, tel): super().__init__(tel, "foc") #print(self.lvmtan) class LVMKMirror(LVMTANInstrument): + """ + Class for the K-mirros + + Parameters + ---------- + tel + Telescope to which the focuser belongs + """ def __init__(self, tel): super().__init__(tel, "km") - + ''' async def cal_traj(self, command): currenttime = datetime.datetime.now() #cmd = await send_message(command, self.lvmtan, "startProfile %d %s" % (position, unit)) return currenttime - ''' + async def startProfile( self, start_date: datetime.datetime, @@ -77,11 +129,27 @@ async def startProfile( ''' class LVMFibsel(LVMTANInstrument): + """ + Class for the fiber selectors + + Parameters + ---------- + tel + Telescope to which the focuser belongs + """ def __init__(self): super().__init__("spec", "fibsel") class LVMTelescope: + """ + Class for the telescopes (Planewave mounts) + + Parameters + ---------- + tel + The name of the telescope + """ def __init__(self, tel): if tel == "test": self.lvmpwi = "lvm.pwi" @@ -90,7 +158,6 @@ def __init__(self, tel): self.latitude = -999 self.longitude = -999 - self.rotationangle = -999 self.scale_matrix = np.matrix([[1,1], #[x_ra , y_ra ] [1,1]]) #[x_dec, y_dec] @@ -99,10 +166,23 @@ def __init__(self, tel): self.ag_break = False async def slew_radec2000(self, command, target_ra_h, target_dec_d): + """ + Slew the telescope to given equatorial coordinates whose epoch is J2000. + + Parameters + ---------- + target_ra_h + Target right ascension in hours in J2000 epoch + target_dec_d + Target declination in degrees in J2000 epoch + """ cmd = await send_message(command,self.lvmpwi,"gotoRaDecJ2000 %f %f" % (target_ra_h, target_dec_d)) return cmd async def reset_offset_radec(self, command): + """ + Reset the offset of both axes to zero. + """ await send_message( command, self.lvmpwi, "offset --ra_reset" ) @@ -113,7 +193,16 @@ async def reset_offset_radec(self, command): return True async def offset_radec(self, command, ra_arcsec, dec_arcsec): - + """ + Give some offset to the mount + + Parameters + ---------- + ra_arcsec + Distance to move along right ascension axis in arcseconds + dec_arcsec + Distance to move along declination axis in arcseconds + """ await send_message( command, self.lvmpwi, "offset --ra_add_arcsec %f" % ra_arcsec ) @@ -124,6 +213,9 @@ async def offset_radec(self, command, ra_arcsec, dec_arcsec): return True async def get_dec2000_deg(self, command): + """ + Return the declination (J2000) of current position in degrees + """ dec2000 = await send_message( command, self.lvmpwi, "status", returnval=True, body="dec_j2000_degs" ) @@ -132,6 +224,9 @@ async def get_dec2000_deg(self, command): # Functions for camera class LVMCamera: + """ + Class for the FLIR guide cameras + """ def __init__(self): self.lvmcam = "lvmcam" self.cam = "lvmcam" @@ -142,23 +237,55 @@ def __init__(self): self.lvmcampath = '' async def single_exposure(self, command, exptime): + """ + Take a single exposure + + Parameters + ---------- + exptime + Exposure time + """ path = await send_message( command, self.lvmcam, "expose %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" ) return path["0"] async def test_exposure(self, command, exptime): + """ + Take a test exposure using ``-t`` option of lvmcam. The image file (Temp.fits) is overwritten whenever this command is executed. + + Parameters + ---------- + exptime + Exposure time + """ path = await send_message( command, self.lvmcam, "expose -t %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" ) return path["0"] class LVMEastCamera(LVMCamera): + """ + Class for the FLIR guide cameras installed in east side + + Parameters + ---------- + tel + Telescope to which the camera belongs + """ def __init__(self, tel): super().__init__() self.cam = tel + '.age' class LVMWestCamera(LVMCamera): + """ + Class for the FLIR guide cameras installed in west side + + Parameters + ---------- + tel + Telescope to which the camera belongs + """ def __init__(self, tel): super().__init__() self.cam = tel + '.agw' \ No newline at end of file diff --git a/python/lvmagp/actor/internalfunc.py b/python/lvmagp/actor/internalfunc.py index a03a0c3..f94b8f6 100644 --- a/python/lvmagp/actor/internalfunc.py +++ b/python/lvmagp/actor/internalfunc.py @@ -14,6 +14,14 @@ class GuideImage: + """ + Class for the guide camera images. + + Parameters + ---------- + filepath + Path of the image file + """ def __init__(self, filepath): self.filepath = filepath self.nstar = 3 @@ -32,6 +40,15 @@ def __init__(self, filepath): self.pixelscale = -999 def findstars(self, nstar=3): + """ + Find ``nstar`` stars using DAOFind and KD tree for sequences of lvmagp. + The result is given by np.ndarray lookes like [[x1, y1], [x2, y2], [x3, y3], ...], and it is also saved in ``self.guidestarposition``. + + Parameters + ---------- + nstar + The number of stars to be found + """ daofind = DAOStarFinder( fwhm=self.initFWHM, threshold=3.0 * self.std, peakmax=60000 - self.median ) # 1sigma = FWHM/(2*sqrt(2ln2)); FWHM = sigma * (2*sqrt(2ln2)) @@ -69,6 +86,9 @@ def findstars(self, nstar=3): return self.guidestarposition # array ; [[x1, y1], [x2, y2], [x3, y3]] def twoDgaussianfit(self): + """ + Condunt 2D Gaussian fitting to find center, flux of the stars in ``self.guidestarposition``. + """ windowradius = 5 # only integer plist = [] @@ -97,6 +117,9 @@ def twoDgaussianfit(self): return plist def update_guidestar_properties(self): + """ + Using ``twoDGaussianfit`` method, update the guidestar properties in ``self.guidestarflux``, ``self.guidestarposition``, ``self.guidestarsize``, and ``slef.FWHM``. + """ if len(self.guidestarposition) == 0: pass @@ -115,6 +138,17 @@ def update_guidestar_properties(self): return True async def astrometry(self, ra_h=-999, dec_d=-999): + """ + Conduct astrometry to find where the image is taken. + Astromery result is saved in astrometry_result.txt in same directory with this python file, also key result (ra,dec,pa) is saved to ``self.ra2000``, ``self.dec2000``, and ``self.pa``. + + Parameters + ---------- + ra_h + The initial guess for right ascension (J2000) in hours + dec_d + The initial guess for declination (J2000) in degrees + """ ospassword = "0000" resultpath = os.path.dirname(os.path.abspath(__file__)) + "/astrometry_result.txt" timeout = 10 @@ -177,6 +211,16 @@ async def astrometry(self, ra_h=-999, dec_d=-999): def findfocus(positions, FWHMs): # both are lists or np.array + """ + Find the optimal focus using LSQ fitting. + + Parameters + ---------- + positions + The positions (encoder values) at each measurement + FWHMs + The measured FWHMs at each measurement + """ t_init = models.Polynomial1D(degree=2) fit_t = fitting.LinearLSQFitter() t = fit_t(t_init, positions, FWHMs) @@ -186,6 +230,20 @@ def findfocus(positions, FWHMs): # both are lists or np.array def cal_pa(ra_h, dec_d, long_d, lat_d): + """ + Calculate position angle at given position and location + + Parameters + ---------- + ra_h + The right ascension (J2000) in hours + dec_d + The declination (J2000) in degrees + long_d + Longitude in degrees + lat_d + Latitude in degrees + """ dec = np.deg2rad(dec_d) lat = np.deg2rad(lat_d) @@ -200,6 +258,20 @@ def cal_pa(ra_h, dec_d, long_d, lat_d): def star_altaz(ra_h, dec_d, long_d, lat_d): + """ + Calculate the alt-az coordinates at now from the equatorial coordinates and location + + Parameters + ---------- + ra_h + The right ascension (J2000) in hours + dec_d + The declination (J2000) in degrees + long_d + Longitude in degrees + lat_d + Latitude in degrees + """ dec = np.deg2rad(dec_d) lat = np.deg2rad(lat_d) @@ -224,6 +296,15 @@ def star_altaz(ra_h, dec_d, long_d, lat_d): def define_visb_limit(Az): # or Hour angle..? + """ + Define the altitude limit at given azimuth angle. + Now it returns 30<=Alt<=90 at any azimuth. + + Parameters + ---------- + Az + Azimuth to calculate the limit + """ # input any condition .. alt_low = 30 alt_high = 90 @@ -231,6 +312,20 @@ def define_visb_limit(Az): # or Hour angle..? def check_target(ra_h, dec_d, long_d, lat_d): + """ + Using the limit defined in ``define_visb_limit``, check whether the target is in observable area or not. + + Parameters + ---------- + ra_h + The right ascension (J2000) in hours + dec_d + The declination (J2000) in degrees + long_d + Longitude in degrees + lat_d + Latitude in degrees + """ alt, az = star_altaz(ra_h, dec_d, long_d, lat_d) alt_low, alt_high = define_visb_limit(az) if (alt_low < alt) and (alt < alt_high): @@ -240,6 +335,20 @@ def check_target(ra_h, dec_d, long_d, lat_d): async def send_message(command, actor, command_to_send, returnval=False, body=""): + """ + Send command to the other actor and return reply from the command if needed. + + Parameters + ---------- + actor + The name of the actor which the command to be sent. + command_to_send + The string of message to be sent to ``actor``. + returnval + If ``returnval=True``, it receives the return (``command.finish``) from the ``actor``. + body + The needed body from the returns. + """ cmd = await command.actor.send_command(actor, command_to_send) cmdwait = await cmd diff --git a/python/lvmagp/actor/user_parameters.py b/python/lvmagp/actor/user_parameters.py index b848058..2e8bcd4 100644 --- a/python/lvmagp/actor/user_parameters.py +++ b/python/lvmagp/actor/user_parameters.py @@ -7,20 +7,20 @@ class usrpars(): # autofocus parameters - # aquisition parameters - aqu_exptime = 5 #in seconds - aqu_max_iter = 2 - aqu_tolerance_arcsec = 30.0 + # acquisition parameters + aqu_exptime = 5 # exposure time for acquisition in seconds + aqu_max_iter = 2 # maximum iteration of astrometry compensation + aqu_tolerance_arcsec = 30.0 # maximum tolerable angular distance between target coordinates and aquisited coordinates - # autoguide paramters - ag_exptime = 3 + # autoguide parameters + ag_exptime = 3 # exposure time for autoguide in seconds ag_halfboxsize = 15 # 1/2 of box in pixel - ag_minsnr = 6 + #ag_minsnr = 6 ag_min_offset = 0.3 # minimum offset to do correction in pixel ag_flux_tolerance = 0.2 # maximum variability of flux due to seeing to identify the guide star - ag_cal_offset_per_step = 4.0 - ag_cal_num_step = 2 + ag_cal_offset_per_step = 4.0 # Step size for calibration in arcseconds + ag_cal_num_step = 2 # number of steps of calibration per axis diff --git a/python/lvmagp/etc/lvmagp.yml b/python/lvmagp/etc/lvmagp.yml index 82b8c9c..e3b2a3f 100644 --- a/python/lvmagp/etc/lvmagp.yml +++ b/python/lvmagp/etc/lvmagp.yml @@ -81,5 +81,5 @@ actor: name: lvmagp host: localhost port: 5672 - version: '0.2.0-alpha' + version: '0.2.1-alpha' log_dir: '../../logs' \ No newline at end of file From f5fc007d300c48a3a23f03f53f14915d957f260f Mon Sep 17 00:00:00 2001 From: mgjeon Date: Mon, 6 Dec 2021 15:15:29 +0900 Subject: [PATCH 6/9] v0.2.2a debug guide command (not completed) --- python/lvmagp/actor/actor.py | 8 ++--- python/lvmagp/actor/astrometry_result.txt | 29 +++++++++--------- python/lvmagp/actor/commands/guide.py | 36 +++++++++++++---------- python/lvmagp/actor/commands/slew.py | 3 +- python/lvmagp/actor/commands/test.py | 16 ++++++++++ python/lvmagp/actor/internalfunc.py | 24 +++++++-------- python/lvmagp/actor/user_parameters.py | 6 ++-- python/lvmagp/etc/lvmagp.yml | 4 +-- 8 files changed, 74 insertions(+), 52 deletions(-) diff --git a/python/lvmagp/actor/actor.py b/python/lvmagp/actor/actor.py index 01bae09..529d771 100644 --- a/python/lvmagp/actor/actor.py +++ b/python/lvmagp/actor/actor.py @@ -46,10 +46,10 @@ def __init__( "Img_pa": {"type": "string"}, "offset_ra": {"type": "string"}, "offset_dec": {"type": "string"}, - "xscale_ra": {"type": "float"}, - "yscale_ra": {"type": "float"}, - "xscale_dec": {"type": "float"}, - "yscale_dec": {"type": "float"} + "xscale_ra": {"type": "string"}, + "yscale_ra": {"type": "string"}, + "xscale_dec": {"type": "string"}, + "yscale_dec": {"type": "string"} }, "additionalProperties": False, } diff --git a/python/lvmagp/actor/astrometry_result.txt b/python/lvmagp/actor/astrometry_result.txt index ddcdc60..ab1f8c8 100644 --- a/python/lvmagp/actor/astrometry_result.txt +++ b/python/lvmagp/actor/astrometry_result.txt @@ -1,25 +1,26 @@ -Reading input file 1 of 1: "/home/sumin/lvmcam/python/lvmcam/assets/test.fits"... +Reading input file 1 of 1: "/home/sumin/lvmcam/python/lvmcam/assets/testshot.fits"... Extracting sources... +This looks like a multi-color image: processing the first image plane only. (NAXIS=3) Downsampling by 2... -simplexy: found 197 sources. +simplexy: found 663 sources. Solving... -Reading file "/home/sumin/lvmcam/python/lvmcam/assets/test.axy"... -Only searching for solutions within 1 degrees of RA,Dec (83.85,-5.45) +Reading file "/home/sumin/lvmcam/python/lvmcam/assets/testshot.axy"... +Only searching for solutions within 1 degrees of RA,Dec (92.25,24.33) Field 1 did not solve (index index-4211.fits, field objects 1-10). Field 1 did not solve (index index-4210.fits, field objects 1-10). Field 1 did not solve (index index-4209.fits, field objects 1-10). Field 1 did not solve (index index-4208.fits, field objects 1-10). Field 1 did not solve (index index-4207-05.fits, field objects 1-10). - log-odds ratio 439.518 (7.58935e+190), 87 match, 0 conflict, 105 distractors, 127 index. - RA,Dec = (83.8516,-5.44941), pixel scale 2.59094 arcsec/pix. - Hit/miss: Hit/miss: ++++++-+++++++++++++++++-++++-++++++-++++---+++--++-++-+++--+++-+-+-+++-+++-+-+-+---+---+--+----+--+ + log-odds ratio 574.743 (4.05134e+249), 117 match, 0 conflict, 311 distractors, 137 index. + RA,Dec = (92.2496,24.3312), pixel scale 2.59625 arcsec/pix. + Hit/miss: Hit/miss: +++++++++-+++++++++++++++-+++-+--+++-++++++-+-++-+-++-+-+-++-+-++-++---++--++-+++-++-++++-+++-++-+-- Field 1: solved with index index-4206-05.fits. -Field 1 solved: writing to file /home/sumin/lvmcam/python/lvmcam/assets/test.solved to indicate this. -Field: /home/sumin/lvmcam/python/lvmcam/assets/test.fits -Field center: (RA,Dec) = (83.851870, -5.449307) deg. -Field center: (RA H:M:S, Dec D:M:S) = (05:35:24.449, -05:26:57.505). -Field size: 69.2306 x 47.6209 arcminutes -Field rotation angle: up is 171.703 degrees E of N +Field 1 solved: writing to file /home/sumin/lvmcam/python/lvmcam/assets/testshot.solved to indicate this. +Field: /home/sumin/lvmcam/python/lvmcam/assets/testshot.fits +Field center: (RA,Dec) = (92.250015, 24.331394) deg. +Field center: (RA H:M:S, Dec D:M:S) = (06:09:00.004, +24:19:53.018). +Field size: 69.2532 x 47.6139 arcminutes +Field rotation angle: up is 99.4551 degrees E of N Field parity: pos -Creating new FITS file "/home/sumin/lvmcam/python/lvmcam/assets/test.new"... +Creating new FITS file "/home/sumin/lvmcam/python/lvmcam/assets/testshot.new"... diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 6298b86..28b662f 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -107,7 +107,7 @@ async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eas for step in range(1,num_step+1): await telescopes[tel].offset_radec(command, 0, offset_per_step) position, flux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, - kmirrors, tel) + kmirrors, tel, positionguess=initposition) xpositions.append(position[:, 0]) ypositions.append(position[:, 1]) @@ -115,8 +115,8 @@ async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eas xpositions = np.array(xpositions) - xpositions[0] ypositions = np.array(ypositions) - ypositions[0] - xscale_dec = np.sum(xpositions/np.arange(num_step+1))/(num_step) # displacement along x-axis by ra offset in pixel per arcsecond. exclude the first index (0,0) - yscale_dec = np.sum(ypositions/np.arange(num_step+1))/(num_step) # exclude the first index (0,0) + xscale_dec = np.sum(xpositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step # displacement along x-axis by ra offset in pixel per arcsecond. exclude the first index (0,0) + yscale_dec = np.sum(ypositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step # exclude the first index (0,0) # ra axis calibration xpositions = [initposition[:, 0]] @@ -131,16 +131,16 @@ async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eas await telescopes[tel].offset_radec(command, -num_step*offset_per_step, 0) - decj2000_deg = telescopes[tel].get_dec2000_deg() + decj2000_deg = await telescopes[tel].get_dec2000_deg(command) xpositions = np.array(xpositions) - xpositions[0] ypositions = np.array(ypositions) - ypositions[0] - xscale_ra = np.sum(xpositions*np.arange(num_step+1))/(num_step)/np.cos(decj2000_deg) # exclude the first index (0,0) - yscale_ra = np.sum(ypositions*np.arange(num_step+1))/(num_step)/np.cos(decj2000_deg) # exclude the first index (0,0) + xscale_ra = np.sum(xpositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step/np.cos(np.deg2rad(decj2000_deg)) # exclude the first index (0,0) + yscale_ra = np.sum(ypositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step/np.cos(np.deg2rad(decj2000_deg)) # exclude the first index (0,0) telescopes[tel].scale_matrix = np.matrix([[xscale_ra, yscale_ra],[xscale_dec, yscale_dec]]) return command.finish(xscale_ra="%.3f pixel/arcsec"%xscale_ra, yscale_ra="%.3f pixel/arcsec"%yscale_ra, - xscale_dec="%.3f pixel/arcsec"%xscale_dec, ysclae_dec="%.3f pixel/arcsec"%yscale_dec) + xscale_dec="%.3f pixel/arcsec"%xscale_dec, yscale_dec="%.3f pixel/arcsec"%yscale_dec) async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], @@ -158,14 +158,14 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas Otherwise, the sequence will get pixel scale from LVMCamera and it assumes that the camera is north-oriented. """ global KHU_inner_test - if KHU_inner_test: + if 0: i = 0 else: initposition, initflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel) while 1: - if KHU_inner_test: + if 0: command.info("%s %d" % (tel, i)) i = i + 1 await asyncio.sleep(8) @@ -331,20 +331,24 @@ async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: """ starposition, starflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel, positionguess=initposition) - - if np.abs(np.average(starflux/initflux - 1), weight=np.log10(initflux)) > usrpars.ag_flux_tolerance: - return command.error("Star flux variation is too large.") + print(starflux) + print(initflux) + if np.abs(np.average(starflux/initflux - 1, weights=2.5*np.log10(initflux*10))) > usrpars.ag_flux_tolerance: + return command.error("Star flux variation %.3f is too large." % np.abs(np.average(starflux/initflux - 1, weights=2.5*np.log10(initflux*10)))) offset = np.mean(starposition - initposition, axis=0) # in x,y [pixel] if useteldata: - offset_arcsec = np.matmul(telescopes[tel].scale_matrix.I, offset.T) # in x,y(=ra,dec) [arcsec] + offset_arcsec = np.matmul(telescopes[tel].scale_matrix.I, offset) # in x,y(=ra,dec) [arcsec] offset_arcsec = np.array(offset_arcsec) else: - offset_arcsec = offset * westcameras[tel].pixelscale # in x,y(=ra,dec) [arcsec] + theta = np.radians(westcameras[tel].rotationangle) + c, s = np.cos(theta), np.sin(theta) + R = np.array(((c, -s), (s, c))) + offset_arcsec = np.dot(R,offset) * westcameras[tel].pixelscale # in x,y(=ra,dec) [arcsec] - decj2000_deg = telescopes[tel].get_dec2000_deg() - offset_arcsec[0] = offset_arcsec[0]/np.cos(decj2000_deg) + decj2000_deg = await telescopes[tel].get_dec2000_deg(command) + offset_arcsec[0] = offset_arcsec[0]/np.cos(np.deg2rad(decj2000_deg)) if (np.sqrt(offset[0]**2+offset[1]**2)) > usrpars.ag_min_offset: print("compensate: ra %.2f arcsec dec %.2f arcsec x %.2f pixel y %.2f pixel" % diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 3ec21fd..8aa1c72 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -76,7 +76,6 @@ async def slew(command: Command, command.info("Initial slew completed.") for iter in range(usrpars.aqu_max_iter + 1): - log.info("Taking image...") command.info("Taking image...") # take an image for astrometry try: @@ -123,6 +122,8 @@ async def slew(command: Command, ra2000_d = 0.5*(eastguideimg.ra2000 + westguideimg.ra2000) dec2000_d = 0.5*(eastguideimg.dec2000 + westguideimg.dec2000) pa_d = 0.5*(eastguideimg.pa + westguideimg.pa) + westcameras[tel].rotationangle = westguideimg.pa + eastcameras[tel].rotationangle = eastguideimg.pa ra2000_hms = await deg_to_dms(ra2000_d / 15) dec2000_dms = await deg_to_dms(dec2000_d) diff --git a/python/lvmagp/actor/commands/test.py b/python/lvmagp/actor/commands/test.py index aeaff54..78114b1 100644 --- a/python/lvmagp/actor/commands/test.py +++ b/python/lvmagp/actor/commands/test.py @@ -22,6 +22,22 @@ async def test(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], ): + + filepath = "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000107.fits" + guideimg1 = GuideImage(filepath) + + filepath = "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000110.fits" + guideimg2 = GuideImage(filepath) + pos = guideimg1.findstars() + print(pos) + + guideimg2.guidestarposition = pos + guideimg2.update_guidestar_properties() + starposition = guideimg2.guidestarposition + print(starposition) + + + ''' log.info("Img_ra2000='%02dh %02dm %06.3fs' Img_dec2000='%02dd %02dm %06.3fs'" % (1,2,3,4,5,6), ) diff --git a/python/lvmagp/actor/internalfunc.py b/python/lvmagp/actor/internalfunc.py index f94b8f6..8533167 100644 --- a/python/lvmagp/actor/internalfunc.py +++ b/python/lvmagp/actor/internalfunc.py @@ -28,11 +28,11 @@ def __init__(self, filepath): self.initFWHM = 3 self.FWHM = -999 self.hdu = fits.open(self.filepath) - self.data, self.hdr = self.hdu[0].data, self.hdu[0].header + self.data, self.hdr = self.hdu[0].data[0], self.hdu[0].header self.mean, self.median, self.std = sigma_clipped_stats(self.data, sigma=3.0) - self.guidestarposition = [] - self.guidestarflux = [] - self.guidestarsize = [] + self.guidestarposition = np.zeros(1) + self.guidestarflux = np.zeros(1) + self.guidestarsize = np.zeros(1) self.ra2000 = -999 self.dec2000 = -999 self.pa = -999 @@ -89,7 +89,7 @@ def twoDgaussianfit(self): """ Condunt 2D Gaussian fitting to find center, flux of the stars in ``self.guidestarposition``. """ - windowradius = 5 # only integer + windowradius = 10 # only integer plist = [] for i in range(len(self.guidestarposition[:, 0])): @@ -124,15 +124,15 @@ def update_guidestar_properties(self): pass plist = self.twoDgaussianfit() - + flux, position, size = [], [], [] for p in plist: - self.guidestarflux.append(p.amplitude) - self.guidestarposition.append([p.x_mean, p.y_mean]) - self.guidestarsize.append([p.x_fwhm, p.y_fwhm]) + flux.append(p.amplitude.value) + position.append([p.x_mean.value, p.y_mean.value]) + size.append([p.x_fwhm, p.y_fwhm]) - self.guidestarflux = np.array(self.guidestarflux) - self.guidestarposition = np.array(self.guidestarposition) - self.guidestarsize = np.array(self.guidestarsize) + self.guidestarflux = np.array(flux) + self.guidestarposition = np.array(position) + self.guidestarsize = np.array(size) self.FWHM = np.median(self.guidestarsize) # float return True diff --git a/python/lvmagp/actor/user_parameters.py b/python/lvmagp/actor/user_parameters.py index 2e8bcd4..2a2fcab 100644 --- a/python/lvmagp/actor/user_parameters.py +++ b/python/lvmagp/actor/user_parameters.py @@ -17,10 +17,10 @@ class usrpars(): ag_halfboxsize = 15 # 1/2 of box in pixel #ag_minsnr = 6 ag_min_offset = 0.3 # minimum offset to do correction in pixel - ag_flux_tolerance = 0.2 # maximum variability of flux due to seeing to identify the guide star + ag_flux_tolerance = 0.3 # maximum variability of flux due to seeing to identify the guide star - ag_cal_offset_per_step = 4.0 # Step size for calibration in arcseconds - ag_cal_num_step = 2 # number of steps of calibration per axis + ag_cal_offset_per_step = 3.0 # Step size for calibration in arcseconds + ag_cal_num_step = 3 # number of steps of calibration per axis diff --git a/python/lvmagp/etc/lvmagp.yml b/python/lvmagp/etc/lvmagp.yml index e3b2a3f..e9d59d1 100644 --- a/python/lvmagp/etc/lvmagp.yml +++ b/python/lvmagp/etc/lvmagp.yml @@ -12,7 +12,7 @@ sci: pixelscale: 2.60 offset_x: 0.0 offset_y: 0.0 - rotationangle: 0.0 + rotationangle: 100.0 foc: varA: null km: @@ -82,4 +82,4 @@ actor: host: localhost port: 5672 version: '0.2.1-alpha' - log_dir: '../../logs' \ No newline at end of file + log_dir: './logs' \ No newline at end of file From 5abf328a243880055376c188ad15c895740979cc Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 10 Dec 2021 13:52:45 +0900 Subject: [PATCH 7/9] v.0.2.3a lvmtipo --- .github/workflows/test.yml | 2 +- .idea/vcs.xml | 2 + python/lvmagp/actor/actor.py | 64 +++-- python/lvmagp/actor/commands/autofocus.py | 15 +- python/lvmagp/actor/commands/guide.py | 301 ++++++++++++++++------ python/lvmagp/actor/commands/slew.py | 77 ++++-- python/lvmagp/actor/commands/test.py | 98 +++---- python/lvmagp/actor/commfunc.py | 99 +++---- python/lvmagp/actor/internalfunc.py | 29 ++- python/lvmagp/actor/user_parameters.py | 19 +- python/lvmagp/etc/lvmagp.yml | 14 +- 11 files changed, 442 insertions(+), 278 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a56e6ed..400d037 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: run: | pip install flake8 # stop the build if there are Python syntax errors or undefined names - flake8 . --count --show-source --statistics + flake8 ./python/lvmagp --count --show-source --statistics - name: Lint with isort run: | diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..929b291 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,7 @@ + + \ No newline at end of file diff --git a/python/lvmagp/actor/actor.py b/python/lvmagp/actor/actor.py index 529d771..d35fc94 100644 --- a/python/lvmagp/actor/actor.py +++ b/python/lvmagp/actor/actor.py @@ -2,25 +2,29 @@ from clu.actor import AMQPActor -from .commands import parser as lvm_command_python +from lvmagp.actor.commfunc import ( # noqa: F401 + LVMEastCamera, + LVMFibsel, + LVMFocuser, + LVMKMirror, + LVMTANInstrument, + LVMTelescope, + LVMWestCamera, +) -from lvmagp.actor.commfunc import LVMTANInstrument,LVMTelescope,LVMEastCamera,LVMWestCamera,LVMFibsel,LVMFocuser,LVMKMirror +from .commands import parser as lvm_command_python # from scpactor import __version__ __all__ = ["lvmagp"] -tel_list = ['sci', 'skye', 'skyw', 'spec'] +tel_list = ["sci", "skye", "skyw", "spec"] class lvmagp(AMQPActor): - """AGP actor. + """AGP actor. In addition to the normal arguments and keyword parameters for `~clu.actor.AMQPActor`, the class accepts the following parameters. - Parameters - ---------- - controllers - The list of `.SCP_Controller` instances to manage. """ parser = lvm_command_python @@ -40,7 +44,7 @@ def __init__( self.schema = { "type": "object", "properties": { - "fail" : {"type": "string"}, + "fail": {"type": "string"}, "Img_ra2000": {"type": "string"}, "Img_dec2000": {"type": "string"}, "Img_pa": {"type": "string"}, @@ -49,7 +53,7 @@ def __init__( "xscale_ra": {"type": "string"}, "yscale_ra": {"type": "string"}, "xscale_dec": {"type": "string"}, - "yscale_dec": {"type": "string"} + "yscale_dec": {"type": "string"}, }, "additionalProperties": False, } @@ -69,30 +73,38 @@ def from_config(cls, config, *args, **kwargs): for (ctrname, ctr) in instance.config.items(): if ctrname in tel_list: - #print(ctrname, ctr) - instance.telescopes.update({ctrname: LVMTelescope(ctrname)}) - instance.telescopes[ctrname].latitude = ctr['tel']['latitude'] - instance.telescopes[ctrname].longitude = ctr['tel']['longitude'] + # print(ctrname, ctr) + instance.telescopes.update({ctrname: LVMTelescope(ctrname, "KHU")}) instance.eastcameras.update({ctrname: LVMEastCamera(ctrname)}) - instance.eastcameras[ctrname].pixelscale = ctr['age']['pixelscale'] - instance.eastcameras[ctrname].offset_x = ctr['age']['offset_x'] - instance.eastcameras[ctrname].offset_y = ctr['age']['offset_y'] - instance.eastcameras[ctrname].rotationangle = ctr['age']['rotationangle'] + instance.eastcameras[ctrname].pixelscale = ctr["age"]["pixelscale"] + instance.eastcameras[ctrname].offset_x = ctr["age"]["offset_x"] + instance.eastcameras[ctrname].offset_y = ctr["age"]["offset_y"] + instance.eastcameras[ctrname].rotationangle = ctr["age"][ + "rotationangle" + ] instance.westcameras.update({ctrname: LVMWestCamera(ctrname)}) - instance.westcameras[ctrname].pixelscale = ctr['agw']['pixelscale'] - instance.westcameras[ctrname].offset_x = ctr['agw']['offset_x'] - instance.westcameras[ctrname].offset_y = ctr['agw']['offset_y'] - instance.westcameras[ctrname].rotationangle = ctr['agw']['rotationangle'] + instance.westcameras[ctrname].pixelscale = ctr["agw"]["pixelscale"] + instance.westcameras[ctrname].offset_x = ctr["agw"]["offset_x"] + instance.westcameras[ctrname].offset_y = ctr["agw"]["offset_y"] + instance.westcameras[ctrname].rotationangle = ctr["agw"][ + "rotationangle" + ] instance.focusers.update({ctrname: LVMFocuser(ctrname)}) instance.kmirrors.update({ctrname: LVMKMirror(ctrname)}) - #print(ctrname,ctr) + # print(ctrname,ctr) - #print(instance.telescopes) + # print(instance.telescopes) - instance.parser_args = [instance.telescopes, instance.eastcameras, instance.westcameras, instance.focusers, instance.kmirrors] - return instance \ No newline at end of file + instance.parser_args = [ + instance.telescopes, + instance.eastcameras, + instance.westcameras, + instance.focusers, + instance.kmirrors, + ] + return instance diff --git a/python/lvmagp/actor/commands/autofocus.py b/python/lvmagp/actor/commands/autofocus.py index 803a4fb..76e1a82 100644 --- a/python/lvmagp/actor/commands/autofocus.py +++ b/python/lvmagp/actor/commands/autofocus.py @@ -49,11 +49,16 @@ async def fine(command: Command, tel: str): agpwd = pwd + "/../../../../" guideimglist = [ - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_02.5.fits", # noqa: E501 - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_03.0.fits", # noqa: E501 - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_04.0.fits", # noqa: E501 - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_05.0.fits", # noqa: E501 - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_06.0.fits", # noqa: E501 + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_02.5.fits", # noqa: E501 + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_03.0.fits", # noqa: E501 + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_04.0.fits", # noqa: E501 + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_05.0.fits", # noqa: E501 + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_06.0.fits", # noqa: E501 ] guideimgidx = [0, 1, 2, 4] diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 28b662f..2af9cfa 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -1,17 +1,29 @@ -import os import click from clu.command import Command -from lvmagp.actor.commfunc import * # noqa: F403 -from lvmagp.actor.internalfunc import * # noqa: F403 +from lvmagp.actor.commfunc import ( # noqa: F401 + LVMEastCamera, + LVMFibsel, + LVMFocuser, + LVMKMirror, + LVMTANInstrument, + LVMTelescope, + LVMWestCamera, +) +from lvmagp.actor.internalfunc import GuideImage # noqa: F403 from lvmagp.actor.user_parameters import usrpars +import asyncio +import numpy as np + from . import parser + question = "Is this develop branch?" KHU_inner_test = True + @parser.group() def guide(*args): pass @@ -20,11 +32,16 @@ def guide(*args): @guide.command() @click.argument("TEL", type=str) @click.option("--useteldata", type=float, is_flag=True) -async def start(command: Command, - telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], - focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel: str, useteldata: bool): +async def start( + command: Command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel: str, + useteldata: bool, +): """ Start the autoguide sequence. @@ -33,14 +50,27 @@ async def start(command: Command, tel Telescope to autoguide useteldata - If ``useteldata`` is flagged, the sequence will use the pixel scale and rotation angle from LVMTelescope. - Otherwise, the sequence will get pixel scale from LVMCamera and it assumes that the camera is north-oriented. + If ``useteldata`` is flagged, the sequence will use the pixel scale and + rotation angle from LVMTelescope. + Otherwise, the sequence will get pixel scale from LVMCamera, and + it assumes that the camera is north-oriented. """ if tel in telescopes: try: - telescopes[tel].ag_task = asyncio.wait_for(autoguide_supervisor(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel, useteldata), timeout=3600) + telescopes[tel].ag_task = asyncio.wait_for( + autoguide_supervisor( + command, + telescopes, + eastcameras, + westcameras, + focusers, + kmirrors, + tel, + useteldata, + ), + timeout=3600, + ) await telescopes[tel].ag_task except asyncio.TimeoutError: @@ -51,13 +81,20 @@ async def start(command: Command, else: return command.fail(text="Telescope '%s' does not exist" % tel) - return command.finish('Guide stopped') + return command.finish("Guide stopped") @guide.command() @click.argument("TEL", type=str) -async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel: str): +async def stop( + command: Command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel: str, +): """ Stop the autoguide sequence. @@ -70,7 +107,9 @@ async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcamera if telescopes[tel].ag_task is not None: telescopes[tel].ag_break = True else: - return command.fail(text="There is no autoguiding loop for telescope '%s'" % tel) + return command.fail( + text="There is no autoguiding loop for telescope '%s'" % tel + ) else: return command.fail(text="Telescope '%s' does not exist" % tel) @@ -79,11 +118,18 @@ async def stop(command: Command, telescopes: dict[str, LVMTelescope], eastcamera @guide.command() @click.argument("TEL", type=str) -async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel: str): +async def calibration( + command: Command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel: str, +): """ - Run calibration sequence to calculate the transformation from the equatorial coordinates to the xy coordinates of the image. + Run calibration sequence to calculate the transformation + from the equatorial coordinates to the xy coordinates of the image. Parameters ---------- @@ -99,52 +145,91 @@ async def calibration(command: Command, telescopes: dict[str, LVMTelescope], eas xpositions, ypositions = [], [] - initposition, initflux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel) + initposition, initflux = await find_guide_stars( + command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel + ) xpositions.append(initposition[:, 0]) ypositions.append(initposition[:, 1]) # dec axis calibration - for step in range(1,num_step+1): + for step in range(1, num_step + 1): await telescopes[tel].offset_radec(command, 0, offset_per_step) - position, flux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, - kmirrors, tel, positionguess=initposition) + position, flux = await find_guide_stars( + command, + telescopes, + eastcameras, + westcameras, + focusers, + kmirrors, + tel, + positionguess=initposition, + ) xpositions.append(position[:, 0]) ypositions.append(position[:, 1]) - await telescopes[tel].offset_radec(command, 0, -num_step*offset_per_step) + await telescopes[tel].offset_radec(command, 0, -num_step * offset_per_step) xpositions = np.array(xpositions) - xpositions[0] ypositions = np.array(ypositions) - ypositions[0] - xscale_dec = np.sum(xpositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step # displacement along x-axis by ra offset in pixel per arcsecond. exclude the first index (0,0) - yscale_dec = np.sum(ypositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step # exclude the first index (0,0) + xscale_dec = ( + np.sum(xpositions[1:] / np.array([[i] * 3 for i in range(1, num_step + 1)])) / + offset_per_step + ) # displacement along x-axis by ra offset in pixel per arcsec. exclude the first index (0,0) + yscale_dec = ( + np.sum(ypositions[1:] / np.array([[i] * 3 for i in range(1, num_step + 1)])) / + offset_per_step + ) # exclude the first index (0,0) # ra axis calibration xpositions = [initposition[:, 0]] ypositions = [initposition[:, 1]] - for step in range(1,num_step+1): + for step in range(1, num_step + 1): await telescopes[tel].offset_radec(command, offset_per_step, 0) - position, flux = await find_guide_stars(command, telescopes, eastcameras, westcameras, focusers, - kmirrors, tel) + position, flux = await find_guide_stars( + command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel + ) xpositions.append(position[:, 0]) ypositions.append(position[:, 1]) - await telescopes[tel].offset_radec(command, -num_step*offset_per_step, 0) + await telescopes[tel].offset_radec(command, -num_step * offset_per_step, 0) decj2000_deg = await telescopes[tel].get_dec2000_deg(command) xpositions = np.array(xpositions) - xpositions[0] ypositions = np.array(ypositions) - ypositions[0] - xscale_ra = np.sum(xpositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step/np.cos(np.deg2rad(decj2000_deg)) # exclude the first index (0,0) - yscale_ra = np.sum(ypositions[1:]/np.array([[i] * 3 for i in range(1,num_step+1)]))/offset_per_step/np.cos(np.deg2rad(decj2000_deg)) # exclude the first index (0,0) - - telescopes[tel].scale_matrix = np.matrix([[xscale_ra, yscale_ra],[xscale_dec, yscale_dec]]) - return command.finish(xscale_ra="%.3f pixel/arcsec"%xscale_ra, yscale_ra="%.3f pixel/arcsec"%yscale_ra, - xscale_dec="%.3f pixel/arcsec"%xscale_dec, yscale_dec="%.3f pixel/arcsec"%yscale_dec) - - -async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], tel, useteldata): + xscale_ra = ( + np.sum(xpositions[1:] / np.array([[i] * 3 for i in range(1, num_step + 1)])) / + offset_per_step / + np.cos(np.deg2rad(decj2000_deg)) + ) # exclude the first index (0,0) + yscale_ra = ( + np.sum(ypositions[1:] / np.array([[i] * 3 for i in range(1, num_step + 1)])) / + offset_per_step / + np.cos(np.deg2rad(decj2000_deg)) + ) # exclude the first index (0,0) + + telescopes[tel].scale_matrix = np.matrix( + [[xscale_ra, yscale_ra], [xscale_dec, yscale_dec]] + ) + return command.finish( + xscale_ra="%.3f pixel/arcsec" % xscale_ra, + yscale_ra="%.3f pixel/arcsec" % yscale_ra, + xscale_dec="%.3f pixel/arcsec" % xscale_dec, + yscale_dec="%.3f pixel/arcsec" % yscale_dec, + ) + + +async def autoguide_supervisor( + command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel, + useteldata, +): """ Manage the autoguide sequence. It starts real autoguide loop and keeps it until the break signal comes. @@ -154,15 +239,18 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas tel Telescope to autoguide useteldata - If ``useteldata`` is flagged, the sequence will use the pixel scale and rotation angle from LVMTelescope. - Otherwise, the sequence will get pixel scale from LVMCamera and it assumes that the camera is north-oriented. + If ``useteldata`` is flagged, + the sequence will use the pixel scale and rotation angle from LVMTelescope. + Otherwise, the sequence will get pixel scale from LVMCamera, and + it assumes that the camera is north-oriented. """ global KHU_inner_test if 0: i = 0 else: - initposition, initflux = await find_guide_stars(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel) + initposition, initflux = await find_guide_stars( + command, telescopes, eastcameras, westcameras, focusers, kmirrors, tel + ) while 1: if 0: @@ -170,8 +258,18 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas i = i + 1 await asyncio.sleep(8) else: - await autoguiding(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel, initposition, initflux, useteldata) + await autoguiding( + command, + telescopes, + eastcameras, + westcameras, + focusers, + kmirrors, + tel, + initposition, + initflux, + useteldata, + ) if telescopes[tel].ag_break is True: telescopes[tel].ag_break = False @@ -180,11 +278,10 @@ async def autoguide_supervisor(command, telescopes: dict[str, LVMTelescope], eas return True -''' Here is old version using task.cancle +""" Here is old version using task.cancle @guide.command() @click.argument("TEL", type=str) async def start(command: Command, tel: str): - exptime = 3 # in seconds pixelscale = 0.5 # in arcsec/pixel halfboxsize = 15 # 1/2 of box in pixel @@ -202,10 +299,8 @@ async def start(command: Command, tel: str): cam1 = LVMCamera(tel + "e") cam2 = LVMCamera(tel + "w") cam1 = LVMCamera("test") # for lab testing - global tasklist tasklist = [0,0,0,0] - try: if tel == 'sci': tasklist[0] = asyncio.create_task(autoguide_supervisor(command, tel)) @@ -221,7 +316,6 @@ async def start(command: Command, tel: str): await tasklist[3] else: return command.fail("Wrong telescope name") - except asyncio.CancelledError: command.info("cancelled_main") @@ -252,20 +346,26 @@ async def autoguide_supervisor(command, tel): if i==5: break - - #initposition, initflux = await register_guide_stars(command, tel) #while 1: # await autoguiding(command,tel, initposition, initflux) - except asyncio.CancelledError: # Something to abort exposure .. command.info('Guide stopped') raise -''' -async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel, positionguess=None): +""" + + +async def find_guide_stars( + command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel, + positionguess=None, +): """ Expose an image, and find three guide stars from the image. Also calculate the center coordinates and flux of found stars. @@ -275,8 +375,10 @@ async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcam tel Telescope to autoguide positionguess - Initial guess of guidestar position. It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] - If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding based on ``positionguess`` without finding new stars. + Initial guess of guidestar position. + It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] + If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding + based on ``positionguess`` without finding new stars. """ global KHU_inner_test command.info("Taking image...") @@ -290,14 +392,14 @@ async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcam guideimgpath = await asyncio.gather(*imgcmd) - except Exception as e: + except Exception: return command.fail(fail="Camera error") westguideimg = GuideImage(guideimgpath[0]) eastguideimg = westguideimg if not KHU_inner_test: - eastguideimg = GuideImage(guideimgpath[1]) + eastguideimg = GuideImage(guideimgpath[1]) # noqa: F841 if positionguess is None: starposition = westguideimg.findstars() @@ -310,9 +412,18 @@ async def find_guide_stars(command, telescopes: dict[str, LVMTelescope], eastcam return starposition, starflux -async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], - westcameras: dict[str, LVMWestCamera], focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel, initposition, initflux, useteldata): +async def autoguiding( + command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel, + initposition, + initflux, + useteldata, +): """ Expose an image, and calculate offset from the image and initial values. Compensate the offset. @@ -326,35 +437,63 @@ async def autoguiding(command, telescopes: dict[str, LVMTelescope], eastcameras: initflux Flux of guide stars when the autoguide is started positionguess - Initial guess of guidestar position. It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] - If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding based on ``positionguess`` without finding new stars. + Initial guess of guidestar position. + It should be given in np.ndarray as [[x1, y1], [x2, y2], ...] + If ``positionguess`` is not None, ``find_guide_stars`` only conduct center finding + based on ``positionguess`` without finding new stars. """ - starposition, starflux = await find_guide_stars(command, telescopes, eastcameras, - westcameras, focusers, kmirrors, tel, positionguess=initposition) + starposition, starflux = await find_guide_stars( + command, + telescopes, + eastcameras, + westcameras, + focusers, + kmirrors, + tel, + positionguess=initposition, + ) print(starflux) print(initflux) - if np.abs(np.average(starflux/initflux - 1, weights=2.5*np.log10(initflux*10))) > usrpars.ag_flux_tolerance: - return command.error("Star flux variation %.3f is too large." % np.abs(np.average(starflux/initflux - 1, weights=2.5*np.log10(initflux*10)))) - - offset = np.mean(starposition - initposition, axis=0) # in x,y [pixel] + if ( + np.abs( + np.average(starflux / initflux - 1, weights=2.5 * np.log10(initflux * 10)) + ) > + usrpars.ag_flux_tolerance + ): + return command.error( + "Star flux variation %.3f is too large." + % np.abs( + np.average( + starflux / initflux - 1, weights=2.5 * np.log10(initflux * 10) + ) + ) + ) + + offset = np.mean(starposition - initposition, axis=0) # in x,y [pixel] if useteldata: - offset_arcsec = np.matmul(telescopes[tel].scale_matrix.I, offset) # in x,y(=ra,dec) [arcsec] + offset_arcsec = np.matmul( + telescopes[tel].scale_matrix.I, offset + ) # in x,y(=ra,dec) [arcsec] offset_arcsec = np.array(offset_arcsec) else: theta = np.radians(westcameras[tel].rotationangle) c, s = np.cos(theta), np.sin(theta) R = np.array(((c, -s), (s, c))) - offset_arcsec = np.dot(R,offset) * westcameras[tel].pixelscale # in x,y(=ra,dec) [arcsec] + offset_arcsec = ( + np.dot(R, offset) * westcameras[tel].pixelscale + ) # in x,y(=ra,dec) [arcsec] decj2000_deg = await telescopes[tel].get_dec2000_deg(command) - offset_arcsec[0] = offset_arcsec[0]/np.cos(np.deg2rad(decj2000_deg)) + offset_arcsec[0] = offset_arcsec[0] / np.cos(np.deg2rad(decj2000_deg)) - if (np.sqrt(offset[0]**2+offset[1]**2)) > usrpars.ag_min_offset: - print("compensate: ra %.2f arcsec dec %.2f arcsec x %.2f pixel y %.2f pixel" % - (offset_arcsec[0], offset_arcsec[1], offset[0], offset[1])) + if (np.sqrt(offset[0] ** 2 + offset[1] ** 2)) > usrpars.ag_min_offset: + print( + "compensate: ra %.2f arcsec dec %.2f arcsec x %.2f pixel y %.2f pixel" + % (offset_arcsec[0], offset_arcsec[1], offset[0], offset[1]) + ) await telescopes[tel].offset_radec(command, *offset_arcsec) return offset_arcsec else: - return [0.,0.] \ No newline at end of file + return [0.0, 0.0] diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 8aa1c72..5e00ecb 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -1,13 +1,25 @@ import os +import asyncio +import numpy as np + import click from clu.command import Command -from lvmagp.actor.commfunc import * # noqa: F403 -from lvmagp.actor.internalfunc import * # noqa: F403 +from lvmagp.actor.commfunc import ( # noqa: F401 + LVMEastCamera, + LVMFibsel, + LVMFocuser, + LVMKMirror, + LVMTANInstrument, + LVMTelescope, + LVMWestCamera, +) +from lvmagp.actor.internalfunc import check_target, cal_pa, GuideImage from lvmagp.actor.user_parameters import usrpars from . import parser + async def deg_to_dms(deg): """ Convert the number in degree unit into a tuple consists of degree, minutes, and seconds. @@ -31,10 +43,17 @@ async def deg_to_dms(deg): @click.argument("TEL", type=str) @click.argument("TARGET_RA_H", type=float) @click.argument("TARGET_DEC_D", type=float) -async def slew(command: Command, - telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], - focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - tel: str, target_ra_h: float, target_dec_d: float): +async def slew( + command: Command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], + tel: str, + target_ra_h: float, + target_dec_d: float, +): """ Slew the telescope to the given equatorial coordinate (J2000). @@ -69,7 +88,7 @@ async def slew(command: Command, command.info("Telescope slewing ...") cmd.append(telescopes[tel].slew_radec2000(command, target_ra_h, target_dec_d)) - except Exception as e: + except Exception: return command.fail(fail="Telescope error") await asyncio.gather(*cmd) @@ -81,23 +100,26 @@ async def slew(command: Command, try: imgcmd = [] imgcmd.append(westcameras[tel].test_exposure(command, usrpars.aqu_exptime)) - #imgcmd.append(westcameras[tel].single_exposure(command, usrpars.aqu_exptime)) + # imgcmd.append(westcameras[tel].single_exposure(command, usrpars.aqu_exptime)) if not test_KHU: - imgcmd.append(eastcameras[tel].test_exposure(command, usrpars.aqu_exptime)) + imgcmd.append( + eastcameras[tel].test_exposure(command, usrpars.aqu_exptime) + ) guideimgpath = await asyncio.gather(*imgcmd) - except Exception as e: + except Exception: return command.fail(fail="Camera error") command.info("Astrometry ...") - if 0: #Here should be changed to the camera version + if 0: # Here should be changed to the camera version pwd = os.path.dirname(os.path.abspath(__file__)) agpwd = pwd + "/../../../../" # Here lvmcam path and naming rule for finding latest guide image.. guideimgpath = ( - agpwd + "testimg/focus_series/synthetic_image_median_field_5s_seeing_02.5.fits" + agpwd + + "testimg/focus_series/synthetic_image_median_field_5s_seeing_02.5.fits" ) # noqa: E501 westguideimg = GuideImage(guideimgpath[0]) @@ -111,17 +133,17 @@ async def slew(command: Command, astcmd = [] astcmd.append(westguideimg.astrometry(ra_h=target_ra_h, dec_d=target_dec_d)) if not test_KHU: - astcmd.append(eastguideimg.astrometry(ra_h=target_ra_h, dec_d=target_dec_d)) + astcmd.append( + eastguideimg.astrometry(ra_h=target_ra_h, dec_d=target_dec_d) + ) cmd = await asyncio.gather(*astcmd) - except Exception as e: - log.error("Astrometry timeout") + except Exception: return command.fail(text="Astrometry timeout") - - ra2000_d = 0.5*(eastguideimg.ra2000 + westguideimg.ra2000) - dec2000_d = 0.5*(eastguideimg.dec2000 + westguideimg.dec2000) - pa_d = 0.5*(eastguideimg.pa + westguideimg.pa) + ra2000_d = 0.5 * (eastguideimg.ra2000 + westguideimg.ra2000) + dec2000_d = 0.5 * (eastguideimg.dec2000 + westguideimg.dec2000) + pa_d = 0.5 * (eastguideimg.pa + westguideimg.pa) westcameras[tel].rotationangle = westguideimg.pa eastcameras[tel].rotationangle = eastguideimg.pa @@ -141,10 +163,13 @@ async def slew(command: Command, offset_dec="%.3f arcsec" % comp_dec_arcsec, ) - # Compensation // Compensation for K-mirror based on astrometry result? may be by offset method.. - + # Compensation // Compensation for K-mirror based on astrometry result? + # may be by offset method.. - if (np.sqrt(comp_ra_arcsec**2+comp_dec_arcsec**2) > usrpars.aqu_tolerance_arcsec): + if ( + np.sqrt(comp_ra_arcsec ** 2 + comp_dec_arcsec ** 2) > + usrpars.aqu_tolerance_arcsec + ): if iter >= usrpars.aqu_max_iter: return command.fail(fail="Compensation failed.") else: @@ -152,10 +177,14 @@ async def slew(command: Command, cmd = [] if not test_KHU: cmd.append(kmirrors[tel].moverel(command, -pa_d, "DEG")) - cmd.append(telescopes[tel].offset_radec(command, comp_ra_arcsec, comp_dec_arcsec)) + cmd.append( + telescopes[tel].offset_radec( + command, comp_ra_arcsec, comp_dec_arcsec + ) + ) await asyncio.gather(*cmd) else: break - return command.finish(text="Acquisition done") \ No newline at end of file + return command.finish(text="Acquisition done") diff --git a/python/lvmagp/actor/commands/test.py b/python/lvmagp/actor/commands/test.py index 78114b1..fc54c24 100644 --- a/python/lvmagp/actor/commands/test.py +++ b/python/lvmagp/actor/commands/test.py @@ -1,32 +1,46 @@ -import os -import click from clu.command import Command -#import logging -#from sdsstools import get_logger - -from lvmagp.actor.commfunc import * # noqa: F403 -from lvmagp.actor.internalfunc import * # noqa: F403 -from lvmagp.actor.user_parameters import usrpars +from lvmagp.actor.commfunc import ( # noqa: F401 + LVMEastCamera, + LVMFibsel, + LVMFocuser, + LVMKMirror, + LVMTANInstrument, + LVMTelescope, + LVMWestCamera, +) +from lvmagp.actor.internalfunc import GuideImage +from lvmagp.actor.user_parameters import usrpars # noqa: F401 from . import parser +# import logging +# from sdsstools import get_logger + + test_KHU = True -#log = get_logger("sdss-lvmagp") -#log.sh.setLevel(logging.DEBUG) +# log = get_logger("sdss-lvmagp") +# log.sh.setLevel(logging.DEBUG) -@parser.command() -#@click.argument("TEL", type=str) -async def test(command: Command, - telescopes: dict[str, LVMTelescope], eastcameras: dict[str, LVMEastCamera], westcameras: dict[str, LVMWestCamera], - focusers: dict[str, LVMFocuser], kmirrors: dict[str, LVMKMirror], - ): - filepath = "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000107.fits" +@parser.command() +# @click.argument("TEL", type=str) +async def test( + command: Command, + telescopes: dict[str, LVMTelescope], + eastcameras: dict[str, LVMEastCamera], + westcameras: dict[str, LVMWestCamera], + focusers: dict[str, LVMFocuser], + kmirrors: dict[str, LVMKMirror], +): + + filepath = \ + "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000107.fits" guideimg1 = GuideImage(filepath) - filepath = "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000110.fits" + filepath = \ + "/home/sumin/lvmcam/python/lvmcam/assets/lvm/sci/agw/20211203/lvm.sci.agw-00000110.fits" guideimg2 = GuideImage(filepath) pos = guideimg1.findstars() print(pos) @@ -35,51 +49,3 @@ async def test(command: Command, guideimg2.update_guidestar_properties() starposition = guideimg2.guidestarposition print(starposition) - - - - ''' - log.info("Img_ra2000='%02dh %02dm %06.3fs' Img_dec2000='%02dd %02dm %06.3fs'" % (1,2,3,4,5,6), - ) - command.info(Img_ra2000="%02dh %02dm %06.3fs" - % (1,2,3), - Img_dec2000="%02dd %02dm %06.3fs" - % (6,5,4)) - ''' - ''' - global test_KHU - resultpath = "/home/sumin/lvmagp/python/lvmagp/actor/astrometry_result.txt" - - ospassword = "0000" - resultpath = os.path.dirname(os.path.abspath(__file__)) + "/../astrometry_result.txt" - timeout = 30 - scalelow = 2 - scalehigh = 3 - radius = 1 - filepath = "/home/sumin/lvmcam/python/lvmcam/assets/2459550/sci.agw-00000075.fits" - ra_h = 0.7 - dec_d = 41.3 - - - - cmd = "echo %s | sudo -S /usr/local/astrometry/bin/solve-field %s --cpulimit %f --overwrite \ - --downsample 2 --scale-units arcsecperpix --scale-low %f --scale-high %f --ra %f --dec %f \ - --radius %f --no-plots > %s" % ( # noqa: E501 - ospassword, - filepath, - timeout, - scalelow, - scalehigh, - ra_h * 15, - dec_d, - radius, - resultpath, - ) - - proc = await asyncio.create_subprocess_shell( - cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE - ) - await proc.communicate() - - print("end") - ''' \ No newline at end of file diff --git a/python/lvmagp/actor/commfunc.py b/python/lvmagp/actor/commfunc.py index 48c5922..c3ccde4 100644 --- a/python/lvmagp/actor/commfunc.py +++ b/python/lvmagp/actor/commfunc.py @@ -1,10 +1,7 @@ -# from clu import AMQPClient, CommandStatus -# from cluplus.proxy import Proxy, ProxyException, ProxyPlainMessagException, invoke, unpack +import numpy as np +from lvmtipo.site import Site from lvmagp.actor.internalfunc import send_message -import datetime -import numpy as np -import asyncio class LVMTANInstrument: @@ -18,6 +15,7 @@ class LVMTANInstrument: inst Type of the instrument """ + def __init__(self, tel, inst): if tel == "test" or inst == "test": self.lvmtan = "test.first.focus_stage" @@ -42,7 +40,7 @@ async def getposition(self, command, unit="STEPS"): ) return cmd - async def moveabs(self, command, position, unit='STEPS'): + async def moveabs(self, command, position, unit="STEPS"): """ Move the device at given absolute position. @@ -53,10 +51,12 @@ async def moveabs(self, command, position, unit='STEPS'): unit Unit of position """ - cmd = await send_message(command, self.lvmtan, "moveAbsolute %d %s" % (position, unit)) + cmd = await send_message( + command, self.lvmtan, "moveAbsolute %d %s" % (position, unit) + ) return cmd - async def moverel(self, command, position, unit='STEPS'): + async def moverel(self, command, position, unit="STEPS"): """ Move the device at given relative position. @@ -67,9 +67,13 @@ async def moverel(self, command, position, unit='STEPS'): unit Unit of position """ - cmd = await send_message(command, self.lvmtan, "moveRelative %d %s" % (position, unit)) + cmd = await send_message( + command, self.lvmtan, "moveRelative %d %s" % (position, unit) + ) return cmd -''' + + +""" async def moveabs(self, command, position, unit="STEPS"): task = asyncio.create_task( @@ -86,7 +90,8 @@ async def moverel(self, command, position, unit="STEPS"): ) ) return task -''' +""" + class LVMFocuser(LVMTANInstrument): """ @@ -97,9 +102,10 @@ class LVMFocuser(LVMTANInstrument): tel Telescope to which the focuser belongs """ + def __init__(self, tel): super().__init__(tel, "foc") - #print(self.lvmtan) + # print(self.lvmtan) class LVMKMirror(LVMTANInstrument): @@ -111,22 +117,13 @@ class LVMKMirror(LVMTANInstrument): tel Telescope to which the focuser belongs """ + def __init__(self, tel): super().__init__(tel, "km") - ''' + async def cal_traj(self, command): - currenttime = datetime.datetime.now() - #cmd = await send_message(command, self.lvmtan, "startProfile %d %s" % (position, unit)) - return currenttime - - async def startProfile( - self, - start_date: datetime.datetime, - positions: list, - frequency: int, - samples_per_segment: int, - max_error: int, - ''' + pass + class LVMFibsel(LVMTANInstrument): """ @@ -137,6 +134,7 @@ class LVMFibsel(LVMTANInstrument): tel Telescope to which the focuser belongs """ + def __init__(self): super().__init__("spec", "fibsel") @@ -150,17 +148,20 @@ class LVMTelescope: tel The name of the telescope """ - def __init__(self, tel): + + def __init__(self, tel, sitename="LCO"): if tel == "test": self.lvmpwi = "lvm.pwi" else: self.lvmpwi = "lvm." + tel + ".pwi" - self.latitude = -999 - self.longitude = -999 + site = Site(name=sitename) + self.latitude = site.lat + self.longitude = site.long - self.scale_matrix = np.matrix([[1,1], #[x_ra , y_ra ] - [1,1]]) #[x_dec, y_dec] + self.scale_matrix = np.matrix( + [[1, 1], [1, 1]] # [x_ra , y_ra ] + ) # [x_dec, y_dec] self.ag_task = None self.ag_break = False @@ -176,19 +177,17 @@ async def slew_radec2000(self, command, target_ra_h, target_dec_d): target_dec_d Target declination in degrees in J2000 epoch """ - cmd = await send_message(command,self.lvmpwi,"gotoRaDecJ2000 %f %f" % (target_ra_h, target_dec_d)) + cmd = await send_message( + command, self.lvmpwi, "gotoRaDecJ2000 %f %f" % (target_ra_h, target_dec_d) + ) return cmd async def reset_offset_radec(self, command): """ Reset the offset of both axes to zero. """ - await send_message( - command, self.lvmpwi, "offset --ra_reset" - ) - await send_message( - command, self.lvmpwi, "offset --dec_reset" - ) + await send_message(command, self.lvmpwi, "offset --ra_reset") + await send_message(command, self.lvmpwi, "offset --dec_reset") return True @@ -227,6 +226,7 @@ class LVMCamera: """ Class for the FLIR guide cameras """ + def __init__(self): self.lvmcam = "lvmcam" self.cam = "lvmcam" @@ -234,7 +234,7 @@ def __init__(self): self.offset_y = -999 self.pixelscale = -999 self.rotationangle = -999 - self.lvmcampath = '' + self.lvmcampath = "" async def single_exposure(self, command, exptime): """ @@ -246,13 +246,18 @@ async def single_exposure(self, command, exptime): Exposure time """ path = await send_message( - command, self.lvmcam, "expose %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" + command, + self.lvmcam, + "expose %f 1 %s" % (exptime, self.cam), + returnval=True, + body="PATH", ) return path["0"] async def test_exposure(self, command, exptime): """ - Take a test exposure using ``-t`` option of lvmcam. The image file (Temp.fits) is overwritten whenever this command is executed. + Take a test exposure using ``-t`` option of lvmcam. + The image file (Temp.fits) is overwritten whenever this command is executed. Parameters ---------- @@ -260,10 +265,15 @@ async def test_exposure(self, command, exptime): Exposure time """ path = await send_message( - command, self.lvmcam, "expose -t %f 1 %s" % (exptime, self.cam), returnval=True, body="PATH" + command, + self.lvmcam, + "expose -t %f 1 %s" % (exptime, self.cam), + returnval=True, + body="PATH", ) return path["0"] + class LVMEastCamera(LVMCamera): """ Class for the FLIR guide cameras installed in east side @@ -273,9 +283,11 @@ class LVMEastCamera(LVMCamera): tel Telescope to which the camera belongs """ + def __init__(self, tel): super().__init__() - self.cam = tel + '.age' + self.cam = tel + ".age" + class LVMWestCamera(LVMCamera): """ @@ -286,6 +298,7 @@ class LVMWestCamera(LVMCamera): tel Telescope to which the camera belongs """ + def __init__(self, tel): super().__init__() - self.cam = tel + '.agw' \ No newline at end of file + self.cam = tel + ".agw" diff --git a/python/lvmagp/actor/internalfunc.py b/python/lvmagp/actor/internalfunc.py index 8533167..adfe485 100644 --- a/python/lvmagp/actor/internalfunc.py +++ b/python/lvmagp/actor/internalfunc.py @@ -1,9 +1,10 @@ import asyncio +import os import warnings from datetime import datetime -import os import numpy as np + # import matplotlib.pyplot as plt from astropy.io import fits from astropy.modeling import fitting, models @@ -22,6 +23,7 @@ class GuideImage: filepath Path of the image file """ + def __init__(self, filepath): self.filepath = filepath self.nstar = 3 @@ -42,7 +44,8 @@ def __init__(self, filepath): def findstars(self, nstar=3): """ Find ``nstar`` stars using DAOFind and KD tree for sequences of lvmagp. - The result is given by np.ndarray lookes like [[x1, y1], [x2, y2], [x3, y3], ...], and it is also saved in ``self.guidestarposition``. + The result is given by np.ndarray lookes like [[x1, y1], [x2, y2], [x3, y3], ...], + and it is also saved in ``self.guidestarposition``. Parameters ---------- @@ -87,7 +90,7 @@ def findstars(self, nstar=3): def twoDgaussianfit(self): """ - Condunt 2D Gaussian fitting to find center, flux of the stars in ``self.guidestarposition``. + Conduct 2D Gaussian fitting to find center, flux of stars in ``self.guidestarposition``. """ windowradius = 10 # only integer plist = [] @@ -104,8 +107,8 @@ def twoDgaussianfit(self): Y = np.ravel(Y) Z = np.ravel( (self.data - self.median)[ - ycenter - windowradius: ycenter + windowradius, - xcenter - windowradius: xcenter + windowradius, + ycenter - windowradius: ycenter + windowradius, + xcenter - windowradius: xcenter + windowradius, ] ) @@ -118,7 +121,8 @@ def twoDgaussianfit(self): def update_guidestar_properties(self): """ - Using ``twoDGaussianfit`` method, update the guidestar properties in ``self.guidestarflux``, ``self.guidestarposition``, ``self.guidestarsize``, and ``slef.FWHM``. + Using ``twoDGaussianfit`` method, update guidestar properties in ``self.guidestarflux``, + ``self.guidestarposition``, ``self.guidestarsize``, and ``slef.FWHM``. """ if len(self.guidestarposition) == 0: pass @@ -140,7 +144,8 @@ def update_guidestar_properties(self): async def astrometry(self, ra_h=-999, dec_d=-999): """ Conduct astrometry to find where the image is taken. - Astromery result is saved in astrometry_result.txt in same directory with this python file, also key result (ra,dec,pa) is saved to ``self.ra2000``, ``self.dec2000``, and ``self.pa``. + Astromery result is saved in astrometry_result.txt in same directory with this python file, + also key result (ra,dec,pa) is saved to ``self.ra2000``, ``self.dec2000``, and ``self.pa``. Parameters ---------- @@ -150,7 +155,9 @@ async def astrometry(self, ra_h=-999, dec_d=-999): The initial guess for declination (J2000) in degrees """ ospassword = "0000" - resultpath = os.path.dirname(os.path.abspath(__file__)) + "/astrometry_result.txt" + resultpath = ( + os.path.dirname(os.path.abspath(__file__)) + "/astrometry_result.txt" + ) timeout = 10 scalelow = 2 scalehigh = 3 @@ -251,7 +258,8 @@ def cal_pa(ra_h, dec_d, long_d, lat_d): LST = t.sidereal_time("apparent").value * 15 HA = np.mod(LST - ra_h * 15, 360) pa = np.arctan( - -np.sin(np.deg2rad(HA)) / (np.cos(dec) * np.tan(lat) - np.sin(dec) * np.cos(np.deg2rad((HA)))) + -np.sin(np.deg2rad(HA)) / + (np.cos(dec) * np.tan(lat) - np.sin(dec) * np.cos(np.deg2rad((HA)))) ) return np.rad2deg(pa) @@ -313,7 +321,8 @@ def define_visb_limit(Az): # or Hour angle..? def check_target(ra_h, dec_d, long_d, lat_d): """ - Using the limit defined in ``define_visb_limit``, check whether the target is in observable area or not. + Using the limit defined in ``define_visb_limit``, + check whether the target is in observable area or not. Parameters ---------- diff --git a/python/lvmagp/actor/user_parameters.py b/python/lvmagp/actor/user_parameters.py index 2a2fcab..6629460 100644 --- a/python/lvmagp/actor/user_parameters.py +++ b/python/lvmagp/actor/user_parameters.py @@ -1,26 +1,19 @@ -class usrpars(): - # location -- it is in lvmagp.yml.. - #latitude = 0 - #longitude = 0 - - +class usrpars: # autofocus parameters - # acquisition parameters aqu_exptime = 5 # exposure time for acquisition in seconds aqu_max_iter = 2 # maximum iteration of astrometry compensation - aqu_tolerance_arcsec = 30.0 # maximum tolerable angular distance between target coordinates and aquisited coordinates + aqu_tolerance_arcsec = 30.0 # maximum tolerable position error # autoguide parameters ag_exptime = 3 # exposure time for autoguide in seconds ag_halfboxsize = 15 # 1/2 of box in pixel - #ag_minsnr = 6 + # ag_minsnr = 6 ag_min_offset = 0.3 # minimum offset to do correction in pixel - ag_flux_tolerance = 0.3 # maximum variability of flux due to seeing to identify the guide star + ag_flux_tolerance = ( + 0.3 # maximum variability of flux due to seeing to identify the guide star + ) ag_cal_offset_per_step = 3.0 # Step size for calibration in arcseconds ag_cal_num_step = 3 # number of steps of calibration per axis - - - diff --git a/python/lvmagp/etc/lvmagp.yml b/python/lvmagp/etc/lvmagp.yml index e9d59d1..844cced 100644 --- a/python/lvmagp/etc/lvmagp.yml +++ b/python/lvmagp/etc/lvmagp.yml @@ -1,8 +1,7 @@ # A dictionary of controller name to ?? sci: tel: - latitude: 37.23908 - longitude: 127.08217 + varA: null age: pixelscale: null offset_x: null @@ -20,8 +19,7 @@ sci: skye: tel: - latitude: -34.0 - longitude: 118.0 + varA: null age: pixelscale: null offset_x: null @@ -39,8 +37,7 @@ skye: skyw: tel: - latitude: -34.0 - longitude: 118.0 + varA: null age: pixelscale: null offset_x: null @@ -58,8 +55,7 @@ skyw: spec: tel: - latitude: -34.0 - longitude: 118.0 + varA: null age: pixelscale: null offset_x: null @@ -81,5 +77,5 @@ actor: name: lvmagp host: localhost port: 5672 - version: '0.2.1-alpha' + version: '0.2.3a' log_dir: './logs' \ No newline at end of file From 45c60d0fd98479bf3ddff1dd8f05cb1af798f1cb Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 10 Dec 2021 14:00:29 +0900 Subject: [PATCH 8/9] v.0.2.3a lvmtipo --- python/cluplus/__init__.py | 0 python/lvmagp/actor/actor.py | 12 +++--------- python/lvmagp/actor/commands/guide.py | 18 ++++++------------ python/lvmagp/actor/commands/slew.py | 18 ++++++------------ python/lvmagp/actor/commands/test.py | 15 +++++---------- python/lvmagp/actor/internalfunc.py | 1 - 6 files changed, 20 insertions(+), 44 deletions(-) delete mode 100644 python/cluplus/__init__.py diff --git a/python/cluplus/__init__.py b/python/cluplus/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/python/lvmagp/actor/actor.py b/python/lvmagp/actor/actor.py index d35fc94..9c8d826 100644 --- a/python/lvmagp/actor/actor.py +++ b/python/lvmagp/actor/actor.py @@ -2,15 +2,9 @@ from clu.actor import AMQPActor -from lvmagp.actor.commfunc import ( # noqa: F401 - LVMEastCamera, - LVMFibsel, - LVMFocuser, - LVMKMirror, - LVMTANInstrument, - LVMTelescope, - LVMWestCamera, -) +from lvmagp.actor.commfunc import (LVMEastCamera, LVMFibsel, # noqa: F401 + LVMFocuser, LVMKMirror, LVMTANInstrument, + LVMTelescope, LVMWestCamera) from .commands import parser as lvm_command_python diff --git a/python/lvmagp/actor/commands/guide.py b/python/lvmagp/actor/commands/guide.py index 2af9cfa..7ec4b15 100644 --- a/python/lvmagp/actor/commands/guide.py +++ b/python/lvmagp/actor/commands/guide.py @@ -1,21 +1,15 @@ +import asyncio + import click +import numpy as np from clu.command import Command -from lvmagp.actor.commfunc import ( # noqa: F401 - LVMEastCamera, - LVMFibsel, - LVMFocuser, - LVMKMirror, - LVMTANInstrument, - LVMTelescope, - LVMWestCamera, -) +from lvmagp.actor.commfunc import (LVMEastCamera, LVMFibsel, # noqa: F401 + LVMFocuser, LVMKMirror, LVMTANInstrument, + LVMTelescope, LVMWestCamera) from lvmagp.actor.internalfunc import GuideImage # noqa: F403 from lvmagp.actor.user_parameters import usrpars -import asyncio -import numpy as np - from . import parser diff --git a/python/lvmagp/actor/commands/slew.py b/python/lvmagp/actor/commands/slew.py index 5e00ecb..c9f6824 100644 --- a/python/lvmagp/actor/commands/slew.py +++ b/python/lvmagp/actor/commands/slew.py @@ -1,20 +1,14 @@ -import os import asyncio -import numpy as np +import os import click +import numpy as np from clu.command import Command -from lvmagp.actor.commfunc import ( # noqa: F401 - LVMEastCamera, - LVMFibsel, - LVMFocuser, - LVMKMirror, - LVMTANInstrument, - LVMTelescope, - LVMWestCamera, -) -from lvmagp.actor.internalfunc import check_target, cal_pa, GuideImage +from lvmagp.actor.commfunc import (LVMEastCamera, LVMFibsel, # noqa: F401 + LVMFocuser, LVMKMirror, LVMTANInstrument, + LVMTelescope, LVMWestCamera) +from lvmagp.actor.internalfunc import GuideImage, cal_pa, check_target from lvmagp.actor.user_parameters import usrpars from . import parser diff --git a/python/lvmagp/actor/commands/test.py b/python/lvmagp/actor/commands/test.py index fc54c24..21c9a2e 100644 --- a/python/lvmagp/actor/commands/test.py +++ b/python/lvmagp/actor/commands/test.py @@ -1,19 +1,14 @@ from clu.command import Command -from lvmagp.actor.commfunc import ( # noqa: F401 - LVMEastCamera, - LVMFibsel, - LVMFocuser, - LVMKMirror, - LVMTANInstrument, - LVMTelescope, - LVMWestCamera, -) +from lvmagp.actor.commfunc import (LVMEastCamera, LVMFibsel, # noqa: F401 + LVMFocuser, LVMKMirror, LVMTANInstrument, + LVMTelescope, LVMWestCamera) from lvmagp.actor.internalfunc import GuideImage -from lvmagp.actor.user_parameters import usrpars # noqa: F401 +from lvmagp.actor.user_parameters import usrpars # noqa: F401 from . import parser + # import logging # from sdsstools import get_logger diff --git a/python/lvmagp/actor/internalfunc.py b/python/lvmagp/actor/internalfunc.py index adfe485..86286cf 100644 --- a/python/lvmagp/actor/internalfunc.py +++ b/python/lvmagp/actor/internalfunc.py @@ -4,7 +4,6 @@ from datetime import datetime import numpy as np - # import matplotlib.pyplot as plt from astropy.io import fits from astropy.modeling import fitting, models From a08c5fdd78e911dc1a65e1949031565106e76c00 Mon Sep 17 00:00:00 2001 From: Hojae Ahn Date: Fri, 10 Dec 2021 14:08:39 +0900 Subject: [PATCH 9/9] delete cluplus --- python/cluplus/proxy.py | 141 ---------------------------------------- 1 file changed, 141 deletions(-) delete mode 100644 python/cluplus/proxy.py diff --git a/python/cluplus/proxy.py b/python/cluplus/proxy.py deleted file mode 100644 index 8151d0e..0000000 --- a/python/cluplus/proxy.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- -# -# @Author: Florian Briegel (briegel@mpia.de) -# @Date: 2021-08-18 -# @Filename: proxy.py -# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause) - -import asyncio -from itertools import chain -from typing import Any, Awaitable, Callable - -from clu import AMQPClient - - -class ProxyException(Exception): - """Base proxy exception""" - - def __init__(self, argv): - super(ProxyException, self).__init__(argv) - - -class ProxyPlainMessagException(ProxyException): - """Plain message formed exception string""" - - def __init__(self, *argv): - super(ProxyException, self).__init__(argv) - - -class _ProxyMethod: - __slots__ = ( - "_amqpc", - "_consumer", - "_command", - ) - - def __init__(self, amqpc, consumer, command): - self._amqpc = amqpc - self._consumer = consumer - self._command = command - - def __getattr__(self, item) -> "_ProxyMethod": - return _ProxyMethod(".".join((self._consumer, item)), func=self.func) - - async def __call__( - self, - *args, - blocking: bool = True, - callback: Callable[[Any], Awaitable[None]] = None, - timeout=1.4142, - **kwargs, - ): - opts = list(chain.from_iterable(("--" + k, v) for k, v in kwargs.items())) - command = await asyncio.wait_for( - self._amqpc.send_command( - self._consumer, self._command.lower(), *args, *opts, callback=callback - ), - timeout, - ) - return await command if blocking else command - - -class Proxy: - __slots__ = ("_consumer", "_amqpc") - - def __init__(self, consumer: str, amqpc: AMQPClient): - self._consumer = consumer - self._amqpc = amqpc - - def __getattr__(self, command) -> _ProxyMethod: - return _ProxyMethod(self._amqpc, self._consumer, command) - - -def _stringToException(errstr): - """converts a string to an exception object""" - try: - return eval(errstr) # Maybe a bad idea - code injection - - except SyntaxError: - return ProxyPlainMessagException(errstr) - - except Exception as e: - return Exception("Unexpected exception in parsing exception string", e) - - -class DictObject(object): - def __str__(self): - return str(self._dict) - - def __init__(self, d): - self._dict = d - for a, b in d.items(): - if isinstance(b, (list, tuple)): - setattr( - self, a, [DictObject(x) if isinstance(x, dict) else x for x in b] - ) - else: - setattr(self, a, DictObject(b) if isinstance(b, dict) else b) - - -async def invoke(*argv, raw=False, **kwargs): - - if len(argv) > 1: - ret = await asyncio.gather(*[asyncio.create_task(cmd) for cmd in argv]) - errors = [] - for r in ret: - hasErrors = False - if r.status.did_fail: - hasErrors = True - errors.append(_stringToException(r.replies[-1].body["error"])) - else: - errors.append(None) - if hasErrors: - raise ProxyException(errors) - if raw: - return [r.replies[-1].body for r in ret] - else: - return [DictObject(r.replies[-1].body) for r in ret] - else: - ret = await argv[0] - if ret.status.did_fail: - raise _stringToException(ret.replies[-1].body["error"]) - else: - if raw: - return ret.replies[-1].body - else: - return DictObject(ret.replies[-1].body) - - -async def unpack(cmd, *argv, **kwargs): - - ret = await invoke(cmd, raw=True) - if len(ret) == 0: - return - elif len(ret) == 1: - return list(ret.values())[ - 0 - ] # Maybe we should check if argv is not empty and throw an exception - elif len(argv) > 1: - return [ret[i] for i in argv] - else: - return list(ret.values())