|
7 | 7 | "source": [ |
8 | 8 | "# AWS Cloud: getting started and retrieving ECCO datasets\n", |
9 | 9 | "\n", |
| 10 | + "Andrew Delman, updated 2024-03-15.\n", |
| 11 | + "\n", |
10 | 12 | "## Introduction\n", |
11 | 13 | "Previous tutorials have discussed how to download ECCO datasets from PO.DAAC to your local machine. However, during 2021-2022 PO.DAAC datasets (including ECCO) migrated to the NASA Earthdata Cloud hosted by Amazon Web Services (AWS). While data downloads from the cloud (using wget, curl, Python requests, etc.) function like downloads from any other website, there are definite advantages to working with datasets within the cloud environment. Data can be opened in an S3 bucket and viewed without downloading, or can be quickly downloaded to a user's cloud instance for computations. For more information on PO.DAAC datasets in the cloud, there are [a number of infographics here](https://podaac.jpl.nasa.gov/cloud-datasets/about).\n", |
12 | 14 | "\n", |
|
37 | 39 | "\n", |
38 | 40 | "*Key pair (login)*: Click on **Create new key pair**. In the pop-up window, make the name whatever you want (e.g., aws_ec2_jupyter), select *Key pair type*: **RSA** and *Private key file format*: **.pem**, then **Create key pair**. This downloads the key file to your Downloads folder, and you should move it to your `.ssh` folder: `mv ~/Downloads/aws_ec2_jupyter.pem ~/.ssh/`. Then change the permissions to read-only for the file owner `chmod 400 ~/.ssh/aws_ec2_jupyter.pem`.\n", |
39 | 41 | "\n", |
40 | | - "*Network settings*: Your institution may have existing security groups that you should use, so click the **Select existing security group** and check with your IT or cloud support to see if there are recommended security groups/VPCs to use. If not or you are doing this on your own, then click **Create security group**, which will create a new security group with a name like *launch-wizard-1*. Make sure that the boxes to allow HTTPS and HTTP traffic from the internet are checked.\n", |
| 42 | + "*Network settings*: Your institution may have existing security groups that you should use, so click the **Select existing security group** and check with your IT or cloud support to see if there are recommended security groups/VPCs to use. If not or you are doing this on your own, then click **Create security group**, which will create a new security group with a name like *launch-wizard-1*. Make sure that the boxes to allow SSH, HTTPS, and HTTP traffic are checked.\n", |
41 | 43 | "\n", |
42 | 44 | "*Configure storage*: Specify a storage volume with at least **15 GiB gp3** as your root volume. This is important, since the python/conda installation with the packages we need will occupy ~7.5 GB, and we need some workspace as a buffer. If you are in Free tier then you can request up to 30 GB across all your instances, so you can use up the full amount in a single instance or split it across two instances with 15 GB each.\n", |
43 | 45 | "\n", |
|
95 | 97 | "~/jupyter_lab_start.sh\n", |
96 | 98 | "```\n", |
97 | 99 | "\n", |
98 | | - "You will get a prompt for a password (optional), or you can leave it blank and press enter. After this is done (and while still connected to your instance through port 9889), open up a window in your local machine's web browser and put ``http://127.0.0.1:9889/`` or ``http://localhost:9889/`` in the URL field. If you set a password for your session, enter it when prompted. A Jupyter lab should open up in the ECCOv4 tutorial Github repository on your instance. Go to the **Tutorials_as_Jupyter_Notebooks** directory, and you will see a number of notebooks ready to run! For example, you can access this one at *AWS_Cloud_getting_started.ipynb*.\n", |
| 100 | + "You will get a prompt for a password (optional), or you can leave it blank and press enter. After this is done (and while still connected to your instance through port 9889), open up a window in your local machine's web browser and put ``http://127.0.0.1:9889/`` or ``http://localhost:9889/`` in the URL field. If you set a password for your session enter it when prompted, or if there is no password just click **Log in**. A Jupyter lab should open up in the ECCOv4 tutorial Github repository on your instance. Go to the **Tutorials_as_Jupyter_Notebooks** directory, and you will see a number of notebooks ready to run! For example, you can access this one at *AWS_Cloud_getting_started.ipynb*.\n", |
99 | 101 | "\n", |
100 | 102 | "## Reconnecting to your instance and Jupyter lab\n", |
101 | 103 | "\n", |
|
119 | 121 | "ssh -i \"~/.ssh/aws_ec2_jupyter.pem\" ec2-user@instance_ip_address -L 9889:localhost:9889\n", |
120 | 122 | "```\n", |
121 | 123 | "\n", |
122 | | - "Once connected to your instance you will need to start a new Jupyter lab session by running:\n", |
| 124 | + "Note that the instance's public IP address may have changed when the instance was stopped and started again. Once connected to your instance you will need to start a new Jupyter lab session by running:\n", |
123 | 125 | "\n", |
124 | 126 | "```\n", |
125 | 127 | "~/jupyter_lab_start.sh\n", |
|
262 | 264 | "source": [ |
263 | 265 | "%%time\n", |
264 | 266 | "\n", |
265 | | - "# Open 12 monthly files (temp/salinity)\n", |
| 267 | + "# Open 12 monthly files (temp/salinity\n", |
| 268 | + "\n", |
| 269 | + "# suppress warnings\n", |
| 270 | + "import warnings\n", |
| 271 | + "warnings.filterwarnings(\"ignore\")\n", |
266 | 272 | "\n", |
267 | 273 | "time_log = [time.time()]\n", |
268 | 274 | "\n", |
|
274 | 280 | "ds = xr.open_mfdataset(file_list,\\\n", |
275 | 281 | " data_vars='minimal',coords='minimal',\\\n", |
276 | 282 | " compat='override',\\\n", |
277 | | - " chunks={'time':1,'k':50,'tile':13,'j':90,'i':90})\n", |
| 283 | + " chunks={'time':1,'k':10,'tile':13,'j':90,'i':90})\n", |
278 | 284 | "\n", |
279 | 285 | "## repeat above with the grid file\n", |
280 | 286 | "grid_file = ecco_podaac_s3_open(ShortName=\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n", |
281 | 287 | " StartDate=\"1992-01\",EndDate=\"2017-12\")\n", |
282 | | - "ds_grid = xr.open_dataset(grid_file)\n", |
| 288 | + "ds_grid = xr.open_mfdataset([grid_file],chunks={'k':10,'tile':13,'j':90,'i':90})\n", |
283 | 289 | "\n", |
284 | 290 | "time_log.append(time.time())\n", |
285 | 291 | "time_to_open_files = np.diff(np.asarray(time_log)[-2:])[0]\n", |
|
290 | 296 | "\n", |
291 | 297 | "## compute volumes of each cell\n", |
292 | 298 | "cell_vol = ds_grid.hFacC*ds_grid.rA*ds_grid.drF\n", |
293 | | - "cell_vol = cell_vol.compute()\n", |
294 | 299 | "\n", |
295 | 300 | "## mean temperature weighted by the volume of each cell\n", |
296 | 301 | "total_vol = cell_vol.sum().compute()\n", |
|
2446 | 2451 | "source": [ |
2447 | 2452 | "#### Method 1b: Open using 2 processes and threads\n", |
2448 | 2453 | "\n", |
2449 | | - "We can use the [dask.distributed](https://distributed.dask.org) library to parallelize the opening of files from S3 and the subsequent computation. However, because of the overhead introduced by the `distributed` scheduler, this will not always speed up your code. This method works best when it is used to open files into xarray datasets with *open_mfdataset* (which by default does not immediately load the data into memory), and then a subset of the data can be loaded into memory at the earliest reasonable opportunity." |
| 2454 | + "We can use the [dask.distributed](https://distributed.dask.org) library to parallelize the opening of files from S3 and the subsequent computation. However, because of the overhead introduced by the `distributed` scheduler, this will not always speed up your code. This method works best when it is used to open files into xarray datasets with *open_mfdataset* (which by default does not immediately load the data into memory), and then a subset of the data can be loaded into memory at the earliest reasonable opportunity.\n", |
| 2455 | + "\n", |
| 2456 | + "> Note: If you are running a an instance with <2 GB memory (including the t2.micro free-tier) you will likely need to restart the kernel to clear your workspace before running the following cells. Then you can uncomment the cells below that reload the Python packages you need. You will also probably need to do the same before running Method 2." |
2450 | 2457 | ] |
2451 | 2458 | }, |
2452 | 2459 | { |
|
2464 | 2471 | } |
2465 | 2472 | ], |
2466 | 2473 | "source": [ |
| 2474 | + "# # un-comment and run this block if you just restarted the kernel\n", |
| 2475 | + "# import numpy as np\n", |
| 2476 | + "# import xarray as xr\n", |
| 2477 | + "# import matplotlib.pyplot as plt# \n", |
| 2478 | + "# from ecco_s3_retrieve import *\n", |
| 2479 | + "# import time\n", |
| 2480 | + "\n", |
2467 | 2481 | "from distributed import Client\n", |
2468 | 2482 | "client = Client()\n", |
2469 | 2483 | "print(client)" |
|
2544 | 2558 | "ds = xr.open_mfdataset(file_list,\\\n", |
2545 | 2559 | " data_vars='minimal',coords='minimal',\\\n", |
2546 | 2560 | " compat='override',\\\n", |
2547 | | - " chunks={'time':1,'k':50,'tile':13,'j':90,'i':90})\n", |
| 2561 | + " chunks={'time':1,'k':10,'tile':13,'j':90,'i':90})\n", |
2548 | 2562 | "\n", |
2549 | 2563 | "## repeat above with the grid file\n", |
2550 | 2564 | "grid_file = ecco_podaac_s3_open(ShortName=\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n", |
2551 | 2565 | " StartDate=\"1992-01\",EndDate=\"2017-12\")\n", |
2552 | | - "ds_grid = xr.open_dataset(grid_file)\n", |
| 2566 | + "ds_grid = xr.open_mfdataset([grid_file],chunks={'k':10,'tile':13,'j':90,'i':90})\n", |
2553 | 2567 | "\n", |
2554 | 2568 | "time_log.append(time.time())\n", |
2555 | 2569 | "time_to_open_files = np.diff(np.asarray(time_log)[-2:])[0]\n", |
|
2560 | 2574 | "\n", |
2561 | 2575 | "## compute volumes of each cell\n", |
2562 | 2576 | "cell_vol = ds_grid.hFacC*ds_grid.rA*ds_grid.drF\n", |
2563 | | - "cell_vol = cell_vol.compute()\n", |
2564 | 2577 | "\n", |
2565 | 2578 | "## mean temperature weighted by the volume of each cell\n", |
2566 | 2579 | "total_vol = cell_vol.sum().compute()\n", |
|
2722 | 2735 | "source": [ |
2723 | 2736 | "%%time\n", |
2724 | 2737 | "\n", |
| 2738 | + "# # un-comment and run this block if you just restarted the kernel\n", |
| 2739 | + "# import numpy as np\n", |
| 2740 | + "# import xarray as xr\n", |
| 2741 | + "# import matplotlib.pyplot as plt# \n", |
| 2742 | + "# from ecco_s3_retrieve import *\n", |
| 2743 | + "# import time\n", |
| 2744 | + "\n", |
| 2745 | + "\n", |
2725 | 2746 | "# Get/download 12 monthly files (temp/salinity) and grid parameters file to user's instance\n", |
2726 | 2747 | "\n", |
2727 | 2748 | "time_log = [time.time()]\n", |
|
2735 | 2756 | "ds = xr.open_mfdataset(file_list,\\\n", |
2736 | 2757 | " data_vars='minimal',coords='minimal',\\\n", |
2737 | 2758 | " compat='override',\\\n", |
2738 | | - " chunks={'time':1,'k':50,'tile':13,'j':90,'i':90})\n", |
| 2759 | + " chunks={'time':1,'k':10,'tile':13,'j':90,'i':90})\n", |
2739 | 2760 | "\n", |
2740 | 2761 | "## repeat above with the grid file\n", |
2741 | 2762 | "grid_file = ecco_podaac_s3_get(ShortName=\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n", |
2742 | 2763 | " StartDate=\"1992-01\",EndDate=\"2017-12\",\\\n", |
2743 | 2764 | " n_workers=2,return_downloaded_files=True)\n", |
2744 | | - "ds_grid = xr.open_dataset(grid_file)\n", |
| 2765 | + "ds_grid = xr.open_mfdataset([grid_file],chunks{'k':10,'tile':13,'j':90,'i':90})\n", |
2745 | 2766 | "\n", |
2746 | 2767 | "time_log.append(time.time())\n", |
2747 | 2768 | "time_to_get_files = np.diff(np.asarray(time_log)[-2:])[0]\n", |
|
2753 | 2774 | "\n", |
2754 | 2775 | "## compute volumes of each cell\n", |
2755 | 2776 | "cell_vol = ds_grid.hFacC*ds_grid.rA*ds_grid.drF\n", |
2756 | | - "cell_vol = cell_vol.compute()\n", |
2757 | 2777 | "\n", |
2758 | 2778 | "## mean temperature weighted by the volume of each cell\n", |
2759 | 2779 | "total_vol = cell_vol.sum().compute()\n", |
|
0 commit comments