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

Improve roll options including uniform sampling of roll range #106

Merged
merged 28 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8bbc9ec
Experiment: allow uniform sampling of roll range
taldcroft Mar 2, 2019
7758ec5
Add max_roll_dev parameter
taldcroft Mar 8, 2019
125b35a
Allow setting AcaReviewTable target offset and use it in roll opt
taldcroft May 14, 2020
6b81a1a
WIP hybrid roll option selection including uniform
taldcroft May 14, 2020
8b6e918
Get multi-method roll options working, passing tests
taldcroft May 15, 2020
e90e1b1
Document max_roll_dev as roll opt arg
taldcroft May 15, 2020
e8814ea
Add test of uniform roll opt selection
taldcroft May 15, 2020
b959370
Remove useless comment
taldcroft May 15, 2020
a62476f
Add ids0 to list of roll intervals and fix most tests
taldcroft May 15, 2020
5ffdd66
Passing all tests now
taldcroft May 15, 2020
d49c2d6
Factor out improve_metric function
taldcroft May 15, 2020
15fc83a
Sort roll and limit max number of roll options
taldcroft May 15, 2020
e42e627
Use target_offset from proseco
taldcroft May 15, 2020
52cd8fc
Update flake8 workflow
taldcroft Jun 14, 2020
b66ef97
Fix a previously-wrong regression test
taldcroft Jun 15, 2020
2dfd481
Fix missed change to use target offset in review catalogs
taldcroft Jun 15, 2020
5e270dd
Clean up printing
taldcroft Jun 15, 2020
7eebf23
Always apply sort and limit of roll options
taldcroft Jun 22, 2020
c465502
Improve run_aca_review docstring
taldcroft Jun 22, 2020
d487ab9
Increase default max_roll_options to 20
taldcroft Jun 22, 2020
72549a3
Make default d_roll be 0.25 for uniq_ids and 0.5 for uniform
taldcroft Jun 22, 2020
e2096c5
Do the uniform roll search only for OR's
taldcroft Jun 22, 2020
fc3834b
Add roll options method to HTML pages
taldcroft Jun 22, 2020
bb92d4e
Check for n_guide < 2 before checking box size
taldcroft Jun 25, 2020
bcb7b6d
Change default max_roll_options to 10
taldcroft Jul 29, 2020
d1f3fed
Improve roll processing loud outputs
taldcroft Jul 29, 2020
4ecd4f3
Chasing perfection
taldcroft Jul 29, 2020
aeca786
Fix test issues from table ordering and change to default d_roll
taldcroft Jul 29, 2020
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
6 changes: 3 additions & 3 deletions .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ jobs:

steps:
- uses: actions/checkout@v1
- name: Set up Python 3.6
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.6
python-version: 3.8
- name: Lint with flake8
run: |
pip install flake8
flake8 . --count --ignore=W504,E402,F541 --max-line-length=100 --show-source --statistics
flake8 . --count --ignore=W503,E402,F541 --max-line-length=100 --show-source --statistics
103 changes: 91 additions & 12 deletions sparkles/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ def main(sys_args=None):


