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

Tickets/DM-46864: Take AOS Sequence #230

Merged
merged 3 commits into from
Oct 19, 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
1 change: 1 addition & 0 deletions doc/news/DM-46864.perf.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update `take_triplet_comcam` to `take_aos_sequence_comcam.py` to allow for doublets and triplets.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@

import asyncio

from lsst.ts.standardscripts.maintel import TakeTripletComCam
from lsst.ts.standardscripts.maintel import TakeAOSSequenceComCam

asyncio.run(TakeTripletComCam.amain())
asyncio.run(TakeAOSSequenceComCam.amain())
2 changes: 1 addition & 1 deletion python/lsst/ts/standardscripts/maintel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@
from .standby_mtcs import *
from .stop import *
from .stop_rotator import *
from .take_aos_sequence_comcam import *
from .take_image_anycam import *
from .take_image_comcam import *
from .take_image_lsstcam import *
from .take_stuttered_comcam import *
from .take_stuttered_lsstcam import *
from .take_triplet_comcam import *
from .track_target import *
from .track_target_and_take_image_comcam import *
from .track_target_and_take_image_gencam import *
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

__all__ = ["TakeTripletComCam"]
__all__ = ["TakeAOSSequenceComCam", "Mode"]

import asyncio
import enum
import json
import types

Expand All @@ -33,9 +34,16 @@
from ..base_block_script import BaseBlockScript


class TakeTripletComCam(BaseBlockScript):
"""Take triplet (intra-focal, extra-focal and in-focus images)
sequence with ComCam.
class Mode(enum.IntEnum):
TRIPLET = enum.auto()
INTRA = enum.auto()
EXTRA = enum.auto()


class TakeAOSSequenceComCam(BaseBlockScript):
"""Take aos sequence, either triplet (intra-focal, extra-focal
and in-focus images), intra doublets (intra and in-focus) or extra
doublets (extra and in-focus) sequences with ComCam.

Parameters
----------
Expand All @@ -46,25 +54,26 @@ class TakeTripletComCam(BaseBlockScript):
-----
**Checkpoints**

* triplet {n} of {m}: before taking a triplet.
* sequence {n} of {m}: before taking a sequence.

"""

def __init__(self, index, descr="Take triplet with ComCam.") -> None:
def __init__(self, index, descr="Take AOS sequence with ComCam.") -> None:
super().__init__(index=index, descr=descr)

self.config = None
self.mtcs = None
self.camera = None
self.ocps = None
self.current_z_position = 0

@classmethod
def get_schema(cls) -> dict:
schema_yaml = """
schema_yaml = f"""
$schema: http://json-schema.org/draft-07/schema#
$id: https://github.com/lsst-ts/ts_standardscripts/maintel/TakeTripletComCam.yaml
title: TakeTripletComCam v1
description: Configuration for TakeTripletComCam.
$id: https://github.com/lsst-ts/ts_standardscripts/maintel/TakeAOSSequenceComCam.yaml
title: TakeAOSSequenceComCam v1
description: Configuration for TakeAOSSequenceComCam.
type: object
properties:
filter:
Expand All @@ -83,15 +92,21 @@ def get_schema(cls) -> dict:
description: De-focus to apply when acquiring the intra/extra focal images (microns).
type: number
default: 1500.
n_triplets:
description: Number of triplets.
n_sequences:
description: Number of aos sequences.
type: integer
default: 1
mode:
description: >-
Mode of operation. Options are 'triplet' (default), 'intra' or 'extra'.
type: string
default: TRIPLET
enum: {[mode.name for mode in Mode]}
program:
description: >-
Optional name of the program this dataset belongs to.
type: string
default: TRIPLET
default: AOSSEQUENCE
reason:
description: Optional reason for taking the data.
anyOf:
Expand Down Expand Up @@ -152,7 +167,9 @@ async def configure(self, config: types.SimpleNamespace) -> None:
self.dz = config.dz

# Set maximum number of iterations
self.n_triplets = config.n_triplets
self.n_sequences = config.n_sequences

self.mode = getattr(Mode, config.mode)

# Set program, reason and note
self.program = config.program
Expand All @@ -169,12 +186,13 @@ def set_metadata(self, metadata: salobj.type_hints.BaseMsgType) -> None:
directly.
"""
# Estimated duration is maximum number of iterations multiplied by
# 3 (data triplet) multiplied by the time it takes to take an image
# 3 or 2 multiplied by the time it takes to take an image
# plus estimation on reading out the images (10s)
number_of_images = 3 if self.mode == Mode.TRIPLET else 2

