From 28d3a81e79d782e870e328021c320d2bfd31912b Mon Sep 17 00:00:00 2001 From: Steve Pothier Date: Mon, 16 Sep 2024 16:23:56 -0700 Subject: [PATCH] cleaner tables --- notebooks_tsqr/NightLog.ipynb | 19 ++++++------ .../logging_and_reporting/source_adapters.py | 23 ++++++--------- python/lsst/ts/logging_and_reporting/utils.py | 29 ++++++++++++------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/notebooks_tsqr/NightLog.ipynb b/notebooks_tsqr/NightLog.ipynb index 54ca7d0..969b7af 100644 --- a/notebooks_tsqr/NightLog.ipynb +++ b/notebooks_tsqr/NightLog.ipynb @@ -28,7 +28,7 @@ "#!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 = '2' # TODO Change to '1' to test with default before push " + "number_of_days = '12' # TODO Change to '1' to test with default before push " ] }, { @@ -111,7 +111,7 @@ " !pip install --upgrade git+https://github.com/lsst-ts/ts_logging_and_reporting.git@prototype >/dev/null\n", "import lsst.ts.logging_and_reporting.source_adapters as sad\n", "import lsst.ts.logging_and_reporting.almanac as alm\n", - "from lsst.ts.logging_and_reporting.utils import md,mdlist" + "from lsst.ts.logging_and_reporting.reports import md,mdlist,dict_to_md" ] }, { @@ -224,18 +224,19 @@ "outputs": [], "source": [ "front = 'https://rubinobs.atlassian.net/projects/BLOCK?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/'\n", - "md('## Nightly Jira BLOCKs')\n", "tickets = nr_adapter.nightly_tickets(nr_recs)\n", + "\n", "if tickets:\n", - " mdstr = ''\n", + " mdstr = '## Nightly Jira BLOCKs'\n", " for day, url_list in tickets.items():\n", " mdstr += f'\\n- {day}'\n", " for ticket_url in url_list:\n", - " mdstr += f'\\n - [{ticket_url.replace(front,\"\")}]({ticket_url})\\n'\n", + " mdstr += f'\\n - [{ticket_url.replace(front,\"\")}]({ticket_url})'\n", " md(mdstr)\n", "else:\n", " md(f'No jira BLOCK tickets found.', color='lightblue')\n", - " md(f'Used: [API Data]({nr_url})')" + " md(f'Used: [API Data]({nr_url})')\n", + " " ] }, { @@ -275,9 +276,9 @@ "outputs": [], "source": [ "if exposure_recs:\n", - " table = exposure_adapter.day_table(exposure_recs, 'date_added', time_only=False)\n", - " print(table)\n", - " #!mdlist(table)\n", + " table = exposure_adapter.day_table(exposure_recs,'date_added', dayobs_field='day_obs')\n", + " #print(table)\n", + " mdlist(table)\n", "else:\n", " md(f'No Exposure Log records found.', color='lightblue')\n", " md(f'Used [API Data]({exposure_url})')" diff --git a/python/lsst/ts/logging_and_reporting/source_adapters.py b/python/lsst/ts/logging_and_reporting/source_adapters.py index 5e6d49c..621d68e 100644 --- a/python/lsst/ts/logging_and_reporting/source_adapters.py +++ b/python/lsst/ts/logging_and_reporting/source_adapters.py @@ -27,7 +27,6 @@ ''' -############################################ # Python Standard Library from urllib.parse import urlencode import itertools @@ -35,10 +34,10 @@ from warnings import warn from collections import defaultdict from abc import ABC - -############################################ # External Packages import requests +# Local Packages +from lsst.ts.logging_and_reporting.utils import datetime_to_dayobs MAX_CONNECT_TIMEOUT = 3.1 # seconds MAX_READ_TIMEOUT = 180 # seconds @@ -84,13 +83,12 @@ def row_str_func(self, datetime_str, rec): # Break on DAY_OBS. Within that, break on DATE, within that only show time. def day_table(self, recs, datetime_field, - time_only=None, - is_dayobs=False, + dayobs_field=None, row_str_func=None, ): def date_time(rec): - if is_dayobs: - dt = datetime.strptime(str(rec[datetime_field]), '%Y%m%d') + if dayobs_field: + dt = datetime.strptime(str(rec[dayobs_field]), '%Y%m%d') else: dt = datetime.fromisoformat(rec[datetime_field]) return dt.replace(microsecond=0) @@ -99,8 +97,8 @@ def obs_night(rec): if 'day_obs' in rec: return rec['day_obs'] else: - # TODO Wrong!!! Unlike day_obs, this will wrap across midnight - return datetime.fromisoformat(rec[datetime_field]).date().strftime('%Y%m%d') + dt = datetime.fromisoformat(rec[datetime_field]) + return datetime_to_dayobs(dt).strftime('%Y%m%d') def obs_date(rec): dt = datetime.fromisoformat(rec[datetime_field]) @@ -110,9 +108,6 @@ def obs_date(rec): print('Nothing to display.') return dates = set([date_time(r).date() for r in recs]) - if time_only is None: - time_only = True if len(dates) == 1 else False - table = list() # Group by night. recs = sorted(recs,key=lambda r: date_time(r)) @@ -123,7 +118,6 @@ def obs_date(rec): table.append(f'### DATE: {date.date()}: ') for rec in g0: dt = date_time(rec) - #! dtstr = str(dt.time()) if time_only else str(dt) dtstr = str(dt.time()) table.append(f'{self.row_str_func(dtstr, rec)}') table.append(':EOT') @@ -242,7 +236,8 @@ def nightly_tickets(self, recs): ticket_url = r['confluence_url'] if ticket_url: tickets[r['day_obs']].add(ticket_url) - return {k:list(v) for k,v in tickets.items()} + #!return {k:list(v) for k,v in tickets.items()} + return {dayobs:list(urls) for dayobs,urls in tickets.items()} class NarrativelogAdapter(SourceAdapter): diff --git a/python/lsst/ts/logging_and_reporting/utils.py b/python/lsst/ts/logging_and_reporting/utils.py index 2380a55..e55b932 100644 --- a/python/lsst/ts/logging_and_reporting/utils.py +++ b/python/lsst/ts/logging_and_reporting/utils.py @@ -21,19 +21,28 @@ import time -from IPython.display import display, Markdown +import datetime -def md(markdown_str, color=None): - # see https://www.w3schools.com/colors/colors_names.asp - if color: - display(Markdown(f"### {markdown_str}")) - else: - display(Markdown(markdown_str)) +# See https://github.com/lsst-sitcom/summit_utils/blob/0b3fd8795c9cca32f30cef0c37625c5d96804b74/python/lsst/summit/utils/efdUtils.py#L633 +def datetime_to_dayobs(dt) -> int: + """Convert a datetime object to dayobs. + Round to the date of the start of the observing night. + Both the input datetime and output dayobs are in the same timezone. + + Parameters + ---------- + dt : `datetime.datetime` + The date-time. + + Returns + ------- + day_obs : `int` + The day_obs, as an integer, e.g. 20231225 (YYYYMMDD) + """ + return (dt - datetime.timedelta(hours=12)).date() + -def mdlist(markdown_list, color=None): - for markdown_str in markdown_list: - md(markdown_str, color=color) def tic(): """Start timer.