def run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=None,
report_level='none', roll_level='none', loud=False, obsids=None,
open_html=False, context=None, raise_exc=True):
report_level='none', roll_level='none', roll_args=None,
loud=False, obsids=None, open_html=False, context=None, raise_exc=True):
"""Do ACA load review based on proseco pickle file from ORviewer.

The ``load_name`` specifies the pickle file from which the ``ACATable``
Expand Down Expand Up @@ -110,13 +110,40 @@ def run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=Non
default is "none", meaning no reports are generated. A final option is
"all" which generates a report for every obsid.

The ``roll_level`` arg specifies the message category at which the review
process will also attempt to find and report on available star catalogs for
different roll options. The available categories are the same as for
``report_level``, with the most common choice being "critical".

The ``roll_args`` arg specifies an optional dict of arguments used in the
call to the ``get_roll_options`` method. Possible args include:

- ``min_improvement``: min value of improvement metric to accept option
(default=0.3)
- ``d_roll``: delta roll for sampling available roll range (deg, default=0.25
for uniq_ids method and 0.5 for uniform method)
- ``max_roll_dev``: maximum roll deviation (deg, default=max allowed by pitch)
- ``method``: method for determining roll intervals ('uniq_ids' | 'uniform').
The 'uniq_ids' method is a faster method that frequently finds an acceptable
roll option, while 'uniform' is a brute-force search of the entire roll
range at ``d_roll`` increments. If not provided, the default is to try
*both* methods in order, stopping when an acceptable option is found.
- ``max_roll_options``: maximum number of roll options to return (default=10)

If roll options are returned then they are sorted by the following keys:

- Number of warnings at ``roll_level`` or worse (e.g. number of criticals)
in ascending order (fewer is better)
- Improvement in descending order (larger improvement is better)

:param load_name: name of loads
:param acars: list of ACAReviewTable objects (optional)
:param make_html: make HTML output report
:param open_html: open the HTML output in default web brower
:param report_dir: output directory
:param report_level: report level threshold for generating acq and guide report
:param roll_level: level threshold for suggesting alternate rolls
:param roll_args: None or dict of arguments for ``get_roll_options``
:param loud: print status information during checking
:param obsids: list of obsids for selecting a subset for review (mostly for debug)
:param is_ORs: list of is_OR values (for roll options review page)
Expand All @@ -128,8 +155,8 @@ def run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=Non
try:
_run_aca_review(load_name=load_name, acars=acars, make_html=make_html,
report_dir=report_dir, report_level=report_level,
roll_level=roll_level, loud=loud, obsids=obsids,
open_html=open_html, context=context)
roll_level=roll_level, roll_args=roll_args,
loud=loud, obsids=obsids, open_html=open_html, context=context)
except Exception:
if raise_exc:
raise
Expand All @@ -141,8 +168,8 @@ def run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=Non


def _run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=None,
report_level='none', roll_level='none', loud=False, obsids=None,
open_html=False, context=None):
report_level='none', roll_level='none', roll_args=None,
loud=False, obsids=None, open_html=False, context=None):

if acars is None:
acars = get_acas_from_pickle(load_name, loud)
Expand All @@ -153,6 +180,9 @@ def _run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=No
if not acars:
raise ValueError('no catalogs founds (check obsid filtering?)')

if roll_args is None:
roll_args = {}

# Make output directory if needed
if make_html:
# Generate outdir from load_name if necessary
Expand All @@ -179,9 +209,32 @@ def _run_aca_review(load_name=None, *, acars=None, make_html=True, report_dir=No
aca.set_stars_and_mask() # Not stored in pickle, need manual restoration
aca.check_catalog()

# Find roll options if requested
if roll_level == 'all' or aca.messages >= roll_level:
# Get roll selection algorithms to try
max_roll_options = roll_args.pop('max_roll_options', 10)
Copy link
Member

Choose a reason for hiding this comment

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

max_roll_options is not mentioned in the documentation comment for roll_args, is this intentional?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, see 70ce3f4.

methods = roll_args.pop(
'method', ('uniq_ids', 'uniform') if aca.is_OR else 'uniq_ids')
if isinstance(methods, str):
methods = [methods]

try:
aca.get_roll_options() # sets roll_options, roll_info attributes
# Set roll_options, roll_info attributes
for method in methods:
aca.roll_options = None
aca.roll_info = None
aca.get_roll_options(method=method, **roll_args)
aca.roll_info['method'] = method

# If there is at least one option with no messages at the
# roll_level (typically "critical") then declare success and
# stop looking for roll options.
if any(not roll_option['acar'].messages >= roll_level
for roll_option in aca.roll_options):
break

aca.sort_and_limit_roll_options(roll_level, max_roll_options)

except Exception: # as err:
err = traceback.format_exc()
aca.add_message('critical', text=f'Running get_roll_options() failed: \n{err}')
Expand Down Expand Up @@ -444,7 +497,7 @@ def __init__(self, *args, **kwargs):
self.rename_column('idx_temp', 'idx')

def run_aca_review(self, *, make_html=False, report_dir='.', report_level='none',
roll_level='none', raise_exc=True):
roll_level='none', roll_args=None, raise_exc=True):
"""Do aca review based for this catalog

