Bases: KPFTranslatorFunction
Modify the CURRENT_BASE keyword based upon the calculated differential
atmospheric refraction value. This is NOT the recommended method for doing
this as it is now done automatically in the kpfguide
keyword service.
This script predates full functionality of kpfguide
and is being left in
place only for emergency use.
Calculation from Filippenko 1982 (PASP, 94:715-721, August 1982)
ARGS:
:EL: float
Elevation of the telescope.
Source code in kpf/utils/CorrectDAR.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | class CorrectDAR(KPFTranslatorFunction):
'''Modify the CURRENT_BASE keyword based upon the calculated differential
atmospheric refraction value. This is NOT the recommended method for doing
this as it is now done automatically in the `kpfguide` keyword service.
This script predates full functionality of `kpfguide` and is being left in
place only for emergency use.
Calculation from Filippenko 1982 (PASP, 94:715-721, August 1982)
ARGS:
=====
:EL: `float` Elevation of the telescope.
'''
@classmethod
def pre_condition(cls, args, logger, cfg):
pass
@classmethod
def perform(cls, args, logger, cfg):
kpfguide = ktl.cache('kpfguide')
dcs = ktl.cache('dcs1')
EL = dcs['EL'].read(binary=True)*180/np.pi
DARarcsec = calculate_DAR_arcsec(EL)
log.info(f"DAR is {DARarcsec:.3f} arcseconds")
dx, dy = calculate_DAR_pix(DARarcsec)
total_pix = (dx**2+dy**2)**0.5
log.info(f"Pixel shift is {dx:.1f}, {dy:.1f} = {total_pix:.1f}")
base_names = {'KPF': 'SCIENCE_BASE',
'SKY': 'SKY_BASE'}
POname = dcs['PONAME'].read()
base_name = base_names.get(POname, None)
if base_name is None:
log.error(f"dcs.PONAME={POname} is not recognized")
log.error("Leaving CURRENT_BASE unmodified")
return
# log.error(f"Using SCIENCE_BASE for testing")
# base_name = 'SCIENCE_BASE'
# Set CURRENT_BASE
log.info(f"dcs.PONAME is {POname}, using {base_name} as reference pixel")
reference_pix = list(kpfguide[base_name].read(binary=True))
log.debug(f"Initial CURRENT_BASE = {reference_pix[0]:.1f} {reference_pix[1]:.1f}")
final_pixel = [reference_pix[0] + dx, reference_pix[1] + dy]
final_pixel_string = f"{final_pixel[0]:.2f} {final_pixel[1]:.2f}"
log.debug(f"Final Pixel = {final_pixel_string}")
min_x_pixel = cfg.getint('guider', 'min_x_pixel', fallback=0)
max_x_pixel = cfg.getint('guider', 'max_x_pixel', fallback=640)
min_y_pixel = cfg.getint('guider', 'min_y_pixel', fallback=0)
max_y_pixel = cfg.getint('guider', 'max_y_pixel', fallback=512)
if final_pixel[0] < min_x_pixel or final_pixel[0] > max_x_pixel or\
final_pixel[1] < min_y_pixel or final_pixel[1] > max_y_pixel:
log.error(f"Target pixel ({final_pixel_string}) is not on guide camera")
log.error("Leaving CURRENT_BASE unmodified")
else:
log.info(f"Writing new CURRENT_BASE = {final_pixel_string}")
kpfguide['CURRENT_BASE'].write(final_pixel)
@classmethod
def post_condition(cls, args, logger, cfg):
pass
|