{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Part 1: Geostrophic balance\n", "Andrew Delman, updated 2025-07-24.\n", "\n", "## Objectives\n", "\n", "To use ECCO state estimate output to illustrate the concept of geostrophic balance; where it does and doesn't explain oceanic flows well.\n", "\n", "By the end of the tutorial, you will be able to:\n", "\n", "* Download or access ECCO fields and query their attributes using ```xarray```\n", "* Plot ECCO fields on a single tile\n", "* Carry out spatial differencing and interpolation on the ECCO native model grid\n", "* Compare the two sides of the geostrophic balance equations\n", "* Compute geostrophic velocities\n", "* Apply masks in 2-D spatial plots\n", "* Use the ```ecco_v4_py``` package to plot global maps of ECCO fields\n", "* Use a statistical measure (normalized difference) to assess the latitude and depth dependence of geostrophic balance\n", "\n", "\n", "## Introduction\n", "\n", "### Conservation of momentum\n", "\n", "Geostrophic balance originates from the conservation of momentum, as expressed by the momentum equation:\n", "\n", "$$\n", "\\frac{D\\bf{u}}{Dt} = -\\frac{1}{\\rho}{\\nabla}p + {\\nu}{\\nabla^2}\\bf{u} + \\bf{F_b}\n", "$$\n", "\n", "following roughly the notation used in Kundu and Cohen (2008) and Vallis (2006). This equation is a simplification of the Navier-Stokes equation for an incompressible fluid. The material derivative $D/Dt \\equiv \\partial{}/\\partial{t} + {\\bf{u}}\\cdot\\nabla$ is the derivative in time *following a fluid parcel*. The symbol $\\nu \\equiv \\mu/\\rho$ indicates the kinematic viscosity, and $F_b$ represents body forces (real or apparent) exerted on the fluid.\n", "\n", "The equation above applies to any incompressible fluid, even the water in a fish tank or swimming pool. However, the body forces $\\bf{F_b}$ are dependent upon the environment of the fluid and the scales being considered. In a physical oceanography context, three forces that are typically very important are (a) gravity, (b) the Coriolis force from rotation of the earth, and (c) friction from surface winds or topography. So the equation above can be rewritten as\n", "\n", "$$\n", "\\frac{\\partial{\\bf{u}}}{\\partial{t}} + {\\bf{u}}\\cdot\\nabla{\\bf{u}} = -\\frac{1}{\\rho}{\\nabla}p + {\\nu}{\\nabla^2}{\\bf{u}} + g\\bf{\\hat{k}} - 2{\\bf{\\Omega}}\\times{\\bf{u}} + \\bf{F_f}\n", "$$\n", "\n", "Of those last three terms: \n", "1. Gravity $g\\bf{\\hat{k}}$ effectively only applies to vertical momentum, and can be neglected in the horizontal momentum equations\n", "1. The Coriolis force $-2{\\bf{\\Omega}}\\times{\\bf{u}}$ can be approximated by its vertical component, $2{\\Omega}\\sin\\theta(v{\\bf{\\hat{i}}} - u{\\bf{\\hat{j}}})$ where $\\Omega$ is the rotation rate of Earth in radians and $\\theta$ is latitude\n", "1. Friction $\\bf{F_f}$ from wind and topography is negligible in the ocean interior.\n", "\n", "To simplify, $f$ is defined as $f \\equiv 2{\\Omega}\\sin\\theta$. So using subscript notation for derivatives ($u_t$ is the derivative of $u$ with respect to $t$) the two horizontal components of momentum conservation are:\n", "\n", "$$\n", "u_t + {\\bf{u}}\\cdot\\nabla{u} = -\\frac{1}{\\rho}{p_x} + {\\nu}{\\nabla^2}u + fv\n", "$$\n", "\n", "$$\n", "v_t + {\\bf{u}}\\cdot\\nabla{v} = -\\frac{1}{\\rho}{p_y} + {\\nu}{\\nabla^2}v - fu\n", "$$\n", "\n", "### Geostrophic balance\n", "\n", "The two horizontal momentum equations still have a number of terms, but in the global oceans most of the flow is explained by a balance between just two terms. In steady state (or for very slowly-varying ocean features) the time derivatives $u_t$, $v_t$ are negligible, and at the large scales of major ocean currents viscosity is relatively small as well (inviscid approximation). This leaves three terms. The 2nd term on the left-hand side is usually negligible at large scales as well (we'll return to this later), so large-scale ocean flows generally follow **geostrophic balance**:\n", "\n", "$$\n", "fv = \\frac{1}{\\rho}{p_x}\n", "$$\n", "$$\n", "fu = -\\frac{1}{\\rho}{p_y}\n", "$$\n", "\n", "(cf. Vallis ch. 2.8, Kundu and Cohen ch. 14.5, Gill ch. 7.6)\n", "\n", "If you've looked at weather maps that show the clockwise or counter-clockwise flow of winds around areas of high or low pressure, you've encountered geostrophic balance in the atmosphere. But what does it look like in the ocean? You're about to see it in action...using output from the ECCO state estimate.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Access the ECCO output\n", "\n", "### Looking for specific variables\n", "\n", "These notebooks use the `ecco_access` Python package to download ECCO output (or access it within the AWS Cloud if you are working on AWS). If you haven't been through the `ecco_access` Python package [intro tutorial](https://ecco-access.readthedocs.io/en/latest/Using_ECCO_access.html) tutorial yet, I recommend going through it before proceeding further with this tutorial.\n", "\n", "What fields will we need? Look at the geostrophic balance equations. On the left-hand side, the Coriolis parameter $f$ is a function of latitude which we can compute, so we only need to download horizontal velocities $u$ and $v$. On the right-hand side we need density $\\rho$ and pressure $p$, as well as the grid parameters that allow us to compute spatial derivatives.\n", "\n", "How do we get those fields, while staying in our comfortable Jupyter notebook environment? There are two ways. \n", "\n", "The first option is to consult the following variable lists to find the NASA Earthdata ShortName of the datasets for the variables that we want:\n", "\n", "[ECCO v4r4 llc90 Grid Dataset Variables - Monthly Means](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_nctiles_monthly_varlist.txt)\n", "\n", "[ECCO v4r4 llc90 Grid Dataset Variables - Daily Means](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_nctiles_daily_varlist.txt)\n", "\n", "[ECCO v4r4 llc90 Grid Dataset Variables - Daily Snapshots](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_nctiles_snapshots_varlist.txt)\n", "\n", "[ECCO v4r4 0.5-Deg Interp Grid Dataset Variables - Monthly Means](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_latlon_monthly_varlist.txt)\n", "\n", "[ECCO v4r4 0.5-Deg Interp Grid Dataset Variables - Daily Means](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_latlon_daily_varlist.txt)\n", "\n", "[ECCO v4r4 Time Series and Grid Parameters](https://raw.githubusercontent.com/ECCO-GROUP/ECCO-v4-Python-Tutorial/master/varlist/v4r4_tseries_grid_varlist.txt)\n", "\n", "Let's have a look at the llc90 grid monthly means variable list. A text search for \"velocity\" shows us that **UVEL** and **VVEL** are the horizontal velocity variables we need. Importantly, we need to know the ShortName of the datasets containing these variables, which is **ECCO_L4_OCEAN_VEL_LLC0090GRID_MONTHLY_V4R4**.\n", "\n", "Searching for \"density\" and we get **RHOAnoma** (in-situ seawater density anomaly), and \"pressure\" gives us **PHIHYD** and **PHIHYDcR** (ocean hydrostatic pressure anomaly)--in this analysis we specifically need to use **PHIHYDcR**, the pressure anomaly at constant depth. These fields are all found in datasets with ShortName **ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_MONTHLY_V4R4**.\n", "\n", "The second option, if we don't know the ShortNames already, is to use *ecco_access* top-level functions to \"query\" the variable lists and find the datasets that we need. You will see examples of these queries below.\n", "\n", "\n", "### Download output\n", "\n", "Make sure to [install](https://ecco-access.readthedocs.io/en/latest/Installation.html) the `ecco_access` Python package if you have not already done so.\n", "\n", "*ecco_access* provides a convenient function, `ecco_podaac_to_xrdataset` that accesses the requested output from PO.DAAC's cloud storage **and** opens an *xarray* dataset.\n", "\n", "We also can specify a \"mode\" option, which tells the function how to access these datasets. The default mode is `download_ifspace`, which downloads these tutorials to your local machine (under `~/Downloads/ECCO_V4r4_PODAAC/`) *if* the downloaded files would occupy less than 50% of available disk space. See the [access modes](https://ecco-access.readthedocs.io/ECCO_access_modes.html) tutorial for more information on these modes.\n", "\n", "> Tip: If you are working in the AWS Cloud, you can specify `incloud_access = True`, which will then use mode = `s3_get_ifspace` by default. The `s3_get_ifspace` mode downloads the files to your local instance if they would occupy less than 50% of available disk space; otherwise the data are accessed remotely (typically slower).\n", "\n", "\n", "Now let's use it to get access to the ECCO output we need, starting with the monthly velocity fields for Jan 2000." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# specify incloud_access = True if working in the AWS Cloud, otherwise False\n", "incloud_access = False\n", "\n", "from os.path import expanduser,join\n", "user_home_dir = expanduser('~')\n", "\n", "if incloud_access:\n", " access_mode = 's3_open_fsspec'\n", " download_root_dir = None\n", " # specify location to store json files that will speed up S3 data access\n", " jsons_root_dir = join(user_home_dir,'MZZ')\n", "else:\n", " access_mode = 'download_ifspace'\n", " # specify location to store downloaded files\n", " # ~/Downloads/ECCO_V4r4_PODAAC is also the default path used for download_root_dir; \n", " # change as needed\n", " download_root_dir = join(user_home_dir,'Downloads','ECCO_V4r4_PODAAC')\n", " jsons_root_dir = None\n", "\n", "import numpy as np\n", "import xarray as xr\n", "import xmitgcm\n", "import xgcm\n", "import glob\n", "import sys\n", "import matplotlib.pyplot as plt\n", "\n", "# import ecco_v4_py and ecco_access\n", "import ecco_v4_py as ecco\n", "import ecco_access as ea" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ShortName Options for query \"velocity\":\n", " Variable Name Description (units)\n", "\n", "Option 1: ECCO_L4_SEA_ICE_VELOCITY_LLC0090GRID_MONTHLY_V4R4 *native grid,monthly means*\n", " SIuice Sea-ice velocity in the model +x direction (m/s)\n", " SIvice Sea-ice velocity in the model +y direction (m/s)\n", "\n", "Option 2: ECCO_L4_OCEAN_VEL_LLC0090GRID_MONTHLY_V4R4 UVEL,VVEL should not be used in volume flux calculations due to time-variable grid cell thicknesses (z* coordinates). Use UVELMASS,VVELMASS instead.\n", " UVEL Horizontal velocity in the model +x direction\n", " (m/s)\n", " VVEL Horizontal velocity in the model +y direction\n", " (m/s)\n", " WVEL Vertical velocity (m/s)\n", "\n", "Option 3: ECCO_L4_OCEAN_3D_VOLUME_FLUX_LLC0090GRID_MONTHLY_V4R4 *native grid,monthly means*\n", " UVELMASS Horizontal velocity in the model +x direction per\n", " unit area of the grid cell \\'u\\' face. Use this in\n", " volume flux calculations as it accounts for\n", " partial cells and time-varying grid cell\n", " thickness. (m/s)\n", " VVELMASS Horizontal velocity in the model +y direction per\n", " unit area of the grid cell \\'v\\' face. Use this in\n", " volume flux calculations as it accounts for\n", " partial cells and time-varying grid cell\n", " thickness. (m/s)\n", " WVELMASS Grid cell face-averaged vertical velocity in the\n", " model +z direction. (m/s)\n", " \n", "\n", "Option 4: ECCO_L4_BOLUS_LLC0090GRID_MONTHLY_V4R4 *native grid,monthly means*\n", " UVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +x direction scaled by time-varying grid\n", " cell thickness (m/s)\n", " VVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +y direction scaled by time-varying grid\n", " cell thickness (m/s)\n", " WVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +z direction (m/s)\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Please select option [1-4]: 2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Using dataset with ShortName: ECCO_L4_OCEAN_VEL_LLC0090GRID_MONTHLY_V4R4\n", "Size of files to be downloaded to instance is 0.029 GB,\n", "which is 0.02% of the 143.844 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:02<00:00, 2.65s/it]\n", "\n", "=====================================\n", "total downloaded: 30.6 Mb\n", "avg download speed: 11.54 Mb/s\n", "Time spent = 2.65132212638855 seconds\n", "\n", "\n" ] } ], "source": [ "# open dataset containing Jan 2000 monthly velocities\n", "\n", "# ds_vel_mo = ea.ecco_podaac_to_xrdataset(\"ECCO_L4_OCEAN_VEL_LLC0090GRID_MONTHLY_V4R4\",\\\n", "# StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", "# mode=access_mode,\\\n", "# download_root_dir=download_root_dir,\\\n", "# jsons_root_dir=jsons_root_dir,\\\n", "# prompt_request_payer=False)\n", "ds_vel_mo = ea.ecco_podaac_to_xrdataset(\"velocity\",grid=\"native\",time_res=\"monthly\",\\\n", " StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " prompt_request_payer=False) # enter \"2\" when prompted" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now do the same for the Jan 2000 monthly density and pressure:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ShortName Options for query \"density\":\n", " Variable Name Description (units)\n", "\n", "Option 1: ECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4 *native grid,monthly means*\n", " SSH Dynamic sea surface height anomaly. Suitable for\n", " comparisons with altimetry sea surface height data\n", " products that apply the inverse barometer\n", " correction. (m)\n", " SSHIBC The inverted barometer correction to sea surface\n", " height due to atmospheric pressure loading. (m)\n", " SSHNOIBC Sea surface height anomaly without the inverted\n", " barometer correction. Suitable for comparisons\n", " with altimetry sea surface height data products\n", " that do NOT apply the inverse barometer\n", " correction. (m)\n", " ETAN Model sea level anomaly, without corrections for\n", " global mean density changes, inverted barometer\n", " effect, or volume displacement due to submerged\n", " sea-ice and snow. (m)\n", "\n", "Option 2: ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_MONTHLY_V4R4 *native grid,monthly means*\n", " RHOAnoma In-situ seawater density anomaly (kg/m^3)\n", " DRHODR Density stratification ((kg/m^3)/m)\n", " PHIHYD Ocean hydrostatic pressure anomaly (m^2/s^2)\n", " PHIHYDcR Ocean hydrostatic pressure anomaly at constant\n", " depths (m^2/s^2)\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Please select option [1-2]: 2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Using dataset with ShortName: ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_MONTHLY_V4R4\n", "Size of files to be downloaded to instance is 0.029 GB,\n", "which is 0.02% of the 143.816 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:02<00:00, 2.45s/it]\n", "\n", "=====================================\n", "total downloaded: 30.98 Mb\n", "avg download speed: 12.65 Mb/s\n", "Time spent = 2.4490714073181152 seconds\n", "\n", "\n" ] } ], "source": [ "# open dataset containing Jan 2000 monthly density/pressure\n", "\n", "# ds_denspress_mo = ea.ecco_podaac_to_xrdataset(\"ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_MONTHLY_V4R4\",\\\n", "# StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", "# mode=access_mode,\\\n", "# download_root_dir=download_root_dir,\\\n", "# jsons_root_dir=jsons_root_dir,\\\n", "# prompt_request_payer=False)\n", "ds_denspress_mo = ea.ecco_podaac_to_xrdataset(\"density\",grid=\"native\",time_res=\"monthly\",\\\n", " StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " prompt_request_payer=False) # enter \"2\" when prompted" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will also access the *daily* velocity and density/pressure output on 01 Jan 2000, changing the `time_res` option to `daily`:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ShortName Options for query \"velocity\":\n", " Variable Name Description (units)\n", "\n", "Option 1: ECCO_L4_SEA_ICE_VELOCITY_LLC0090GRID_DAILY_V4R4 *native grid,daily means*\n", " SIuice Sea-ice velocity in the model +x direction (m/s)\n", " SIvice Sea-ice velocity in the model +y direction (m/s)\n", "\n", "Option 2: ECCO_L4_OCEAN_VEL_LLC0090GRID_DAILY_V4R4 UVEL,VVEL should not be used in volume flux calculations due to time-variable grid cell thicknesses (z* coordinates). Use UVELMASS,VVELMASS instead.\n", " UVEL Horizontal velocity in the model +x direction\n", " (m/s)\n", " VVEL Horizontal velocity in the model +y direction\n", " (m/s)\n", " WVEL Vertical velocity (m/s)\n", "\n", "Option 3: ECCO_L4_OCEAN_3D_VOLUME_FLUX_LLC0090GRID_DAILY_V4R4 *native grid,daily means*\n", " UVELMASS Horizontal velocity in the model +x direction per\n", " unit area of the grid cell \\'u\\' face. Use this in\n", " volume flux calculations as it accounts for\n", " partial cells and time-varying grid cell\n", " thickness. (m/s)\n", " VVELMASS Horizontal velocity in the model +y direction per\n", " unit area of the grid cell \\'v\\' face. Use this in\n", " volume flux calculations as it accounts for\n", " partial cells and time-varying grid cell\n", " thickness. (m/s)\n", " WVELMASS Grid cell face-averaged vertical velocity in the\n", " model +z direction. (m/s)\n", " \n", "\n", "Option 4: ECCO_L4_BOLUS_LLC0090GRID_DAILY_V4R4 *native grid,daily means*\n", " UVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +x direction scaled by time-varying grid\n", " cell thickness (m/s)\n", " VVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +y direction scaled by time-varying grid\n", " cell thickness (m/s)\n", " WVELSTAR Gent-McWilliams parameterized bolus velocity in\n", " the model +z direction (m/s)\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Please select option [1-4]: 2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Using dataset with ShortName: ECCO_L4_OCEAN_VEL_LLC0090GRID_DAILY_V4R4\n", "Size of files to be downloaded to instance is 0.029 GB,\n", "which is 0.02% of the 143.788 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:01<00:00, 1.97s/it]\n", "\n", "=====================================\n", "total downloaded: 30.68 Mb\n", "avg download speed: 15.56 Mb/s\n", "Time spent = 1.9719030857086182 seconds\n", "\n", "\n", "ShortName Options for query \"density\":\n", " Variable Name Description (units)\n", "\n", "Option 1: ECCO_L4_SSH_LLC0090GRID_DAILY_V4R4 *native grid,daily means*\n", " SSH Dynamic sea surface height anomaly. Suitable for\n", " comparisons with altimetry sea surface height data\n", " products that apply the inverse barometer\n", " correction. (m)\n", " SSHIBC The inverted barometer correction to sea surface\n", " height due to atmospheric pressure loading. (m)\n", " SSHNOIBC Sea surface height anomaly without the inverted\n", " barometer correction. Suitable for comparisons\n", " with altimetry sea surface height data products\n", " that do NOT apply the inverse barometer\n", " correction. (m)\n", " ETAN Model sea level anomaly, without corrections for\n", " global mean density changes, inverted barometer\n", " effect, or volume displacement due to submerged\n", " sea-ice and snow. (m)\n", "\n", "Option 2: ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_DAILY_V4R4 *native grid,daily means*\n", " RHOAnoma In-situ seawater density anomaly (kg/m^3)\n", " DRHODR Density stratification ((kg/m^3)/m)\n", " PHIHYD Ocean hydrostatic pressure anomaly (m^2/s^2)\n", " PHIHYDcR Ocean hydrostatic pressure anomaly at constant\n", " depths (m^2/s^2)\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Please select option [1-2]: 2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Using dataset with ShortName: ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_DAILY_V4R4\n", "Size of files to be downloaded to instance is 0.029 GB,\n", "which is 0.02% of the 143.75900000000001 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:02<00:00, 2.46s/it]\n", "\n", "=====================================\n", "total downloaded: 31.2 Mb\n", "avg download speed: 12.67 Mb/s\n", "Time spent = 2.4622464179992676 seconds\n", "\n", "\n" ] } ], "source": [ "# open dataset containing Jan 2000 monthly velocities\n", "\n", "# ds_vel_daily = ea.ecco_podaac_to_xrdataset(\"ECCO_L4_OCEAN_VEL_LLC0090GRID_DAILY_V4R4\",\\\n", "# StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", "# mode=access_mode,\\\n", "# download_root_dir=download_root_dir,\\\n", "# jsons_root_dir=jsons_root_dir,\\\n", "# prompt_request_payer=False)\n", "ds_vel_daily = ea.ecco_podaac_to_xrdataset(\"velocity\",grid=\"native\",time_res=\"daily\",\\\n", " StartDate=\"2000-01-01\",EndDate=\"2000-01-01\",\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " prompt_request_payer=False) # enter \"2\" when prompted\n", "\n", "# ds_denspress_daily = ea.ecco_podaac_to_xrdataset(\"ECCO_L4_DENS_STRAT_PRESS_LLC0090GRID_DAILY_V4R4\",\\\n", "# StartDate=\"2000-01\",EndDate=\"2000-01\",\\\n", "# mode=access_mode,\\\n", "# download_root_dir=download_root_dir,\\\n", "# jsons_root_dir=jsons_root_dir,\\\n", "# prompt_request_payer=False)\n", "ds_denspress_daily = ea.ecco_podaac_to_xrdataset(\"density\",grid=\"native\",time_res=\"daily\",\\\n", " StartDate=\"2000-01-01\",EndDate=\"2000-01-01\",\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " prompt_request_payer=False) # enter \"2\" when prompted" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the grid parameters file (leave out `time_res` specification in this case):" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ShortName Options for query \"geometry\":\n", " Variable Name Description (units)\n", "\n", "Option 1: ECCO_L4_GEOMETRY_LLC0090GRID_V4R4 *for native LLC90 grid*\n", " CS Cosine of tracer grid cell orientation vs\n", " geographical north (-1 to 1)\n", " SN Sine of tracer grid cell orientation vs\n", " geographical north (-1 to 1)\n", " rA Area of tracer grid cell (m^2)\n", " dxG Distance between 'southwest' and 'southeast'\n", " corners of the tracer grid cell (m)\n", " dyG Distance between 'southwest' and 'northwest'\n", " corners of the tracer grid cell (m)\n", " Depth Model seafloor depth below ocean surface at rest\n", " (m)\n", " rAz Area of vorticity 'g' grid cell (m^2)\n", " dxC Distance between centers of adjacent tracer grid\n", " cells in the 'x' direction (m)\n", " dyC Distance between centers of adjacent tracer grid\n", " cells in the 'y' direction (m)\n", " rAw Area of 'v' grid cell, staggered between adjacent\n", " tracer grid cells in the 'x' direction (m^2)\n", " rAs Area of 'u' grid cell, staggered between adjacent\n", " tracer grid cells in the 'y' direction (m^2)\n", " drC Distance between the centers of adjacent tracer\n", " grid cells in the 'z' direction (m)\n", " drF Distance between the upper and lower interfaces of\n", " the model grid cell (m)\n", " PHrefC Reference ocean hydrostatic pressure at tracer\n", " grid cell center (m^2/s^2)\n", " PHrefF Reference ocean hydrostatic pressure at tracer\n", " grid cell top/bottom interface (m^2/s^2)\n", " hFacC Vertical open (wet) fraction of tracer grid cell\n", " (fraction from 0 to 1)\n", " hFacW Vertical open (wet) fraction of tracer grid cell\n", " 'west' face (fraction from 0 to 1)\n", " hFacS Vertical open (wet) fraction of tracer grid cell\n", " 'south' face (fraction from 0 to 1)\n", " maskC Wet/dry boolean mask for tracer grid cell (True\n", " for hFacC > 0, otherwise False)\n", " maskW Wet/dry boolean mask for 'west' face of tracer\n", " grid cell (True for hFacW > 0, otherwise False)\n", " maskS Wet/dry boolean mask for 'south' face of tracer\n", " grid cell (True for hFacS > 0, otherwise False)\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Proceed with option 1? [y/n]: y\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Using dataset with ShortName: ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\n", "Size of files to be downloaded to instance is 0.008 GB,\n", "which is 0.01% of the 143.73 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:02<00:00, 2.21s/it]\n", "\n", "=====================================\n", "total downloaded: 8.57 Mb\n", "avg download speed: 3.88 Mb/s\n", "Time spent = 2.2117831707000732 seconds\n", "\n", "\n" ] } ], "source": [ "# ds_grid = ea.ecco_podaac_to_xrdataset(\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n", "# mode=access_mode,\\\n", "# download_root_dir=download_root_dir,\\\n", "# jsons_root_dir=jsons_root_dir,\\\n", "# prompt_request_payer=False)\n", "ds_grid = ea.ecco_podaac_to_xrdataset(\"geometry\",grid=\"native\",\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " prompt_request_payer=False) # enter \"y\" when prompted" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Open/view ECCO files\n", "\n", "### View and plot density/pressure anomalies on a single \"tile\"\n", "\n", "Now let's load one of our datasets and create a couple plots. First we'll load some Python packages that will help us read and plot the data, then we'll load the monthly density/stratification/pressure dataset into our workspace.\n", "\n", "> Tip: If you have any errors involving reading the netCDF file in the code below, try installing the ```netCDF4``` or ```h5netcdf``` packages, using pip install {pkgname} or conda install -c conda-forge {pkgname}." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have just loaded the contents of the netCDF file into the workspace using the package ```xarray```. We can look at a summary of the contents of this xarray DataSet:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset> Size: 89MB\n",
"Dimensions: (i: 90, i_g: 90, j: 90, j_g: 90, k: 50, k_u: 50, k_l: 50,\n",
" k_p1: 51, tile: 13, time: 1, nv: 2, nb: 4)\n",
"Coordinates: (12/22)\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * i_g (i_g) int32 360B 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j_g (j_g) int32 360B 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * k_u (k_u) int32 200B 0 1 2 3 4 5 6 7 8 ... 41 42 43 44 45 46 47 48 49\n",
" ... ...\n",
" Zu (k_u) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" Zl (k_l) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" time_bnds (time, nv) datetime64[ns] 16B dask.array<chunksize=(1, 2), meta=np.ndarray>\n",
" XC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" YC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" Z_bnds (k, nv) float32 400B dask.array<chunksize=(50, 2), meta=np.ndarray>\n",
"Dimensions without coordinates: nv, nb\n",
"Data variables:\n",
" RHOAnoma (time, k, tile, j, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
" DRHODR (time, k_l, tile, j, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
" PHIHYD (time, k, tile, j, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
" PHIHYDcR (time, k, tile, j, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
"Attributes: (12/62)\n",
" acknowledgement: This research was carried out by the Jet...\n",
" author: Ian Fenty and Ou Wang\n",
" cdm_data_type: Grid\n",
" comment: Fields provided on the curvilinear lat-l...\n",
" Conventions: CF-1.8, ACDD-1.3\n",
" coordinates_comment: Note: the global 'coordinates' attribute...\n",
" ... ...\n",
" time_coverage_duration: P1M\n",
" time_coverage_end: 2000-02-01T00:00:00\n",
" time_coverage_resolution: P1M\n",
" time_coverage_start: 2000-01-01T00:00:00\n",
" title: ECCO Ocean Density, Stratification, and ...\n",
" uuid: 166a1992-4182-11eb-82f9-0cc47a3f43f9<xarray.DataArray 'RHOAnoma' (time: 1, k: 50, tile: 13, j: 90, i: 90)> Size: 21MB\n",
"dask.array<open_dataset-RHOAnoma, shape=(1, 50, 13, 90, 90), dtype=float32, chunksize=(1, 25, 7, 45, 45), chunktype=numpy.ndarray>\n",
"Coordinates:\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * tile (tile) int32 52B 0 1 2 3 4 5 6 7 8 9 10 11 12\n",
" * time (time) datetime64[ns] 8B 2000-01-16T12:00:00\n",
" XC (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" YC (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" Z (k) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
"Attributes:\n",
" long_name: In-situ seawater density anomaly\n",
" units: kg m-3\n",
" coverage_content_type: modelResult\n",
" valid_min: -18.81316375732422\n",
" valid_max: 25.540061950683594\n",
" comment: In-situ seawater density anomaly relative to the ...<xarray.DataArray 'PHIHYDcR' (time: 1, k: 50, tile: 13, j: 90, i: 90)> Size: 21MB\n",
"dask.array<open_dataset-PHIHYDcR, shape=(1, 50, 13, 90, 90), dtype=float32, chunksize=(1, 25, 7, 45, 45), chunktype=numpy.ndarray>\n",
"Coordinates:\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * tile (tile) int32 52B 0 1 2 3 4 5 6 7 8 9 10 11 12\n",
" * time (time) datetime64[ns] 8B 2000-01-16T12:00:00\n",
" XC (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" YC (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" Z (k) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
"Attributes:\n",
" long_name: Ocean hydrostatic pressure anomaly at constant de...\n",
" units: m2 s-2\n",
" coverage_content_type: modelResult\n",
" comment: PHIHYD = p(k) / rhoConst - g z(k,t), where p = hy...\n",
" valid_min: 78.17041778564453\n",
" valid_max: 783.6217041015625<xarray.Dataset> Size: 68MB\n",
"Dimensions: (i: 90, i_g: 90, j: 90, j_g: 90, k: 50, k_u: 50, k_l: 50,\n",
" k_p1: 51, tile: 13, time: 1, nv: 2, nb: 4)\n",
"Coordinates: (12/22)\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * i_g (i_g) int32 360B 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j_g (j_g) int32 360B 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * k_u (k_u) int32 200B 0 1 2 3 4 5 6 7 8 ... 41 42 43 44 45 46 47 48 49\n",
" ... ...\n",
" Zu (k_u) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" Zl (k_l) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" time_bnds (time, nv) datetime64[ns] 16B dask.array<chunksize=(1, 2), meta=np.ndarray>\n",
" XC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" YC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" Z_bnds (k, nv) float32 400B dask.array<chunksize=(50, 2), meta=np.ndarray>\n",
"Dimensions without coordinates: nv, nb\n",
"Data variables:\n",
" UVEL (time, k, tile, j, i_g) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
" VVEL (time, k, tile, j_g, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
" WVEL (time, k_l, tile, j, i) float32 21MB dask.array<chunksize=(1, 25, 7, 45, 45), meta=np.ndarray>\n",
"Attributes: (12/62)\n",
" acknowledgement: This research was carried out by the Jet...\n",
" author: Ian Fenty and Ou Wang\n",
" cdm_data_type: Grid\n",
" comment: Fields provided on the curvilinear lat-l...\n",
" Conventions: CF-1.8, ACDD-1.3\n",
" coordinates_comment: Note: the global 'coordinates' attribute...\n",
" ... ...\n",
" time_coverage_duration: P1M\n",
" time_coverage_end: 2000-02-01T00:00:00\n",
" time_coverage_resolution: P1M\n",
" time_coverage_start: 2000-01-01T00:00:00\n",
" title: ECCO Ocean Velocity - Monthly Mean llc90...\n",
" uuid: 32bd652c-4182-11eb-bd5c-0cc47a3f82e7<xarray.Dataset> Size: 89MB\n",
"Dimensions: (i: 90, i_g: 90, j: 90, j_g: 90, k: 50, k_u: 50, k_l: 50,\n",
" k_p1: 51, tile: 13, nb: 4, nv: 2)\n",
"Coordinates: (12/20)\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * i_g (i_g) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j_g (j_g) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * k_u (k_u) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" ... ...\n",
" Zp1 (k_p1) float32 204B dask.array<chunksize=(51,), meta=np.ndarray>\n",
" Zu (k_u) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" Zl (k_l) float32 200B dask.array<chunksize=(50,), meta=np.ndarray>\n",
" XC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" YC_bnds (tile, j, i, nb) float32 2MB dask.array<chunksize=(13, 90, 90, 4), meta=np.ndarray>\n",
" Z_bnds (k, nv) float32 400B dask.array<chunksize=(50, 2), meta=np.ndarray>\n",
"Dimensions without coordinates: nb, nv\n",
"Data variables: (12/21)\n",
" CS (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" SN (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" rA (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" dxG (tile, j_g, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" dyG (tile, j, i_g) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" Depth (tile, j, i) float32 421kB dask.array<chunksize=(13, 90, 90), meta=np.ndarray>\n",
" ... ...\n",
" hFacC (k, tile, j, i) float32 21MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
" hFacW (k, tile, j, i_g) float32 21MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
" hFacS (k, tile, j_g, i) float32 21MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
" maskC (k, tile, j, i) bool 5MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
" maskW (k, tile, j, i_g) bool 5MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
" maskS (k, tile, j_g, i) bool 5MB dask.array<chunksize=(25, 7, 45, 45), meta=np.ndarray>\n",
"Attributes: (12/58)\n",
" acknowledgement: This research was carried out by the Jet...\n",
" author: Ian Fenty and Ou Wang\n",
" cdm_data_type: Grid\n",
" comment: Fields provided on the curvilinear lat-l...\n",
" Conventions: CF-1.8, ACDD-1.3\n",
" coordinates_comment: Note: the global 'coordinates' attribute...\n",
" ... ...\n",
" references: ECCO Consortium, Fukumori, I., Wang, O.,...\n",
" source: The ECCO V4r4 state estimate was produce...\n",
" standard_name_vocabulary: NetCDF Climate and Forecast (CF) Metadat...\n",
" summary: This dataset provides geometric paramete...\n",
" title: ECCO Geometry Parameters for the Lat-Lon...\n",
" uuid: 87ff7d24-86e5-11eb-9c5f-f8f21e2ee3e0<xarray.DataArray 'dp_dx' (time: 1, k: 50, tile: 13, j: 90, i: 90)> Size: 21MB\n",
"array([[[[[ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" ...,\n",
" [-1.78578217e-03, -2.80201435e-04, 4.48737061e-04, ...,\n",
" 2.56811129e-03, 2.54054624e-03, 2.38151103e-03],\n",
" [-1.97579130e-03, -1.17824820e-04, 6.02442888e-04, ...,\n",
" 2.95511540e-03, 3.09964363e-03, 3.09713813e-03],\n",
" [-1.60034164e-03, 3.31102929e-04, 6.47389097e-04, ...,\n",
" 3.22869234e-03, 3.55401146e-03, 3.75702744e-03]],\n",
"\n",
" [[-8.98729253e-04, 7.29348627e-04, 2.39784946e-04, ...,\n",
" 3.42662539e-03, 3.89235793e-03, 4.29460499e-03],\n",
" [-2.40144931e-04, 7.03949365e-04, -7.84797710e-04, ...,\n",
" 3.54899094e-03, 4.10596048e-03, 4.68219491e-03],\n",
" [ 5.17581939e-05, 1.75516907e-04, -2.09984998e-03, ...,\n",
" 3.58781964e-03, 4.15722188e-03, 4.85306140e-03],\n",
"...\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan]],\n",
"\n",
" [[ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" ...,\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan],\n",
" [ nan, nan, nan, ...,\n",
" nan, nan, nan]]]]],\n",
" dtype=float32)\n",
"Coordinates:\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * tile (tile) int32 52B 0 1 2 3 4 5 6 7 8 9 10 11 12\n",
"Dimensions without coordinates: time