metadata.duration = (
self.n_triplets
* 3
self.n_sequences
* number_of_images
* (
self.exposure_time
+ self.camera.read_out_time
Expand Down Expand Up @@ -224,67 +242,69 @@ async def configure_tcs(self) -> None:
else:
self.log.debug("MTCS already defined, skipping.")

async def take_triplet(
self,
) -> None:
"""Take triplet (intra focal, extra focal and in-focus)
image sequence.
"""
self.log.debug("Moving to intra-focal position")

await self.mtcs.offset_camera_hexapod(x=0, y=0, z=self.dz, u=0, v=0)

self.log.info("Taking intra-focal image")

async def take_aos_sequence(self) -> None:
"""Take out-of-focus sequence images."""
supplemented_group_id = self.next_supplemented_group_id()

intra_visit_id = await self.camera.take_cwfs(
exptime=self.exposure_time,
n=1,
group_id=supplemented_group_id,
filter=self.filter,
reason="INTRA" + ("" if self.reason is None else f"_{self.reason}"),
program=self.program,
note=self.note,
)
if self.mode == Mode.TRIPLET or self.mode == Mode.INTRA:
self.log.debug("Moving to intra-focal position")

# Move the hexapod to the target z position
z_offset = self.dz - self.current_z_position
await self.mtcs.offset_camera_hexapod(x=0, y=0, z=z_offset, u=0, v=0)
self.current_z_position = self.dz

self.log.info("Taking in-focus image")
intra_visit_id = await self.camera.take_cwfs(
exptime=self.exposure_time,
n=1,
group_id=supplemented_group_id,
filter=self.filter,
reason="INTRA" + ("" if self.reason is None else f"_{self.reason}"),
program=self.program,
note=self.note,
)

self.log.debug("Moving to extra-focal position")
if self.mode == Mode.TRIPLET or self.mode == Mode.EXTRA:
self.log.debug("Moving to extra-focal position")

# Hexapod offsets are relative, so need to move 2x the offset
# to get from the intra- to the extra-focal position.
z_offset = -(self.dz * 2.0)
await self.mtcs.offset_camera_hexapod(x=0, y=0, z=z_offset, u=0, v=0)
# Move the hexapod to the target z position
z_offset = -self.dz - self.current_z_position
await self.mtcs.offset_camera_hexapod(x=0, y=0, z=z_offset, u=0, v=0)
self.current_z_position = -self.dz

self.log.info("Taking extra-focal image")
self.log.info("Taking extra-focal image")

extra_visit_id = await self.camera.take_cwfs(
exptime=self.exposure_time,
n=1,
group_id=supplemented_group_id,
filter=self.filter,
reason="EXTRA" + ("" if self.reason is None else f"_{self.reason}"),
program=self.program,
note=self.note,
)
extra_visit_id = await self.camera.take_cwfs(
exptime=self.exposure_time,
n=1,
group_id=supplemented_group_id,
filter=self.filter,
reason="EXTRA" + ("" if self.reason is None else f"_{self.reason}"),
program=self.program,
note=self.note,
)

self.log.info("Send processing request to RA OCPS.")
config = {
"LSSTComCamSim-FROM-OCS_DONUTPAIR": f"{intra_visit_id[0]},{extra_visit_id[0]}"
}
ocps_execute_task = asyncio.create_task(
self.ocps.cmd_execute.set_start(
config=json.dumps(config),
timeout=self.camera.fast_timeout,
if self.mode == Mode.TRIPLET:
self.log.info("Send processing request to RA OCPS.")
config = {
"LSSTComCamSim-FROM-OCS_DONUTPAIR": f"{intra_visit_id[0]},{extra_visit_id[0]}"
}
ocps_execute_task = asyncio.create_task(
self.ocps.cmd_execute.set_start(
config=json.dumps(config),
timeout=self.camera.fast_timeout,
)
)
)

self.log.debug("Moving to in-focus position")

# Move the hexapod back to in focus position
await self.mtcs.offset_camera_hexapod(x=0, y=0, z=self.dz, u=0, v=0)
# Move the hexapod to the target z position
z_offset = -self.current_z_position
await self.mtcs.offset_camera_hexapod(x=0, y=0, z=z_offset, u=0, v=0)
self.current_z_position = 0

self.log.info("Taking in-focus image")

await self.camera.take_acq(
exptime=self.exposure_time,
n=1,
Expand All @@ -295,17 +315,18 @@ async def take_triplet(
note=self.note,
)

try:
await ocps_execute_task
except Exception:
self.log.exception("Executing OCPS task failed. Ignoring.")
if self.mode == Mode.TRIPLET:
try:
await ocps_execute_task
except Exception:
self.log.exception("Executing OCPS task failed. Ignoring.")

async def run_block(self) -> None:
"""Execute script operations."""
await self.assert_feasibility()

for i in range(self.n_triplets):
self.log.info(f"Starting triplet {i+1} of {self.n_triplets}")
await self.checkpoint(f"triplet {i+1} of {self.n_triplets}")
for i in range(self.n_sequences):
self.log.info(f"Starting aos sequence {i+1} of {self.n_sequences}")
await self.checkpoint(f"out-of-focus sequence {i+1} of {self.n_sequences}")

await self.take_triplet()
await self.take_aos_sequence()
Loading
Loading