From 4b2371f0e0049c5e6484dc43121d5d52b8616ddd Mon Sep 17 00:00:00 2001 From: DeanHenze <deanchenze@gmail.com> Date: Wed, 30 Oct 2024 14:06:54 -0700 Subject: [PATCH 1/2] Add kerchunk_recipes notebook. Restructure some of the notebooks under 'Advanced Cloud' into a sub-category 'Cloud Optimized Data Formats'. --- _quarto.yml | 3 + .../Advanced_cloud/kerchunk_recipes.ipynb | 2274 +++++++++++++++++ quarto_text/Advanced.qmd | 10 +- quarto_text/CloudOptimizedFormats.qmd | 17 + 4 files changed, 2300 insertions(+), 4 deletions(-) create mode 100644 notebooks/Advanced_cloud/kerchunk_recipes.ipynb create mode 100644 quarto_text/CloudOptimizedFormats.qmd diff --git a/_quarto.yml b/_quarto.yml index 951f2b1e..dd1ecabe 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -254,6 +254,9 @@ website: contents: - text: "Notebook" href: notebooks/aws_lambda_sst/podaac-lambda-invoke-sst-global-mean.ipynb + - section: quarto_text/CloudOptimizedFormats.qmd + contents: + - text: "Testing" - section: quarto_text/Dask_Coiled.qmd contents: - text: "Basic Dask" diff --git a/notebooks/Advanced_cloud/kerchunk_recipes.ipynb b/notebooks/Advanced_cloud/kerchunk_recipes.ipynb new file mode 100644 index 00000000..eaa21f1d --- /dev/null +++ b/notebooks/Advanced_cloud/kerchunk_recipes.ipynb @@ -0,0 +1,2274 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "180973dc-a4fc-43aa-bbc5-d56ce3e9edba", + "metadata": {}, + "source": [ + "# Kerchunk Useful Recipes with NASA Earthdata\n", + "\n", + "#### *Author: Dean Henze, PO.DAAC*\n", + "\n", + "*Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise, does not constitute or imply its endorsement by the United States Government or the Jet Propulsion Laboratory, California Institute of Technology.*" + ] + }, + { + "cell_type": "markdown", + "id": "31e719d0-17d1-45e9-9933-cb49a7cef7a9", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "This notebook goes through several functionalities of kerchunk, specifically using it with NASA Earthdata and utilizing the `earthaccess` package. It is meant to be a quick-start reference that introduces some key capabilities / characteristics of the package once a user has a high-level understanding of kerchunk as well as the cloud-computing challenges it addresses (see references in the *Prerequisite knowledge* section below). In short, kerchunk is a Python package to create \"reference files\", which can be thought of as road maps for the computer to efficiently navigate through large arrays in an Earthdata file (or any file). Once a reference file for a data set is created, it can be accessed and used to e.g. to lazy load data faster, access subsets of the data quicker (spatially, temporally, or any other dimension in the data set), and in some cases perform computations faster.\n", + "\n", + "The functionalities of kerchunk covered in this notebook are:\n", + "\n", + "1. **Generating a reference file in JSON format for a year of the MUR 0.01 degree resolution sea surface temperature (SST) data set**, available on PO.DAAC. It also covers speeding up the generation using parallel computing. MUR 0.01 is a daily, gridded global data set (doi [10.5067/GHGMR-4FJ04](https://doi.org/10.5067/GHGMR-4FJ04)).\n", + "2. **Generating a reference file in PARQUET format** for a year of the MUR 0.01 degree data. This will become important as cloud data sets get so large that saving their reference files in JSON format also becomes too large. We find in Section 2 that saving the same reference information in PARQUET format reduced disk size by ~30x. \n", + "3. **Combining reference files**. The ability to combine reference files together rather than having to create the combined product from scratch is important since it can save computing resources/time. This notebooks explores (3.1) Adding an extra day of the MUR record to the reference file created in Section 1, and (3.2) Creating a reference file for an additional year of MUR data and combining it with the reference file created in Section 1.\n", + "4. **Using the reference file to perform a basic analysis on the MUR data set with a parallel computing cluster.** Parallel computing on both a local and distributed cluster are tested. For the local cluster, we are able to run all computations successfully. For the distributed cluster, we are only able to run computations if the reference file is first loaded fully into memory." + ] + }, + { + "cell_type": "markdown", + "id": "bbce1593-e158-44d4-aab8-9f91027a19ba", + "metadata": {}, + "source": [ + "## Requirements, prerequisite knowledge, learning outcomes\n", + "\n", + "#### Requirements to run this notebook\n", + "\n", + "* Earthdata login account: An Earthdata Login account is required to access data from the NASA Earthdata system. Please visit https://urs.earthdata.nasa.gov to register and manage your Earthdata Login account.\n", + "\n", + "* Compute environment: This notebook is meant to be run in the cloud (AWS instance running in us-west-2). We used an `m6i.8xlarge` EC2 instance (32 CPU's, 128 GiB memory) to complete Section 4 on parallel computing, although this is likely overkill for the other sections. At minimum we recommend a VM with 10 CPU's to make the parallel computations in Sections 1.2.1 and 3.2 faster.\n", + "\n", + "* Optional Coiled account: To run the optional sections on distributed clusters, Create a coiled account (free to sign up), and connect it to an AWS account. For more information on Coiled, setting up an account, and connecting it to an AWS account, see their website [https://www.coiled.io](https://www.coiled.io). \n", + "\n", + "#### Prerequisite knowledge\n", + "\n", + "* This notebook covers kerchunk functionality but does not present the high-level ideas behind it. For an understanding of reference files and how they are meant to enhance in-cloud access to file formats that are not cloud optimized (such netCDF, HDF), please see e.g. this [kerchunk page](https://fsspec.github.io/kerchunk/), or [this page on virtualizarr](https://virtualizarr.readthedocs.io/en/latest/) (a package with similar functionality).\n", + "\n", + "* Familiarity with the `earthaccess` and `Xarray` packages. Familiarity with directly accessing NASA Earthdata in the cloud. \n", + "\n", + "* The Cookbook notebook on [Dask basics](https://podaac.github.io/tutorials/notebooks/Advanced_cloud/basic_dask.html) is handy for those new to parallel computating and wanting to implement it in Sections 1.2.1 and 3.2.\n", + "\n", + "#### Learning Outcomes\n", + "\n", + "This notebook demonstrates several recipes for key kerchunk functionalities with NASA Earthdata. It is meant to be used after the user has a high level understanding of kerchunk and the challenges it is trying to solve, at which point this notebook: \n", + "\n", + "* Demonstrates how to implement the package,\n", + "* Highlights several characteristics of the package which will likely be of interest for utilizing it with Earthdata in common workflows. " + ] + }, + { + "cell_type": "markdown", + "id": "88f65dd1-39f6-480a-aa63-adbbd9863e8f", + "metadata": {}, + "source": [ + "## Import Packages\n", + "We ran this notebook in a Python 3.12 environment. The minimal working install we used to run this notebook from a clean environment was:\n", + "```\n", + "pip install kerchunk==0.2.6 fastparquet==2024.5.0 xarray==2024.1.0 earthaccess==0.11.0 fsspec==2024.10.0 \"dask[complete]\"==2024.5.2 h5netcdf==1.3.0 ujson==5.10.0 matplotlib==3.9.2 jupyterlab jupyter-server-proxy\n", + "```\n", + "And optionally:\n", + "```\n", + "pip install coiled==1.58.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fc0b1c0c-c8f9-412c-8038-4b674de896c9", + "metadata": {}, + "outputs": [], + "source": [ + "# Built-in packages\n", + "import os\n", + "import json\n", + "\n", + "# Filesystem management \n", + "import fsspec\n", + "import earthaccess\n", + "\n", + "# Data analysis\n", + "import xarray as xr\n", + "from kerchunk.df import refs_to_dataframe\n", + "from kerchunk.hdf import SingleHdf5ToZarr\n", + "from kerchunk.combine import MultiZarrToZarr\n", + "\n", + "# Parallel computing \n", + "import multiprocessing\n", + "from dask import delayed\n", + "import dask.array as da\n", + "from dask.distributed import Client\n", + "\n", + "# Other\n", + "import ujson\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8e601488-7348-45cb-bfed-068121fc4d2f", + "metadata": {}, + "outputs": [], + "source": [ + "import coiled" + ] + }, + { + "cell_type": "markdown", + "id": "e9e58626-85f4-4fed-b5af-04736ca6f83d", + "metadata": {}, + "source": [ + "## Other Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "22c5a123-6025-4a85-a7b0-4b9b747a9a8d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<xarray.core.options.set_options at 0x7fb123452450>" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "xr.set_options( # display options for xarray objects\n", + " display_expand_attrs=False,\n", + " display_expand_coords=True,\n", + " display_expand_data=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "20756ad2-4fdf-4f7a-8582-aa7d59ea35e5", + "metadata": {}, + "source": [ + "## 1. Generating a reference file in JSON format for one year of MUR 0.01 degree SST" + ] + }, + { + "cell_type": "markdown", + "id": "6901e7c4-66ca-4dfb-bd8f-aaf2f0291764", + "metadata": {}, + "source": [ + "### 1.1 Locate Data File S3 endpoints in Earthdata Cloud \n", + "The first step is to find the S3 endpoints to the files and generate file-like objects to use with kerchunk. Handling access credentials to Earthdata and then finding the endpoints can be done a number of ways (e.g. using the `requests`, `s3fs` packages) but we choose to use the `earthaccess` package for its convenience and brevity. We will get two years of MUR files, from beginning 2019 to end 2020. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "20dbc070-d5f7-407e-b92e-4fda1b8a82ba", + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter your Earthdata Login username: deanh808\n", + "Enter your Earthdata password: ········\n" + ] + }, + { + "data": { + "text/plain": [ + "<earthaccess.auth.Auth at 0x7fb1a410c920>" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Get Earthdata creds\n", + "earthaccess.login()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7519aab1-b2aa-40fa-862a-62ed69439ff4", + "metadata": {}, + "outputs": [], + "source": [ + "# Get AWS creds\n", + "fs = earthaccess.get_s3_filesystem(daac=\"PODAAC\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "487b4dd6-39c6-4d7e-8051-eddcd22e2a4a", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "fe22eb2e195a4c16b3bdff0a7bd8b0a0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "QUEUEING TASKS | : 0%| | 0/732 [00:00<?, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "13129d3fba734a95914067b232b66a96", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "PROCESSING TASKS | : 0%| | 0/732 [00:00<?, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2117989fff404d5b8d297bb4d6c2a8b3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "COLLECTING RESULTS | : 0%| | 0/732 [00:00<?, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Locate MUR file information for years 2019-2020 and generate file-like objects:\n", + "granule_info = earthaccess.search_data(\n", + " short_name=\"MUR-JPL-L4-GLOB-v4.1\",\n", + " temporal=(\"2019-01-01\", \"2020-12-31\"),\n", + " )\n", + "fobjs = earthaccess.open(granule_info)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "54bce89b-1068-4f77-b72b-be13fc074e02", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'s3://podaac-ops-cumulus-protected/MUR-JPL-L4-GLOB-v4.1/20190101090000-JPL-L4_GHRSST-SSTfnd-MUR-GLOB-v02.0-fv04.1.nc'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Endpoints can be found in this attribute:\n", + "example_endpoint = fobjs[0].full_name\n", + "example_endpoint" + ] + }, + { + "cell_type": "markdown", + "id": "410b4028-b31d-4c28-a78d-2fedebcf967c", + "metadata": {}, + "source": [ + "### 1.2 Generate kerchunk reference files for each MUR file in year 2019\n", + "It is necessary to create reference files for each data file individually before they can be combined into a single reference file for the entire record. The time for generating many of these individual files can add up, so this section also covers the option to use parallel computing." + ] + }, + { + "cell_type": "markdown", + "id": "a146d00a-cf61-4ed4-96e2-6db0a19bb466", + "metadata": {}, + "source": [ + "First, define a small wrapper function around kerchunk and earthaccess packages." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8d15c636-e401-4b14-880a-f248b4b5d0f7", + "metadata": {}, + "outputs": [], + "source": [ + "def single_ref_earthaccess(fobj, dir_save=None):\n", + " \"\"\"\n", + " Create a reference for a single data file. \"fobj\" (earthaccess.store.EarthAccessFile \n", + " object) is the output from earthaccess.open(), which also has the file endpoint. \n", + " Option to save as a JSON to direcotry \"dir_save\", with file name of the corresponding \n", + " data file with \".json\" appended. Otherwise reference info is returned.\n", + " \"\"\"\n", + " endpoint = fobj.full_name\n", + " reference = SingleHdf5ToZarr(fobj, endpoint, inline_threshold=0).translate()\n", + " \n", + " if dir_save is not None:\n", + " with open(dir_save + endpoint.split('/')[-1]+'.json', 'w') as outf:\n", + " outf.write(ujson.dumps(reference))\n", + " else:\n", + " return reference, endpoint # returns both the kerchunk reference and the path the file on podaac-ops-cumulus-protected" + ] + }, + { + "cell_type": "markdown", + "id": "28b850da-5df5-460e-81f3-0450a2904667", + "metadata": {}, + "source": [ + "Which can immediately be used to create a reference file and open one of the MUR files with Xarray, at which point it can be used just as if we had opened the MUR netCDF file directly:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "aba98768-e3bf-4693-9778-cc2ca14d43be", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.44 s, sys: 1.01 s, total: 3.45 s\n", + "Wall time: 13.9 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Create reference file:\n", + "reference, endpoint = single_ref_earthaccess(fobjs[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "15707ccc-fcb3-4bf9-94cb-71b11d468054", + "metadata": {}, + "outputs": [], + "source": [ + "# Open data using the reference file, using a small wrapper function around xarray's open_dataset. \n", + "# This will shorten code blocks in other sections. \n", + "def opendf_withref(ref, fs_data):\n", + " \"\"\"\n", + " \"ref\" is a kerchunk reference file or object. \"fs_data\" is a filesystem with credentials to\n", + " access the actual data files. \n", + " \"\"\"\n", + " storage_opts = {\"fo\": ref, \"remote_protocol\": \"s3\", \"remote_options\": fs_data.storage_options}\n", + " fs_ref = fsspec.filesystem('reference', **storage_opts)\n", + " m = fs_ref.get_mapper('')\n", + " data = xr.open_dataset(\n", + " m, engine=\"zarr\", chunks={},\n", + " backend_kwargs={\"consolidated\": False}\n", + " )\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "cf7a4fe9-5d2c-49c6-936e-91a4c481647c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.Dataset>\n", + "Dimensions: (time: 1, lat: 17999, lon: 36000)\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00\n", + "Data variables:\n", + " analysed_sst (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " analysis_error (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " dt_1km_data (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " mask (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sea_ice_fraction (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + "Attributes: (47)\n", + "CPU times: user 103 ms, sys: 8.7 ms, total: 111 ms\n", + "Wall time: 469 ms\n" + ] + } + ], + "source": [ + "%%time\n", + "data = opendf_withref(reference, fs)\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "id": "25fd7864-25f5-4b54-b47f-2072b21ab35e", + "metadata": {}, + "source": [ + "**For us, reference file creation took ~10 seconds, so processing a year would take *10 x 365 ~ 60 minutes***. One could easily write a simple for-loop to accomplish this, e.g.\n", + "\n", + "```\n", + "for fobj in fobjs[:365]:\n", + " single_ref_earthaccess(fobj, dir_save=<directory of your choice>)\n", + "```\n", + "\n", + "However, we speed things up using basic parallel computing. " + ] + }, + { + "cell_type": "markdown", + "id": "9e4fc53c-2bf2-4b9d-9ab7-32a498011bd4", + "metadata": {}, + "source": [ + "### 1.2.1 Parallelize using Dask local cluster\n", + "If using the suggested `m6i.8xlarge` AWS EC2 instance, there are 32 CPUs available and each should have enough memory that we can utilize all 32 at once. If working on a different VM-type, change the `n_workers` in the call to `Client()` below as needed." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "914018a4-0858-4ee1-acbe-b4039fea7584", + "metadata": {}, + "outputs": [], + "source": [ + "## Save reference JSONs in this directory:\n", + "dir_refs_indv_2019 = './reference_jsons_individual_2019/'\n", + "!mkdir $dir_refs_indv_2019" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f6bae28c-0527-4ad8-8065-f6187fb46961", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU count = 32\n" + ] + } + ], + "source": [ + "# Check how many cpu's are on this VM:\n", + "print(\"CPU count =\", multiprocessing.cpu_count())" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "081fdd0e-03c7-4746-9066-9c1342b99cb2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LocalCluster(01fc9997, 'tcp://127.0.0.1:36457', workers=32, threads=32, memory=122.32 GiB)\n", + "View any work being done on the cluster here https://cluster-idaxm.dask.host/jupyter/proxy/8787/status\n" + ] + } + ], + "source": [ + "# Start up cluster and print some information about it:\n", + "client = Client(n_workers=32, threads_per_worker=1)\n", + "print(client.cluster)\n", + "print(\"View any work being done on the cluster here\", client.dashboard_link)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "3ed0c70a-dcf8-40ad-a4fc-68b1b0e47f51", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/coiled/env/lib/python3.12/site-packages/distributed/client.py:3164: UserWarning: Sending large graph of size 51.61 MiB.\n", + "This may cause some slowdown.\n", + "Consider scattering data ahead of time and using futures.\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1min 26s, sys: 18.8 s, total: 1min 45s\n", + "Wall time: 5min 18s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "# Setup parallel computations:\n", + "single_ref_earthaccess_par = delayed(single_ref_earthaccess)\n", + "tasks = [single_ref_earthaccess_par(fo, dir_save=dir_refs_indv_2019) for fo in fobjs[:365]]\n", + "\n", + "# Run parallel computations:\n", + "results = da.compute(*tasks)" + ] + }, + { + "cell_type": "markdown", + "id": "b083114d-de86-4860-911f-f44e21877725", + "metadata": {}, + "source": [ + "### 1.2.2 Optional Alternative: Parallelize using distributed cluster with Coiled\n", + "At PO.DAAC we have been testing the third party software/package Coiled which makes it easy to spin up distributed computing clusters in the cloud. Since we suspect that Coiled may become a key member of the Cloud ecosystem for earth science researchers, this optional section is included, which can be used as an alternative to Section 1.2.1 for generating the reference files in parallel." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05070095-1d23-4691-a984-5c7a13371b4c", + "metadata": {}, + "outputs": [], + "source": [ + "## Save reference JSONs in this directory:\n", + "dir_refs_indv_2019 = './reference_jsons_individual_2019/'\n", + "!mkdir $dir_refs_indv_2019" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8fa76bec-1ef7-4ed1-bc58-f16eea3aa9e8", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "73ce9a4acf724d998e8b19117a00dcd0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b655ecf3e9ad4278bd79e67391ea7679", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 58.2 s, sys: 17.1 s, total: 1min 15s\n", + "Wall time: 9min 7s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "## --------------------------------------------\n", + "## Create single reference files with parallel computing using Coiled\n", + "## --------------------------------------------\n", + "\n", + "# Wrap `create_single_ref` into coiled function:\n", + "single_ref_earthaccess_par = coiled.function(\n", + " region=\"us-west-2\", spot_policy=\"on-demand\", \n", + " vm_type=\"m6i.large\", n_workers=16\n", + " )(single_ref_earthaccess)\n", + "\n", + "# Begin computations:\n", + "results = single_ref_earthaccess_par.map(fobjs[:365])\n", + "\n", + "# Save results to JSONs as they become available:\n", + "for reference, endpoint in results:\n", + " name_ref = dir_refs_indv_2019 + endpoint.split('/')[-1].replace('.nc', '.json')\n", + " with open(name_ref, 'w') as outf:\n", + " outf.write(ujson.dumps(reference))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "3d0c311a-9523-44d4-96eb-b88db5bda632", + "metadata": {}, + "outputs": [], + "source": [ + "single_ref_earthaccess_par.cluster.shutdown()" + ] + }, + { + "cell_type": "markdown", + "id": "d9ba2934-e00a-416c-98ab-2be6c7c4836e", + "metadata": {}, + "source": [ + "### 1.3 Create the combined reference file and use it to open the data\n", + "However the single reference files were generated in the previous section, they can now be used to create a single reference file for the entire year 2019. The computation time for this step can also be decreased with parallel computing, but in this case serial computing is used." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "becc2715-d6aa-463f-993b-717892758cca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 27 s, sys: 6.18 s, total: 33.2 s\n", + "Wall time: 2min 30s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "## --------------------------------------------\n", + "## Create combined reference file\n", + "## --------------------------------------------\n", + "\n", + "ref_files_indv = [dir_refs_indv_2019+f for f in os.listdir(dir_refs_indv_2019) if f.endswith('.json')]\n", + "ref_files_indv.sort()\n", + "\n", + "## Combined reference file\n", + "kwargs_mzz = {'remote_protocol':\"s3\", 'remote_options':fs.storage_options, 'concat_dims':[\"time\"]}\n", + "mzz = MultiZarrToZarr(ref_files_indv, **kwargs_mzz)\n", + "ref_combined = mzz.translate()\n", + "\n", + " # Save reference info to JSON:\n", + "with open(\"ref_combined_2019.json\", 'wb') as outf:\n", + " outf.write(ujson.dumps(ref_combined).encode())" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "92f0ea99-2643-4936-9821-4c6428682b98", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.Dataset>\n", + "Dimensions: (time: 365, lat: 17999, lon: 36000)\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-3...\n", + "Data variables:\n", + " analysed_sst (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " analysis_error (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " dt_1km_data (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " mask (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sea_ice_fraction (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sst_anomaly (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + "Attributes: (47)\n", + "CPU times: user 2.27 s, sys: 358 ms, total: 2.63 s\n", + "Wall time: 2.67 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Open the portion of the MUR record corresponding to the reference file created:\n", + "data = opendf_withref(json.load(open(\"ref_combined_2019.json\")), fs)\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "id": "a176122c-e85b-4bf1-aa70-804f50d396bb", + "metadata": {}, + "source": [ + "The data will open quickly now that we have the reference file. Compare that to an attempt at opening these same files with `Xarray` the \"traditional\" way with a call to `xr.open_mfdataset()`. On a smaller machine, the following line of code will either fail or take a long (possibly very long) amount of time:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "ec7ac19b-217b-472b-993a-0c560a228c30", + "metadata": {}, + "outputs": [], + "source": [ + "## You can try un-commenting and running this but your notebook will probably crash:\n", + "# data = xr.open_mfdataset(fobjs[:365])" + ] + }, + { + "cell_type": "markdown", + "id": "44e285c2-7a7b-48f8-85bc-1cad89ec55ed", + "metadata": {}, + "source": [ + "## 2. Generate the same MUR reference file but in PARQUET format\n", + "\n", + "For larger datasets, the combined reference file in JSON format can become large. For example, if we wanted to create a reference JSON for the entire MUR 0.01 degree record it is estimated to be 1-2 GB, and the MUR data set isn't even *that* large in the scheme of things. One solution to this is to save the reference information in PARQUET format (demonstrated in this section) which reduces the disk space required.\n", + "\n", + "Instead of re-creating all individual reference files, this section will load the combined 2019 reference file, then re-save in parquet format and use it to open the MUR data." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "9496eccc-79e5-4ee2-9989-20b4f636dab8", + "metadata": {}, + "outputs": [], + "source": [ + "ref_combined_2019 = json.load(open(\"ref_combined_2019.json\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "a665d526-f89a-4269-af4d-8ee0915147e4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3.26 s, sys: 140 ms, total: 3.4 s\n", + "Wall time: 3.22 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Save reference info to parquet:\n", + "refs_to_dataframe(ref_combined_2019, \"ref_combined_2019.parq\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "2d00609d-053d-43f6-9ee6-e0c413b302b9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.Dataset>\n", + "Dimensions: (time: 365, lat: 17999, lon: 36000)\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-3...\n", + "Data variables:\n", + " analysed_sst (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " analysis_error (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " dt_1km_data (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " mask (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sea_ice_fraction (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sst_anomaly (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + "Attributes: (47)\n", + "CPU times: user 65.4 ms, sys: 20.7 ms, total: 86.2 ms\n", + "Wall time: 383 ms\n" + ] + } + ], + "source": [ + "%%time\n", + "data = opendf_withref(\"ref_combined_2019.parq\", fs)\n", + "print(data)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "c6934772-0a1d-4e06-93c9-d556ab2829f9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "JSON: 77.881403 MB\n", + "PARQUET: 2.502714 MB\n" + ] + } + ], + "source": [ + "## Compare size of JSON vs parquet, printed in MB\n", + " # JSON\n", + "print(\"JSON:\", os.path.getsize(\"ref_combined_2019.json\")/10**6, \"MB\")\n", + " # parquet\n", + "size_parq = 0 \n", + "for path, dirs, files in os.walk(\"ref_combined_2019.parq\"):\n", + " for f in files:\n", + " fp = os.path.join(path, f)\n", + " size_parq += os.path.getsize(fp)\n", + "print(\"PARQUET:\", size_parq/10**6, \"MB\")" + ] + }, + { + "cell_type": "markdown", + "id": "605954f8-1a25-4945-bccd-b3c0d40af29b", + "metadata": {}, + "source": [ + "## 3. Combining reference files\n", + "This section demonstrates that reference files can be combined in two examples:\n", + "\n", + "1. A single reference file (for the first day of 2020) is appended to the combined reference file for 2019 generated in the previous section.\n", + "2. A second year-long combined reference file is created for all of 2020 and combined with the 2019 reference file.\n", + "\n", + "In both cases, a key result is that creating the final product (e.g. combining two reference files) is much shorter than it would have been to create it from scratch." + ] + }, + { + "cell_type": "markdown", + "id": "5525766d-d62d-4de2-a7b0-1c460aaa001d", + "metadata": {}, + "source": [ + "### 3.1 Adding an extra day of the MUR record to our existing reference file." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "51b0736a-e581-4e7f-991a-6a2ced3e3504", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5.07 s, sys: 1.95 s, total: 7.02 s\n", + "Wall time: 21.7 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Create reference file for first day in 2020:\n", + "ref_add, endpoint_add = single_ref_earthaccess(fobjs[365])\n", + "\n", + "name_ref_add = endpoint_add.split('/')[-1].replace('.nc', '.json')\n", + "with open(name_ref_add, 'w') as outf:\n", + " outf.write(ujson.dumps(ref_add))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "19a23add-33df-4928-8f25-b425985fe81a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 4.02 s, sys: 2.25 s, total: 6.27 s\n", + "Wall time: 5.16 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "# Add it to the combined reference file:\n", + "kwargs_mzz = {'remote_protocol':\"s3\", 'remote_options':fs.storage_options, 'concat_dims':[\"time\"]}\n", + "mzz = MultiZarrToZarr([\"ref_combined_2019.json\", name_ref_add], **kwargs_mzz)\n", + "ref_combined_add1day = mzz.translate()\n", + "\n", + " # Save reference info to JSON:\n", + "with open(\"ref_combined_add1day.json\", 'wb') as outf:\n", + " outf.write(ujson.dumps(ref_combined_add1day).encode())" + ] + }, + { + "cell_type": "markdown", + "id": "9c65d58c-ac99-4ca9-a3fb-05c09d2329b9", + "metadata": {}, + "source": [ + "**Appending an additional file does not take much time!**" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "dd59aa08-a5f2-40bc-bdd8-07e8c6e782b3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "366\n", + "<xarray.Dataset>\n", + "Dimensions: (time: 366, lat: 17999, lon: 36000)\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2020-01-0...\n", + "Data variables:\n", + " analysed_sst (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " analysis_error (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " dt_1km_data (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " mask (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sea_ice_fraction (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sst_anomaly (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + "Attributes: (47)\n", + "CPU times: user 1.48 s, sys: 145 ms, total: 1.63 s\n", + "Wall time: 1.76 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Open data using new reference file:\n", + "data = opendf_withref(\"ref_combined_add1day.json\", fs)\n", + "print(len(data[\"time\"]))\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "id": "af585b0b-9c7e-45dd-9ea0-8b39f83af375", + "metadata": {}, + "source": [ + "### 3.2 Combining two year-long combined reference files\n", + "Individual files for 2020 are created and combined into a single reference file, then this file is combined with the 2019 reference file. As before, parallel computing is used to speed up creation of the files, but this could also be accomplished with a for-loop. " + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "238e9c31-af8a-4cf8-9c9b-8f687978d419", + "metadata": {}, + "outputs": [], + "source": [ + "## Save individual reference JSONs in this directory:\n", + "dir_refs_indv_2020 = './reference_jsons_individual_2020/'\n", + "!mkdir $dir_refs_indv_2020" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d67f7a3a-511e-4bde-8385-121854129842", + "metadata": {}, + "outputs": [], + "source": [ + "## !!!!!!!!!!!\n", + "## This line only needs to be run if you don't have a cluster already running\n", + "## from Section 1.2.1\n", + "## !!!!!!!!!!!\n", + "# Start up cluster:\n", + "client = Client(n_workers=32, threads_per_worker=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "30a37e94-5b90-4902-9be1-c76db23d774d", + "metadata": {}, + "outputs": [], + "source": [ + "# Setup parallel computations:\n", + "single_ref_earthaccess_par = delayed(single_ref_earthaccess)\n", + "tasks = [single_ref_earthaccess_par(fo, dir_save=dir_refs_indv_2020) for fo in fobjs[365:]]" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "ffb9967c-e962-4524-91b9-6eb9845e0f76", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/coiled/env/lib/python3.12/site-packages/distributed/client.py:3164: UserWarning: Sending large graph of size 51.63 MiB.\n", + "This may cause some slowdown.\n", + "Consider scattering data ahead of time and using futures.\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2min 2s, sys: 53.6 s, total: 2min 55s\n", + "Wall time: 6min 4s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Run parallel computations:\n", + "results = da.compute(*tasks)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "39cc7952-bcfc-46c6-b53c-edd4e17f90ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 37.4 s, sys: 15.1 s, total: 52.5 s\n", + "Wall time: 2min 11s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "## --------------------------------------------\n", + "## Create combined reference file for 2020\n", + "## --------------------------------------------\n", + "\n", + "ref_files_indv = [dir_refs_indv_2020+f for f in os.listdir(dir_refs_indv_2020) if f.endswith('.json')]\n", + "ref_files_indv.sort()\n", + "\n", + "## Combined reference file\n", + "kwargs_mzz = {'remote_protocol':\"s3\", 'remote_options':fs.storage_options, 'concat_dims':[\"time\"]}\n", + "mzz = MultiZarrToZarr(ref_files_indv, **kwargs_mzz)\n", + "ref_combined = mzz.translate()\n", + "\n", + " # Save reference info to JSON:\n", + "with open(\"ref_combined_2020.json\", 'wb') as outf:\n", + " outf.write(ujson.dumps(ref_combined).encode())" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "eb120878-6fd7-42d1-9d75-86fb54ce6630", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 10.7 s, sys: 5.73 s, total: 16.4 s\n", + "Wall time: 12.8 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "## --------------------------------------------\n", + "## Then create combined reference file for 2019 and 2020\n", + "## --------------------------------------------\n", + "\n", + "kwargs_mzz = {'remote_protocol':\"s3\", 'remote_options':fs.storage_options, 'concat_dims':[\"time\"]}\n", + "mzz = MultiZarrToZarr([\"ref_combined_2019.json\", \"ref_combined_2020.json\"], **kwargs_mzz)\n", + "ref_combined_2years = mzz.translate()\n", + "\n", + " # Save reference info to JSON:\n", + "with open(\"ref_combined_2019-2020.json\", 'wb') as outf:\n", + " outf.write(ujson.dumps(ref_combined_2years).encode())" + ] + }, + { + "cell_type": "markdown", + "id": "a18fb8d4-4d10-4f61-b426-c77e5a92daaf", + "metadata": {}, + "source": [ + "***Note the large difference in computation time to create the 2020 combined reference file from the individual reference files, vs. combining the two year-long reference files for 2019 and 2020. The latter is much shorter!***" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "c1af9234-1aee-4537-ac6c-97e2f2395609", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "732\n", + "<xarray.Dataset>\n", + "Dimensions: (time: 732, lat: 17999, lon: 36000)\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2021-01-0...\n", + "Data variables:\n", + " analysed_sst (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " analysis_error (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + " dt_1km_data (time, lat, lon) timedelta64[ns] dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " mask (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sea_ice_fraction (time, lat, lon) float32 dask.array<chunksize=(1, 1447, 2895), meta=np.ndarray>\n", + " sst_anomaly (time, lat, lon) float32 dask.array<chunksize=(1, 1023, 2047), meta=np.ndarray>\n", + "Attributes: (47)\n", + "CPU times: user 3.21 s, sys: 467 ms, total: 3.68 s\n", + "Wall time: 3.63 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Open data using new reference file:\n", + "data = opendf_withref(\"ref_combined_2019-2020.json\", fs)\n", + "print(len(data[\"time\"]))\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "id": "96dc2738-5a47-4356-807a-ae86607a806d", + "metadata": {}, + "source": [ + "## 4. Using a reference file to analyze the MUR data with parallel computing\n", + "\n", + "This section verifies that the reference file can be used to perform computations on the MUR data, additionally verifying that parallel computing can be implemented with the computations. We try parallel computations using both a local and distributed cluster. \n", + "\n", + "The analysis will bin/average the 2019 MUR SST data by month, to generate a \"mean seasonal cycle\" (of course, one year of data isn't enough to produce a real a mean seasonal cycle). The analysis uses Xarray built in functions which naturally parallelize on Dask clusters." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "f9040928-42a0-44b5-a532-d2ba81169ea9", + "metadata": {}, + "outputs": [], + "source": [ + "def seasonal_cycle_regional(data_array, lat_region, lon_region):\n", + " \"\"\"\n", + " Uses built in Xarray functions to generate a mean seasonal cycle at each grid point \n", + " over a specified region. Any temporal linear trends are first removed at each point \n", + " respecitvely, then data are binned and averaged by month. \n", + " \"\"\"\n", + " ## Subset to region:\n", + " da_regional = data_array.sel(lat=slice(*lat_region), lon=slice(*lon_region))\n", + " \n", + " ## Remove any linear trends:\n", + " p = da_regional.polyfit(dim='time', deg=1) # Degree 1 polynomial fit coefficients over time for each lat, lon.\n", + " fit = xr.polyval(da_regional['time'], p.polyfit_coefficients) # Compute linear trend time series at each lat, lon.\n", + " da_detrend = (da_regional - fit) # xarray is smart enough to subtract along the time dim only.\n", + " \n", + " ## Mean seasonal cycle:\n", + " seasonal_cycle = da_detrend.groupby(\"time.month\").mean(\"time\")\n", + " return seasonal_cycle" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "037824cf-1c4e-4122-a457-32e8a7f09e27", + "metadata": {}, + "outputs": [], + "source": [ + "# Region to perform analysis over:\n", + "lat_region = (30, 45)\n", + "lon_region = (-135, -105)" + ] + }, + { + "cell_type": "markdown", + "id": "bc9ea98b-8f78-440d-8ca7-df20ef6cea4c", + "metadata": {}, + "source": [ + "### 4.1 Using a local cluster\n", + "This section was run using 16 workers on an `m6i.8xlarge` EC2 instance. Any warning messages generated by the cluster are left in the output here intentionally. Note that despite the warning messages, the parallel computations complete successfully. " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "b3049e68-de11-4171-bce3-524eec799a3d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU count = 32\n" + ] + } + ], + "source": [ + "print(\"CPU count =\", multiprocessing.cpu_count())" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "0f394dec-4fc9-49b0-8015-b9ceb7d62ea9", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/coiled/env/lib/python3.12/site-packages/distributed/node.py:182: UserWarning: Port 8787 is already in use.\n", + "Perhaps you already have a cluster running?\n", + "Hosting the HTTP server on port 39973 instead\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LocalCluster(5c690e69, 'tcp://127.0.0.1:44549', workers=16, threads=16, memory=122.32 GiB)\n" + ] + }, + { + "data": { + "text/plain": [ + "'https://cluster-idaxm.dask.host/jupyter/proxy/39973/status'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "## Local Dask Cluster\n", + "client = Client(n_workers=16, threads_per_worker=1)\n", + "print(client.cluster)\n", + "client.dashboard_link" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "52fd8390-86b6-4dd0-aeb8-f36a2b58cbad", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n", + "<defs>\n", + "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n", + "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n", + "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", + "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", + "</symbol>\n", + "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n", + "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n", + "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", + "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", + "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", + "</symbol>\n", + "</defs>\n", + "</svg>\n", + "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n", + " *\n", + " */\n", + "\n", + ":root {\n", + " --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n", + " --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n", + " --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n", + " --xr-border-color: var(--jp-border-color2, #e0e0e0);\n", + " --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n", + " --xr-background-color: var(--jp-layout-color0, white);\n", + " --xr-background-color-row-even: var(--jp-layout-color1, white);\n", + " --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n", + "}\n", + "\n", + "html[theme=dark],\n", + "body[data-theme=dark],\n", + "body.vscode-dark {\n", + " --xr-font-color0: rgba(255, 255, 255, 1);\n", + " --xr-font-color2: rgba(255, 255, 255, 0.54);\n", + " --xr-font-color3: rgba(255, 255, 255, 0.38);\n", + " --xr-border-color: #1F1F1F;\n", + " --xr-disabled-color: #515151;\n", + " --xr-background-color: #111111;\n", + " --xr-background-color-row-even: #111111;\n", + " --xr-background-color-row-odd: #313131;\n", + "}\n", + "\n", + ".xr-wrap {\n", + " display: block !important;\n", + " min-width: 300px;\n", + " max-width: 700px;\n", + "}\n", + "\n", + ".xr-text-repr-fallback {\n", + " /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n", + " display: none;\n", + "}\n", + "\n", + ".xr-header {\n", + " padding-top: 6px;\n", + " padding-bottom: 6px;\n", + " margin-bottom: 4px;\n", + " border-bottom: solid 1px var(--xr-border-color);\n", + "}\n", + "\n", + ".xr-header > div,\n", + ".xr-header > ul {\n", + " display: inline;\n", + " margin-top: 0;\n", + " margin-bottom: 0;\n", + "}\n", + "\n", + ".xr-obj-type,\n", + ".xr-array-name {\n", + " margin-left: 2px;\n", + " margin-right: 10px;\n", + "}\n", + "\n", + ".xr-obj-type {\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-sections {\n", + " padding-left: 0 !important;\n", + " display: grid;\n", + " grid-template-columns: 150px auto auto 1fr 20px 20px;\n", + "}\n", + "\n", + ".xr-section-item {\n", + " display: contents;\n", + "}\n", + "\n", + ".xr-section-item input {\n", + " display: none;\n", + "}\n", + "\n", + ".xr-section-item input + label {\n", + " color: var(--xr-disabled-color);\n", + "}\n", + "\n", + ".xr-section-item input:enabled + label {\n", + " cursor: pointer;\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-section-item input:enabled + label:hover {\n", + " color: var(--xr-font-color0);\n", + "}\n", + "\n", + ".xr-section-summary {\n", + " grid-column: 1;\n", + " color: var(--xr-font-color2);\n", + " font-weight: 500;\n", + "}\n", + "\n", + ".xr-section-summary > span {\n", + " display: inline-block;\n", + " padding-left: 0.5em;\n", + "}\n", + "\n", + ".xr-section-summary-in:disabled + label {\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-section-summary-in + label:before {\n", + " display: inline-block;\n", + " content: '►';\n", + " font-size: 11px;\n", + " width: 15px;\n", + " text-align: center;\n", + "}\n", + "\n", + ".xr-section-summary-in:disabled + label:before {\n", + " color: var(--xr-disabled-color);\n", + "}\n", + "\n", + ".xr-section-summary-in:checked + label:before {\n", + " content: '▼';\n", + "}\n", + "\n", + ".xr-section-summary-in:checked + label > span {\n", + " display: none;\n", + "}\n", + "\n", + ".xr-section-summary,\n", + ".xr-section-inline-details {\n", + " padding-top: 4px;\n", + " padding-bottom: 4px;\n", + "}\n", + "\n", + ".xr-section-inline-details {\n", + " grid-column: 2 / -1;\n", + "}\n", + "\n", + ".xr-section-details {\n", + " display: none;\n", + " grid-column: 1 / -1;\n", + " margin-bottom: 5px;\n", + "}\n", + "\n", + ".xr-section-summary-in:checked ~ .xr-section-details {\n", + " display: contents;\n", + "}\n", + "\n", + ".xr-array-wrap {\n", + " grid-column: 1 / -1;\n", + " display: grid;\n", + " grid-template-columns: 20px auto;\n", + "}\n", + "\n", + ".xr-array-wrap > label {\n", + " grid-column: 1;\n", + " vertical-align: top;\n", + "}\n", + "\n", + ".xr-preview {\n", + " color: var(--xr-font-color3);\n", + "}\n", + "\n", + ".xr-array-preview,\n", + ".xr-array-data {\n", + " padding: 0 5px !important;\n", + " grid-column: 2;\n", + "}\n", + "\n", + ".xr-array-data,\n", + ".xr-array-in:checked ~ .xr-array-preview {\n", + " display: none;\n", + "}\n", + "\n", + ".xr-array-in:checked ~ .xr-array-data,\n", + ".xr-array-preview {\n", + " display: inline-block;\n", + "}\n", + "\n", + ".xr-dim-list {\n", + " display: inline-block !important;\n", + " list-style: none;\n", + " padding: 0 !important;\n", + " margin: 0;\n", + "}\n", + "\n", + ".xr-dim-list li {\n", + " display: inline-block;\n", + " padding: 0;\n", + " margin: 0;\n", + "}\n", + "\n", + ".xr-dim-list:before {\n", + " content: '(';\n", + "}\n", + "\n", + ".xr-dim-list:after {\n", + " content: ')';\n", + "}\n", + "\n", + ".xr-dim-list li:not(:last-child):after {\n", + " content: ',';\n", + " padding-right: 5px;\n", + "}\n", + "\n", + ".xr-has-index {\n", + " font-weight: bold;\n", + "}\n", + "\n", + ".xr-var-list,\n", + ".xr-var-item {\n", + " display: contents;\n", + "}\n", + "\n", + ".xr-var-item > div,\n", + ".xr-var-item label,\n", + ".xr-var-item > .xr-var-name span {\n", + " background-color: var(--xr-background-color-row-even);\n", + " margin-bottom: 0;\n", + "}\n", + "\n", + ".xr-var-item > .xr-var-name:hover span {\n", + " padding-right: 5px;\n", + "}\n", + "\n", + ".xr-var-list > li:nth-child(odd) > div,\n", + ".xr-var-list > li:nth-child(odd) > label,\n", + ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n", + " background-color: var(--xr-background-color-row-odd);\n", + "}\n", + "\n", + ".xr-var-name {\n", + " grid-column: 1;\n", + "}\n", + "\n", + ".xr-var-dims {\n", + " grid-column: 2;\n", + "}\n", + "\n", + ".xr-var-dtype {\n", + " grid-column: 3;\n", + " text-align: right;\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-var-preview {\n", + " grid-column: 4;\n", + "}\n", + "\n", + ".xr-index-preview {\n", + " grid-column: 2 / 5;\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-var-name,\n", + ".xr-var-dims,\n", + ".xr-var-dtype,\n", + ".xr-preview,\n", + ".xr-attrs dt {\n", + " white-space: nowrap;\n", + " overflow: hidden;\n", + " text-overflow: ellipsis;\n", + " padding-right: 10px;\n", + "}\n", + "\n", + ".xr-var-name:hover,\n", + ".xr-var-dims:hover,\n", + ".xr-var-dtype:hover,\n", + ".xr-attrs dt:hover {\n", + " overflow: visible;\n", + " width: auto;\n", + " z-index: 1;\n", + "}\n", + "\n", + ".xr-var-attrs,\n", + ".xr-var-data,\n", + ".xr-index-data {\n", + " display: none;\n", + " background-color: var(--xr-background-color) !important;\n", + " padding-bottom: 5px !important;\n", + "}\n", + "\n", + ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n", + ".xr-var-data-in:checked ~ .xr-var-data,\n", + ".xr-index-data-in:checked ~ .xr-index-data {\n", + " display: block;\n", + "}\n", + "\n", + ".xr-var-data > table {\n", + " float: right;\n", + "}\n", + "\n", + ".xr-var-name span,\n", + ".xr-var-data,\n", + ".xr-index-name div,\n", + ".xr-index-data,\n", + ".xr-attrs {\n", + " padding-left: 25px !important;\n", + "}\n", + "\n", + ".xr-attrs,\n", + ".xr-var-attrs,\n", + ".xr-var-data,\n", + ".xr-index-data {\n", + " grid-column: 1 / -1;\n", + "}\n", + "\n", + "dl.xr-attrs {\n", + " padding: 0;\n", + " margin: 0;\n", + " display: grid;\n", + " grid-template-columns: 125px auto;\n", + "}\n", + "\n", + ".xr-attrs dt,\n", + ".xr-attrs dd {\n", + " padding: 0;\n", + " margin: 0;\n", + " float: left;\n", + " padding-right: 10px;\n", + " width: auto;\n", + "}\n", + "\n", + ".xr-attrs dt {\n", + " font-weight: normal;\n", + " grid-column: 1;\n", + "}\n", + "\n", + ".xr-attrs dt:hover span {\n", + " display: inline-block;\n", + " background: var(--xr-background-color);\n", + " padding-right: 10px;\n", + "}\n", + "\n", + ".xr-attrs dd {\n", + " grid-column: 2;\n", + " white-space: pre-wrap;\n", + " word-break: break-all;\n", + "}\n", + "\n", + ".xr-icon-database,\n", + ".xr-icon-file-text2,\n", + ".xr-no-icon {\n", + " display: inline-block;\n", + " vertical-align: middle;\n", + " width: 1em;\n", + " height: 1.5em !important;\n", + " stroke-width: 0;\n", + " stroke: currentColor;\n", + " fill: currentColor;\n", + "}\n", + "</style><pre class='xr-text-repr-fallback'><xarray.DataArray 'analysed_sst' (time: 365, lat: 17999, lon: 36000)>\n", + "dask.array<rechunk-merge, shape=(365, 17999, 36000), dtype=float32, chunksize=(200, 300, 300), chunktype=numpy.ndarray>\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 -89.96 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-31T09:00:00\n", + "Attributes: (7)</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'analysed_sst'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>time</span>: 365</li><li><span class='xr-has-index'>lat</span>: 17999</li><li><span class='xr-has-index'>lon</span>: 36000</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-8b18919e-3a04-4e22-9e2f-a8bf39a2d6ac' class='xr-array-in' type='checkbox' checked><label for='section-8b18919e-3a04-4e22-9e2f-a8bf39a2d6ac' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array<chunksize=(200, 300, 300), meta=np.ndarray></span></div><div class='xr-array-data'><table>\n", + " <tr>\n", + " <td>\n", + " <table style=\"border-collapse: collapse;\">\n", + " <thead>\n", + " <tr>\n", + " <td> </td>\n", + " <th> Array </th>\n", + " <th> Chunk </th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " \n", + " <tr>\n", + " <th> Bytes </th>\n", + " <td> 881.06 GiB </td>\n", + " <td> 68.66 MiB </td>\n", + " </tr>\n", + " \n", + " <tr>\n", + " <th> Shape </th>\n", + " <td> (365, 17999, 36000) </td>\n", + " <td> (200, 300, 300) </td>\n", + " </tr>\n", + " <tr>\n", + " <th> Dask graph </th>\n", + " <td colspan=\"2\"> 14400 chunks in 4 graph layers </td>\n", + " </tr>\n", + " <tr>\n", + " <th> Data type </th>\n", + " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", + " </tr>\n", + " </tbody>\n", + " </table>\n", + " </td>\n", + " <td>\n", + " <svg width=\"194\" height=\"124\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", + "\n", + " <!-- Horizontal lines -->\n", + " <line x1=\"10\" y1=\"0\" x2=\"24\" y2=\"14\" style=\"stroke-width:2\" />\n", + " <line x1=\"10\" y1=\"3\" x2=\"24\" y2=\"17\" />\n", + " <line x1=\"10\" y1=\"6\" x2=\"24\" y2=\"20\" />\n", + " <line x1=\"10\" y1=\"9\" x2=\"24\" y2=\"23\" />\n", + " <line x1=\"10\" y1=\"12\" x2=\"24\" y2=\"26\" />\n", + " <line x1=\"10\" y1=\"15\" x2=\"24\" y2=\"29\" />\n", + " <line x1=\"10\" y1=\"18\" x2=\"24\" y2=\"32\" />\n", + " <line x1=\"10\" y1=\"22\" x2=\"24\" y2=\"36\" />\n", + " <line x1=\"10\" y1=\"25\" x2=\"24\" y2=\"39\" />\n", + " <line x1=\"10\" y1=\"28\" x2=\"24\" y2=\"42\" />\n", + " <line x1=\"10\" y1=\"31\" x2=\"24\" y2=\"45\" />\n", + " <line x1=\"10\" y1=\"34\" x2=\"24\" y2=\"48\" />\n", + " <line x1=\"10\" y1=\"37\" x2=\"24\" y2=\"51\" />\n", + " <line x1=\"10\" y1=\"41\" x2=\"24\" y2=\"55\" />\n", + " <line x1=\"10\" y1=\"44\" x2=\"24\" y2=\"58\" />\n", + " <line x1=\"10\" y1=\"47\" x2=\"24\" y2=\"61\" />\n", + " <line x1=\"10\" y1=\"50\" x2=\"24\" y2=\"64\" />\n", + " <line x1=\"10\" y1=\"53\" x2=\"24\" y2=\"67\" />\n", + " <line x1=\"10\" y1=\"56\" x2=\"24\" y2=\"70\" />\n", + " <line x1=\"10\" y1=\"59\" x2=\"24\" y2=\"74\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Vertical lines -->\n", + " <line x1=\"10\" y1=\"0\" x2=\"10\" y2=\"59\" style=\"stroke-width:2\" />\n", + " <line x1=\"18\" y1=\"8\" x2=\"18\" y2=\"68\" />\n", + " <line x1=\"24\" y1=\"14\" x2=\"24\" y2=\"74\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Colored Rectangle -->\n", + " <polygon points=\"10.0,0.0 24.987517576607736,14.987517576607734 24.987517576607736,74.9841842432744 10.0,59.99666666666667\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", + "\n", + " <!-- Horizontal lines -->\n", + " <line x1=\"10\" y1=\"0\" x2=\"130\" y2=\"0\" style=\"stroke-width:2\" />\n", + " <line x1=\"18\" y1=\"8\" x2=\"138\" y2=\"8\" />\n", + " <line x1=\"24\" y1=\"14\" x2=\"144\" y2=\"14\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Vertical lines -->\n", + " <line x1=\"10\" y1=\"0\" x2=\"24\" y2=\"14\" style=\"stroke-width:2\" />\n", + " <line x1=\"16\" y1=\"0\" x2=\"30\" y2=\"14\" />\n", + " <line x1=\"22\" y1=\"0\" x2=\"36\" y2=\"14\" />\n", + " <line x1=\"28\" y1=\"0\" x2=\"42\" y2=\"14\" />\n", + " <line x1=\"35\" y1=\"0\" x2=\"49\" y2=\"14\" />\n", + " <line x1=\"41\" y1=\"0\" x2=\"55\" y2=\"14\" />\n", + " <line x1=\"47\" y1=\"0\" x2=\"61\" y2=\"14\" />\n", + " <line x1=\"54\" y1=\"0\" x2=\"68\" y2=\"14\" />\n", + " <line x1=\"60\" y1=\"0\" x2=\"74\" y2=\"14\" />\n", + " <line x1=\"66\" y1=\"0\" x2=\"80\" y2=\"14\" />\n", + " <line x1=\"73\" y1=\"0\" x2=\"87\" y2=\"14\" />\n", + " <line x1=\"79\" y1=\"0\" x2=\"93\" y2=\"14\" />\n", + " <line x1=\"85\" y1=\"0\" x2=\"99\" y2=\"14\" />\n", + " <line x1=\"92\" y1=\"0\" x2=\"106\" y2=\"14\" />\n", + " <line x1=\"98\" y1=\"0\" x2=\"112\" y2=\"14\" />\n", + " <line x1=\"104\" y1=\"0\" x2=\"118\" y2=\"14\" />\n", + " <line x1=\"111\" y1=\"0\" x2=\"125\" y2=\"14\" />\n", + " <line x1=\"117\" y1=\"0\" x2=\"131\" y2=\"14\" />\n", + " <line x1=\"123\" y1=\"0\" x2=\"137\" y2=\"14\" />\n", + " <line x1=\"130\" y1=\"0\" x2=\"144\" y2=\"14\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Colored Rectangle -->\n", + " <polygon points=\"10.0,0.0 130.0,0.0 144.98751757660773,14.987517576607734 24.987517576607736,14.987517576607734\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", + "\n", + " <!-- Horizontal lines -->\n", + " <line x1=\"24\" y1=\"14\" x2=\"144\" y2=\"14\" style=\"stroke-width:2\" />\n", + " <line x1=\"24\" y1=\"17\" x2=\"144\" y2=\"17\" />\n", + " <line x1=\"24\" y1=\"20\" x2=\"144\" y2=\"20\" />\n", + " <line x1=\"24\" y1=\"23\" x2=\"144\" y2=\"23\" />\n", + " <line x1=\"24\" y1=\"26\" x2=\"144\" y2=\"26\" />\n", + " <line x1=\"24\" y1=\"29\" x2=\"144\" y2=\"29\" />\n", + " <line x1=\"24\" y1=\"32\" x2=\"144\" y2=\"32\" />\n", + " <line x1=\"24\" y1=\"36\" x2=\"144\" y2=\"36\" />\n", + " <line x1=\"24\" y1=\"39\" x2=\"144\" y2=\"39\" />\n", + " <line x1=\"24\" y1=\"42\" x2=\"144\" y2=\"42\" />\n", + " <line x1=\"24\" y1=\"45\" x2=\"144\" y2=\"45\" />\n", + " <line x1=\"24\" y1=\"48\" x2=\"144\" y2=\"48\" />\n", + " <line x1=\"24\" y1=\"51\" x2=\"144\" y2=\"51\" />\n", + " <line x1=\"24\" y1=\"55\" x2=\"144\" y2=\"55\" />\n", + " <line x1=\"24\" y1=\"58\" x2=\"144\" y2=\"58\" />\n", + " <line x1=\"24\" y1=\"61\" x2=\"144\" y2=\"61\" />\n", + " <line x1=\"24\" y1=\"64\" x2=\"144\" y2=\"64\" />\n", + " <line x1=\"24\" y1=\"67\" x2=\"144\" y2=\"67\" />\n", + " <line x1=\"24\" y1=\"70\" x2=\"144\" y2=\"70\" />\n", + " <line x1=\"24\" y1=\"74\" x2=\"144\" y2=\"74\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Vertical lines -->\n", + " <line x1=\"24\" y1=\"14\" x2=\"24\" y2=\"74\" style=\"stroke-width:2\" />\n", + " <line x1=\"30\" y1=\"14\" x2=\"30\" y2=\"74\" />\n", + " <line x1=\"36\" y1=\"14\" x2=\"36\" y2=\"74\" />\n", + " <line x1=\"42\" y1=\"14\" x2=\"42\" y2=\"74\" />\n", + " <line x1=\"49\" y1=\"14\" x2=\"49\" y2=\"74\" />\n", + " <line x1=\"55\" y1=\"14\" x2=\"55\" y2=\"74\" />\n", + " <line x1=\"61\" y1=\"14\" x2=\"61\" y2=\"74\" />\n", + " <line x1=\"68\" y1=\"14\" x2=\"68\" y2=\"74\" />\n", + " <line x1=\"74\" y1=\"14\" x2=\"74\" y2=\"74\" />\n", + " <line x1=\"80\" y1=\"14\" x2=\"80\" y2=\"74\" />\n", + " <line x1=\"87\" y1=\"14\" x2=\"87\" y2=\"74\" />\n", + " <line x1=\"93\" y1=\"14\" x2=\"93\" y2=\"74\" />\n", + " <line x1=\"99\" y1=\"14\" x2=\"99\" y2=\"74\" />\n", + " <line x1=\"106\" y1=\"14\" x2=\"106\" y2=\"74\" />\n", + " <line x1=\"112\" y1=\"14\" x2=\"112\" y2=\"74\" />\n", + " <line x1=\"118\" y1=\"14\" x2=\"118\" y2=\"74\" />\n", + " <line x1=\"125\" y1=\"14\" x2=\"125\" y2=\"74\" />\n", + " <line x1=\"131\" y1=\"14\" x2=\"131\" y2=\"74\" />\n", + " <line x1=\"137\" y1=\"14\" x2=\"137\" y2=\"74\" />\n", + " <line x1=\"144\" y1=\"14\" x2=\"144\" y2=\"74\" style=\"stroke-width:2\" />\n", + "\n", + " <!-- Colored Rectangle -->\n", + " <polygon points=\"24.987517576607736,14.987517576607734 144.98751757660773,14.987517576607734 144.98751757660773,74.9841842432744 24.987517576607736,74.9841842432744\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", + "\n", + " <!-- Text -->\n", + " <text x=\"84.987518\" y=\"94.984184\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >36000</text>\n", + " <text x=\"164.987518\" y=\"44.985851\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,164.987518,44.985851)\">17999</text>\n", + " <text x=\"7.493759\" y=\"87.490425\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,7.493759,87.490425)\">365</text>\n", + "</svg>\n", + " </td>\n", + " </tr>\n", + "</table></div></div></li><li class='xr-section-item'><input id='section-46a40640-018d-49b6-969a-dcbc6f523906' class='xr-section-summary-in' type='checkbox' checked><label for='section-46a40640-018d-49b6-969a-dcbc6f523906' class='xr-section-summary' >Coordinates: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>-89.99 -89.98 ... 89.98 89.99</div><input id='attrs-e49a8084-b68a-4143-802f-b9f1e4b7253e' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-e49a8084-b68a-4143-802f-b9f1e4b7253e' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-78847008-ce11-4b72-9af6-63a14449b912' class='xr-var-data-in' type='checkbox'><label for='data-78847008-ce11-4b72-9af6-63a14449b912' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>Y</dd><dt><span>comment :</span></dt><dd>none</dd><dt><span>long_name :</span></dt><dd>latitude</dd><dt><span>standard_name :</span></dt><dd>latitude</dd><dt><span>units :</span></dt><dd>degrees_north</dd><dt><span>valid_max :</span></dt><dd>90.0</dd><dt><span>valid_min :</span></dt><dd>-90.0</dd></dl></div><div class='xr-var-data'><pre>array([-89.99, -89.98, -89.97, ..., 89.97, 89.98, 89.99], dtype=float32)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lon</span></div><div class='xr-var-dims'>(lon)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>-180.0 -180.0 ... 180.0 180.0</div><input id='attrs-16116dea-311a-4b09-a2bd-da96bf2c0a8e' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-16116dea-311a-4b09-a2bd-da96bf2c0a8e' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-1ceb21db-d257-4333-b973-6fb2330423e7' class='xr-var-data-in' type='checkbox'><label for='data-1ceb21db-d257-4333-b973-6fb2330423e7' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>X</dd><dt><span>comment :</span></dt><dd>none</dd><dt><span>long_name :</span></dt><dd>longitude</dd><dt><span>standard_name :</span></dt><dd>longitude</dd><dt><span>units :</span></dt><dd>degrees_east</dd><dt><span>valid_max :</span></dt><dd>180.0</dd><dt><span>valid_min :</span></dt><dd>-180.0</dd></dl></div><div class='xr-var-data'><pre>array([-179.99, -179.98, -179.97, ..., 179.98, 179.99, 180. ],\n", + " dtype=float32)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>datetime64[ns]</div><div class='xr-var-preview xr-preview'>2019-01-01T09:00:00 ... 2019-12-...</div><input id='attrs-04bb9aa4-0170-4701-bdd2-91bc06507fb4' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-04bb9aa4-0170-4701-bdd2-91bc06507fb4' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-cfb58675-edea-4885-a04a-c7b6fd0d9d87' class='xr-var-data-in' type='checkbox'><label for='data-cfb58675-edea-4885-a04a-c7b6fd0d9d87' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>T</dd><dt><span>comment :</span></dt><dd>Nominal time of analyzed fields</dd><dt><span>long_name :</span></dt><dd>reference time of sst field</dd><dt><span>standard_name :</span></dt><dd>time</dd></dl></div><div class='xr-var-data'><pre>array(['2019-01-01T09:00:00.000000000', '2019-01-02T09:00:00.000000000',\n", + " '2019-01-03T09:00:00.000000000', ..., '2019-12-29T09:00:00.000000000',\n", + " '2019-12-30T09:00:00.000000000', '2019-12-31T09:00:00.000000000'],\n", + " dtype='datetime64[ns]')</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-4f1003ca-1a36-4aec-a716-615339a84ea2' class='xr-section-summary-in' type='checkbox' ><label for='section-4f1003ca-1a36-4aec-a716-615339a84ea2' class='xr-section-summary' >Indexes: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>lat</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-c38a76ab-eb15-4f17-93d7-fc1ac8734764' class='xr-index-data-in' type='checkbox'/><label for='index-c38a76ab-eb15-4f17-93d7-fc1ac8734764' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-89.98999786376953, -89.9800033569336, -89.97000122070312,\n", + " -89.95999908447266, -89.94999694824219, -89.94000244140625,\n", + " -89.93000030517578, -89.91999816894531, -89.91000366210938,\n", + " -89.9000015258789,\n", + " ...\n", + " 89.9000015258789, 89.91000366210938, 89.91999816894531,\n", + " 89.93000030517578, 89.94000244140625, 89.94999694824219,\n", + " 89.95999908447266, 89.97000122070312, 89.9800033569336,\n", + " 89.98999786376953],\n", + " dtype='float32', name='lat', length=17999))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>lon</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-74587abd-53b6-4f00-9ea9-3daead1f6f2e' class='xr-index-data-in' type='checkbox'/><label for='index-74587abd-53b6-4f00-9ea9-3daead1f6f2e' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-179.99000549316406, -179.97999572753906, -179.97000122070312,\n", + " -179.9600067138672, -179.9499969482422, -179.94000244140625,\n", + " -179.92999267578125, -179.9199981689453, -179.91000366210938,\n", + " -179.89999389648438,\n", + " ...\n", + " 179.91000366210938, 179.9199981689453, 179.92999267578125,\n", + " 179.94000244140625, 179.9499969482422, 179.9600067138672,\n", + " 179.97000122070312, 179.97999572753906, 179.99000549316406,\n", + " 180.0],\n", + " dtype='float32', name='lon', length=36000))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>time</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-b8405649-6d9e-4505-afb7-5154f10d86ae' class='xr-index-data-in' type='checkbox'/><label for='index-b8405649-6d9e-4505-afb7-5154f10d86ae' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(DatetimeIndex(['2019-01-01 09:00:00', '2019-01-02 09:00:00',\n", + " '2019-01-03 09:00:00', '2019-01-04 09:00:00',\n", + " '2019-01-05 09:00:00', '2019-01-06 09:00:00',\n", + " '2019-01-07 09:00:00', '2019-01-08 09:00:00',\n", + " '2019-01-09 09:00:00', '2019-01-10 09:00:00',\n", + " ...\n", + " '2019-12-22 09:00:00', '2019-12-23 09:00:00',\n", + " '2019-12-24 09:00:00', '2019-12-25 09:00:00',\n", + " '2019-12-26 09:00:00', '2019-12-27 09:00:00',\n", + " '2019-12-28 09:00:00', '2019-12-29 09:00:00',\n", + " '2019-12-30 09:00:00', '2019-12-31 09:00:00'],\n", + " dtype='datetime64[ns]', name='time', length=365, freq=None))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-d61a9663-1fea-4047-bdbb-b37afa064fae' class='xr-section-summary-in' type='checkbox' ><label for='section-d61a9663-1fea-4047-bdbb-b37afa064fae' class='xr-section-summary' >Attributes: <span>(7)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>comment :</span></dt><dd>"Final" version using Multi-Resolution Variational Analysis (MRVA) method for interpolation</dd><dt><span>long_name :</span></dt><dd>analysed sea surface temperature</dd><dt><span>source :</span></dt><dd>MODIS_T-JPL, MODIS_A-JPL, AMSR2-REMSS, AVHRR19_G-NAVO, AVHRRMTA_G-NAVO, iQUAM-NOAA/NESDIS, Ice_Conc-OSISAF</dd><dt><span>standard_name :</span></dt><dd>sea_surface_foundation_temperature</dd><dt><span>units :</span></dt><dd>kelvin</dd><dt><span>valid_max :</span></dt><dd>32767</dd><dt><span>valid_min :</span></dt><dd>-32767</dd></dl></div></li></ul></div></div>" + ], + "text/plain": [ + "<xarray.DataArray 'analysed_sst' (time: 365, lat: 17999, lon: 36000)>\n", + "dask.array<rechunk-merge, shape=(365, 17999, 36000), dtype=float32, chunksize=(200, 300, 300), chunktype=numpy.ndarray>\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 -89.96 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-31T09:00:00\n", + "Attributes: (7)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = opendf_withref(\"ref_combined_2019.parq\", fs)\n", + "sst = data['analysed_sst']\n", + "sst = sst.chunk(chunks={'lat': 300, 'lon': 300, 'time': 200})\n", + "sst" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "d0491e97-9058-48cc-b02b-b9c95cb7a710", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 31.7 s, sys: 7.21 s, total: 38.9 s\n", + "Wall time: 55.3 s\n" + ] + } + ], + "source": [ + "%%time\n", + "seasonal_cycle = seasonal_cycle_regional(sst, lat_region, lon_region).compute()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "a5ee8dfa-b66c-44bf-bf82-66dbce678037", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$\\\\Delta$T (K)')" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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ac98v/j4+NCrVy9WrlxJnTp1aNWqFSEhIaxfv55WrVo993phVlZWLFu2jPbt29OhQwfat29P9erViYmJ4eTJkyQkJGT4tuzq6kqfPn34+++/ATI0YaX76aefOHv2LJ9//jkbN26kZcuWCCG4fPkyW7duJSQkxNDclZk33niDgwcPMn/+fP777z9at26Nr68vISEhXLx4kUOHDrFo0aKnLiDatGlTRo4cyffff0+VKlXo1asXQghWrlzJnTt3GDVqFE2bNs3V/ZaZli1bsmzZMrp3707NmjVRq9V07dqVatWq0b59ez766CM+/fRTypQpQ/v27fH39yciIoKrV6+yd+9ePvvsMypWrPjccWSlXbt2NGjQgP79++Ph4cGOHTs4evQo9evXZ+TIkYZyHh4eLF68mD59+lC9enXat29PhQoVSE5OJigoiD179tCwYUM2b96co/MOGjSI6dOnM3LkSHbt2oW/vz+nTp1ix44d9OzZk1WrVhmVt7e3p27duvz7778MGjSIsmXLolKpGDRoEP7+/nTr1o3SpUszb948bt++Tc2aNblw4QI7d+6kY8eOmSZQ2THV82zkyJFs3bqVxo0b07dvX6ytrdm9ezd3796lefPmzz3hXenSpZk+fTrjxo2jWrVq9O3bFzs7O9atW8elS5fo1q0bL7/88nOdIyt5eW25eW0kJibSqFEjypUrR+3atSlRogRxcXGsX7+e4OBgxo8fb/QZUeSZaxiY9OwuXrwovvrqK9GmTRsREBAgrK2thbW1tShdurQYMmRIlvNcREZGig8//FBUqVJF2NjYCHt7e1G2bFnx0ksviVWrVhmVvX79uujVq5fw8PAQtra2om7dumLJkiWZDpPcvHmzGDx4sChfvrxwcHAQ9vb2olKlSmLSpEkZJgkUQj9EtXfv3sLd3V1YWFgIf39/MXr06EzLZjesObOhmbGxsWLcuHGiZMmSwsrKSpQtW1Z8+umnIiUlJdPhzrmdVFAI/Rwer776qihWrJiwsLAQnp6eonnz5lkOP06fE6h+/frZHjc6Olp89NFHokKFCsLKyko4OTmJGjVqiI8//thoqGp298nSpUtF69athYuLi7CwsBB+fn6iefPmYubMmZnev1mZM2eOqFu3rrC1tTU8/pnNu/K0eLJy//590bdvX+Hu7i5UKpUAxNy5c43KbNu2TXTp0kV4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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "## Test plot seasonal cycle at a few gridpoint locations\n", + "\n", + "# Points to plot seasonal cycle at:\n", + "lat_points = (38, 38, 38, 38)\n", + "lon_points = (-123.25, -125, -128, -132)\n", + "\n", + "fig = plt.figure()\n", + "ax = plt.axes()\n", + "\n", + "for lat, lon in zip(lat_points, lon_points):\n", + " scycle_point = seasonal_cycle.sel(lat=lat, lon=lon)\n", + " ax.plot(scycle_point['month'], scycle_point.values, 'o-')\n", + "\n", + "ax.set_title(\"Seasonal cycle of temperature anomalies \\n at four test points\", fontsize=14)\n", + "ax.set_xlabel(\"month\", fontsize=12)\n", + "ax.set_ylabel(r\"$\\Delta$T (K)\", fontsize=12)" + ] + }, + { + "cell_type": "markdown", + "id": "923baa69-85d3-4718-864f-c67bfc0fc15c", + "metadata": {}, + "source": [ + "### 4.2 Optional: Using a distributed cluster\n", + "We use the third party software/package Coiled to spin up our distributed cluster." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "b6107bc2-f5b9-44f7-8591-5b3c49e7ffe6", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "daf54a40c5fb41cfbf330391ca3e84a8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b581a0bf1bb4e1c83851a3ccfe9781d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cluster = coiled.Cluster(\n", + " n_workers=25, \n", + " region=\"us-west-2\", \n", + " worker_vm_types=\"c7g.large\", # or can try \"m7a.medium\"\n", + " scheduler_vm_types=\"c7g.large\", # or can try \"m7a.medium\"\n", + " ) \n", + "client = cluster.get_client()" + ] + }, + { + "cell_type": "markdown", + "id": "9caf1c67-e9a1-4537-9a73-c78f69dcc307", + "metadata": {}, + "source": [ + "***Note that computations on the distributed cluster work if we fully load the reference information into memory first, but not if we just pass the path to the reference file!***" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "79eb4578-e229-48e5-920e-705727d61cbb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.DataArray 'analysed_sst' (time: 365, lat: 17999, lon: 36000)>\n", + "dask.array<rechunk-merge, shape=(365, 17999, 36000), dtype=float32, chunksize=(200, 300, 300), chunktype=numpy.ndarray>\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 -89.96 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-31T09:00:00\n", + "Attributes: (7)\n", + "CPU times: user 3.64 s, sys: 936 ms, total: 4.58 s\n", + "Wall time: 4.03 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "##==================================================================\n", + "## Only works if the reference is loaded into memory first!!!!\n", + "##==================================================================\n", + "with open(\"ref_combined_2019.json\") as f:\n", + " ref_loaded = json.load(f)\n", + "data = opendf_withref(ref_loaded, fs)\n", + "sst = data['analysed_sst']\n", + "sst = sst.chunk(chunks={'lat': 300, 'lon': 300, 'time': 200})\n", + "print(sst)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "4af68582-641e-4aef-a936-d9b927cbd7a4", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/coiled/env/lib/python3.12/site-packages/distributed/client.py:3164: UserWarning: Sending large graph of size 71.82 MiB.\n", + "This may cause some slowdown.\n", + "Consider scattering data ahead of time and using futures.\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 18 s, sys: 7.88 s, total: 25.9 s\n", + "Wall time: 46.5 s\n" + ] + } + ], + "source": [ + "%%time\n", + "seasonal_cycle = seasonal_cycle_regional(sst, lat_region, lon_region).compute()" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "2219062e-69b1-4bc6-a646-f571c9064e55", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, '$\\\\Delta$T (K)')" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHiCAYAAAAODw0hAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAADHjUlEQVR4nOzddXxTVxvA8d9NUnc3oBR3h+Lu7jKGjI1t7xgyYIMxAaawAWPuyIY7wx0Gw92d4nXqnpz3j9BAqNBC2rTlfPn0Q3vvyb3PjT45qgghBJIkSZIkSUWUytwBSJIkSZIk5SWZ7EiSJEmSVKTJZEeSJEmSpCJNJjuSJEmSJBVpMtmRJEmSJKlIk8mOJEmSJElFmkx2JEmSJEkq0mSyI0mSJElSkSaTHUmSJEmSijSZ7EgvtKFDh6IoCkFBQeYOJcdKlixJyZIlzR2GQWpqKlOmTKFs2bJYWVmhKApr1qwxd1iSVCjs3r0bRVGYMmWK0fbmzZujKIp5giqCZLJTSMXHx/PFF19Qq1Yt7O3tsbKyolixYjRp0oT333+fa9eumTtE6QUxc+ZMpk6diq+vL+PHj2fy5MlUqFAh29soikLz5s3zJ8AiLCgoCEVRGDp0qLlDkaQCTWPuAKTci42NpXHjxpw+fZoyZcrw8ssv4+bmRnh4OIcPH2batGmULl2a0qVLmztU6QWwfv167O3t2bZtG5aWluYOR5KKhL/++ouEhARzh1FkyGSnEJo9ezanT5/mtdde47fffstQ1Xnjxg2Sk5PNFJ30orl37x5ubm4y0ZEkEypRooS5QyhSZDNWIXTgwAEARowYkWmbbkBAQKbNCKGhobzzzjuUKVMGKysr3N3d6dWrF2fPns1QdteuXQwbNozy5ctjb2+Pvb09derU4bfffss0puPHj9O7d29KlCiBlZUVHh4e1K1bl88//zxD2bNnz9K3b188PT2xsrIiICCAMWPGEBERkaFsev+UuLg4Ro8eja+vL1ZWVlSrVo0VK1ZkKH/58mXee+89atWqhZubG9bW1pQrV46JEycSFxeXaey5df36dV5//XUCAgKwsrLC09OT5s2bM2/ePAC2b9+Ooii89dZbmd7+2rVrqFQq2rVrZ7Q9NjaWqVOnUq1aNWxtbXFycqJmzZp89NFHpKamPjUuIQRz5syhUaNGODo6YmtrS506dZgzZ06ur3Hu3LkEBgYaHvvAwEDD9aWbMmUKiqJw48YNbt68iaIoKIqSbX+i9P4JAHv27DHcRlGUDMdfu3YtrVq1wsXFBWtra6pUqcKMGTPQarVG5ebNm2e4/bp16wgMDMTW1hY/Pz8++ugjdDodAPPnz6d69erY2NhQokQJvv766wzxpV/T7t27+fPPP6latSrW1tb4+fnxzjvvEBsbm+l1nT59mv79++Pj44OlpSX+/v6MHDkyw3P68WanCxcu0KNHD9zc3Iz6ja1evZoBAwZQpkwZw/OgSZMmrFy5MsN1BwQEGK7t8fty9+7dQPZ90h6/1icfnylTprB//37atm2Ls7Oz0fuMKZ5nKSkpfP/997Rr147ixYsbXkc9e/bkxIkTGco//hhv3bqVhg0bYmtri5ubG0OGDMn0vQNg3bp1tGjRAicnJ2xsbKhevTqzZs0iLS3NqNyTj0vnzp1xdnbGxcWFAQMGEB4eDujfe1u1aoWjoyMuLi689tprxMfHP9e1ZSW7Pjs5fW3odDr++OMP6tWrh6urKzY2NhQrVowuXboYPe4vBCEVOi+//LIAxNKlS3N8m6tXr4pixYoJQLRt21aMGzdODBo0SNja2go7Oztx8OBBo/Lt2rUTpUuXFgMHDhQTJkwQb7zxhvD39xeAGDt2rFHZEydOCCsrK2FraysGDBggJk6cKN58803RtGlTUaJECaOye/fuFba2tkKj0Yj+/fuLiRMnimbNmglAlC5dWoSFhRmV9/f3F76+vqJBgwaiQoUK4u233xbDhg0Ttra2QlEUsWXLFqPyX375pXB1dRW9evUS77zzjhg9erQIDAwUgKhfv75ISUkxKj9kyBABiBs3buTofty7d69wdHQUiqKI9u3bi4kTJ4o33nhD1KtXT9SoUUMIIYROpxOlS5cWTk5OIj4+PsMxJk6cKACxfPlyw7aQkBBRoUIFAYgaNWqIsWPHijFjxoj27dsLCwsL8eDBA6P7xN/f3+iYOp1ODBgwQACibNmy4o033hAjR440HHPcuHE5uj4hhBg5cqQAhJ+fnxg1apQYNWqU8PPzE4AYNWqUodyuXbvE5MmThZOTk3BychKTJ08WkydPFt98802Wx75x44aYPHmyAIS/v7/hNpMnTxYnTpzIcB/5+fmJYcOGiXfeeUfUqVNHAKJ3795Gx5w7d64ARNeuXYW1tbXo37+/eOedd0S5cuUEID744APx1VdfCUdHRzFo0CCj65k/f77RsdJj69Kli7C1tRWvvPKKmDBhgqhdu3aWz6G1a9cKKysrYWNjI/r37y/effdd0alTJ8NjERkZaXT9gGjUqJFwdHQUjRo1EmPHjhVDhgwRd+/eFUIIUb58eVG1alUxZMgQMXHiRPHqq68KDw8PAYjvvvvOcKwTJ06I0aNHC0BUr17d6L5Mfz5n9/xOv9Zdu3YZPaaAaNOmjbCwsBBt27YV7777rujXr58QwnTPs/v37wuVSiWaNWsmXn/9dTFhwgTRp08fYWVlJaytrcXhw4czfYx79OghLC0tRa9evcS4ceNE3bp1Dffnk2bOnCkA4erqKt58800xbtw4UbZsWQGI7t27C51Ol+Fxadq0qXB2dhatW7cW48aNM7w3NWrUSOzdu1fY2NiIrl27inHjxhmeE6+88spzXVv6fT558mSj7ennflJuXhvvvfee4b11xIgRYuLEiWLQoEEiICBAfPDBBzl6rIoKmewUQmvXrhWAcHBwEOPGjRNbtmwR4eHh2d6mYcOGQq1Wi82bNxttv3TpknBwcBBVq1Y12n79+vUMx0hNTRVt2rQRarVa3Lx507B97NixAhBr1qzJcJvH49JqtaJ06dICyBDHu+++KwAxbNgwo+3pCVa3bt1EcnKyYfv27dsFINq1a2dU/s6dO0bl0k2dOlUAYsGCBUbbc5PsJCUlCT8/P6FSqcSmTZsy7L99+7bh9+nTpwtAzJs3z6hMamqq8PHxEZ6enkYfmr169RKAmDRpUobjBgcHi9TUVMPfmSU7v/32m+GN9/HjJicniy5dughAHD169KnXuGfPHgGIihUriqioKMP2yMhIQ/Lw77//Gt0ms3ieBhDNmjXLdN/WrVsNj21cXJxhu06nE2+++aYAxIoVKwzb0z8ILSwsjD5IYmJihKenp7C1tRXe3t7i2rVrhn23bt0SlpaWGZ736QmApaWlOHXqlNG5X3rpJQGIGTNmGLaHh4cLR0dH4efnJ4KCgoyOtXjxYgGIt99+27At/UMVEB9//HGm1/94nOliY2NF1apVMyTQ6ccbMmRIpsd61mQHEHPmzMlwG1M9z5KSksSdO3cybD979qywt7cXrVu3Ntqe/hhrNBqxb98+w/a0tDTRvHlzAYgDBw4Ytl+9elVoNBrh6ekpbt26ZXTexo0bC0D89ddfhu2PPy6zZ882bNfpdKJjx44CEM7OzkbvcSkpKaJatWpCo9GI4ODgZ7623CQ7uX1tuLq6Cl9f30y/dEVERGTYVpTJZKeQmjlzprC3tze8QB/P3i9fvmxU9vjx45kmEunSk5UzZ8489bwrV67M8CGefvsna1me9O+//wpAdOjQIcO+2NhY4erqKqytrY2SlfRkJ7Pky9/fX7i6uj41ZiH0L2xADB061Gh7bpKdpUuXCkAMHjz4qWVDQ0OFpaWlaNy4sdH2NWvWCEC8++67hm33798XiqKI0qVLZ6g1yExmyUW1atWEnZ2dSEhIyFD+9OnTOf7WPWzYsCxrDRcuXJhlQmrKZKdr164CMEqo00VFRQlFUUSvXr0M29I/CJ/8hv349UydOjXDvpYtWwq1Wm2USKYnAK+99lqG8kFBQUKtVosqVaoYts2aNSvDB+fjatWqJdzd3Q1/p3+oent7Z5qUZye9pmL37t0ZjmfqZKdWrVqZHs9Uz7PsdOnSRVhaWhq9FtIf48xee+n7Hq/1+uSTTwQgpk+fnqH8f//9JwDRsmVLw7b0+7F06dJGNT5CCPHXX38JQLRo0SLDsdLPs3Pnzme+ttwkO7l9bbi6uoqSJUuKpKSkHMVXlMkOyoXU2LFjGT58OJs3b2b//v0cPXqUQ4cO8eOPP/Lnn3+ydOlSunbtCsDBgwcBCAkJyTCXA8DFixcN/1epUgXQ9x+ZMWMGa9as4dq1axnape/du2f4vW/fvsyePZsePXrQr18/2rRpQ9OmTfHz8zO6TXp7dWZDjtP7BG3dupVLly5RtWpVwz5nZ2dD34THFStWzNB/KZ0Qgrlz5zJv3jzOnj1LdHS0oc/Gk3Hn1uHDhwFo27btU8t6eHjQs2dPlixZwsWLFw19qP744w8AXnvtNUPZo0ePIoSgRYsWWFhY5DquhIQEzpw5g6+vL9OnT8+wP72/T/rjnJ3sHqMWLVoAcPLkyVzHmBsHDx7Ezs4uyz4gNjY2mV5LjRo1Mmzz8fHJdp9WqyUkJCTDc7VJkyYZyvv7+1O8eHHOnTtHSkoKlpaWhtfWoUOHMp3uISkpifDwcMLDw3F3dzdsr169epYdukNDQ5k2bRqbNm3i5s2bJCYmGu1/nudwTtWtWzfDNlM+z0D/PPrqq6/Yt28fwcHBGfqlhYeHGx6/dLVr185wnGLFigEQFRVl2Jbd87hBgwZYW1tn+jyuVq1ahn4yT3sOQcbH5FmuLSdy+9ro378/P/30E1WqVKF///60aNGCBg0aYGNjk+tzF3Yy2SnEHBwc6NOnD3369AEgOjqaSZMm8dNPP/Hqq69y9+5dLC0tiYyMBGDDhg1s2LAhy+OlJzQpKSk0b96c48ePU7NmTQYNGoSbmxsajYagoCDmz59vNNorMDCQ3bt388UXX7Bo0SLmzp0L6N8wp0+fbviQjImJAcDLyyvT86e/+NPLpXNycsq0vEajMUpkAEaNGsUPP/xA8eLF6dq1Kz4+PlhZWQEwderU5xqlFh0dDZDhgzErb7zxBkuWLOGPP/5gxowZ3Lt3j02bNtGsWTPKlSv3zMd90oMHDxBCcPfuXaZOnZpluScT1szExMSgUqnw8PDIsM/LywtFUTI8PqYWGRlJWlparq/F0dExwzaNRvPUfZl1/s7qOerl5UVQUBCxsbG4ubkZXls//vhjlrGmx/t4spPV8SMjI6lbty63bt2iUaNGtG7dGmdnZ9RqNSdPnmTt2rX5MtIys/hM+Tzbv38/LVu2BPRfHsqWLYu9vb1hQspTp05lep3ZPY6Pd87N7r1GURS8vLy4e/duro6f0+fQs15bTuT2tfHtt98SEBDA3Llz+eyzz/jss8+wtramb9++zJw50+g5WdTJZKcIcXJy4ocffmDDhg3cvHmTM2fOULt2bcOL9Pvvv+ftt99+6nHWrl3L8ePHefXVVw01EemWLFnC/PnzM9ymSZMmbNq0icTERA4dOsS6dev46aef6NSpE2fPnqVUqVKGOEJCQjI9b3BwMJD5m0pOhIaG8uOPP1KtWjUOHDiAra2t0bGze4PICWdnZ4BM3yQz07x5cypUqMBff/3FF198wdy5c9FqtQwfPvy5jvuk9Purdu3aHD169JmO8fixdDodYWFheHp6Gu0LDQ1FCPHMj09uYlAUxTACxhyyeo6GhISgKAoODg7Ao/v+zJkzhlrRnMhqlM2ff/7JrVu3+PTTT/nwww+N9k2bNo21a9fm+BwAKpV+wO2To4/gUZKd0/hM+Tz7/PPPSU5OZu/evTRu3Nho38GDBzl16tRzHf/x9xp/f3+jfUIIQkJC8ux5nJfXltvXhkajYfz48YwfP5579+6xZ88e5s6dy19//UVwcDBbtmx55lgKGzn0vIhRFAU7OzujbYGBgQAZmnyykl4d361btwz79u7dm+1tbWxsaN68OTNnzmTSpEkkJiaybds2AGrWrAmQ6ZDH+Ph4jh49io2NDeXLl89RnE+6fv06Qghat25tlOjkJO6cqFevHgBbt27N8W1ef/11wsLCWLNmDXPmzMHFxYVevXoZlalTpw4qlYpdu3blaIj5kxwcHKhYsSIXLlwwqsp/Ftk9RunbMqvOzy2VSpVhmGy6wMBAIiIiuHLlynOf51ll9ny5efMmt2/fpnLlyoYmqNy+tp4mt689tVoNkOV96eLiAmSeSOdmGDSY9nl27do1XF1dMyQDCQkJHD9+/LmODdk/jw8dOkRSUpJJnseZyctre57Xhq+vLwMGDGDz5s2UKVOG7du3Z2giLcpkslMI/frrrxw5ciTTfWvWrOHChQs4OzsbvmnWq1ePwMBAFi9ezNKlSzPcRqfTsWfPHsPf6d+E9u3bZ1Ruz549/P777xluf+DAAZKSkjJsT/92bG1tDUCjRo0oXbo0mzZtYvv27UZlP/vsMyIiIhgwYMAzT06XHvf+/fuNmrfu3LnD+++//0zHfFzXrl0pVqwYCxYsyPQbUWYfKEOGDMHa2pp33nmH69evM2jQIMP9kc7Ly4tevXpx7dq1TGufQkNDM/1m/rhRo0aRkJDA8OHDM21GuHHjRo7W/xoyZAigb/J7vLkqOjraEFt6mefh6urKnTt3Mt03atQoAIYNG5bp/CnBwcFcuHDhuWPIzl9//cXp06cNfwshmDRpElqt1mhphldeeQUHBwc++OADzp07l+E4CQkJhn49OZHVa2/RokVs3LgxQ3kXFxcUReH27duZHi+9782TcxitWLHC6DWfU6Z6nvn7+/PgwQOj+0yr1TJ+/HjCwsJyHdeTXnrpJTQaDbNmzTLqT5OSksKECRMA8myJjby8tty8NpKTk9m/f3+GMvHx8cTFxWFhYWGo+XsRyGasQmjTpk28+eablClThkaNGuHr60t8fDwnTpxg7969qFQqfvrpJ0NfFYDFixfTokUL+vfvz+zZs6lVqxY2NjbcunWLAwcOEBYWZkhYunTpQsmSJfnqq684e/YsVapU4dKlS6xfv54ePXpkmMxv+vTp7Nq1i6ZNmxIQEIC1tTXHjx9nx44dlCpVih49egD6b/Pz5s2jXbt2dOzYkT59+uDv78+BAwfYvXs3pUuXZtq0ac98v/j4+NCrVy9WrlxJnTp1aNWqFSEhIaxfv55WrVo993phVlZWLFu2jPbt29OhQwfat29P9erViYmJ4eTJkyQkJGT4tuzq6kqfPn34+++/ATI0YaX76aefOHv2LJ9//jkbN26kZcuWCCG4fPkyW7duJSQkxNDclZk33niDgwcPMn/+fP777z9at26Nr68vISEhXLx4kUOHDrFo0aKnLiDatGlTRo4cyffff0+VKlXo1asXQghWrlzJnTt3GDVqFE2bNs3V/ZaZli1bsmzZMrp3707NmjVRq9V07dqVatWq0b59ez766CM+/fRTypQpQ/v27fH39yciIoKrV6+yd+9ePvvsMypWrPjccWSlXbt2NGjQgP79++Ph4cGOHTs4evQo9evXZ+TIkYZyHh4eLF68mD59+lC9enXat29PhQoVSE5OJigoiD179tCwYUM2b96co/MOGjSI6dOnM3LkSHbt2oW/vz+nTp1ix44d9OzZk1WrVhmVt7e3p27duvz7778MGjSIsmXLolKpGDRoEP7+/nTr1o3SpUszb948bt++Tc2aNblw4QI7d+6kY8eOmSZQ2THV82zkyJFs3bqVxo0b07dvX6ytrdm9ezd3796lefPmzz3hXenSpZk+fTrjxo2jWrVq9O3bFzs7O9atW8elS5fo1q0bL7/88nOdIyt5eW25eW0kJibSqFEjypUrR+3atSlRogRxcXGsX7+e4OBgxo8fb/QZUeSZaxiY9OwuXrwovvrqK9GmTRsREBAgrK2thbW1tShdurQYMmRIlvNcREZGig8//FBUqVJF2NjYCHt7e1G2bFnx0ksviVWrVhmVvX79uujVq5fw8PAQtra2om7dumLJkiWZDpPcvHmzGDx4sChfvrxwcHAQ9vb2olKlSmLSpEkZJgkUQj9EtXfv3sLd3V1YWFgIf39/MXr06EzLZjesObOhmbGxsWLcuHGiZMmSwsrKSpQtW1Z8+umnIiUlJdPhzrmdVFAI/Rwer776qihWrJiwsLAQnp6eonnz5lkOP06fE6h+/frZHjc6Olp89NFHokKFCsLKyko4OTmJGjVqiI8//thoqGp298nSpUtF69athYuLi7CwsBB+fn6iefPmYubMmZnev1mZM2eOqFu3rrC1tTU8/pnNu/K0eLJy//590bdvX+Hu7i5UKpUAxNy5c43KbNu2TXTp0kV4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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "## Test plot seasonal cycle at a few gridpoint locations\n", + "\n", + "# Points to plot seasonal cycle at:\n", + "lat_points = (38, 38, 38, 38)\n", + "lon_points = (-123.25, -125, -128, -132)\n", + "\n", + "fig = plt.figure()\n", + "ax = plt.axes()\n", + "\n", + "for lat, lon in zip(lat_points, lon_points):\n", + " scycle_point = seasonal_cycle.sel(lat=lat, lon=lon)\n", + " ax.plot(scycle_point['month'], scycle_point.values, 'o-')\n", + "\n", + "ax.set_title(\"Seasonal cycle of temperature anomalies \\n at four test points\", fontsize=14)\n", + "ax.set_xlabel(\"month\", fontsize=12)\n", + "ax.set_ylabel(r\"$\\Delta$T (K)\", fontsize=12)" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "e1dbb25a-f069-4b6f-b607-27edf0fc1ead", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.DataArray 'analysed_sst' (time: 365, lat: 17999, lon: 36000)>\n", + "dask.array<rechunk-merge, shape=(365, 17999, 36000), dtype=float32, chunksize=(200, 300, 300), chunktype=numpy.ndarray>\n", + "Coordinates:\n", + " * lat (lat) float32 -89.99 -89.98 -89.97 -89.96 ... 89.97 89.98 89.99\n", + " * lon (lon) float32 -180.0 -180.0 -180.0 -180.0 ... 180.0 180.0 180.0\n", + " * time (time) datetime64[ns] 2019-01-01T09:00:00 ... 2019-12-31T09:00:00\n", + "Attributes: (7)\n" + ] + } + ], + "source": [ + "##==================================================================\n", + "## Loading the data with the reference this way will lead to errors!!!!\n", + "##==================================================================\n", + "data = opendf_withref(\"ref_combined_2019.parq\", fs)\n", + "sst = data['analysed_sst']\n", + "sst = sst.chunk(chunks={'lat': 300, 'lon': 300, 'time': 200})\n", + "print(sst)" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "1f937f80-e752-4a52-9cee-b7b695eca9db", + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Error during deserialization of the task graph. This frequently\noccurs if the Scheduler and Client have different environments.\nFor more information, see\nhttps://docs.dask.org/en/stable/deployment-considerations.html#consistent-software-environments\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/mapping.py:155\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 154\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 155\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfs\u001b[38;5;241m.\u001b[39mcat(k)\n\u001b[1;32m 156\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmissing_exceptions \u001b[38;5;28;01mas\u001b[39;00m exc:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:864\u001b[0m, in \u001b[0;36mcat\u001b[0;34m()\u001b[0m\n\u001b[1;32m 863\u001b[0m \u001b[38;5;66;03m# TODO: if references is lazy, pre-fetch all paths in batch before access\u001b[39;00m\n\u001b[0;32m--> 864\u001b[0m proto_dict \u001b[38;5;241m=\u001b[39m _protocol_groups(path, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreferences)\n\u001b[1;32m 865\u001b[0m out \u001b[38;5;241m=\u001b[39m {}\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:50\u001b[0m, in \u001b[0;36m_protocol_groups\u001b[0;34m()\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(paths, \u001b[38;5;28mstr\u001b[39m):\n\u001b[0;32m---> 50\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m {_prot_in_references(paths, references): [paths]}\n\u001b[1;32m 51\u001b[0m out \u001b[38;5;241m=\u001b[39m {}\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:43\u001b[0m, in \u001b[0;36m_prot_in_references\u001b[0;34m()\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_prot_in_references\u001b[39m(path, references):\n\u001b[0;32m---> 43\u001b[0m ref \u001b[38;5;241m=\u001b[39m references\u001b[38;5;241m.\u001b[39mget(path)\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ref, (\u001b[38;5;28mlist\u001b[39m, \u001b[38;5;28mtuple\u001b[39m)):\n", + "File \u001b[0;32m<frozen _collections_abc>:807\u001b[0m, in \u001b[0;36mget\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:381\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 380\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, key):\n\u001b[0;32m--> 381\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_load_one_key(key)\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:290\u001b[0m, in \u001b[0;36m_load_one_key\u001b[0;34m()\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Get the reference for one key\u001b[39;00m\n\u001b[1;32m 287\u001b[0m \n\u001b[1;32m 288\u001b[0m \u001b[38;5;124;03mReturns bytes, one-element list or three-element list.\u001b[39;00m\n\u001b[1;32m 289\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m--> 290\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_items:\n\u001b[1;32m 291\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_items[key]\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:156\u001b[0m, in \u001b[0;36m__getattr__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m item \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_items\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrecord_size\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mzmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 156\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msetup()\n\u001b[1;32m 157\u001b[0m \u001b[38;5;66;03m# avoid possible recursion if setup fails somehow\u001b[39;00m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/reference.py:163\u001b[0m, in \u001b[0;36msetup\u001b[0;34m()\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_items \u001b[38;5;241m=\u001b[39m {}\n\u001b[0;32m--> 163\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_items[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.zmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfs\u001b[38;5;241m.\u001b[39mcat_file(\n\u001b[1;32m 164\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mjoin([\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mroot, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.zmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m 165\u001b[0m )\n\u001b[1;32m 166\u001b[0m met \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_items[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.zmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/spec.py:771\u001b[0m, in \u001b[0;36mcat_file\u001b[0;34m()\u001b[0m\n\u001b[1;32m 770\u001b[0m \u001b[38;5;66;03m# explicitly set buffering off?\u001b[39;00m\n\u001b[0;32m--> 771\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mopen(path, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrb\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;28;01mas\u001b[39;00m f:\n\u001b[1;32m 772\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m start \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/spec.py:1301\u001b[0m, in \u001b[0;36mopen\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1300\u001b[0m ac \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mpop(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mautocommit\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_intrans)\n\u001b[0;32m-> 1301\u001b[0m f \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_open(\n\u001b[1;32m 1302\u001b[0m path,\n\u001b[1;32m 1303\u001b[0m mode\u001b[38;5;241m=\u001b[39mmode,\n\u001b[1;32m 1304\u001b[0m block_size\u001b[38;5;241m=\u001b[39mblock_size,\n\u001b[1;32m 1305\u001b[0m autocommit\u001b[38;5;241m=\u001b[39mac,\n\u001b[1;32m 1306\u001b[0m cache_options\u001b[38;5;241m=\u001b[39mcache_options,\n\u001b[1;32m 1307\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m 1308\u001b[0m )\n\u001b[1;32m 1309\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m compression \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/local.py:195\u001b[0m, in \u001b[0;36m_open\u001b[0;34m()\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmakedirs(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_parent(path), exist_ok\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m--> 195\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m LocalFileOpener(path, mode, fs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/local.py:359\u001b[0m, in \u001b[0;36m__init__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 358\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mblocksize \u001b[38;5;241m=\u001b[39m io\u001b[38;5;241m.\u001b[39mDEFAULT_BUFFER_SIZE\n\u001b[0;32m--> 359\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_open()\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/implementations/local.py:364\u001b[0m, in \u001b[0;36m_open\u001b[0;34m()\u001b[0m\n\u001b[1;32m 363\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mautocommit \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmode:\n\u001b[0;32m--> 364\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mf \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpath, mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmode)\n\u001b[1;32m 365\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompression:\n", + "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/tmp/ref_combined_2019.parq/.zmetadata'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/storage.py:1446\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1445\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1446\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmap[key]\n\u001b[1;32m 1447\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexceptions \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/fsspec/mapping.py:159\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m default\n\u001b[0;32m--> 159\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mexc\u001b[39;00m\n\u001b[1;32m 160\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "\u001b[0;31mKeyError\u001b[0m: 'analysed_sst/.zarray'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/core.py:202\u001b[0m, in \u001b[0;36m_load_metadata_nosync\u001b[0;34m()\u001b[0m\n\u001b[1;32m 201\u001b[0m mkey \u001b[38;5;241m=\u001b[39m _prefix_to_array_key(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_store, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_key_prefix)\n\u001b[0;32m--> 202\u001b[0m meta_bytes \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_store[mkey]\n\u001b[1;32m 203\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/storage.py:1448\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1447\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexceptions \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m-> 1448\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n", + "\u001b[0;31mKeyError\u001b[0m: 'analysed_sst/.zarray'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mArrayNotFoundError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/distributed/scheduler.py:4686\u001b[0m, in \u001b[0;36mupdate_graph\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4685\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 4686\u001b[0m graph \u001b[38;5;241m=\u001b[39m deserialize(graph_header, graph_frames)\u001b[38;5;241m.\u001b[39mdata\n\u001b[1;32m 4687\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m graph_header, graph_frames\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/distributed/protocol/serialize.py:449\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 448\u001b[0m dumps, loads, wants_context \u001b[38;5;241m=\u001b[39m families[name]\n\u001b[0;32m--> 449\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m loads(header, frames)\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/distributed/protocol/serialize.py:111\u001b[0m, in \u001b[0;36mpickle_loads\u001b[0;34m()\u001b[0m\n\u001b[1;32m 106\u001b[0m buffers \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m 107\u001b[0m ensure_writeable_flag(ensure_memoryview(mv), w)\n\u001b[1;32m 108\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m mv, w \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(buffers, header[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwriteable\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m 109\u001b[0m ]\n\u001b[0;32m--> 111\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pickle\u001b[38;5;241m.\u001b[39mloads(pik, buffers\u001b[38;5;241m=\u001b[39mbuffers)\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/distributed/protocol/pickle.py:94\u001b[0m, in \u001b[0;36mloads\u001b[0;34m()\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m buffers:\n\u001b[0;32m---> 94\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pickle\u001b[38;5;241m.\u001b[39mloads(x, buffers\u001b[38;5;241m=\u001b[39mbuffers)\n\u001b[1;32m 95\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/core.py:2572\u001b[0m, in \u001b[0;36m__setstate__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2571\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__setstate__\u001b[39m(\u001b[38;5;28mself\u001b[39m, state):\n\u001b[0;32m-> 2572\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mstate)\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/core.py:170\u001b[0m, in \u001b[0;36m__init__\u001b[0;34m()\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[38;5;66;03m# initialize metadata\u001b[39;00m\n\u001b[0;32m--> 170\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_load_metadata()\n\u001b[1;32m 172\u001b[0m \u001b[38;5;66;03m# initialize attributes\u001b[39;00m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/core.py:193\u001b[0m, in \u001b[0;36m_load_metadata\u001b[0;34m()\u001b[0m\n\u001b[1;32m 192\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_synchronizer \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 193\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_load_metadata_nosync()\n\u001b[1;32m 194\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/zarr/core.py:204\u001b[0m, in \u001b[0;36m_load_metadata_nosync\u001b[0;34m()\u001b[0m\n\u001b[1;32m 203\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m--> 204\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ArrayNotFoundError(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_path) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 205\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 206\u001b[0m \u001b[38;5;66;03m# decode and store metadata as instance members\u001b[39;00m\n", + "\u001b[0;31mArrayNotFoundError\u001b[0m: array not found at path %r' \"array not found at path %r' 'analysed_sst'\"", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m<timed exec>:1\u001b[0m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/xarray/core/dataarray.py:1156\u001b[0m, in \u001b[0;36mDataArray.compute\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 1137\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Manually trigger loading of this array's data from disk or a\u001b[39;00m\n\u001b[1;32m 1138\u001b[0m \u001b[38;5;124;03mremote source into memory and return a new array. The original is\u001b[39;00m\n\u001b[1;32m 1139\u001b[0m \u001b[38;5;124;03mleft unaltered.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1153\u001b[0m \u001b[38;5;124;03mdask.compute\u001b[39;00m\n\u001b[1;32m 1154\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 1155\u001b[0m new \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcopy(deep\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[0;32m-> 1156\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mnew\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/xarray/core/dataarray.py:1130\u001b[0m, in \u001b[0;36mDataArray.load\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mload\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Self:\n\u001b[1;32m 1113\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Manually trigger loading of this array's data from disk or a\u001b[39;00m\n\u001b[1;32m 1114\u001b[0m \u001b[38;5;124;03m remote source into memory and return this array.\u001b[39;00m\n\u001b[1;32m 1115\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1128\u001b[0m \u001b[38;5;124;03m dask.compute\u001b[39;00m\n\u001b[1;32m 1129\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 1130\u001b[0m ds \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_temp_dataset\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1131\u001b[0m new \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_from_temp_dataset(ds)\n\u001b[1;32m 1132\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_variable \u001b[38;5;241m=\u001b[39m new\u001b[38;5;241m.\u001b[39m_variable\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/xarray/core/dataset.py:846\u001b[0m, in \u001b[0;36mDataset.load\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 843\u001b[0m chunkmanager \u001b[38;5;241m=\u001b[39m get_chunked_array_type(\u001b[38;5;241m*\u001b[39mlazy_data\u001b[38;5;241m.\u001b[39mvalues())\n\u001b[1;32m 845\u001b[0m \u001b[38;5;66;03m# evaluate all the chunked arrays simultaneously\u001b[39;00m\n\u001b[0;32m--> 846\u001b[0m evaluated_data \u001b[38;5;241m=\u001b[39m \u001b[43mchunkmanager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mlazy_data\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalues\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 848\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, data \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(lazy_data, evaluated_data):\n\u001b[1;32m 849\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvariables[k]\u001b[38;5;241m.\u001b[39mdata \u001b[38;5;241m=\u001b[39m data\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/xarray/core/daskmanager.py:70\u001b[0m, in \u001b[0;36mDaskManager.compute\u001b[0;34m(self, *data, **kwargs)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39mdata: DaskArray, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mtuple\u001b[39m[np\u001b[38;5;241m.\u001b[39mndarray, \u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m]:\n\u001b[1;32m 68\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mdask\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01marray\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m compute\n\u001b[0;32m---> 70\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/dask/base.py:661\u001b[0m, in \u001b[0;36mcompute\u001b[0;34m(traverse, optimize_graph, scheduler, get, *args, **kwargs)\u001b[0m\n\u001b[1;32m 658\u001b[0m postcomputes\u001b[38;5;241m.\u001b[39mappend(x\u001b[38;5;241m.\u001b[39m__dask_postcompute__())\n\u001b[1;32m 660\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m shorten_traceback():\n\u001b[0;32m--> 661\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[43mschedule\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdsk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkeys\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 663\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m repack([f(r, \u001b[38;5;241m*\u001b[39ma) \u001b[38;5;28;01mfor\u001b[39;00m r, (f, a) \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(results, postcomputes)])\n", + "File \u001b[0;32m/opt/coiled/env/lib/python3.12/site-packages/distributed/client.py:2234\u001b[0m, in \u001b[0;36mClient._gather\u001b[0;34m(self, futures, errors, direct, local_worker)\u001b[0m\n\u001b[1;32m 2232\u001b[0m exc \u001b[38;5;241m=\u001b[39m CancelledError(key)\n\u001b[1;32m 2233\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2234\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exception\u001b[38;5;241m.\u001b[39mwith_traceback(traceback)\n\u001b[1;32m 2235\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[1;32m 2236\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m errors \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mskip\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n", + "\u001b[0;31mRuntimeError\u001b[0m: Error during deserialization of the task graph. This frequently\noccurs if the Scheduler and Client have different environments.\nFor more information, see\nhttps://docs.dask.org/en/stable/deployment-considerations.html#consistent-software-environments\n" + ] + } + ], + "source": [ + "%%time\n", + "seasonal_cycle = seasonal_cycle_regional(sst, lat_region, lon_region).compute()" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "7937d3d8-a446-4fb4-ac92-13cc01ae8109", + "metadata": {}, + "outputs": [], + "source": [ + "client.shutdown()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4a4a16b-9a8a-421d-8cd1-dbeb984ec8fa", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/quarto_text/Advanced.qmd b/quarto_text/Advanced.qmd index 454d4b2e..300e2914 100644 --- a/quarto_text/Advanced.qmd +++ b/quarto_text/Advanced.qmd @@ -10,6 +10,12 @@ subtitle: When you want to dive into optimizing cloud workflows ### **Zarr** - [Tutorial for NetCDF4 Files](../external/zarr_access.ipynb) - Teaches about the Zarr cloud optimized format +### **Kerchunk and Virtualizarr** +- [Kerchunk recipes](../notebooks/Advanced_cloud/kerchunk_recipes.ipynb) - Meant to be used after having a high-level understanding of the pacakge, this notebook goes through several functionalities of kerchunk that we found relevant to Earthdata users. Workflows here combine Kerchunk with the earthaccess package. +- [Kerchunk JSON Generation](../external/SWOT_to_kerchunk.ipynb) - An additional tutorial on generating a Kerchunk JSON file, demonstrating its use with one of the SWOT data sets hosted on PO.DAAC. Creates output for input in the following tutorial. +- [Integrating Dask, Kerchunk, Zarr and Xarray](../external/SWOT_SSH_dashboard.ipynb) - Efficiently visualize a whole collection of data in an interactive dashboard via cloud-optimized formats. +- Virtualizarr (coming soon) + ### **Dask and Coiled** - [Introduction to Dask Tutorial](../notebooks/Advanced_cloud/basic_dask.ipynb) - covers the basics of using Dask for parallel computing with NASA Earth Data completely in the cloud - [Dask Function Replication Example](../notebooks/Advanced_cloud/dask_delayed_01.ipynb) - demonstrates a more complex example of replicating a function over many files in parallel using `dask.delayed()`. The example analysis generates spatial correlation maps of sea surface temperature vs sea surface height, using data sets available on PO.DAAC. @@ -17,9 +23,5 @@ subtitle: When you want to dive into optimizing cloud workflows - [Coiled Function Replication Example](../notebooks/Advanced_cloud/coiled_function_01.ipynb) - demonstrates a more complex example of replicating a function over many files in parallel using `coiled.function()`. The example analysis generates spatial correlation maps of sea surface temperature vs sea surface height, using data sets available on PO.DAAC. This replicates the analysis from the [Dask Function Replication Example](../notebooks/Advanced_cloud/dask_delayed_01.ipynb), but changes the method of parallel computation. Instead of using a local cluster on a single VM (Dask), many VM's are combined into a distributed cluster (Coiled). - [Coiled Dataset Chunking Example](../notebooks/Advanced_cloud/coiled_cluster_01.ipynb) - demonstrates a more complex example of applying computations to a large dataset via chunking and parallel computing. The example analysis generates seasonal cycles of sea surface temperature off the west coast of the U.S.A for a decade of ultra-high resolution data. Parallel computations are distributed over many VM's using Coiled's `coiled.cluster()`. -### Using **Kerchunk, Zarr & Dask** in the Cloud -- [Kerchunk JSON Generation](../external/SWOT_to_kerchunk.ipynb) - Generates a Kerchunk JSON file for a single PO.DAAC Collection, creates output for input in following tutorial. -- [Integrating Dask, Kerchunk, Zarr and Xarray](../external/SWOT_SSH_dashboard.ipynb) - Efficiently visualize a whole collection of data in an interactive dashboard via cloud-optimized formats. - ### **Harmony-py** - [Subsetting tutorial](https://harmony-py.readthedocs.io/en/main/user/tutorial.html) - a tutorial for a Python library that integrates with NASA's [Harmony Services](https://harmony.earthdata.nasa.gov/). diff --git a/quarto_text/CloudOptimizedFormats.qmd b/quarto_text/CloudOptimizedFormats.qmd new file mode 100644 index 00000000..99ee3934 --- /dev/null +++ b/quarto_text/CloudOptimizedFormats.qmd @@ -0,0 +1,17 @@ +--- +title: Cloud Optimized Data Formats +subtitle: Faster data access when working in the cloud +--- + +Traditional Earth data formats like netCDF and HDF are not optimal for storing and then accessing those data in the cloud, e.g. for streaming data from the files rather than direct downloading. They do work, but new file formats are emerging which will allow data to be accessed faster. In some cases, future data sets will be completely in these new formats, such as [Zarr](https://guide.cloudnativegeo.org/zarr/intro.html) (no netCDF, HDF available). In other cases, technology is emerging that will allow data sets to still be written in more traditional formats, but with supplementary files which act as a "road map" to the data, allowing machines/software to navigate the data files more efficiently. Which ever is implemented, a key goal is to minimize the additional technical knowledge a user must aquire just to access the data. For example, the Python package `Xarray` is already adding new capabilities to its `open_mfdataset()` function so it works in a similar way whether using netCDF or cloud optimized data. There are many resources to gain a high-level understanding of cloud optimized data, such as this page [Cloud-Optimized Geospatial Formats Guide](https://guide.cloudnativegeo.org). + +### **Zarr** +- [Tutorial for NetCDF4 Files](../external/zarr_access.ipynb) - Teaches about the Zarr cloud optimized format + +### **Kerchunk and Virtualizarr** +Both [Kerchunk](https://fsspec.github.io/kerchunk/) and [Virtualizarr](https://virtualizarr.readthedocs.io/en/latest/) are Python packages that aim to achieve cloud-optimized results while still allowing a data set to be stored in traditional formats (e.g. netCDF, HDF). These packages create relatively small supplementary files that can be used by software to more efficiently navigate through a collection of e.g. netCDF files. This allows much faster lazy loading, faster selection and access to subsets of the data, and in some cases faster computations. + +- [Kerchunk recipes](../notebooks/Advanced_cloud/kerchunk_recipes.ipynb) - Meant to be used after having a high-level understanding of the pacakge, this notebook goes through several functionalities of kerchunk that we found relevant to Earthdata users. Workflows here combine Kerchunk with the earthaccess package. +- [Kerchunk JSON Generation](../external/SWOT_to_kerchunk.ipynb) - An additional tutorial on generating a Kerchunk JSON file, demonstrating its use with one of the SWOT data sets hosted on PO.DAAC. Creates output for input in the following tutorial. +- [Integrating Dask, Kerchunk, Zarr and Xarray](../external/SWOT_SSH_dashboard.ipynb) - Efficiently visualize a whole collection of data in an interactive dashboard via cloud-optimized formats. +- Virtualizarr (coming soon) \ No newline at end of file From 976f7c883ae805c3e028aabb0f20737840d9f069 Mon Sep 17 00:00:00 2001 From: cassienickles <cassienickles95@gmail.com> Date: Wed, 30 Oct 2024 14:30:56 -0700 Subject: [PATCH 2/2] Update _quarto.yml Update the table of contents to match the new Cloud Optimized Data Formats page in the cookbook --- _quarto.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/_quarto.yml b/_quarto.yml index dd1ecabe..bbc9a9ca 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -256,7 +256,14 @@ website: href: notebooks/aws_lambda_sst/podaac-lambda-invoke-sst-global-mean.ipynb - section: quarto_text/CloudOptimizedFormats.qmd contents: - - text: "Testing" + - text: "Zarr" + href: external/zarr_access.ipynb + - text: "Kerchunk Recipes" + href: notebooks/Advanced_cloud/kerchunk_recipes.ipynb + - text: "Kerchunk JSON Generation" + href: external/SWOT_to_kerchunk.ipynb + - text: "Dask, Kerchunk, & Zarr" + href: external/SWOT_SSH_dashboard.ipynb - section: quarto_text/Dask_Coiled.qmd contents: - text: "Basic Dask" @@ -269,10 +276,6 @@ website: href: notebooks/Advanced_cloud/coiled_function_01.ipynb - text: "Coiled Dataset Chunking Example" href: notebooks/Advanced_cloud/coiled_cluster_01.ipynb - - text: "Kerchunk" - href: external/SWOT_to_kerchunk.ipynb - - text: "Dask, Kerchunk, & Zarr" - href: external/SWOT_SSH_dashboard.ipynb - href: quarto_text/Experimental.qmd text: "In Development" - href: quarto_text/Workshops.qmd