Skip to content

Commit 5f8f71f

Browse files
andy-theiakafitzgeraldcyschneck
authored
Ncl Climatology Entry (#80)
* climatology ncl entry and raw first take * a few small changes * add functions to index table * Fix index and edit entry * Add receipt and small changes * Updates to entry * add pyproject.toml file * testing codespell * typo and small changes * typo * use .codespellrc for now * fix codespell config * one more try on codespell * fix links in table * eol * fix another link * Update ncl/ncl_index/ncl-index-table.csv Co-authored-by: Andy McKeen <[email protected]> * adjust urls in ncl script * updates to ncl index for consistency * clear notebook outputs * use geocat-datafiles * appease pre-commit * NCL and receipt updates to use new subsets and correct for calendar issues * formatting * tidy up the NCL entries notebook * update to use new datafile * review updates * address comments in ncl index as well * adjust rel_tol * add note about calendar attribute to NCL script * adjust tolerance again and comment * formatting * rel_tol to abs_tol * rel_tol and abs_tol * fix titles and labels * whoops --------- Co-authored-by: Katelyn FitzGerald <[email protected]> Co-authored-by: Cora Schneck <[email protected]>
1 parent 9ad2596 commit 5f8f71f

File tree

6 files changed

+617
-4
lines changed

6 files changed

+617
-4
lines changed

.codespellrc

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[codespell]
2-
skip=.git,*.pdf,*.svg
3-
ignore-regex=^\s*"image/\S+": ".*
2+
skip = .git,*.pdf,*.svg
3+
ignore-words-list = ond
4+
ignore-regex = ^\s*"image/\S+": ".*
+330
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Climatology"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"## Overview\n",
15+
"The NCL climatology functions listed below can be replicated using `xarray` and/or `geocat.comp`\n",
16+
"\n",
17+
"- [calcDayAnomTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/calcDayAnomTLL.shtml)\n",
18+
"- [calcMonAnomTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/calcMonAnomTLL.shtml)\n",
19+
"- [clmDayTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/clmDayTLL.shtml)\n",
20+
"- [clmMonTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/clmMonTLL.shtml)\n",
21+
"- [month_to_season](https://www.ncl.ucar.edu/Document/Functions/Contributed/month_to_season.shtml)\n",
22+
"- [rmMonAnnCycTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/rmMonAnnCycTLL.shtml)\n",
23+
"- [stdMonTLL](https://www.ncl.ucar.edu/Document/Functions/Contributed/stdMonTLL.shtml)\n"
24+
]
25+
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
30+
"## calcDayAnomTLL\n",
31+
"`calcDayAnomTLL` calculates daily anomalies from a daily data climatology"
32+
]
33+
},
34+
{
35+
"cell_type": "markdown",
36+
"metadata": {},
37+
"source": [
38+
"### Grab and Go"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": null,
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"import xarray as xr\n",
48+
"import geocat.datafiles as gdf\n",
49+
"from matplotlib import pyplot as plt\n",
50+
"\n",
51+
"ds = xr.open_dataset(gdf.get(\"applications_files/inputs/CMIP6_sea_ice_daily_subset.nc\"))\n",
52+
"aice = ds.aice_d\n",
53+
"DayTLL = aice.groupby(aice.time.dt.dayofyear)\n",
54+
"clmDayTLL = DayTLL.mean(dim=\"time\")\n",
55+
"calcDayAnomTLL = DayTLL - clmDayTLL\n",
56+
"\n",
57+
"calcDayAnomTLL = calcDayAnomTLL.assign_attrs(long_name=\"sea ice anomaly\")\n",
58+
"\n",
59+
"calcDayAnomTLL[0, :, :].plot();"
60+
]
61+
},
62+
{
63+
"cell_type": "markdown",
64+
"metadata": {},
65+
"source": [
66+
"## calcMonAnomTLL\n",
67+
"`calcMonAnomTLL` calculates monthly anomalies by subtracting the long-term mean from each point"
68+
]
69+
},
70+
{
71+
"cell_type": "markdown",
72+
"metadata": {},
73+
"source": [
74+
"### Grab and Go"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": null,
80+
"metadata": {},
81+
"outputs": [],
82+
"source": [
83+
"import xarray as xr\n",
84+
"import geocat.datafiles as gdf\n",
85+
"\n",
86+
"ds = xr.open_dataset(\n",
87+
" gdf.get(\"applications_files/inputs/CMIP6_sea_ice_monthly_subset.nc\")\n",
88+
")\n",
89+
"aice = ds.aice\n",
90+
"MonTLL = aice.groupby(aice.time.dt.month)\n",
91+
"clmMonTLL = MonTLL.mean(dim=\"time\")\n",
92+
"calcMonAnomTLL = MonTLL - clmMonTLL\n",
93+
"\n",
94+
"calcMonAnomTLL = calcMonAnomTLL.assign_attrs(long_name=\"sea ice anomaly\")\n",
95+
"\n",
96+
"calcMonAnomTLL[0, :, :].plot();"
97+
]
98+
},
99+
{
100+
"cell_type": "markdown",
101+
"metadata": {},
102+
"source": [
103+
"## clmDayTLL\n",
104+
"`clmDayTLL` calculates long-term daily means (daily climatology) from daily data"
105+
]
106+
},
107+
{
108+
"cell_type": "markdown",
109+
"metadata": {},
110+
"source": [
111+
"### Grab and Go"
112+
]
113+
},
114+
{
115+
"cell_type": "code",
116+
"execution_count": null,
117+
"metadata": {},
118+
"outputs": [],
119+
"source": [
120+
"import xarray as xr\n",
121+
"import geocat.datafiles as gdf\n",
122+
"\n",
123+
"ds = xr.open_dataset(gdf.get(\"applications_files/inputs/CMIP6_sea_ice_daily_subset.nc\"))\n",
124+
"aice = ds.aice_d\n",
125+
"DayTLL = aice.groupby(aice.time.dt.dayofyear)\n",
126+
"clmDayTLL = DayTLL.mean(dim=\"time\")\n",
127+
"\n",
128+
"clmDayTLL[:, 10, 10].plot()\n",
129+
"plt.title(\"daily climatology\")\n",
130+
"plt.xlabel(\"day of year\")\n",
131+
"plt.ylabel(\"sea ice area\");"
132+
]
133+
},
134+
{
135+
"cell_type": "markdown",
136+
"metadata": {},
137+
"source": [
138+
"## clmMonTLL\n",
139+
"`clmMonTLL` calculates long-term monthly means (monthly climatology) from monthly data"
140+
]
141+
},
142+
{
143+
"cell_type": "markdown",
144+
"metadata": {},
145+
"source": [
146+
"### Grab and Go"
147+
]
148+
},
149+
{
150+
"cell_type": "code",
151+
"execution_count": null,
152+
"metadata": {},
153+
"outputs": [],
154+
"source": [
155+
"import xarray as xr\n",
156+
"import geocat.datafiles as gdf\n",
157+
"\n",
158+
"ds = xr.open_dataset(\n",
159+
" gdf.get(\"applications_files/inputs/CMIP6_sea_ice_monthly_subset.nc\")\n",
160+
")\n",
161+
"aice = ds.aice\n",
162+
"MonTLL = aice.groupby(aice.time.dt.month)\n",
163+
"clmMonTLL = MonTLL.mean(dim=\"time\")\n",
164+
"\n",
165+
"clmMonTLL[:, 10, 10].plot()\n",
166+
"plt.title(\"monthly climatology\")\n",
167+
"plt.xlabel(\"month of year\")\n",
168+
"plt.ylabel(\"sea ice area\");"
169+
]
170+
},
171+
{
172+
"cell_type": "markdown",
173+
"metadata": {},
174+
"source": [
175+
"## month_to_season\n",
176+
"`month_to_season` computes a user-specified three-month seasonal mean (DJF, JFM, FMA, MAM, AMJ, MJJ, JJA, JAS, ASO, SON, OND, NDJ)\n",
177+
"\n",
178+
"```{note}\n",
179+
"You can do something similar with directly with Xarray as shown in [this example in the Xarray documentation](https://docs.xarray.dev/en/stable/examples/monthly-means.html#Calculating-Seasonal-Averages-from-Time-Series-of-Monthly-Means). However, it requires substantially more code and doesn't have as much flexibility with respect to how the seasons are defined.\n",
180+
"```"
181+
]
182+
},
183+
{
184+
"cell_type": "markdown",
185+
"metadata": {},
186+
"source": [
187+
"### Grab and Go"
188+
]
189+
},
190+
{
191+
"cell_type": "code",
192+
"execution_count": null,
193+
"metadata": {},
194+
"outputs": [],
195+
"source": [
196+
"import xarray as xr\n",
197+
"import geocat.datafiles as gdf\n",
198+
"from geocat.comp import month_to_season\n",
199+
"\n",
200+
"ds = xr.open_dataset(\n",
201+
" gdf.get(\"applications_files/inputs/CMIP6_sea_ice_monthly_subset.nc\")\n",
202+
")\n",
203+
"aice = ds.aice\n",
204+
"mon_to_season = month_to_season(aice, \"ASO\")\n",
205+
"\n",
206+
"mon_to_season = mon_to_season.assign_attrs(long_name=\"sea ice area\")\n",
207+
"\n",
208+
"mon_to_season[0, :, :].plot()\n",
209+
"\n",
210+
"plt.title(\"2010 seasonal mean\");"
211+
]
212+
},
213+
{
214+
"cell_type": "markdown",
215+
"metadata": {},
216+
"source": [
217+
"## rmMonAnnCycTLL\n",
218+
"`rmMonAnnCycTLL` removes the annual cycle from monthly data"
219+
]
220+
},
221+
{
222+
"cell_type": "markdown",
223+
"metadata": {},
224+
"source": [
225+
"### Grab and Go"
226+
]
227+
},
228+
{
229+
"cell_type": "code",
230+
"execution_count": null,
231+
"metadata": {},
232+
"outputs": [],
233+
"source": [
234+
"import xarray as xr\n",
235+
"import geocat.datafiles as gdf\n",
236+
"\n",
237+
"ds = xr.open_dataset(\n",
238+
" gdf.get(\"applications_files/inputs/CMIP6_sea_ice_monthly_subset.nc\")\n",
239+
")\n",
240+
"aice = ds.aice\n",
241+
"MonTLL = aice.groupby(aice.time.dt.month)\n",
242+
"clmMonTLL = MonTLL.mean(dim=\"time\")\n",
243+
"rmMonAnnCycTLL = MonTLL - clmMonTLL\n",
244+
"\n",
245+
"rmMonAnnCycTLL[:, 10, 10].plot()\n",
246+
"plt.title(\"annual cycle removed\")\n",
247+
"plt.ylabel(\"sea ice area\");"
248+
]
249+
},
250+
{
251+
"cell_type": "markdown",
252+
"metadata": {},
253+
"source": [
254+
"## stdMonTLL\n",
255+
"`stdMonTLL` calculates standard deviations of monthly means"
256+
]
257+
},
258+
{
259+
"cell_type": "markdown",
260+
"metadata": {},
261+
"source": [
262+
"### Grab and Go"
263+
]
264+
},
265+
{
266+
"cell_type": "code",
267+
"execution_count": null,
268+
"metadata": {},
269+
"outputs": [],
270+
"source": [
271+
"import xarray as xr\n",
272+
"import geocat.datafiles as gdf\n",
273+
"\n",
274+
"ds = xr.open_dataset(\n",
275+
" gdf.get(\"applications_files/inputs/CMIP6_sea_ice_monthly_subset.nc\")\n",
276+
")\n",
277+
"aice = ds.aice\n",
278+
"MonTLL = aice.groupby(aice.time.dt.month)\n",
279+
"stdMonTLL = MonTLL.std(ddof=1)\n",
280+
"\n",
281+
"stdMonTLL[0, :, :].plot();"
282+
]
283+
},
284+
{
285+
"cell_type": "markdown",
286+
"metadata": {},
287+
"source": [
288+
"---"
289+
]
290+
},
291+
{
292+
"cell_type": "markdown",
293+
"metadata": {},
294+
"source": [
295+
"## Python Resources\n",
296+
"\n",
297+
"- GeoCAT Applications [climatology page](https://ncar.github.io/geocat-applications/applications/data_analysis/climatology.html)\n",
298+
"- Climatematch Academy [Xarray Data Analysis and Climatology tutorial](https://comptools.climatematch.io/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.html)\n",
299+
"- Project Pythia Foundations [Computations and Masks with Xarray tutorial](https://foundations.projectpythia.org/core/xarray/computation-masking.html)\n",
300+
"- Xarray User Guide [section on time series data](https://docs.xarray.dev/en/stable/user-guide/time-series.html)"
301+
]
302+
},
303+
{
304+
"cell_type": "markdown",
305+
"metadata": {},
306+
"source": []
307+
}
308+
],
309+
"metadata": {
310+
"kernelspec": {
311+
"display_name": "Python 3 (ipykernel)",
312+
"language": "python",
313+
"name": "python3"
314+
},
315+
"language_info": {
316+
"codemirror_mode": {
317+
"name": "ipython",
318+
"version": 3
319+
},
320+
"file_extension": ".py",
321+
"mimetype": "text/x-python",
322+
"name": "python",
323+
"nbconvert_exporter": "python",
324+
"pygments_lexer": "ipython3",
325+
"version": "3.12.3"
326+
}
327+
},
328+
"nbformat": 4,
329+
"nbformat_minor": 4
330+
}

