diff --git a/.vscode/launch.json b/.vscode/launch.json index 71fbe2e..2b12f79 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -375,7 +375,9 @@ //"args": ["-v", "1", "--noinput", "--start_year", "2025", "--end_year", "2025", "--start_yd", "316", "--num_cores", "1", "--no_cleanup"] // Do not write _1S.nc file if it has no time data //"args": ["-v", "1", "--mission", "2006.338.11", "--noinput", "--no_cleanup" ], - "args": ["-v", "1", "--mission", "2017.347.00", "--noinput", "--no_cleanup" ], + //"args": ["-v", "1", "--mission", "2017.347.00", "--noinput", "--no_cleanup" ], + //Test --update_ssds_provenance and .html file creation with footer link + "args": ["-v", "1", "--mission", "2026.113.00", "--noinput", "--no_cleanup", "--clobber", "--update_ssds_provenance"] }, @@ -493,7 +495,7 @@ // Test time range of DeploymentPlots with ahi planktivore deployment April 2025 //"args": ["-v", "1", "--auv_name", "ahi", "--start", "20250401", "--end", "20250501", "--update_ssds_provenance", "--force"] // Test web page building with a short deployment - "args": ["-v", "1", "--dlist", "ahi/missionlogs/2025/20251022_20251024.dlist", "--update_ssds_provenance", "--force", "--notify"] + "args": ["-v", "1", "--dlist", "ahi/missionlogs/2025/20251022_20251024.dlist", "--update_ssds_provenance", "--force", "--notify", "mccann@mbari.org"] // Test --force option for rebuilding web pages with a short deployment //"args": ["-v", "1", "--last_n_days", "10", "--update_ssds_provenance", "--force"] // Test --notify option diff --git a/src/data/create_products.py b/src/data/create_products.py index 3718342..42f02c8 100755 --- a/src/data/create_products.py +++ b/src/data/create_products.py @@ -2240,7 +2240,12 @@ def _write_dorado_mission_html(self, png_path: Path) -> None: f'

Processing log

\n' f" {gulper_line}" "
\n" - f"

Created by create_products.py on {now}

\n" + '

' + f"Created by create_products.py on {now}" + f'Processrun details in SSDS" + "

\n" "\n" "\n" ) @@ -2386,6 +2391,16 @@ def plot_2column(self) -> str: # noqa: C901, PLR0912, PLR0915 output_file = Path( images_dir, f"{self.auv_name}_{self.mission}_{self.freq}_2column_cmocean.png" ) + created = datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z") + fig.text( + 0, + 0, + f"Created by auv-python's create_products.py on {created}.", + fontsize=6, + fontstyle="italic", + ha="left", + va="bottom", + ) plt.savefig(output_file, dpi=100, bbox_inches="tight") plt.show() plt.close(fig) @@ -2529,6 +2544,16 @@ def plot_biolume_2column(self) -> str: # noqa: C901, PLR0912, PLR0915 output_file = Path( images_dir, f"{self.auv_name}_{self.mission}_{self.freq}_2column_biolume.png" ) + created = datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z") + fig.text( + 0, + 0, + f"Created by auv-python's create_products.py on {created}.", + fontsize=6, + fontstyle="italic", + ha="left", + va="bottom", + ) plt.savefig(output_file, dpi=100, bbox_inches="tight") plt.show() plt.close(fig) @@ -2675,6 +2700,16 @@ def plot_planktivore_2column(self) -> str: # noqa: C901, PLR0912, PLR0915 images_dir, f"{self.auv_name}_{self.mission}_{self.freq}_2column_planktivore.png", ) + created = datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z") + fig.text( + 0, + 0, + f"Created by auv-python's create_products.py on {created}.", + fontsize=6, + fontstyle="italic", + ha="left", + va="bottom", + ) plt.savefig(output_file, dpi=100, bbox_inches="tight") plt.show() plt.close(fig) diff --git a/src/data/lrauv_deployment_plots.py b/src/data/lrauv_deployment_plots.py index bdf671b..f16a3dd 100755 --- a/src/data/lrauv_deployment_plots.py +++ b/src/data/lrauv_deployment_plots.py @@ -798,11 +798,19 @@ def _write_per_png_html( # noqa: C901, PLR0913 html_title_single = title.replace("\n", " \u2014 ") script_github_url = get_script_github_url("src/data/lrauv_deployment_plots.py") created_ts = datetime.now(tz=UTC).strftime("%Y-%m-%d %H:%M:%S UTC") + ssds_explorer_url = ( + "https://mooring-ssds.shore.mbari.org/explorer/ssds_metadata/dataproducer/" + f"?resource_name={html_path.name}" + ) footer = ( "
\n" - "

Created by " + '

' + "Created by " f'lrauv_deployment_plots.py' - f" on {created_ts}

\n" + f" on {created_ts}" + f'' + "Processrun details in SSDS" + "

\n" ) html = ( "\n" diff --git a/src/data/process.py b/src/data/process.py index 3c12fb2..6f36812 100755 --- a/src/data/process.py +++ b/src/data/process.py @@ -69,7 +69,7 @@ class data are: download_process and calibrate, while for LRAUV class data from archive import LOG_NAME, Archiver from calibrate import EXPECTED_SENSORS, Calibrate_NetCDF from combine import Combine_NetCDF -from create_products import CreateProducts +from create_products import MISSIONIMAGES, CreateProducts from dorado_info import FAILED, TEST, dorado_info from emailer import NOTIFICATION_EMAIL, Emailer from logs2netcdfs import BASE_PATH, MISSIONLOGS, MISSIONNETCDFS, AUV_NetCDF @@ -787,6 +787,35 @@ def _collect_lrauv_netcdf_resources( return resources + def _collect_dorado_plot_resources(self, mission: str) -> list[dict]: + """Return Resource dicts for PNG and HTML plots produced by create_products.py. + + The HTML resource names match the ?resource_name= filter used in the + 'Processrun details in SSDS' footer link on each HTML page, so they + resolve to this processrun in the SSDS explorer. + """ + images_dir = Path(self.config["base_path"], self.auv_name, MISSIONIMAGES, mission) + plot_suffixes = [ + ("2column_cmocean", "Standard 2-column plot"), + ("2column_biolume", "Bioluminescence 2-column plot"), + ("2column_planktivore", "Planktivore 2-column plot"), + ] + resources: list[dict] = [] + for suffix, description in plot_suffixes: + stem = f"{self.auv_name}_{mission}_{FREQ}_{suffix}" + for ext, rtype in [("png", "Quick Look Plot"), ("html", "html")]: + f = images_dir / f"{stem}.{ext}" + if f.exists(): + resources.append( + { + "name": f.name, + "uristring": get_web_url(str(f)), + "description": f"Created by create_products.py: {description}", + "resourcetype_name": rtype, + } + ) + return resources + def _submit_provenance( # noqa: PLR0913 self, output_nc: str, @@ -1020,6 +1049,7 @@ def process_mission(self, mission: str, src_dir: str = "") -> None: # noqa: C90 f"{self.auv_name}_{mission}_{LOG_NAME}", ) ), + additional_resources=self._collect_dorado_plot_resources(mission), ) # self.archive() is called in finally: blocks in process_missions()