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

Move dark attribute from MetaAttribute to property #280

Merged
merged 3 commits into from
Feb 19, 2019
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
3 changes: 0 additions & 3 deletions proseco/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@ def _get_aca_catalog(**kwargs):
aca.set_stars(filter_near_fov=False)
kwargs.pop('stars', None)

# Share a common dark map for memory / processing
kwargs['dark'] = aca.dark

aca.log('Starting get_acq_catalog')
aca.acqs = get_acq_catalog(stars=aca.stars, **kwargs)

Expand Down
61 changes: 36 additions & 25 deletions proseco/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
from Ska.quatutil import radec2yagzag, yagzag2radec
import agasc
from Quaternion import Quat
from mica.archive.aca_dark import get_dark_cal_image

from . import characteristics as ACA

# For testing this is used to cache fid tables for a detector
FIDS_CACHE = {}
APL = AcaPsfLibrary()

# Cache recently retrieved images which are called with the same args/kwargs
get_dark_cal_image = functools.lru_cache(maxsize=6)(get_dark_cal_image)


def yagzag_to_radec(yag, zag, att):
"""
Expand Down Expand Up @@ -263,6 +267,7 @@ class AliasAttribute:
The <subclass> name is the lower case version of everything before
``Table`` in the subclass name, so GuideTable => 'guide'.
"""

def __get__(self, instance, owner):
if instance is None:
# When called without an instance, return self to allow access
Expand Down Expand Up @@ -514,7 +519,7 @@ class ACACatalogTable(BaseCatalogTable):
name = 'aca_cat'

# Catalog attributes, gets set in MetaAttribute or AliasAttribute
allowed_kwargs = set()
allowed_kwargs = set(['dark'])

required_attrs = ('dither_acq', 'dither_guide', 'date')

Expand All @@ -532,7 +537,6 @@ class ACACatalogTable(BaseCatalogTable):
detector = MetaAttribute()
sim_offset = MetaAttribute()
focus_offset = MetaAttribute()
dark = MetaAttribute(pickle=False)
stars = MetaAttribute(pickle=False)
include_ids_acq = IntListMetaAttribute(default=[])
include_halfws_acq = IntListMetaAttribute(default=[])
Expand All @@ -544,6 +548,34 @@ class ACACatalogTable(BaseCatalogTable):
print_log = MetaAttribute(default=False)
log_info = MetaAttribute(default={}, is_kwarg=False)

@property
def dark(self):
if hasattr(self, '_dark'):
return self._dark

# Dark current map handling. If asking for `dark` attribute without having set
# it then auto-fetch from mica. Note that get_dark_cal_image caches returned values
# using LRU cache on all params, so this is efficient for the different
# catalog tables.
self.log(f'Getting dark cal image at date={self.date} t_ccd={self.t_ccd:.1f}')
self.dark = get_dark_cal_image(date=self.date, select='before',
t_ccd_ref=self.t_ccd,
aca_image=True)
return self._dark

@dark.setter
def dark(self, value):
if not isinstance(value, ACAImage):
assert value.shape == (1024, 1024)
value = ACAImage(value, row0=-512, col0=-512, copy=False)

self._dark = value

# Set pixel regions from ACA.bad_pixels to have acqs.dark=700000 (5.0 mag
# star) per pixel.
for r0, r1, c0, c1 in ACA.bad_pixels:
self._dark.aca[r0:r1 + 1, c0:c1 + 1] = ACA.bad_pixel_dark_current

def set_attrs_from_kwargs(self, **kwargs):
for name, val in kwargs.items():
if name in self.allowed_kwargs:
Expand Down Expand Up @@ -609,29 +641,6 @@ def set_attrs_from_kwargs(self, **kwargs):
if not isinstance(dither, ACABox):
setattr(self, dither_attr, ACABox(dither))

# Dark current map handling. Either get from mica archive or from
# kwarg input.
if self.dark is None:
from mica.archive.aca_dark import get_dark_cal_image
self.log(f'Getting dark cal image at date={self.date} t_ccd={self.t_ccd:.1f}')
self.dark = get_dark_cal_image(date=self.date, select='before',
t_ccd_ref=self.t_ccd, aca_image=True)
elif not isinstance(self.dark, ACAImage):
self.dark = ACAImage(self.dark, row0=-512, col0=-512, copy=False)

# Set pixel regions from ACA.bad_pixels to have acqs.dark=700000 (5.0 mag
# star) per pixel.
self.set_bad_pixels_in_dark()

def set_bad_pixels_in_dark(self):
"""
Set pixel regions from ACA.bad_pixels to have acqs.dark=700000 (5.0 mag
star) per pixel. This will effectively spoil any star or fid.

"""
for r0, r1, c0, c1 in ACA.bad_pixels:
self.dark.aca[r0:r1 + 1, c0:c1 + 1] = ACA.bad_pixel_dark_current

def set_stars(self, acqs=None, filter_near_fov=True):
"""Set the object ``stars`` attribute to an appropriate StarsTable object.

Expand Down Expand Up @@ -891,6 +900,7 @@ def has_column_spoiler(self, cand, stars, mask=None):
else:
return False


# AGASC columns not needed (at this moment) for acq star selection.
# Change as needed.
AGASC_COLS_DROP = [
Expand Down Expand Up @@ -967,6 +977,7 @@ def get_logger(logger):
else:
def null_logger(*args, **kwargs):
pass

return null_logger

def get_catalog_for_plot(self):
Expand Down
22 changes: 22 additions & 0 deletions proseco/tests/test_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,28 @@ def offset(id, drow, dcol, dmag, rmult=1):
assert aca.acqs['id'].tolist() == [101, 102, 103, 104]


def test_dark_property():
"""
Test that in the case of a common t_ccd, all the dark current maps are
actually the same object.

:return: None
"""
aca = get_aca_catalog(**STD_INFO)
for attr in ('acqs', 'guides', 'fids'):
assert aca.dark is getattr(aca, attr).dark

kwargs = STD_INFO.copy()
del kwargs['t_ccd']
kwargs['t_ccd_acq'] = -12.5
kwargs['t_ccd_guide'] = -11.5
aca = get_aca_catalog(**kwargs)
assert aca.dark is aca.guides.dark
assert aca.dark is aca.fids.dark
assert aca.dark is not aca.acqs.dark
assert aca.dark.mean() > aca.acqs.dark.mean()


def test_dense_star_field_regress():
"""
Test getting stars at the most dense star field in the sky. Taken from:
Expand Down