Skip to content

Commit 8bb790e

Browse files
committed
some more tutorial updates for ecco_access
1 parent bad9550 commit 8bb790e

11 files changed

Lines changed: 4178 additions & 990 deletions

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Example_MHT.ipynb

Lines changed: 202 additions & 97 deletions
Large diffs are not rendered by default.

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Example_OSNAP.ipynb

Lines changed: 192 additions & 87 deletions
Large diffs are not rendered by default.

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Example_calculations_with_scalar_quantities.ipynb

Lines changed: 1852 additions & 181 deletions
Large diffs are not rendered by default.

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Gradient_calc_on_native_grid.ipynb

Lines changed: 117 additions & 89 deletions
Large diffs are not rendered by default.

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Heat_budget_closure.ipynb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"# Global Heat Budget Closure\n",
88
"*Contributors*: [Jan-Erik Tesdal](https://github.com/jetesdal), [Ryan Abernathey](https://github.com/rabernat), [Ian Fenty](https://github.com/ifenty), and [Andrew Delman](https://github.com/andrewdelman)\n",
99
"\n",
10-
"Updated 2024-10-16\n",
10+
"Updated 2024-10-17\n",
1111
"\n",
1212
"A major part of this tutorial is based on \"*A Note on Practical Evaluation of Budgets in ECCO Version 4 Release 3\"* by Christopher G. Piecuch (https://ecco.jpl.nasa.gov/drive/files/Version4/Release3/doc/v4r3_budgets_howto.pdf). Calculation steps and Python code presented here are converted from the MATLAB code presented in the above reference."
1313
]
@@ -220,8 +220,7 @@
220220
"## Set top-level file directory for the ECCO NetCDF files\n",
221221
"## =================================================================\n",
222222
"\n",
223-
"## currently set to /efs_ecco/ECCO_V4r4_PODAAC, \n",
224-
"## the default if ecco_podaac_download was used to download dataset granules\n",
223+
"## currently set to ~/Downloads/ECCO_V4r4_PODAAC\n",
225224
"ECCO_dir = join(user_home_dir,'ECCO_V4r4_PODAAC')\n",
226225
"\n",
227226
"# # for access_mode = 's3_open_fsspec', need to specify the root directory \n",

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Interpolating_Fields_to_LatLon_Grid.ipynb

