{ "cells": [ { "cell_type": "markdown", "id": "c6a29764-f39c-431c-8e77-fbc6bfe20f01", "metadata": {}, "source": [ "# Demo\n", "\n", "The purpose of this notebook is to demonstrate the functionality of `gliderflightOG1`.\n", "\n", "The demo is organised to show\n", "\n", "- Step 1: Regressing the Seaglider steady flight model for chosen parameters\n", "\n", "- Step 2: Recalculating the glider flight using the flight model and chosen parameters\n", "\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "6a1920f3", "metadata": { "execution": { "iopub.execute_input": "2025-09-22T21:00:17.353819Z", "iopub.status.busy": "2025-09-22T21:00:17.353587Z", "iopub.status.idle": "2025-09-22T21:00:18.595462Z", "shell.execute_reply": "2025-09-22T21:00:18.594952Z" } }, "outputs": [], "source": [ "\n", "import xarray as xr\n", "from gliderflightOG1 import plotters, tools\n", "import numpy as np\n", "from gliderflightOG1 import seaglider # Assuming correct project style\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "bb7592d5", "metadata": { "execution": { "iopub.execute_input": "2025-09-22T21:00:18.597539Z", "iopub.status.busy": "2025-09-22T21:00:18.597191Z", "iopub.status.idle": "2025-09-22T21:00:18.644868Z", "shell.execute_reply": "2025-09-22T21:00:18.644299Z" } }, "outputs": [], "source": [ "\n", "# 1. Load your dataset\n", "glider = xr.open_dataset('../data/sg014_20080214T220104_delayed.nc')\n", "glider = tools.calc_w_meas(glider)\n", "\n", "# 2. Rename and clean up fields as needed\n", "glider = glider.rename({\n", " 'VBD_CC': 'VBD',\n", " 'divenum': 'DIVENUM',\n", "})\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "384b3ab6", "metadata": { "execution": { "iopub.execute_input": "2025-09-22T21:00:18.646913Z", "iopub.status.busy": "2025-09-22T21:00:18.646724Z", "iopub.status.idle": "2025-09-22T21:00:18.654533Z", "shell.execute_reply": "2025-09-22T21:00:18.653999Z" } }, "outputs": [], "source": [ "\n", "# 3. Add missing variables\n", "# a) Create UPDN from PITCH\n", "glider = glider.assign_coords(TIME=glider['TIME']) # Make sure TIME is coordinate\n", "glider['UPDN'] = xr.where(glider['PITCH'] > 0, 1, -1)\n", "\n", "# b) Create VERTICAL_SPEED from dP/dt\n", "# Assume TIME is in seconds or known units\n", "\n", "\n", "# c) Create fake C_VBD\n", "glider['C_VBD'] = xr.zeros_like(glider['VBD'])\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "92fb8d8b", "metadata": { "execution": { "iopub.execute_input": "2025-09-22T21:00:18.656055Z", "iopub.status.busy": "2025-09-22T21:00:18.655885Z", "iopub.status.idle": "2025-09-22T21:00:18.659389Z", "shell.execute_reply": "2025-09-22T21:00:18.658918Z" } }, "outputs": [], "source": [ "\n", "# d) Add starter attributes\n", "glider.attrs.update({\n", " 'hd_a': 0.0036, # starting guess\n", " 'hd_b': 0.0098, # starting guess\n", " 'hd_c': 0.0010, # starting guess\n", " 'vbdbias': 0.0, # start assuming no bias\n", " 'abs_compress': 4e-6, # reasonable guess\n", " 'therm_expan': 2e-5, # reasonable guess\n", " 'rho0': 1025.0, # typical seawater density\n", " 'vbd_min_cnts': 0.0,\n", " 'vbd_cnts_per_cc': 1.0,\n", " 'temp_ref': 10.0,\n", " 'volmax': 0.0,\n", " 'mass': 52.0, # Approx mass of glider [kg]\n", "})\n", "\n", "# 4. Subselect a few dives to test\n", "dives_to_use = glider['DIVENUM'].values\n", "ensmat = dives_to_use[:20] # first 20 dives for testing\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "254dc998", "metadata": { "execution": { "iopub.execute_input": "2025-09-22T21:00:18.660871Z", "iopub.status.busy": "2025-09-22T21:00:18.660700Z", "iopub.status.idle": "2025-09-22T21:00:18.681974Z", "shell.execute_reply": "2025-09-22T21:00:18.681470Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 17MB\n",
       "Dimensions:                               (N_MEASUREMENTS: 54404)\n",
       "Coordinates:\n",
       "    LONGITUDE                             (N_MEASUREMENTS) float64 435kB ...\n",
       "    LATITUDE                              (N_MEASUREMENTS) float64 435kB ...\n",
       "    TIME                                  (N_MEASUREMENTS) datetime64[ns] 435kB ...\n",
       "    DEPTH                                 (N_MEASUREMENTS) float64 435kB ...\n",
       "Dimensions without coordinates: N_MEASUREMENTS\n",
       "Data variables: (12/59)\n",
       "    TEMP_RAW_QC                           (N_MEASUREMENTS) float32 218kB ...\n",
       "    TEMP_QC                               (N_MEASUREMENTS) float32 218kB ...\n",
       "    GLIDE_SPEED_QC                        (N_MEASUREMENTS) float32 218kB ...\n",
       "    TIME_DOXY                             (N_MEASUREMENTS) datetime64[ns] 435kB ...\n",
       "    DOXY_QC                               (N_MEASUREMENTS) float32 218kB ...\n",
       "    PSAL_RAW_QC                           (N_MEASUREMENTS) float32 218kB ...\n",
       "    ...                                    ...\n",
       "    SENSOR_CTD_0019,                      (N_MEASUREMENTS) float64 435kB ...\n",
       "    SENSOR_DISSOLVED_GAS_SENSORS_UNKNOWN  (N_MEASUREMENTS) float64 435kB ...\n",
       "    PLATFORM_SERIAL_NUMBER                <U5 20B ...\n",
       "    GLIDER_VERT_VELO_DZDT                 (N_MEASUREMENTS) float64 435kB nan ...\n",
       "    UPDN                                  (N_MEASUREMENTS) int64 435kB -1 ... -1\n",
       "    C_VBD                                 (N_MEASUREMENTS) float32 218kB 0.0 ...\n",
       "Attributes: (12/52)\n",
       "    title:                                      OceanGliders trajectory file\n",
       "    id:                                         sg014_20080214T220104_delayed\n",
       "    platform:                                   sub-surface gliders\n",
       "    platform_vocabulary:                        https://vocab.nerc.ac.uk/coll...\n",
       "    naming_authority:                           edu.washington.apl\n",
       "    institution:                                School of Oceanography\\nUnive...\n",
       "    ...                                         ...\n",
       "    rho0:                                       1025.0\n",
       "    vbd_min_cnts:                               0.0\n",
       "    vbd_cnts_per_cc:                            1.0\n",
       "    temp_ref:                                   10.0\n",
       "    volmax:                                     0.0\n",
       "    mass:                                       52.0
" ], "text/plain": [ " Size: 17MB\n", "Dimensions: (N_MEASUREMENTS: 54404)\n", "Coordinates:\n", " LONGITUDE (N_MEASUREMENTS) float64 435kB ...\n", " LATITUDE (N_MEASUREMENTS) float64 435kB ...\n", " TIME (N_MEASUREMENTS) datetime64[ns] 435kB ...\n", " DEPTH (N_MEASUREMENTS) float64 435kB ...\n", "Dimensions without coordinates: N_MEASUREMENTS\n", "Data variables: (12/59)\n", " TEMP_RAW_QC (N_MEASUREMENTS) float32 218kB ...\n", " TEMP_QC (N_MEASUREMENTS) float32 218kB ...\n", " GLIDE_SPEED_QC (N_MEASUREMENTS) float32 218kB ...\n", " TIME_DOXY (N_MEASUREMENTS) datetime64[ns] 435kB ...\n", " DOXY_QC (N_MEASUREMENTS) float32 218kB ...\n", " PSAL_RAW_QC (N_MEASUREMENTS) float32 218kB ...\n", " ... ...\n", " SENSOR_CTD_0019, (N_MEASUREMENTS) float64 435kB ...\n", " SENSOR_DISSOLVED_GAS_SENSORS_UNKNOWN (N_MEASUREMENTS) float64 435kB ...\n", " PLATFORM_SERIAL_NUMBER " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 7. Apply optimized parameters and run flight model\n", "# Update glider attributes with optimized parameters\n", "glider.attrs.update({\n", "# 'hd_a': regressout_norm[0],\n", "# 'hd_b': regressout_norm[1], \n", " 'vbdbias': regressout_norm[2],\n", " # Keep other parameters as they were\n", "})\n", "\n", "# Run flight model with optimized parameters\n", "try:\n", " # Calculate flight velocities using the optimized parameters\n", " glider_with_model = seaglider.flightvec_ds(\n", " glider, \n", " xl=1.0, # typical glider length in meters\n", " hd_a=glider.attrs['hd_a'],\n", " hd_b=glider.attrs['hd_b'], \n", " hd_c=glider.attrs['hd_c']\n", " )\n", " \n", " print(\"Flight model calculation completed successfully!\")\n", " print(f\"Added variables: {list(set(glider_with_model.data_vars) - set(glider.data_vars))}\")\n", " \n", " # Simple plot showing model results\n", " import matplotlib.pyplot as plt\n", " \n", " # Plot a subset of the data for visualization\n", " time_subset = slice(0, 500) # First 500 data points\n", " \n", " fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))\n", " \n", " # Plot vertical velocities\n", " if 'VERTICAL_SPEED' in glider_with_model:\n", " ax1.plot(glider_with_model['TIME'][time_subset], \n", " glider_with_model['VERTICAL_SPEED'][time_subset], \n", " 'b-', label='Observed', alpha=0.7)\n", " \n", " if 'umag' in glider_with_model:\n", " ax1.plot(glider_with_model['TIME'][time_subset], \n", " glider_with_model['umag'][time_subset], \n", " 'r-', label='Model (umag)', alpha=0.7)\n", " \n", " ax1.set_ylabel('Velocity (m/s)')\n", " ax1.set_title('Glider Flight Model Results')\n", " ax1.legend()\n", " ax1.grid(True, alpha=0.3)\n", " \n", " # Plot glide angle if available\n", " if 'thdeg' in glider_with_model:\n", " ax2.plot(glider_with_model['TIME'][time_subset], \n", " glider_with_model['thdeg'][time_subset], \n", " 'g-', label='Glide Angle (degrees)', alpha=0.7)\n", " ax2.set_ylabel('Angle (degrees)')\n", " ax2.legend()\n", " ax2.grid(True, alpha=0.3)\n", " \n", " ax2.set_xlabel('Time')\n", " \n", " plt.tight_layout()\n", " plt.show()\n", " \n", "except Exception as e:\n", " print(f\"Error running flight model: {e}\")\n", " print(\"This may be due to missing variables or incompatible data format.\")\n", " print(\"Check that all required variables are present in the dataset.\")" ] } ], "metadata": { "kernelspec": { "display_name": "venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }