Skip to content

Commit bde96e2

Browse files
authored
Add documentation template (#30)
1 parent 44a9cc6 commit bde96e2

File tree

8 files changed

+228
-22
lines changed

8 files changed

+228
-22
lines changed

ci/environment-docs.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ dependencies:
99
- netcdf4
1010
- pip
1111
- pooch
12-
- pooch
1312
- pydantic
14-
- sphinx-book-theme
13+
- furo
1514
- sphinx-copybutton
1615
- xarray
1716
- zarr

docs/source/conf.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
# Autosummary pages will be generated by sphinx-autogen instead of sphinx-build
6363
autosummary_generate = []
6464
autodoc_typehints = 'none'
65+
autodoc_preserve_defaults = True
6566

6667
# Napoleon configurations
6768

@@ -102,7 +103,7 @@
102103

103104
# The theme to use for HTML and HTML Help pages. See the documentation for
104105
# a list of builtin themes.
105-
html_theme = 'sphinx_book_theme'
106+
html_theme = 'furo'
106107
html_title = ''
107108

108109
html_context = {
@@ -111,22 +112,8 @@
111112
'github_version': 'main',
112113
'doc_path': 'docs',
113114
}
114-
html_theme_options = dict(
115-
# analytics_id='' this is configured in rtfd.io
116-
# canonical_url="",
117-
repository_url='https://github.com/NCAR/xcollection',
118-
repository_branch='main',
119-
path_to_docs='docs',
120-
use_edit_page_button=True,
121-
use_repository_button=True,
122-
use_issues_button=True,
123-
home_page_in_toc=False,
124-
github_url='https://github.com/NCAR/xcollection',
125-
twitter_url='https://twitter.com/NCARXDev',
126-
extra_navbar='',
127-
navbar_footer_text='',
128-
extra_footer="""Theme by the <a href="https://ebp.jupyterbook.org">Executable Book Project</a>""",
129-
)
115+
html_theme_options = dict()
116+
130117

131118
# Output file base name for HTML help builder.
132119
htmlhelp_basename = 'xcollectiondoc'

docs/source/how-to-guides/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# How-to Guides
2+
3+
```{toctree}
4+
---
5+
maxdepth: 2
6+
caption: How-to Guides
7+
---
8+
```

docs/source/index.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,26 @@
22
33
```
44

5-
## Documentation Contents
5+
```{toctree}
6+
---
7+
maxdepth: 2
8+
hidden:
9+
---
10+
tutorials/index.md
11+
```
12+
13+
```{toctree}
14+
---
15+
maxdepth: 2
16+
hidden:
17+
---
18+
how-to-guides/index.md
19+
```
620

721
```{toctree}
822
---
923
maxdepth: 2
10-
caption: Reference
24+
hidden:
1125
---
12-
changelog.md
26+
reference/index.md
1327
```

docs/source/reference/index.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# API Reference
2+
3+
This page provides an auto-generated summary of xcollection’s API.
4+
For more details and examples, refer to the relevant chapters in the main part of the documentation.
5+
6+
```{toctree}
7+
---
8+
maxdepth: 2
9+
caption: Reference
10+
---
11+
main.md
12+
```

docs/source/reference/main.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Collection
2+
3+
```{eval-rst}
4+
.. autoclass:: xcollection.main.Collection
5+
:members:
6+
:noindex:
7+
8+
.. autofunction:: xcollection.main.open_collection
9+
```

docs/source/tutorials/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Tutorials
2+
3+
```{toctree}
4+
---
5+
maxdepth: 2
6+
caption: Tutorials
7+
---
8+
```

xcollection/main.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,43 @@ class Config:
4343

4444
@pydantic.dataclasses.dataclass(config=Config)
4545
class Collection(MutableMapping):
46+
"""A collection of datasets. The keys are the dataset names and the values are the datasets.
47+
48+
Parameters
49+
----------
50+
datasets : dict, optional
51+
A dictionary of datasets to initialize the collection with.
52+
53+
Examples
54+
--------
55+
>>> import xcollection as xc
56+
>>> import xarray as xr
57+
>>> ds = xr.tutorial.open_dataset('rasm')
58+
>>> c = xc.Collection({'foo': ds.isel(time=0), 'bar': ds.isel(y=0)})
59+
>>> c
60+
<Collection (2 keys)>
61+
🔑 foo
62+
<xarray.Dataset>
63+
Dimensions: (y: 205, x: 275)
64+
Coordinates:
65+
time object 1980-09-16 12:00:00
66+
xc (y, x) float64 ...
67+
yc (y, x) float64 ...
68+
Dimensions without coordinates: y, x
69+
Data variables:
70+
Tair (y, x) float64 ...
71+
🔑 bar
72+
<xarray.Dataset>
73+
Dimensions: (time: 36, x: 275)
74+
Coordinates:
75+
* time (time) object 1980-09-16 12:00:00 ... 1983-08-17 00:00:00
76+
xc (x) float64 ...
77+
yc (x) float64 ...
78+
Dimensions without coordinates: x
79+
Data variables:
80+
Tair (time, x) float64 ...
81+
"""
82+
4683
datasets: typing.Dict[pydantic.StrictStr, typing.Union[xr.Dataset, xr.DataArray]] = None
4784

4885
@pydantic.validator('datasets', pre=True, each_item=True)
@@ -95,18 +132,22 @@ def _ipython_display_(self):
95132
display(HTML(self._repr_html_()))
96133

97134
def keys(self) -> typing.Iterable[str]:
135+
"""Return the keys of the collection."""
98136
return self.datasets.keys()
99137

100138
def values(self) -> typing.Iterable[xr.Dataset]:
139+
"""Return the values of the collection."""
101140
return self.datasets.values()
102141

103142
def items(self) -> typing.Iterable[typing.Tuple[str, xr.Dataset]]:
143+
"""Return the items of the collection."""
104144
return self.datasets.items()
105145

106146
def choose(
107147
self, data_vars: typing.Union[str, typing.List[str]], *, mode: str = 'any'
108148
) -> 'Collection':
109149
"""Return a collection with datasets containing all or any of the specified data variables.
150+
110151
Parameters
111152
----------
112153
data_vars : str or list of str
@@ -119,6 +160,45 @@ def choose(
119160
Collection
120161
A new collection containing only the selected datasets.
121162
163+
Examples
164+
--------
165+
>>> c
166+
<Collection (3 keys)>
167+
🔑 foo
168+
<xarray.Dataset>
169+
Dimensions: (y: 205, x: 275)
170+
Coordinates:
171+
time object 1980-09-16 12:00:00
172+
xc (y, x) float64 ...
173+
yc (y, x) float64 ...
174+
Dimensions without coordinates: y, x
175+
Data variables:
176+
Tair (y, x) float64 ...
177+
🔑 bar
178+
<xarray.Dataset>
179+
Dimensions: (time: 36, x: 275)
180+
Coordinates:
181+
* time (time) object 1980-09-16 12:00:00 ... 1983-08-17 00:00:00
182+
xc (x) float64 ...
183+
yc (x) float64 ...
184+
Dimensions without coordinates: x
185+
Data variables:
186+
Tair (time, x) float64 ...
187+
🔑 baz
188+
<xarray.Dataset>
189+
Dimensions: ()
190+
Data variables:
191+
*empty*
192+
>>> len(c)
193+
3
194+
>>> c.keys()
195+
dict_keys(['foo', 'bar', 'baz'])
196+
>>> d = c.choose(data_vars=['Tair'], mode='any')
197+
>>> len(d)
198+
2
199+
>>> d.keys()
200+
dict_keys(['foo', 'bar'])
201+
>>> d = c.choose(data_vars=['Tair'], mode='all')
122202
"""
123203

124204
_VALID_MODES = ['all', 'any']
@@ -144,6 +224,7 @@ def _select_vars(dset):
144224

145225
def keymap(self, func: typing.Callable[[str], str]) -> 'Collection':
146226
"""Apply a function to each key in the collection.
227+
147228
Parameters
148229
----------
149230
func : callable
@@ -154,6 +235,36 @@ def keymap(self, func: typing.Callable[[str], str]) -> 'Collection':
154235
Collection
155236
A new collection containing the results of the function.
156237
238+
Examples
239+
--------
240+
>>> c
241+
<Collection (2 keys)>
242+
🔑 foo
243+
<xarray.Dataset>
244+
Dimensions: (y: 205, x: 275)
245+
Coordinates:
246+
time object 1980-09-16 12:00:00
247+
xc (y, x) float64 ...
248+
yc (y, x) float64 ...
249+
Dimensions without coordinates: y, x
250+
Data variables:
251+
Tair (y, x) float64 ...
252+
🔑 bar
253+
<xarray.Dataset>
254+
Dimensions: (time: 36, x: 275)
255+
Coordinates:
256+
* time (time) object 1980-09-16 12:00:00 ... 1983-08-17 00:00:00
257+
xc (x) float64 ...
258+
yc (x) float64 ...
259+
Dimensions without coordinates: x
260+
Data variables:
261+
Tair (time, x) float64 ...
262+
>>> c.keys()
263+
dict_keys(['foo', 'bar'])
264+
>>> d = c.keymap(lambda x: x.upper())
265+
>>> d.keys()
266+
dict_keys(['FOO', 'BAR'])
267+
157268
"""
158269
if not callable(func):
159270
raise TypeError(f'First argument must be callable function, got {type(func)}')
@@ -167,6 +278,7 @@ def map(
167278
**kwargs: typing.Dict[str, typing.Any],
168279
) -> 'Collection':
169280
"""Apply a function to each dataset in the collection.
281+
170282
Parameters
171283
----------
172284
func : callable
@@ -183,6 +295,52 @@ def map(
183295
Collection
184296
A new collection containing the results of the function.
185297
298+
Examples
299+
--------
300+
>>> c
301+
<Collection (2 keys)>
302+
🔑 foo
303+
<xarray.Dataset>
304+
Dimensions: (y: 205, x: 275)
305+
Coordinates:
306+
time object 1980-09-16 12:00:00
307+
xc (y, x) float64 ...
308+
yc (y, x) float64 ...
309+
Dimensions without coordinates: y, x
310+
Data variables:
311+
Tair (y, x) float64 ...
312+
🔑 bar
313+
<xarray.Dataset>
314+
Dimensions: (time: 36, x: 275)
315+
Coordinates:
316+
* time (time) object 1980-09-16 12:00:00 ... 1983-08-17 00:00:00
317+
xc (x) float64 ...
318+
yc (x) float64 ...
319+
Dimensions without coordinates: x
320+
Data variables:
321+
Tair (time, x) float64 ...
322+
>>> c.map(func=lambda x: x.isel(x=slice(0, 10)))
323+
<Collection (2 keys)>
324+
🔑 foo
325+
<xarray.Dataset>
326+
Dimensions: (y: 205, x: 10)
327+
Coordinates:
328+
time object 1980-09-16 12:00:00
329+
xc (y, x) float64 ...
330+
yc (y, x) float64 ...
331+
Dimensions without coordinates: y, x
332+
Data variables:
333+
Tair (y, x) float64 ...
334+
🔑 bar
335+
<xarray.Dataset>
336+
Dimensions: (time: 36, x: 10)
337+
Coordinates:
338+
* time (time) object 1980-09-16 12:00:00 ... 1983-08-17 00:00:00
339+
xc (x) float64 ...
340+
yc (x) float64 ...
341+
Dimensions without coordinates: x
342+
Data variables:
343+
Tair (time, x) float64 ...
186344
"""
187345
if not callable(func):
188346
raise TypeError(f'First argument must be callable function, got {type(func)}')
@@ -195,6 +353,7 @@ def map(
195353

196354
def to_zarr(self, store, mode: str = 'w', **kwargs):
197355
"""Write the collection to a Zarr store.
356+
198357
Parameters
199358
----------
200359
store : str or pathlib.Path
@@ -210,6 +369,9 @@ def to_zarr(self, store, mode: str = 'w', **kwargs):
210369
kwargs
211370
Additional keyword arguments to pass to :py:func:`~xr.Dataset.to_zarr` function.
212371
372+
Examples
373+
--------
374+
>>> c.to_zarr(store='/tmp/foo.zarr', mode='w')
213375
"""
214376

215377
if kwargs.get('group', None) is not None:
@@ -220,6 +382,7 @@ def to_zarr(self, store, mode: str = 'w', **kwargs):
220382
return [value.to_zarr(store, group=key, mode=mode, **kwargs) for key, value in self.items()]
221383

222384
def weighted(self, weights, **kwargs) -> 'Collection':
385+
"""Return a collection with datasets weighted by the given weights."""
223386
return CollectionWeighted(self, weights, *kwargs)
224387

225388

@@ -252,6 +415,7 @@ def _implementation(self, func, dim, **kwargs) -> 'Collection':
252415

253416
def open_collection(store: typing.Union[str, pydantic.DirectoryPath], **kwargs):
254417
"""Open a collection stored in a Zarr store.
418+
255419
Parameters
256420
----------
257421
store : str or pathlib.Path
@@ -264,6 +428,11 @@ def open_collection(store: typing.Union[str, pydantic.DirectoryPath], **kwargs):
264428
Collection
265429
A collection containing the datasets in the Zarr store.
266430
431+
Examples
432+
--------
433+
>>> import xcollection as xc
434+
>>> c = xc.open_collection('/tmp/foo.zarr', decode_times=True, use_cftime=True)
435+
267436
"""
268437

269438
import zarr

0 commit comments

Comments
 (0)