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

Adding telescope constraints to the time_dependent plots #548

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 36 additions & 1 deletion astroplan/plots/time_dependent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import copy
from xmlrpc.client import boolean
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this used anywhere?

import numpy as np
import operator
import astropy.units as u
Expand All @@ -12,6 +13,7 @@

from ..exceptions import PlotWarning
from ..utils import _set_mpl_style_sheet
from ..constraints import Constraint

__all__ = ['plot_airmass', 'plot_schedule_airmass', 'plot_parallactic',
'plot_altitude']
Expand Down Expand Up @@ -51,7 +53,8 @@ def _has_twin(ax):
def plot_airmass(targets, observer, time, ax=None, style_kwargs=None,
style_sheet=None, brightness_shading=False,
altitude_yaxis=False, min_airmass=1.0, min_region=None,
max_airmass=3.0, max_region=None, use_local_tz=False):
max_airmass=3.0, max_region=None, use_local_tz=False,
constraints=None):
r"""
Plots airmass as a function of time for a given target.

Expand Down Expand Up @@ -126,6 +129,10 @@ def plot_airmass(targets, observer, time, ax=None, style_kwargs=None,
use_local_tz : bool
If the time is specified in a local timezone, the time will be plotted
in that timezone.

constraints : Constraint or list of Constraint objects (optional)
If a list of boolean constraints is provided, the objects will have
blackened curves outside the constraints.

Returns
-------
Expand Down Expand Up @@ -176,6 +183,23 @@ def plot_airmass(targets, observer, time, ax=None, style_kwargs=None,

if not isinstance(targets, Sequence):
targets = [targets]

# Firstly, check that the constraints are valid if any.
if constraints is not None:
if isinstance(constraints, Constraint):
constraints = [constraints]

assert isinstance(constraints, (list, tuple, np.ndarray)), "constraints must be an array-like object or a single Constraint instance."
for cons in constraints:
assert isinstance(cons, Constraint), "All constraint objects must be Constraints"

# Make sure they're boolean
assert hasattr(cons, 'boolean_constraint'), "Each constraints element must have the 'boolean_constraint attribute."
assert cons.boolean_constraint, "Cannot work with non-boolean constraints."
# Then make sure they're not some weird user-generated constraint.
assert hasattr(cons, 'compute_constraint'), "Constraints must have a 'compute_constraint' method."


Comment on lines +186 to +202
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than including asserts in the function here, a more common approach is to extract the elements of the list that meet the validation criteria, without raising an error.


for target in targets:
# Calculate airmass
Expand All @@ -192,6 +216,17 @@ def plot_airmass(targets, observer, time, ax=None, style_kwargs=None,
# Plot data (against timezone-offset time)
ax.plot_date(timetoplot.plot_date, masked_airmass, label=target_name, **style_kwargs)

# Plot black curves for where the target is outside constraints
if constraints:
cons_mask = np.ones(len(airmass), dtype=bool)
for cons in constraints:
cons_mask &= cons(observer, target, time_ut)

# Handle discontinuous curves:
time_vals = np.where((~cons_mask)&(airmass>1),timetoplot.plot_date, np.nan)
am_vals = np.where((~cons_mask)&(airmass>1), airmass, np.nan)
ax.plot_date(time_vals, am_vals, "k", lw=3)

# Format the time axis
xlo, xhi = (timetoplot[0]), (timetoplot[-1])
ax.set_xlim([xlo.plot_date, xhi.plot_date])
Expand Down