Source code for iact_estimator.observability

"""Module that stores all functions related to observability estimation from the given location."""

from datetime import datetime

from astropy.time import Time

from astroplan import (
    AtNightConstraint,
    MoonSeparationConstraint,
    AltitudeConstraint,
    MoonIlluminationConstraint,
)
import astropy.units as u

from astroplan import (
    is_observable,
    months_observable,
    is_event_observable,
    time_grid_from_range,
)


__all__ = ["define_constraints"]


def get_days_in_this_year():
    """Get the number of days in the current year.

    Accounts for leap years."""
    this_year = datetime.today().year
    start_of_year = Time(f"{this_year}-01-01")
    end_of_year = Time(f"{this_year}-12-31")

    # Add 1 to include the last day
    num_days = int((end_of_year - start_of_year).to_value("day") + 1)
    return num_days * u.day


[docs] def define_constraints(config): constraints_config = config["observation"]["constraints"] moon_separation = constraints_config["moon_separation"] moon_illumination = constraints_config["moon_illumination_fraction"] zenith = constraints_config["zenith"] constraints = [ AtNightConstraint(u.Quantity(constraints_config["max_solar_altitude"])), MoonSeparationConstraint( min=u.Quantity(moon_separation["min"]), max=u.Quantity(moon_separation["max"]) if moon_separation["max"] else None, ephemeris=moon_separation["ephemeris"], ), MoonIlluminationConstraint( min=u.Quantity(moon_illumination["min"]) if moon_illumination["min"] else None, max=u.Quantity(moon_illumination["max"]), ephemeris=moon_separation["ephemeris"], ), AltitudeConstraint( min=90 * u.deg - u.Quantity(zenith["max"]), max=90 * u.deg - u.Quantity(zenith["min"]), ), ] return constraints
def check_observability( constraints, observer, target_source, time_range, time_grid_resolution ): """Check is the target source is observable and which months are best. Parameters ---------- constraints : `~astroplan.constraints.Constraint` or list(~astroplan.constraints.Constraint)` One or more observational constraints. observer : `~astroplan.Observer` Instance of an _astroplan_ observer. target_source : `~astroplan.FixedTarget` Instance of an _astroplan_ fixed target source, time_range : list(~astropy.time.Time), shape=(2,) Start and stop observation time. time_grid_resolution : `~astropy.units.Quantity` Unit of time to test observability along the provided time range. Returns ------- ever_observable : bool True if the target source is observable within at least one time unit. best_months : set Set of months where the target source is more suited for observation. """ # Are targets *ever* observable in the time range? ever_observable = is_observable( constraints, observer, target_source, time_range=time_range, time_grid_resolution=time_grid_resolution, ) # During what months are the targets ever observable? best_months = months_observable( constraints, observer, target_source, time_range, time_grid_resolution=time_grid_resolution, ) return ever_observable, best_months def get_total_available_time( target_source, observer, constraints, time_range, time_resolution ): """Get available observation time. Args: target_source (astroplan.FixedTarget) observer (astroplan.Observer) constraints (astroplan.Constraint or list(astroplan.Constraint)): Set of constraining limits for the observation. time_range (list(astropy.time.Time)): [start, stop] time stamps time_resolution (u.Quantity): time step over which to evaluate the constraints. Returns: total_available_time (u.Quantity): in hours. """ time_grid = time_grid_from_range(time_range, time_resolution=time_resolution) is_observable_at_time = is_event_observable( constraints, observer, target_source, times=time_grid ) total_observable_time = is_observable_at_time.sum() total_available_time = total_observable_time * time_resolution.to("h") return total_available_time