ncl/ncl_entries/ncl_entries.rst

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Data Analysis
88
.. toctree::
99
:maxdepth: 1
1010

11+
climatology_functions.ipynb
1112
trigonometric_functions.ipynb
1213
general_applied_math.ipynb
1314
specx_specxy_anal.ipynb

ncl/ncl_index/ncl-index-table.csv

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ NCL Function,Description,Python Equivalent,Notes
99
`cosh <https://www.ncl.ucar.edu/Document/Functions/Built-in/cosh.shtml>`__,"Computes the hyperbolic cosine of numeric types","``math.cosh()`` or ``numpy.cosh()``",`example notebook <../ncl_entries/trigonometric_functions.ipynb#cosh>`__
1010
`sinh <https://www.ncl.ucar.edu/Document/Functions/Built-in/sinh.shtml>`__,"Computes the hyperbolic sine of numeric types","``math.sinh()`` or ``numpy.sinh()``",`example notebook <../ncl_entries/trigonometric_functions.ipynb#sinh>`__
1111
`tanh <https://www.ncl.ucar.edu/Document/Functions/Built-in/tanh.shtml>`__,"Computes the hyperbolic tangent of numeric types","``math.tanh()`` or ``numpy.tanh()``",`example notebook <../ncl_entries/trigonometric_functions.ipynb#tanh>`__
12-
`days_in_month <https://www.ncl.ucar.edu/Document/Functions/Built-in/days_in_month.shtml>`__,"Calculates the number of days in a month given month and year","``cftime.datetime().daysinmonth``",`example notebook <../ncl_entries/days_in_month.ipynb>`__
13-
`day_of_week <https://www.ncl.ucar.edu/Document/Functions/Built-in/day_of_week.shtml>`__,"Calculates the day of the week given month, day, and year","``cftime.datetime().dayofwk``",`example notebook <../ncl_entries/day_of_week.ipynb>`__
12+
`days_in_month <https://www.ncl.ucar.edu/Document/Functions/Built-in/days_in_month.shtml>`__,"Calculates the number of days in a month given month and year","``cftime.datetime()``",`example notebook <../ncl_entries/days_in_month.ipynb>`__
13+
`day_of_week <https://www.ncl.ucar.edu/Document/Functions/Built-in/day_of_week.shtml>`__,"Calculates the day of the week given month, day, and year","``cftime.datetime()``",`example notebook <../ncl_entries/day_of_week.ipynb>`__
14+
`calcDayAnomTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/calcDayAnomTLL.shtml>`__,"Calculates daily anomalies from a daily data climatology","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#calcdayanomtll>`__
15+
`calcMonAnomTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/calcMonAnomTLL.shtml>`__,"Calculates monthly anomalies by subtracting the long-term mean from each point","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#calcmonanomtll>`__
16+
`clmDayTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/clmDayTLL.shtml>`__,"Calculates long-term daily means (daily climatology) from daily data","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#clmdaytll>`__
17+
`clmMonTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/clmMonTLL.shtml>`__,"Calculates long-term monthly means (monthly climatology) from monthly data","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#clmmontll>`__
18+
`month_to_season <https://www.ncl.ucar.edu/Document/Functions/Contributed/month_to_season.shtml>`__,"Computes a user-specified three-month seasonal mean","``geocat.comp.month_to_season()``",`example notebook <../ncl_entries/climatology_functions.ipynb#month-to-season>`__
19+
`rmMonAnnCycTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/rmMonAnnCycTLL.shtml>`__,"Removes the annual cycle from monthly data","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#rmmonanncyctll>`__
20+
`stdMonTLL <https://www.ncl.ucar.edu/Document/Functions/Contributed/stdMonTLL.shtml>`__,"Calculates standard deviations of monthly means","``xarray.DataArray.groupby()``",`example notebook <../ncl_entries/climatology_functions.ipynb#stdmontll>`__
1421
`abs <https://www.ncl.ucar.edu/Document/Functions/Built-in/abs.shtml>`__,"Returns the absolute value of numeric data","``abs()`` or ``numpy.abs()``",`example notebook <../ncl_entries/general_applied_math.ipynb#abs-fabs>`__
1522
`avg <https://www.ncl.ucar.edu/Document/Functions/Built-in/avg.shtml>`__,"Computes the average of a variable regardless of dimensionality","``numpy.average()`` or ``numpy.mean()``",`example notebook <../ncl_entries/general_applied_math.ipynb#avg>`__
1623
`cumsum <https://www.ncl.ucar.edu/Document/Functions/Built-in/cumsum.shtml>`__,"Calculates the cumulative sum","``numpy.cumsum()``",`example notebook <../ncl_entries/general_applied_math.ipynb#cumsum>`__

0 commit comments

Comments
 (0)