diff --git a/notebooks_tsqr/NightLog.ipynb b/notebooks_tsqr/NightLog.ipynb index a465b52..f99d7c5 100644 --- a/notebooks_tsqr/NightLog.ipynb +++ b/notebooks_tsqr/NightLog.ipynb @@ -4,6 +4,17 @@ "cell_type": "markdown", "id": "0", "metadata": {}, + "source": [ + "# Table of Contents\n", + "* [Overview of NightLog Report](#overview)\n", + "* [DDV](#ddv)\n", + "* [Almanac](#almanac)" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, "source": [ "# Initialization" ] @@ -11,7 +22,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -28,13 +39,13 @@ "#!day_obs = 'TODAY' # TODO Change to 'TODAY' to test with default before push \n", "\n", "# Total number of days of data to display (ending on day_obs)\n", - "number_of_days = '1' # TODO Change to '1' to test with default before push " + "number_of_days = '31' # TODO Change to '1' to test with default before push " ] }, { "cell_type": "code", "execution_count": null, - "id": "2", + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -69,7 +80,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3", + "id": "4", "metadata": {}, "outputs": [], "source": [ @@ -95,7 +106,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4", + "id": "5", "metadata": {}, "outputs": [], "source": [ @@ -111,15 +122,15 @@ }, { "cell_type": "markdown", - "id": "5", + "id": "6", "metadata": {}, "source": [ - "# Overview" + "# Overview of NightLog Report " ] }, { "cell_type": "markdown", - "id": "6", + "id": "7", "metadata": {}, "source": [ "### Where an this run?\n", @@ -133,14 +144,14 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "8", "metadata": {}, "outputs": [], "source": [ "# Display overview of Report context \n", - "md(f'''## Project Wide Night(s) Report \n", - "- Run on logs from **{server}/**\n", - "- Report **{days} observing night(s)** with the last reported night starting **{date}**.\n", + "md(f'''## Project-Wide Night(s) Report \n", + "- Run on logs and databases from **{server}/**\n", + "- Report **{days} observing night(s)** with the last reported night starting on **{date}**.\n", "- This report will include available data from noon **{min_date}** to noon **{max_date}** (inclusive).\n", "- Using ***Prototype* Logging and Reporting** Version: **{lrversion}**\n", "''')\n", @@ -150,21 +161,22 @@ "sources_md_str += '\\n- EFD'\n", "sources_md_str += '\\n- (DDV)'\n", "sources_md_str += '\\n- (Astroplan for Almanac)'\n", - "md(f'### This report uses the following sources: {sources_md_str}')" + "md(f'### This report uses the following data sources: {sources_md_str}')" ] }, { "cell_type": "markdown", - "id": "8", + "id": "9", "metadata": {}, "source": [ - "# DDV" + "\n", + "# DDV " ] }, { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "10", "metadata": {}, "outputs": [], "source": [ @@ -174,7 +186,7 @@ }, { "cell_type": "markdown", - "id": "10", + "id": "11", "metadata": {}, "source": [ "# Almanac" @@ -183,7 +195,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11", + "id": "12", "metadata": {}, "outputs": [], "source": [ @@ -193,7 +205,7 @@ }, { "cell_type": "markdown", - "id": "12", + "id": "13", "metadata": {}, "source": [ "# Night Report" @@ -202,7 +214,7 @@ { "cell_type": "code", "execution_count": null, - "id": "13", + "id": "14", "metadata": {}, "outputs": [], "source": [ @@ -221,7 +233,7 @@ { "cell_type": "code", "execution_count": null, - "id": "14", + "id": "15", "metadata": {}, "outputs": [], "source": [ @@ -247,7 +259,7 @@ }, { "cell_type": "markdown", - "id": "15", + "id": "16", "metadata": {}, "source": [ "# Exposure Log" @@ -256,7 +268,7 @@ { "cell_type": "code", "execution_count": null, - "id": "16", + "id": "17", "metadata": {}, "outputs": [], "source": [ @@ -279,7 +291,7 @@ { "cell_type": "code", "execution_count": null, - "id": "17", + "id": "18", "metadata": {}, "outputs": [], "source": [ @@ -298,7 +310,7 @@ }, { "cell_type": "markdown", - "id": "18", + "id": "19", "metadata": {}, "source": [ "# Narrative Log\n" @@ -307,7 +319,7 @@ { "cell_type": "code", "execution_count": null, - "id": "19", + "id": "20", "metadata": {}, "outputs": [], "source": [ @@ -328,7 +340,7 @@ }, { "cell_type": "markdown", - "id": "20", + "id": "21", "metadata": {}, "source": [ "# Developer Only Section" @@ -337,7 +349,7 @@ { "cell_type": "code", "execution_count": null, - "id": "21", + "id": "22", "metadata": {}, "outputs": [], "source": [ @@ -348,7 +360,7 @@ { "cell_type": "code", "execution_count": null, - "id": "22", + "id": "23", "metadata": {}, "outputs": [], "source": [ @@ -361,7 +373,7 @@ }, { "cell_type": "markdown", - "id": "23", + "id": "24", "metadata": {}, "source": [ "# Finale" @@ -370,7 +382,7 @@ { "cell_type": "code", "execution_count": null, - "id": "24", + "id": "25", "metadata": {}, "outputs": [], "source": [ diff --git a/python/lsst/ts/logging_and_reporting/almanac.py b/python/lsst/ts/logging_and_reporting/almanac.py index a527629..7505377 100644 --- a/python/lsst/ts/logging_and_reporting/almanac.py +++ b/python/lsst/ts/logging_and_reporting/almanac.py @@ -1,53 +1,96 @@ -from datetime import datetime, date, time, timedelta +import datetime as dt import math from astroplan import Observer from astropy.time import Time +# Compare to https://www.timeanddate.com/sun/@5296409 class Almanac: + """Get almanac data for a night give a day_obs. + A day_obs is the date of the start of an observing night. Therefore + for sunrise and morning twilight we get time on the date AFTER day_obs. + For sunset and evening twilight we get time on date of day_obs. + For moonrise/set we get the time nearest to the midnight after day_ob. + """ + def __init__(self, *, day_obs=None, site='Rubin'): if day_obs is None: - astro_day = date.today() - timedelta(days=1) + astro_day = dt.date.today() - dt.timedelta(days=1) else: - astro_day = datetime.strptime(str(day_obs), '%Y%m%d').date() + astro_day = dt.datetime.strptime(str(day_obs), '%Y%m%d').date() self.observer = Observer.at_site(site, timezone='Chile/Continental') self.astro_day = astro_day - self.astro_noon = datetime.combine(self.astro_day,time(12)) - + day1 = dt.timedelta(days=1) + self.astro_midnight = Time(dt.datetime.combine(self.astro_day+day1, + dt.time(0) + ), + format='datetime' + ) self.get_moon() self.get_sun() def get_moon(self): - self.moon_rise_time = self.observer.moon_rise_time(self.astro_noon) - self.moon_set_time = self.observer.moon_set_time(self.astro_noon) + self.moon_rise_time = self.observer.moon_rise_time( + self.astro_midnight, + which='nearest' + ) + self.moon_set_time = self.observer.moon_set_time( + self.astro_midnight, + which='nearest' + ) # Percent of moon lit - self.moon_illum = self.observer.moon_illumination(self.astro_noon) + self.moon_illum = self.observer.moon_illumination( + self.astro_midnight + ) def get_sun(self): - time = self.observer.datetime_to_astropy_time(self.astro_noon) - # ast(ronoimical) twilight: -18 degrees) self.ast_twilight_morning = self.observer.twilight_morning_astronomical( - time) + self.astro_midnight, + which='next' + ) self.ast_twilight_evening = self.observer.twilight_evening_astronomical( - time) + self.astro_midnight, + which='previous' + ) + # nau(tical) twilight: -12 degrees) self.nau_twilight_morning = self.observer.twilight_morning_nautical( - time) + self.astro_midnight, + which='next' + ) self.nau_twilight_evening = self.observer.twilight_evening_nautical( - time) + self.astro_midnight, + which='previous' + ) + # civ(il) twilight: -6 degrees) self.civ_twilight_morning = self.observer.twilight_morning_civil( - time) + self.astro_midnight, + which='next' + ) self.civ_twilight_evening = self.observer.twilight_evening_civil( - time) + self.astro_midnight, + which='previous' + ) + + self.sun_rise_time = self.observer.sun_rise_time( + self.astro_midnight, + which='next' + ) + self.sun_set_time = self.observer.sun_set_time( + self.astro_midnight, + which='previous' + ) - self.sun_rise_time = self.observer.sun_rise_time(time) - self.sun_set_time = self.observer.sun_set_time(time) + @property + def night_hours(self): + day_delta = self.ast_twilight_morning - self.ast_twilight_evening + return day_delta.to_value('hr') @property def as_dict(self): diff --git a/python/lsst/ts/logging_and_reporting/source_adapters.py b/python/lsst/ts/logging_and_reporting/source_adapters.py index 76031ab..a4111b5 100644 --- a/python/lsst/ts/logging_and_reporting/source_adapters.py +++ b/python/lsst/ts/logging_and_reporting/source_adapters.py @@ -59,7 +59,7 @@ def validate_response(response, endpoint_url): msg = f'Error: {response.json()} {endpoint_url=} {response.reason}' raise ex.BadStatus(msg) - + class SourceAdapter(ABC): """Abstract Base Class for all source adapters. """ @@ -440,7 +440,8 @@ def check_endpoints(self, timeout=None, verbose=True): url_http_status_code[url] = 'GET error' else: url_http_status_code[url] = r.status_code - return url_http_status_code, all([v==200 for v in url_http_status_code.values()]) + allgood_p = all([v==200 for v in url_http_status_code.values()]) + return url_http_status_code, allgood_p def get_instruments(self): url = f'{self.server}/{self.service}/instruments' @@ -518,6 +519,13 @@ def get_messages(self, ) return status + # day_obs:: YYYMMDD (int or str) + # Use almanac begin of night values for day_obs. + # Use almanac end of night values for day_obs + 1. + def night_tally_observation_gaps(self, day_obs, instrument): + almanac = alm.Almanac(day_obs=day_obs) + total_observable_hours = almanac.night_hours + recs = self.get_night_exposures(instrument, day_obs) def get_observation_gaps(self, instruments=None): if not instruments: