Skip to content

Commit

Permalink
Add new mtcs.mtrotator.move_rotator
Browse files Browse the repository at this point in the history
  • Loading branch information
b1quint committed Oct 20, 2023
1 parent 8f3405f commit 51c5384
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import asyncio

from lsst.ts.standardscripts.maintel.mtrotator import MoveRotator

asyncio.run(MoveRotator.amain())
22 changes: 22 additions & 0 deletions python/lsst/ts/standardscripts/maintel/mtrotator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from .move_rotator import MoveRotator
141 changes: 141 additions & 0 deletions python/lsst/ts/standardscripts/maintel/mtrotator/move_rotator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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__ = ["MoveRotator"]

import yaml
from lsst.ts.observatory.control.maintel.mtcs import MTCS

from ...base_block_script import BaseBlockScript


class MoveRotator(BaseBlockScript):
"""Move the rotator to a given angle. It has the option of completing the
script before the rotator reaches the desired angle.
Parameters
----------
index : `int`
Index of Script SAL component.
Notes
-----
**Checkpoints**
- "Start moving rotator to {angle} degrees.": Start moving rotator.
- "Stop script and keep rotator moving.": Stop script.
- "Rotator reached {angle} degrees.": Rotator reached angle.
"""

def __init__(self, index: int) -> None:
super().__init__(index=index, descr="Move Rotator")

self.mtcs = None

self.rotator_velocity = 3.5 # degrees per second
self.short_timeout = 10 # seconds
self.long_timeout = 120 # seconds

@classmethod
def get_schema(cls):
url = "https://github.com/lsst-ts/"
path = (
"ts_standardscripts/blob/main/python/lsst/ts/standardscripts/"
"maintel/mtrotator/move_rotator.py"
)
schema_yaml = f"""
$schema: http://json-schema.org/draft-07/schema#
$id: {url}{path}
title: MoveRotator v1
description: Configuration for Maintel move rotator SAL Script.
type: object
properties:
angle:
description: final angle of the rotator.
type: number
minimum: -90
maximum: 90
wait_for_complete:
description: >-
whether wait for the rotator to reach the desired angle or
complete the script before the rotator reaches the desired
angle.
type: boolean
default: true
required:
- angle
additionalProperties: false
"""
schema_dict = yaml.safe_load(schema_yaml)

base_schema_dict = super().get_schema()

for properties in base_schema_dict["properties"]:
schema_dict["properties"][properties] = base_schema_dict["properties"][
properties
]

return schema_dict

async def configure(self, config):
"""
Configure the script.
Parameters
----------
config : `dict`
Dictionary containing the configuration parameters.
"""
await self.configure_tcs()

self.target_angle = config.angle
self.wait_for_complete = config.wait_for_complete

await super().configure(config=config)

async def configure_tcs(self) -> None:
"""
Handle creating MTCS object and waiting for remote to start.
"""
if self.mtcs is None:
self.log.debug("Creating MTCS.")
self.mtcs = MTCS(
domain=self.domain,
log=self.log,
)
await self.mtcs.start_task
else:
self.log.debug("MTCS already defined, skipping.")

def set_metadata(self, metadata):
"""Set the metadata for the script."""
metadata.duration = self.long_timeout

async def run_block(self):
"""Run the script."""
await self.checkpoint(f"Start moving rotator to {self.target_angle} degrees.")
await self.mtcs.move_rotator(
angle=self.target_angle, wait_for_complete=self.wait_for_complete
)
await self.checkpoint(
f"Move rotator returned. Wait for complete: {self.wait_for_complete}."
)
118 changes: 118 additions & 0 deletions tests/test_maintel_mtrotator_move_rotator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import unittest

from lsst.ts import standardscripts
from lsst.ts.observatory.control.maintel.mtcs import MTCS, MTCSUsages
from lsst.ts.standardscripts.maintel.mtrotator import MoveRotator


class TestMoveRotator(
standardscripts.BaseScriptTestCase, unittest.IsolatedAsyncioTestCase
):
async def basic_make_script(self, index):
self.script = MoveRotator(index=index)

self.script.mtcs = MTCS(
domain=self.script.domain,
intended_usage=MTCSUsages.DryTest,
log=self.script.log,
)

self.start_angle = 0.0 # degrees
self.very_short_sleep = 0.1 # seconds
self.script.mtcs.move_rotator = unittest.mock.AsyncMock()

return (self.script,)

async def test_configure_default(self):
"""Test the default configuration"""

async with self.make_script():
target_angle = 45.0

await self.configure_script(angle=target_angle)

assert self.script.target_angle == target_angle
assert self.script.wait_for_complete is True
assert self.script.program is None
assert self.script.reason is None
assert self.script.checkpoint_message is None

async def test_configure_dont_wait_for_complete(self):
"""Test with the configuration where ``wait_for_complete`` is False"""

async with self.make_script():
target_angle = 45.0
wait_for_complete = False

await self.configure_script(angle=target_angle, wait_for_complete=False)

assert self.script.target_angle == target_angle
assert self.script.wait_for_complete is wait_for_complete
assert self.script.program is None
assert self.script.reason is None
assert self.script.checkpoint_message is None

async def test_configure_with_program_reason(self):
"""Testing a valid configuration: with program and reason"""

# Try configure with a list of valid actuators ids
async with self.make_script():
self.script.get_obs_id = unittest.mock.AsyncMock(
side_effect=["202306060001"]
)
await self.configure_script(
angle=10.0,
wait_for_complete=True,
program="BLOCK-123",
reason="SITCOM-321",
)

assert self.script.program == "BLOCK-123"
assert self.script.reason == "SITCOM-321"
assert (
self.script.checkpoint_message
== "MoveRotator BLOCK-123 202306060001 SITCOM-321"
)

async def test_run_with_default_config(self):
async with self.make_script():
target_angle = 45.0

await self.configure_script(angle=target_angle)

await self.run_script()

self.script.mtcs.move_rotator.assert_called_once_with(
angle=target_angle, wait_for_complete=True
)

async def test_executable(self):
scripts_dir = standardscripts.get_scripts_dir()
script_path = scripts_dir / "maintel" / "mtrotator" / "move_rotator.py"
print(script_path)
await self.check_executable(script_path)


if __name__ == "__main__":
unittest.main()

0 comments on commit 51c5384

Please sign in to comment.