-
Notifications
You must be signed in to change notification settings - Fork 0
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-40956 Take Twilight Flats #146
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an initial round of comments.
python/lsst/ts/externalscripts/auxtel/latiss_take_twilight_flats.py
Outdated
Show resolved
Hide resolved
else: | ||
self.log.debug("ATCS already defined, skipping.") | ||
|
||
@property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, move this property definition so it is close to the tcs one.
python/lsst/ts/externalscripts/auxtel/latiss_take_twilight_flats.py
Outdated
Show resolved
Hide resolved
python/lsst/ts/externalscripts/maintel/take_twilight_flats_comcam.py
Outdated
Show resolved
Hide resolved
python/lsst/ts/externalscripts/maintel/take_twilight_flats_comcam.py
Outdated
Show resolved
Hide resolved
python/lsst/ts/externalscripts/maintel/take_twilight_flats_lsstcam.py
Outdated
Show resolved
Hide resolved
python/lsst/ts/externalscripts/maintel/take_twilight_flats_lsstcam.py
Outdated
Show resolved
Hide resolved
python/lsst/ts/externalscripts/maintel/take_twilight_flats_comcam.py
Outdated
Show resolved
Hide resolved
------- | ||
instrument_filter: `string` | ||
""" | ||
filter = self.config.filter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filter
is a valid python keyword:
In [1]: filter?
Init signature: filter(self, /, *args, **kwargs)
Docstring:
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.
Please, don't shadow it here. Just use self.config.filter
directly, you are not really gaining anything by doing this.
python/lsst/ts/externalscripts/auxtel/latiss_take_twilight_flats.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here some additional comments.
Also, it looks like the unit tests are failing because sumit_utils
is not available in the container. You can make it available by adding lsst-sitcom/summit_utils
to the list of extra_packages in the Jenkinsfile.
|
||
return schema_dict | ||
|
||
@abc.abstractmethod |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider having all the abstract method defined close together.
raise NotImplementedError() | ||
|
||
async def offset_telescope(self): | ||
"""Abstract method to dither the camera if desired.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix docstring.
|
||
await super().configure(config) | ||
|
||
self.client = self.make_consdb_client() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this method defined anywhere here. Also, you already defined self.client = ConsDbClient()
during initialization.
raise NotImplementedError() | ||
|
||
@abc.abstractmethod | ||
def get_instrument_filter(self) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure all the abstract methods are defined together.
# Take one 1s flat to calibrate the exposure time | ||
self.log.info("Taking 1s flat to calibrate exposure time.") | ||
exp_time = 1 | ||
await self.camera.take_flats( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be a take_acq
instead? We probably don't want to use this image for flat field right?
exp_time = self.get_new_exptime(sky_counts, exp_time) | ||
|
||
if exp_time > self.config.max_exp_time: | ||
raise Exception( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really a fail condition? it probably means the sky is too dark to take sky flats right?
I would suggest logging it as a warning and returning or break the loop. If you want to fail the script, please, raise RuntimeError
instead of Exception
.
if np.abs(self.config.dither) > 0: | ||
self.offset_telescope() | ||
|
||
await self.camera.take_flats( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to add support for sky flat type in the camera.
) | ||
|
||
if (where_sun < self.config.min_sun) or (where_sun > self.config.max_sun): | ||
raise Exception( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, don't raise Exception
... either use RuntimeError
or, in this case, an AssertionError
.
|
||
return coords[arg] | ||
|
||
def confirm_sun_location(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming this method to assert_sun_location
and then raise an AssertionError
if the sun is not in the limits.
34d630a
to
ec3ebd8
Compare
raise NotImplementedError() | ||
|
||
@abc.abstractmethod | ||
async def setup_instrument(self, ra, dec) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you rename this method to something that reflects what it is supposed to do now? maybe track_radec_and_setup_instrument
? Also, you are not passing the instrument configuration, so, consider using the same strategy for ra and dec, in which case, I would suggest a name like track_and_setup_instrument
|
||
@abc.abstractmethod | ||
async def setup_instrument(self, ra, dec) -> str: | ||
"""Abstract method to set the instrument filter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is also doing the slew/tracking now.
|
||
async def offset_telescope(self): | ||
"""Dither the camera between exposures if desired.""" | ||
await self.atcs.offset_azel( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
atcs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is another round of comments..
timeout = 30 | ||
query = f"SELECT * from cbd_latiss.visit1_quicklook where exposure_id = {self.latest_exposure_id}" | ||
item = "post_isr_pixel_median" | ||
sky_counts = self.client.wait_for_item_in_row(query, item, timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a regular method and not a coroutine, you will need to run this in an executor. It should be something like this:
First, at the top:
import functools
then here you would do:
get_sky_counts = functools.partial(self.client.wait_for_item_in_row, query, item, timeout)
sky_counts = await asyncio.get_running_loop().run_in_executor(
None, get_sky_counts
)
you might want to find the name of the parameters you are passing to wait_for_item_in_row
and use them instead of relying on their ordering, e.g.:
get_sky_counts = functools.partial(self.client.wait_for_item_in_row, query=query, item=item, timeout=timeout)
note that I don't know if the names are correct, I just guessing.
|
||
return schema_dict | ||
|
||
async def offset_telescope(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like you can remove this method and just use the call inline.
f" The elevation of the Sun is {sun_coordinates[1]:.2f} deg" | ||
) | ||
|
||
if (sun_coordinates[1] < self.config.min_sun_elevation) or ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor detail, but you can make this in a single statement with:
assert (sun_coordinates[1] < self.config.min_sun_elevation) or (sun_coordinates[1] > self.config.max_sun_elevation), f"Sun elevation {sun_coordinates} is outside appropriate elvation limits. Aborting."
sun_coordinates[1] > self.config.max_sun_elevation | ||
): | ||
raise AssertionError( | ||
f"Sun elevation {sun_coordinates} is outside appropriate elvation limits. Aborting." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a typo in "elvation" -> "elevation". But also, consider removing "Aborting" at the end and also logging what are the conditions. Something like:
f"Sun elevation {sun_coordinates[1]} is outside appropriate limits. "
f"Must be below {self.config.min_sun_elevation} or above {self.config.max_sun_elevation}."
|
||
return target_radec | ||
|
||
def get_empty_field(self, target, radius=5): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to convert this method to a coroutine and run the query in an executor (see below).
Otherwise calling this will block the async event loop and will look like the script has died.
dec=self.config.dec, | ||
) | ||
), | ||
asyncio.create_task(self._wait_rotator_reach_filter_change_angle()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need this.
asyncio.create_task( | ||
self.mtcs.slew_icrs( | ||
ra=self.config.ra, | ||
dec=self.config.dec, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to pass rot_type=RotType.Physical
.
|
||
await self.lsstcam.setup_filter(filter=self.config.band_filter) | ||
|
||
async def _wait_rotator_reach_filter_change_angle(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this.
try: | ||
from lsst.summit.utils import ConsDbClient | ||
|
||
CONSDB_AVAILABLE = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing this, consider mocking the behavior. For example, take a look at: https://github.com/lsst-ts/ts_standardscripts/blob/65fd9b9e57cdb0ef93a658f99f89975708767c32/tests/test_base_block_script.py#L76-L78
You can mock the behavior of method calls by patching them.
self.mtcs.slew_icrs( | ||
ra=self.config.ra, | ||
dec=self.config.dec, | ||
rot_type=RotType.PhysicalSky, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one needs to be RotType.Physical
instead. this will ensure the rotator is kept at the fixed position.
ad98282
to
c227238
Compare
31694f7
to
b43f822
Compare
6c8ded4
to
9ae2427
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes approved in the interest of getting these merged. Expect some improvement after on-sky testing with ComCam.
No description provided.