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 47381: Support Summit Observing Weeks 45-46 of 2024 #161

Merged
merged 10 commits into from
Nov 19, 2024
Merged
1 change: 1 addition & 0 deletions doc/news/DM-47381.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In maintel/parameter_march_comcam, wait for extra visit to be ingested before requesting OCSP processing.
1 change: 1 addition & 0 deletions doc/news/DM-47381.feature.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In maintel/tma/random_walk_and_take_image_gencam.py, add get_instrument_name method.
6 changes: 6 additions & 0 deletions doc/news/DM-47381.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
In base_take_twilight_flats.py:
- Make rotator angle configurable.
- Allow ignoring mtdome.
- increase number of darks at end of twilight base_take_twilight_flats.
- increase consdb polling timeout.
- add option to give twilight flats a pointing.
76 changes: 59 additions & 17 deletions python/lsst/ts/externalscripts/base_take_twilight_flats.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ def get_schema(cls):
min_exp_time:
description: Minimum exposure time allowed.
type: number
minimum: 0.1
default: 1.0
min_sun_elevation:
description: Lowest position of sun in degrees at which twilight flats can be taken.
Expand All @@ -238,10 +239,22 @@ def get_schema(cls):
minimum: 0.0
maximum: 90.0
default: 45.0
target_az:
description: Target azimuth for sky flats.
type: number
default: 90
point_directly:
description: If True, point at target az el. If False, point relative to sun.
type: boolean
default: False
tracking:
description: If True, track sky. If False, keep az and el constant.
type: boolean
default: True
rotator_angle:
description: Rotator angle in degrees relative to physical sky.
type: number
default: 0
ignore:
description: >-
CSCs from the camera group to ignore in status check.
Expand Down Expand Up @@ -282,6 +295,9 @@ async def configure(self, config: types.SimpleNamespace):
if comp in self.camera.components_attr:
self.log.debug(f"Ignoring Camera component {comp}.")
setattr(self.camera.check, comp, False)
elif comp in ["mtdome", "mtdometrajectory"]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why make it only mtdome and mtdometrajectory? shouldn't this be

elif comp in self.tcs.components_attr:

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea here was that we only wanted to allow the option to ignore the mtdome and mtdometrajectory componets. For example, if a user ignored the mtmount, mtdome, and mtdometrajectory, we were worried it would leave open the option for the telescope to be pointed in the direction of the sun while taking data.