The ``report_level`` arg specifies the message category at which the full
Expand All @@ -454,10 +507,30 @@ def run_aca_review(self, *, make_html=False, report_dir='.', report_level='none'
default is "none", meaning no reports are generated. A final option is
"all" which generates a report for every obsid.

The ``roll_level`` arg specifies the message category at which the review
process will also attempt to find and report on available star catalogs for
different roll options. The available categories are the same as for
``report_level``, with the most common choice being "critical".

The ``roll_args`` arg specifies an optional dict of arguments used in the
call to the ``get_roll_options`` method. Possible args include:

- ``min_improvement``: min value of improvement metric to accept option
(default=0.3)
- ``d_roll``: delta roll for sampling available roll range (deg, default=0.25
for uniq_ids method and 0.5 for uniform method)
- ``max_roll_dev``: maximum roll deviation (deg, default=max allowed by pitch)
- ``method``: method for determining roll intervals ('uniq_ids' | 'uniform').
The 'uniq_ids' method is a faster method that frequently finds an acceptable
roll option, while 'uniform' is a brute-force search of the entire roll
range at ``d_roll`` increments. If not provided, the default is to try
*both* methods in order, stopping when an acceptable option is found.

:param make_html: make HTML report (default=False)
:param report_dir: output directory for report (default='.')
:param report_level: report level threshold for generating acq and guide report
:param roll_level: level threshold for suggesting alternate rolls
:param roll_args: None or dict of arguments for ``get_roll_options``
:param raise_exc: if False then catch exception and return traceback (default=True)
:returns: exception message: str or None

Expand All @@ -467,7 +540,7 @@ def run_aca_review(self, *, make_html=False, report_dir='.', report_level='none'
# Do aca review checks and update acas[0] in place
exc = run_aca_review(load_name=f'Obsid {self.obsid}', acars=acars, make_html=make_html,
report_dir=report_dir, report_level=report_level,
roll_level=roll_level,
roll_level=roll_level, roll_args=roll_args,
loud=False, raise_exc=raise_exc)
return exc

Expand All @@ -484,7 +557,7 @@ def review_status(self):
@property
def att_targ(self):
if not hasattr(self, '_att_targ'):
self._att_targ = self._calc_targ_from_aca(self.att, 0, 0)
self._att_targ = self._calc_targ_from_aca(self.att, *self.target_offset)
return self._att_targ

@property
Expand Down Expand Up @@ -599,6 +672,7 @@ def make_roll_options_report(self):
roll_context['roll_options_index'] = rolls_index.as_posix()
for key in ('roll_min', 'roll_max', 'roll_nom'):
roll_context[key] = f'{self.roll_info[key]:.2f}'
roll_context['roll_method'] = self.roll_info['method']
self.context.update(roll_context)

# Make a separate preview page for the roll options
Expand Down Expand Up @@ -632,8 +706,8 @@ def plot(self, ax=None, **kwargs):
idxs = self.get_candidate_better_stars()
stars = self.stars[idxs]
for star in stars:
already_checked = ((star['id'] in self.acqs.cand_acqs['id']) and
(star['id'] in self.guides.cand_guides['id']))
already_checked = ((star['id'] in self.acqs.cand_acqs['id'])
and (star['id'] in self.guides.cand_guides['id']))
selected = (star['id'] in set(self.acqs['id']) | set(self.guides['id']))
if (not already_checked and not selected):
circle = Circle((star['row'], star['col']), radius=20,
Expand Down Expand Up @@ -797,6 +871,11 @@ def check_guide_geometry(self):
guide_idxs = np.flatnonzero(ok)
n_guide = len(guide_idxs)

if n_guide < 2:
msg = f'Cannot check geometry with fewer than 2 guide stars'
self.add_message('critical', msg)
return

def dist2(g1, g2):
out = (g1['yang'] - g2['yang']) ** 2 + (g1['zang'] - g2['zang']) ** 2
return out
Expand Down
7 changes: 5 additions & 2 deletions sparkles/index_template_preview.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ <h1> {{load_name}} sparkles review</h1>
{% if roll_options_table %}
<h3>Roll options (roll_min={{roll_min}}
roll_nom={{roll_nom}}
roll_max={{roll_max}}</h3>
roll_max={{roll_max}}
method={{roll_method}}
</h3>)
{{roll_options_table | safe}}
{% endif %}

Expand All @@ -118,7 +120,8 @@ <h2> {{id_label}} {{aca.report_id}} at {{aca.date}}</h1>
<h3><a href="{{aca.context['roll_options_index']}}">Roll options
report</a> (roll_min={{aca.context['roll_min']}}
roll_nom={{aca.context['roll_nom']}}
roll_max={{aca.context['roll_max']}})</h3>
roll_max={{aca.context['roll_max']}}
method={{aca.context['roll_method']}})</h3>
{{aca.context['roll_options_table'] | safe}}
<span>
{% endif %}
Expand Down
Loading