Lines changed: 142 additions & 505 deletions
Large diffs are not rendered by default.

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Plotting_Tiles.ipynb

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@
5353
"\n",
5454
"## Plotting single tiles using ``imshow``, ``pcolormesh``, and ``contourf``\n",
5555
"\n",
56-
"First, let's load the all 13 tiles for sea surface height and the model grid parameters."
56+
"First, let's load the all 13 tiles for sea surface height and the model grid parameters.\n",
57+
"\n",
58+
"> **Note:** The notebook uses the `ecco_access` library to download (or direct access in the AWS Cloud) the ECCO output. It is recommended to set up `ecco_access` [in your Python path](https://ecco-v4-python-tutorial.readthedocs.io/ECCO_access_intro.html#Setting-up-ecco_access), if you haven't already."
5759
]
5860
},
5961
{
@@ -71,9 +73,20 @@
7173
"import warnings\n",
7274
"warnings.filterwarnings('ignore')\n",
7375
"\n",
74-
"\n",
75-
"# indicate whether you are working in a cloud instance (True if yes, False otherwise)\n",
76-
"incloud_access = False"
76+
"import ecco_access as ea\n",
77+
"\n",
78+
"# indicate mode of access\n",
79+
"# options are:\n",
80+
"# 'download': direct download from internet to your local machine\n",
81+
"# 'download_ifspace': like download, but only proceeds \n",
82+
"# if your machine have sufficient storage\n",
83+
"# 's3_open': access datasets in-cloud from an AWS instance\n",
84+
"# 's3_open_fsspec': use jsons generated with fsspec and \n",
85+
"# kerchunk libraries to speed up in-cloud access\n",
86+
"# 's3_get': direct download from S3 in-cloud to an AWS instance\n",
87+
"# 's3_get_ifspace': like s3_get, but only proceeds if your instance \n",
88+
"# has sufficient storage\n",
89+
"access_mode = 'download_ifspace'"
7790
]
7891
},
7992
{
@@ -121,9 +134,12 @@
121134
"## Set top-level file directory for the ECCO NetCDF files\n",
122135
"## =================================================================\n",
123136
"\n",
124-
"## currently set to ~/Downloads/ECCO_V4r4_PODAAC, \n",
125-
"## the default if ecco_podaac_download was used to download dataset granules\n",
126-
"ECCO_dir = join(user_home_dir,'Downloads','ECCO_V4r4_PODAAC')"
137+
"## currently set to /Downloads/ECCO_V4r4_PODAAC\n",
138+
"ECCO_dir = join(user_home_dir,'Downloads','ECCO_V4r4_PODAAC')\n",
139+
"\n",
140+
"# # for access_mode = 's3_open_fsspec', need to specify the root directory \n",
141+
"# # containing the jsons\n",
142+
"# jsons_root_dir = join('/efs_ecco','mzz-jsons')"
127143
]
128144
},
129145
{
@@ -139,24 +155,15 @@
139155
"ShortNames_list = [\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n",
140156
" \"ECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4\",\\\n",
141157
" \"ECCO_L4_TEMP_SALINITY_LLC0090GRID_MONTHLY_V4R4\"]\n",
142-
"if incloud_access == True:\n",
143-
" from ecco_s3_retrieve import ecco_podaac_s3_get_diskaware\n",
144-
" files_dict = ecco_podaac_s3_get_diskaware(ShortNames=ShortNames_list,\\\n",
158+
"\n",
159+
"ds_dict = ea.ecco_podaac_access(ShortNames_list,\\\n",
145160
" StartDate='2000-01',EndDate='2000-12',\\\n",
146-
" max_avail_frac=0.5,\\\n",
147-
" download_root_dir=ECCO_dir)\n",
148-
" ecco_grid = xr.open_dataset(files_dict[ShortNames_list[0]])\n",
149-
" ds_SSH = xr.open_mfdataset(files_dict[ShortNames_list[1]],\\\n",
150-
" compat='override',data_vars='minimal',coords='minimal')\n",
151-
" ds_temp_sal = xr.open_mfdataset(files_dict[ShortNames_list[2]],\\\n",
152-
" compat='override',data_vars='minimal',coords='minimal')\n",
153-
"else:\n",
154-
" ecco_grid = xr.open_dataset(glob.glob(join(ECCO_dir,ShortNames_list[0],'*.nc'))[0])\n",
155-
" ds_SSH = xr.open_mfdataset(glob.glob(join(ECCO_dir,ShortNames_list[1],'*2000-*.nc')),\\\n",
156-
" compat='override',data_vars='minimal',coords='minimal')\n",
157-
" ds_temp_sal = xr.open_mfdataset(glob.glob(join(ECCO_dir,ShortNames_list[2],'*2000-*.nc')),\\\n",
158-
" compat='override',data_vars='minimal',coords='minimal')\n",
161+
" download_root_dir=ECCO_dir,\\\n",
162+
" max_avail_frac=0.5)\n",
159163
"\n",
164+
"ecco_grid = ds_dict[ShortNames_list[0]]\n",
165+
"ds_SSH = ds_dict[ShortNames_list[1]]\n",
166+
"ds_temp_sal = ds_dict[ShortNames_list[2]]\n",
160167
"\n",
161168
"## select only *surface* temperature and salinity (SST and SSS)\n",
162169
"ds_SST_SSS = ds_temp_sal.isel(k=0)\n",
@@ -3225,7 +3232,7 @@
32253232
"name": "python",
32263233
"nbconvert_exporter": "python",
32273234
"pygments_lexer": "ipython3",
3228-
"version": "3.11.8"
3235+
"version": "3.11.9"
32293236
}
32303237
},
32313238
"nbformat": 4,

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Salt_and_salinity_budget.ipynb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"# Salt, Salinity and Freshwater Budgets\n",
88
"*Contributors*: [Jan-Erik Tesdal](https://github.com/jetesdal), [Ryan Abernathey](https://github.com/rabernat), [Ian Fenty](https://github.com/ifenty), [Emma Boland](https://github.com/emmomp), and [Andrew Delman](https://github.com/andrewdelman).\n",
99
"\n",
10+
"Updated 2024-10-17\n",
11+
"\n",
1012
"A major part of this tutorial is based on \"*A Note on Practical Evaluation of Budgets in ECCO Version 4 Release 3\"* by Christopher G. Piecuch (https://dspace.mit.edu/handle/1721.1/111094?show=full). Calculation steps and Python code presented here are converted from the MATLAB code presented in the above reference."
1113
]
1214
},
@@ -271,8 +273,7 @@
271273
"## Set top-level file directory for the ECCO NetCDF files\n",
272274
"## =================================================================\n",
273275
"\n",
274-
"## currently set to /efs_ecco/ECCO_V4r4_PODAAC, \n",
275-
"## the default if ecco_podaac_download was used to download dataset granules\n",
276+
"## currently set to ~/Downloads/ECCO_V4r4_PODAAC\n",
276277
"ECCO_dir = join(user_home_dir,'ECCO_V4r4_PODAAC')\n",
277278
"\n",
278279
"# # for access_mode = 's3_open_fsspec', need to specify the root directory \n",

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Volume_budget_closure.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,7 @@
526526
"## Set top-level file directory for the ECCO NetCDF files\n",
527527
"## =================================================================\n",
528528
"\n",
529-
"## currently set to /efs_ecco/ECCO_V4r4_PODAAC, \n",
530-
"## the default if ecco_podaac_download was used to download dataset granules\n",
529+
"## currently set to ~/Downloads/ECCO_V4r4_PODAAC\n",
531530
"ECCO_dir = join(user_home_dir,'ECCO_V4r4_PODAAC')\n",
532531
"\n",
533532
"# # for access_mode = 's3_open_fsspec', need to specify the root directory \n",
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "ad5ec9ef-46c3-4446-b5ee-233ad7ed2283",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from ecco_s3_retrieve import *"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": 2,
16+
"id": "a7b41b61-b63c-4696-b146-34f65c923aa2",
17+
"metadata": {},
18+
"outputs": [
19+
{
20+
"name": "stdout",
21+
"output_type": "stream",
22+
"text": [
23+
"Help on function ecco_podaac_s3_open in module ecco_s3_retrieve:\n",
24+
"\n",
25+
"ecco_podaac_s3_open(ShortName, StartDate, EndDate)\n",
26+
" This routine searches for and opens ECCO datasets from S3 buckets in the PO.DAAC Cloud.\n",
27+
" It returns a list of opened file(s) on S3 that can be passed to xarray.\n",
28+
" This function is intended to be called from an EC2 instance running in AWS region us-west-2.\n",
29+
" \n",
30+
" Parameters\n",
31+
" ----------\n",
32+
" ShortName: str, the ShortName that identifies the dataset on PO.DAAC.\n",
33+
" \n",
34+
" StartDate,EndDate: str, in 'YYYY', 'YYYY-MM', or 'YYYY-MM-DD' format, \n",
35+
" define date range [StartDate,EndDate] for download.\n",
36+
" EndDate is included in the time range (unlike typical Python ranges).\n",
37+
" ECCOv4r4 date range is '1992-01-01' to '2017-12-31'.\n",
38+
" For 'SNAPSHOT' datasets, an additional day is added to EndDate to enable closed budgets\n",
39+
" within the specified date range.\n",
40+
" \n",
41+
" Returns\n",
42+
" -------\n",
43+
" open_files: str or list, opened file(s) on S3 that can be passed directly to xarray (open_dataset or open_mfdataset)\n",
44+
"\n"
45+
]
46+
}
47+
],
48+
"source": [
49+
"help(ecco_podaac_s3_open)"
50+
]
51+
},
52+
{
53+
"cell_type": "code",
54+
"execution_count": 3,
55+
"id": "5dd4f5ad-8e63-4ea1-880d-35ff89499aff",
56+
"metadata": {},
57+
"outputs": [],
58+
"source": [
59+
"import numpy as np\n",
60+
"import xarray as xr"
61+
]
62+
},
63+
{
64+
"cell_type": "code",
65+
"execution_count": 4,
66+
"id": "01e934e2-f796-4314-a60c-1ded8f5297ad",
67+
"metadata": {},
68+
"outputs": [
69+
{
70+
"name": "stdout",
71+
"output_type": "stream",
72+
"text": [
73+
"Please provide Earthdata Login credentials for access.\n"
74+
]
75+
},
76+
{
77+
"name": "stdin",
78+
"output_type": "stream",
79+
"text": [
80+
"Username: adelman\n"
81+
]
82+
},
83+
{
84+
"ename": "NameError",
85+
"evalue": "name 'getpass' is not defined",
86+
"output_type": "error",
87+
"traceback": [
88+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
89+
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
90+
"File \u001b[0;32m~/ECCO-v4-Python-Tutorial/Tutorials_as_Jupyter_Notebooks/ecco_s3_retrieve.py:63\u001b[0m, in \u001b[0;36mecco_podaac_s3_query.<locals>.setup_earthdata_login_auth\u001b[0;34m(url)\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 63\u001b[0m username, _, password \u001b[38;5;241m=\u001b[39m \u001b[43mnetrc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfile\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_netrc\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mauthenticators(url)\n\u001b[1;32m 65\u001b[0m \u001b[38;5;66;03m# if the file is not found, prompt the user for the login/password\u001b[39;00m\n",
91+
"File \u001b[0;32m/srv/conda/envs/notebook/lib/python3.11/netrc.py:74\u001b[0m, in \u001b[0;36mnetrc.__init__\u001b[0;34m(self, file)\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 74\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mfile\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mutf-8\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m fp:\n\u001b[1;32m 75\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_parse(file, fp, default_netrc)\n",
92+
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/home/jovyan/.netrc'",
93+
"\nDuring handling of the above exception, another exception occurred:\n",
94+
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
95+
"Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m files \u001b[38;5;241m=\u001b[39m \u001b[43mecco_podaac_s3_open\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m\\\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mStartDate\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m2000-01\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mEndDate\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m2000-12\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n",
96+
"File \u001b[0;32m~/ECCO-v4-Python-Tutorial/Tutorials_as_Jupyter_Notebooks/ecco_s3_retrieve.py:362\u001b[0m, in \u001b[0;36mecco_podaac_s3_open\u001b[0;34m(ShortName, StartDate, EndDate)\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m \n\u001b[1;32m 361\u001b[0m \u001b[38;5;66;03m# get list of files\u001b[39;00m\n\u001b[0;32m--> 362\u001b[0m s3_files_list \u001b[38;5;241m=\u001b[39m \u001b[43mecco_podaac_s3_query\u001b[49m\u001b[43m(\u001b[49m\u001b[43mShortName\u001b[49m\u001b[43m,\u001b[49m\u001b[43mStartDate\u001b[49m\u001b[43m,\u001b[49m\u001b[43mEndDate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 364\u001b[0m num_grans \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlen\u001b[39m(s3_files_list)\n\u001b[1;32m 365\u001b[0m \u001b[38;5;28mprint\u001b[39m (\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mTotal number of matching granules: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mnum_grans\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m)\n",
97+
"File \u001b[0;32m~/ECCO-v4-Python-Tutorial/Tutorials_as_Jupyter_Notebooks/ecco_s3_retrieve.py:169\u001b[0m, in \u001b[0;36mecco_podaac_s3_query\u001b[0;34m(ShortName, StartDate, EndDate)\u001b[0m\n\u001b[1;32m 163\u001b[0m EndDate \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(np\u001b[38;5;241m.\u001b[39mdatetime64(EndDate,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mD\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;241m+\u001b[39m np\u001b[38;5;241m.\u001b[39mtimedelta64(\u001b[38;5;241m1\u001b[39m,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mD\u001b[39m\u001b[38;5;124m'\u001b[39m))\n\u001b[1;32m 166\u001b[0m \u001b[38;5;66;03m## Log into Earthdata using your username and password\u001b[39;00m\n\u001b[1;32m 167\u001b[0m \n\u001b[1;32m 168\u001b[0m \u001b[38;5;66;03m# actually log in with this command:\u001b[39;00m\n\u001b[0;32m--> 169\u001b[0m \u001b[43msetup_earthdata_login_auth\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 171\u001b[0m \u001b[38;5;66;03m# Query the NASA Common Metadata Repository to find the URL of every granule associated with the desired \u001b[39;00m\n\u001b[1;32m 172\u001b[0m \u001b[38;5;66;03m# ECCO Dataset and date range of interest.\u001b[39;00m\n\u001b[1;32m 173\u001b[0m \n\u001b[1;32m 174\u001b[0m \u001b[38;5;66;03m# create a Python dictionary with our search criteria: `ShortName` and `temporal`\u001b[39;00m\n\u001b[1;32m 175\u001b[0m input_search_params \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mShortName\u001b[39m\u001b[38;5;124m'\u001b[39m: ShortName,\n\u001b[1;32m 176\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtemporal\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m,\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mjoin([StartDate, EndDate])}\n",
98+
"File \u001b[0;32m~/ECCO-v4-Python-Tutorial/Tutorials_as_Jupyter_Notebooks/ecco_s3_retrieve.py:68\u001b[0m, in \u001b[0;36mecco_podaac_s3_query.<locals>.setup_earthdata_login_auth\u001b[0;34m(url)\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mFileNotFoundError\u001b[39;00m, \u001b[38;5;167;01mTypeError\u001b[39;00m):\n\u001b[1;32m 67\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPlease provide Earthdata Login credentials for access.\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m---> 68\u001b[0m username, password \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mUsername: \u001b[39m\u001b[38;5;124m'\u001b[39m), \u001b[43mgetpass\u001b[49m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPassword: \u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 70\u001b[0m manager \u001b[38;5;241m=\u001b[39m request\u001b[38;5;241m.\u001b[39mHTTPPasswordMgrWithDefaultRealm()\n\u001b[1;32m 71\u001b[0m manager\u001b[38;5;241m.\u001b[39madd_password(\u001b[38;5;28;01mNone\u001b[39;00m, url, username, password)\n",
99+
"\u001b[0;31mNameError\u001b[0m: name 'getpass' is not defined"
100+
]
101+
}
102+
],
103+
"source": [
104+
"files = ecco_podaac_s3_open(\"ECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4\",\\\n",
105+
" StartDate='2000-01',EndDate='2000-12')"
106+
]
107+
}
108+
],
109+
"metadata": {
110+
"kernelspec": {
111+
"display_name": "Python 3 (ipykernel)",
112+
"language": "python",
113+
"name": "python3"
114+
},
115+
"language_info": {
116+
"codemirror_mode": {
117+
"name": "ipython",
118+
"version": 3
119+
},
120+
"file_extension": ".py",
121+
"mimetype": "text/x-python",
122+
"name": "python",
123+
"nbconvert_exporter": "python",
124+
"pygments_lexer": "ipython3",
125+
"version": "3.11.9"
126+
}
127+
},
128+
"nbformat": 4,
129+
"nbformat_minor": 5
130+
}

0 commit comments

Comments
 (0)