self.log.debug(f"Ignoring dome component {comp}.")
setattr(self.tcs.check, comp, False)
else:
self.log.warning(
f"Component {comp} not in CSC Group. "
Expand Down Expand Up @@ -355,9 +371,26 @@ def get_target_radec(self):
target ra dec
"""

min_sun_distance = 60

az_sun, el_sun = self.tcs.get_sun_azel()

target_az = (az_sun + self.config.distance_from_sun) % 360
if self.config.point_directly:
if np.abs(az_sun - (self.config.target_az % 360)) < min_sun_distance:
raise RuntimeError(
f"Distance from sun {az_sun - (self.config.target_az % 360)} is "
f"less than {min_sun_distance}. Stopping."
)

target_az = self.config.target_az
else:
if np.abs(self.config.distance_from_sun) < min_sun_distance:
raise RuntimeError(
f"Distance from sun {self.config.distance_from_sun} is less than {min_sun_distance}. "
"Stopping."
)

target_az = (az_sun + self.config.distance_from_sun) % 360

target_radec = self.tcs.radec_from_azel(target_az, self.config.target_el)

Expand Down Expand Up @@ -452,8 +485,8 @@ def assert_sun_location(self):
sun_coordinates[1] > self.config.max_sun_elevation
):
raise RuntimeError(
f"Sun elevation {sun_coordinates} is outside appropriate elevation limits. \
Must be above {self.config.min_sun_elevation} or below {self.config.max_sun_elevation}."
f"Sun elevation {sun_coordinates} is outside appropriate elevation limits. "
f"Must be above {self.config.min_sun_elevation} or below {self.config.max_sun_elevation}."
)

async def take_twilight_flats(self):
Expand All @@ -477,8 +510,10 @@ async def take_twilight_flats(self):
await self.slew_azel_and_setup_instrument(az, self.config.target_el)

# Take one 1s flat to calibrate the exposure time
self.log.info("Taking 1s flat to calibrate exposure time.")
exp_time = 1
self.log.info(
f"Taking {self.config.min_exp_time}s flat to calibrate exposure time."
)
exp_time = self.config.min_exp_time
# TODO: change from take_acq to take_sflat (DM-46675)
flat_image = await self.camera.take_acq(
exptime=exp_time,
Expand All @@ -495,7 +530,6 @@ async def take_twilight_flats(self):
i = 0

while i < self.config.n_flat:

# TODO: make consistent with LATISS and comcam
sky_counts = await self.get_sky_counts()
self.log.info(
Expand All @@ -506,18 +540,27 @@ async def take_twilight_flats(self):

if exp_time > self.config.max_exp_time:
self.log.warning(
f"Calculated exposure time {exp_time} above max exposure time \
{self.config.max_exp_time} s. Taking images with exposure \
time {self.config.max_exp_time}."
f"Calculated exposure time {exp_time} above max exposure time "
f"{self.config.max_exp_time} s. Taking images with exposure "
f" time {self.config.max_exp_time}."
)
exp_time = self.config.max_exp_time

if exp_time < self.config.min_exp_time:
self.log.warning(
f"Calculated exposure time {exp_time} below min exposure time \
{self.config.min_exp_time}. Stopping."
)
break
if self.where_sun == "setting":
sleep_time = 30
self.log.warning(
f"Calculated exposure time {exp_time} below min exposure time "
f"{self.config.min_exp_time}. Waiting {sleep_time}s."
)
await asyncio.sleep(sleep_time)
continue
else:
self.log.warning(
f"Calculated exposure time {exp_time} below min exposure time "
f"{self.config.min_exp_time}. Stopping."
)
break

await self.checkpoint(
f"Taking flat {i+1} of {self.config.n_flat} with exposure time {exp_time}."
Expand Down Expand Up @@ -555,7 +598,6 @@ async def take_twilight_flats(self):
nrepeats = 4

for k in range(nrepeats):

if np.abs(self.config.dither) > 0:
await self.tcs.offset_azel(
az=self.config.dither,
Expand All @@ -581,8 +623,8 @@ async def take_twilight_flats(self):
self.assert_sun_location()

await self.camera.take_darks(
exptime=30,
ndarks=2,
exptime=15,
ndarks=40,
group_id=self.group_id,
program=self.program,
reason=self.reason,
Expand Down
11 changes: 11 additions & 0 deletions python/lsst/ts/externalscripts/maintel/parameter_march_comcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def __init__(self, index, descr="Perform a parameter march with ComCam.") -> Non

self.instrument_name = "LSSTComCam"

self.max_image_in_oods_retries = 9

@property
def camera(self):
return self.comcam
Expand Down Expand Up @@ -110,6 +112,7 @@ async def take_images(

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

self.camera.rem.ccoods.evt_imageInOODS.flush()
extra_visit_id = await self.camera.take_cwfs(
exptime=self.config.exp_time,
n=1,
Expand All @@ -118,6 +121,14 @@ async def take_images(
reason="EXTRA" + ("" if self.reason is None else f"_{self.reason}"),
program=self.config.program,
)
self.log.info("Waiting for data to be ingested by OODS.")
for _ in range(self.max_image_in_oods_retries):
try:
await self.camera.rem.ccoods.evt_imageInOODS.next(
flush=False, timeout=self.camera.long_timeout
)
except asyncio.TimeoutError:
break

self.log.info("Send processing request to RA OCPS.")
config = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async def get_sky_counts(self) -> float:
float
Sky counts in electrons.
"""
timeout = 30
timeout = 60
detector_num = 4
ccd_exp_id = computeCcdExposureId(
"LSSTComCam", self.latest_exposure_id, detector_num
Expand Down Expand Up @@ -179,9 +179,15 @@ async def track_radec_and_setup_instrument(self, ra, dec):
dec : float
Dec of target field.
"""
current_filter = await self.comcam.get_current_filter()

self.tracking_started = True
await self.mtcs.slew_icrs(
ra=ra,
dec=dec,
rot_type=RotType.Physical,
rot=0,
)

current_filter = await self.comcam.get_current_filter()

if current_filter != self.config.filter:
self.log.debug(
Expand All @@ -197,8 +203,11 @@ async def track_radec_and_setup_instrument(self, ra, dec):
ra=ra,
dec=dec,
rot_type=RotType.PhysicalSky,
rot=self.config.rotator_angle,
)

self.tracking_started = True

async def slew_azel_and_setup_instrument(self, az, el):
"""Abstract method to set the instrument. Change the filter
and slew and track target.
Expand All @@ -225,6 +234,7 @@ async def slew_azel_and_setup_instrument(self, az, el):
await self.mtcs.point_azel(
az=az,
el=el,
rot_tel=self.config.rotator_angle,
)

async def configure(self, config):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def __init__(self, index, add_remotes: bool = True):
RandomWalk.get_azel_random_walk,
)

self.instrument_name = "GenCam"

async def _take_data(self):
"""Takes data with all the generic cameras"""
for i in range(self.config.num_exp):
Expand Down Expand Up @@ -118,6 +120,9 @@ async def assert_feasibility(self):
self.tcs.assert_all_enabled(), self.tcs.assert_liveliness(), *tasks
)

def get_instrument_name(self):
return self.instrument_name

async def configure(self, config):
"""Configure the script.

Expand Down
Loading