Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-42690: Support Summit Observing Weeks 5-6 of 2024 #125

Merged
merged 3 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/news/DM-42690.perf.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
In ``/auxtel/latiss_wep_align.py``, change how the source selection is checked when running wep.
Instead of relying on the intra-focal image as the basis, compute the distance to the boresight and either use the source detected (if it is close enough to the bore sight) or use the source detected for the other image.
It will also raise an exception if both sources are too far from the boresight.

In ``auxtel/latiss_base_align.py``, add gains when converting from wavefront error to hexapod correction.

7 changes: 6 additions & 1 deletion python/lsst/ts/externalscripts/auxtel/latiss_base_align.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ def __init__(self, index=1, remotes=True, descr=""):
]
)

# Gains to be applied to the calculated corrections.
# These should be less than 1.
self.gain = np.array([0.5, 0.5, 0.9])

# Default values for rotator angle and rotator strategy.
self.rot = 0.0
self.rot_strategy = RotType.SkyAuto
Expand Down Expand Up @@ -308,7 +312,7 @@ def calculate_results(self) -> LatissAlignResults:
rot_zern = np.matmul(
self.zern, self.matrix_rotation(self.angle + self.camera_rotation_angle)
)
hexapod_offset = np.matmul(rot_zern, self.matrix_sensitivity)
hexapod_offset = np.matmul(rot_zern, self.matrix_sensitivity) * self.gain
tel_offset = np.matmul(hexapod_offset, self.hexapod_offset_scale)

self.log.info(
Expand All @@ -317,6 +321,7 @@ def calculate_results(self) -> LatissAlignResults:
(len(self.zern) * '{:0.1f}, ').format(*self.zern)}]
De-rotated [coma-X, coma-Y, focus] zernike coefficients [nm]: [{
(len(rot_zern) * '{:0.1f}, ').format(*rot_zern)}]
Gain: {self.gain}
Hexapod [x, y, z] offsets [mm] : {(len(hexapod_offset) * '{:0.3f}, ').format(*hexapod_offset)}
Telescope offsets [arcsec]: {(len(tel_offset) * '{:0.1f}, ').format(*tel_offset)}
==============================
Expand Down
49 changes: 38 additions & 11 deletions python/lsst/ts/externalscripts/auxtel/latiss_wep_align.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import numpy as np
import pandas
from lsst.afw.geom import SkyWcs
from lsst.geom import PointD
from lsst.pipe.base.struct import Struct

try:
Expand All @@ -38,7 +39,10 @@
from lsst.ts.observing.utilities.auxtel.latiss.getters import (
get_image_sync as get_image,
)
from lsst.ts.observing.utilities.auxtel.latiss.utils import parse_visit_id
from lsst.ts.observing.utilities.auxtel.latiss.utils import (
calculate_xy_offsets,
parse_visit_id,
)
from lsst.ts.wep.task.calcZernikesTask import (
CalcZernikesTask,
CalcZernikesTaskConfig,
Expand All @@ -52,6 +56,8 @@
warnings.warn("Cannot import required libraries. Script will not work.")


from lsst.ts.observatory.control.constants.latiss_constants import boresight

from .latiss_base_align import LatissAlignResults, LatissBaseAlign


Expand Down Expand Up @@ -136,6 +142,7 @@ def run_wep(
extra_visit_id: int,
donut_diameter: int,
timeout_get_image: float,
max_distance_from_boresight: float = 500.0,
) -> typing.Tuple[Struct, Struct, Struct]:
best_effort_isr = BestEffortIsr()

Expand Down Expand Up @@ -170,23 +177,43 @@ def run_wep(
f"Extra image ({exposure_extra}) success is {result_extra.success}."
)

dy = (
result_extra.brightestObjCentroidCofM[0]
- result_intra.brightestObjCentroidCofM[0]
dx_boresight_extra, dy_boresight_extra = calculate_xy_offsets(
PointD(
result_extra.brightestObjCentroid[0], result_extra.brightestObjCentroid[1]
),
boresight,
)
dx = (
result_extra.brightestObjCentroidCofM[1]
- result_intra.brightestObjCentroidCofM[1]
dx_boresight_intra, dy_boresight_intra = calculate_xy_offsets(
PointD(
result_intra.brightestObjCentroid[0], result_intra.brightestObjCentroid[1]
),
boresight,
)
dr = np.sqrt(dy**2 + dx**2)

position_out_of_range = dr > 100
dr_boresight_extra = np.sqrt(dx_boresight_extra**2 + dy_boresight_extra**2)
dr_boresight_intra = np.sqrt(dx_boresight_intra**2 + dy_boresight_intra**2)

extra_source_out_of_bounds = dr_boresight_extra > max_distance_from_boresight
intra_source_out_of_bounds = dr_boresight_intra > max_distance_from_boresight

donut_catalog_intra = get_donut_catalog(result_intra, exposure_intra.getWcs())
if extra_source_out_of_bounds and intra_source_out_of_bounds:
raise RuntimeError(
"Both the intra and extra images detected sources are out of bounds. "
f"Should be closer than {max_distance_from_boresight}. "
f"Got {dr_boresight_extra} and {dr_boresight_intra}."
)

donut_catalog_intra = get_donut_catalog(
*(
(result_intra, exposure_intra.getWcs())
if not intra_source_out_of_bounds
else (result_extra, exposure_extra.getWcs())
)
)
donut_catalog_extra = get_donut_catalog(
*(
(result_extra, exposure_extra.getWcs())
if position_out_of_range
if not extra_source_out_of_bounds
else (result_intra, exposure_intra.getWcs())
)
)
Expand Down
Loading