Repository: UXARRAY/uxarray
Pull request #1223: Fix Numba Compilation Timeout in Docs
Author: login: philipc2
Labels: name: documentation
description: Improvements or additions to documentation
Created: 2025-04-24T14:34:02Z | Merged: 2025-04-26T01:15:20Z

<!--  The PR title should summarize the changes, for example "Add `Grid._build_face_dimension` function".
      Avoid non-descriptive titles such as "Addresses issue #229". -->

<!--  Replace XXX with the number of the issue that this PR will resolve. If this PR closed more than one,
      you may add a comma separated sequence-->

## Overview
<!--  Please provide a few bullet points summarizing the changes in this PR. This should include
      points on any bug fixes, new functions, or other changes that have been made. -->
- Resolves certain Numba cells timing out by increasing `nb_execution_timeout` value
  - [Bounding Box Subset](https://uxarray--1223.org.readthedocs.build/en/1223/user-guide/subset.html#bounding-box)
  - [Zonal Average](https://uxarray--1223.org.readthedocs.build/en/1223/user-guide/zonal-average.html)
- Updates RTD config to use the latest OS and Mamba version, consistent with [Xarray](https://github.com/pydata/xarray/blob/main/.readthedocs.yaml) 



Diff:
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 6ba1d9f1d..3a4406fff 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -1,21 +1,22 @@
-# .readthedocs.yml
-# Read the Docs configuration file
-# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
-
-# Required
 version: 2
 
 build:
-  os: "ubuntu-20.04"
+  os: ubuntu-lts-latest
   tools:
-    python: "mambaforge-4.10"
+    python: mambaforge-latest
   jobs:
+    post_checkout:
+      - git fetch --unshallow || true
+    pre_install:
+      - git update-index --assume-unchanged docs/conf.py ci/docs.yml
     post_create_environment:
       - pip install . --no-deps -vv
 
-# Build documentation in the docs/ directory with Sphinx
 sphinx:
   configuration: docs/conf.py
+  fail_on_warning: false
 
 conda:
   environment: ci/docs.yml
+
+formats: []
diff --git a/docs/conf.py b/docs/conf.py
index e2a9bb1e3..943cb81fe 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -80,6 +80,10 @@ def __getattr__(cls, name):
     "xarray": ("http://xarray.pydata.org/en/stable/", None),
 }
 
+
+# Notebook execution (per cell)
+nb_execution_timeout = 120
+
 remove_from_toctrees = ["generated/*"]
 
 napoleon_use_admonition_for_examples = True
diff --git a/docs/user-guide/subset.ipynb b/docs/user-guide/subset.ipynb
index a6af0db9d..e3f472d80 100644
--- a/docs/user-guide/subset.ipynb
+++ b/docs/user-guide/subset.ipynb
@@ -19,14 +19,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "import warnings\n",
     "\n",
@@ -40,7 +38,9 @@
     "plot_opts = {\"width\": 700, \"height\": 350}\n",
     "hv.extension(\"bokeh\")\n",
     "warnings.filterwarnings(\"ignore\")"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -58,14 +58,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "datafiles = (\n",
     "    geodf.get(\n",
@@ -73,51 +71,53 @@
     "    ),\n",
     "    geodf.get(\"netcdf_files/MPAS/FalkoJudt/dyamond_1/30km/x1.655362.grid_subset.nc\"),\n",
     ")"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "uxds = ux.open_dataset(datafiles[1], datafiles[0])"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "clim = (uxds[\"relhum_200hPa\"][0].values.min(), uxds[\"relhum_200hPa\"][0].values.max())"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "features = gf.coastline(\n",
     "    projection=ccrs.PlateCarree(), line_width=1, scale=\"50m\"\n",
     ") * gf.states(projection=ccrs.PlateCarree(), line_width=1, scale=\"50m\")"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -135,19 +135,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "uxds[\"relhum_200hPa\"][0].plot(\n",
     "    rasterize=True, periodic_elements=\"exclude\", title=\"Global Grid\", **plot_opts\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -163,17 +163,17 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "uxds[\"relhum_200hPa\"][0].values.mean()"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -193,31 +193,31 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "uxds[\"relhum_200hPa\"].subset"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "uxds[\"relhum_200hPa\"].uxgrid.subset"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -235,29 +235,27 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "lon_bounds = (-87.6298 - 2, -87.6298 + 2)\n",
     "lat_bounds = (41.8781 - 2, 41.8781 + 2)"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "bbox_subset_nodes = uxds[\"relhum_200hPa\"][0].subset.bounding_box(\n",
     "    lon_bounds,\n",
@@ -271,7 +269,9 @@
     "    title=\"Bounding Box Subset (Corner Node Query)\",\n",
     "    **plot_opts,\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -289,30 +289,28 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "center_coord = [-87.6298, 41.8781]\n",
     "\n",
     "r = 2"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "bcircle_subset = uxds[\"relhum_200hPa\"][0].subset.bounding_circle(center_coord, r)\n",
     "\n",
@@ -323,7 +321,9 @@
     "    title=\"Bounding Circle Subset\",\n",
     "    **plot_opts,\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -341,28 +341,26 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "center_coord = [-87.6298, 41.8781]"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "nn_subset = uxds[\"relhum_200hPa\"][0].subset.nearest_neighbor(\n",
     "    center_coord, k=30, element=\"nodes\"\n",
@@ -375,7 +373,9 @@
     "    title=\"Nearest Neighbor Subset (Query 30 closest nodes)\",\n",
     "    **plot_opts,\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -391,14 +391,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "nn_subset_120 = uxds[\"relhum_200hPa\"][0].subset.nearest_neighbor(\n",
     "    center_coord, k=120, element=\"face centers\"\n",
@@ -411,7 +409,9 @@
     "    title=\"Nearest Neighbor Subset (Query 120 Closest Faces)\",\n",
     "    **plot_opts,\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -427,14 +427,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "nn_subset_1 = uxds[\"relhum_200hPa\"][0].subset.nearest_neighbor(\n",
     "    center_coord, k=1, element=\"face centers\"\n",
@@ -447,7 +445,9 @@
     "    title=\"Nearest Neighbor Subset (Query Closest Face)\",\n",
     "    **plot_opts,\n",
     ") * features"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -467,92 +467,36 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {
     "collapsed": false,
     "jupyter": {
      "outputs_hidden": false
     }
    },
-   "outputs": [],
    "source": [
     "print(\"Global Mean:            \", uxds[\"relhum_200hPa\"][0].values.mean())\n",
     "print(\"Bounding Box Mean:      \", bbox_subset_nodes.values.mean())\n",
     "print(\"Bounding Circle Mean:   \", bcircle_subset.values.mean())"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Retrieving Orignal Grid Indices"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Sometimes having the original grids' indices is useful. These indices can be stored within the subset with the `inverse_indices` variable. This can be used to store the indices of the original face centers, edge centers, and node indices. This variable can be used within the subset as follows:\n",
-    "\n",
-    "* Passing in `True`, which will store the face center indices\n",
-    "* Passing in a list of which indices to store, along with `True`, to indicate what kind of original grid indices to store.\n",
-    "    * Options for which indices to select include: `face`, `node`, and `edge`\n",
-    "\n",
-    "This currently only works when the element is `face centers`. Elements `nodes` and `edge centers` will be supported in the future."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
+   ],
    "outputs": [],
-   "source": [
-    "subset_grid = uxds[\"relhum_200hPa\"][0].subset.bounding_circle(\n",
-    "    center_coord,\n",
-    "    r,\n",
-    "    element=\"face centers\",\n",
-    "    inverse_indices=([\"face\", \"node\", \"edge\"], True),\n",
-    ")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "These indices can be retrieve through the grid:"
-   ]
+   "execution_count": null
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
    "metadata": {},
-   "outputs": [],
-   "source": [
-    "subset_grid.uxgrid.inverse_indices"
-   ]
-  },
-  {
    "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Determining if a Grid is a Subset"
-   ]
+   "source": "## Determining if a Grid is a Subset"
   },
   {
    "cell_type": "markdown",
    "metadata": {},
-   "source": [
-    "To check if a Grid (or dataset using `.uxgrid`) is a subset, we can use `Grid.is_subset`, which will return either `True` or `False`, depending on whether the `Grid` is a subset. Since `subset_indices` is a subset, using this feature we will return `True`:"
-   ]
+   "source": "To check if a Grid (or dataset using `.uxgrid`) is a subset, we can use `Grid.is_subset`, which will return either `True` or `False`, depending on whether the `Grid` is a subset. Since `nn_subset_120` is a subset, using this feature we will return `True`:"
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {},
+   "source": "nn_subset_120.uxgrid.is_subset",
    "outputs": [],
-   "source": [
-    "subset_grid.uxgrid.is_subset"
-   ]
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -563,12 +507,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
    "metadata": {},
-   "outputs": [],
    "source": [
     "uxds.uxgrid.is_subset"
-   ]
+   ],
+   "outputs": [],
+   "execution_count": null
   }
  ],
  "metadata": {


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR addresses Numba cell compilation timeouts in documentation notebooks by increasing the notebook execution timeout and updating the ReadTheDocs configuration for an up-to-date environment.  
- Increase nb_execution_timeout in docs/conf.py to 120 to reduce Numba timeouts.  
- Reformat notebook cells in docs/user-guide/subset.ipynb to standardize the ordering of keys.  
- Update .readthedocs.yml to use ubuntu-lts-latest and mambaforge-latest along with additional checkout and pre-install steps.

### Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

| File                         | Description                                                            |
| ---------------------------- | ---------------------------------------------------------------------- |
| docs/user-guide/subset.ipynb | Reordered JSON cell keys for consistency across notebook cells.        |
| docs/conf.py                 | Increased nb_execution_timeout to 120 for improved Numba cell execution. |
| .readthedocs.yml             | Updated OS and Python tool versions; added post_checkout and pre_install commands. |




state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T03:08:48Z
user: login: rajeeja
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T17:17:51Z
user: login: philipc2
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-25T19:47:38Z

Review comments:
diff_hunk: @@ -80,6 +80,10 @@ def __getattr__(cls, name):
     "xarray": ("http://xarray.pydata.org/en/stable/", None),
 }
 
+
+# Notebook execution (per cell)
+nb_execution_timeout = 120
path: docs/conf.py
user: login: rajeeja
body: If Numba compilation times continue to grow we may want to get rid of bulky notebooks or use cache etc.
created_at: 2025-04-25T17:17:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -80,6 +80,10 @@ def __getattr__(cls, name):
     "xarray": ("http://xarray.pydata.org/en/stable/", None),
 }
 
+
+# Notebook execution (per cell)
+nb_execution_timeout = 120
path: docs/conf.py
user: login: philipc2
body: The size of the notebook or dataset doesn't have an impact on the Numba compilation. 
created_at: 2025-04-25T19:47:38Z
author_association: MEMBER

PR comments:
user: login: review-notebook-app[bot]
created_at: 2025-04-25T01:45:49Z
body: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/UXARRAY/uxarray/pull/1223"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>
author_association: NONE
user: login: rajeeja
created_at: 2025-04-25T17:16:55Z
body: Good job updating to the latest OS and Mamba and improving doc build reliability.
Was a script used for Standardizing cell key ordering? If so, please put it as a blurb somewhere so others can apply it consistently.


author_association: CONTRIBUTOR
user: login: rajeeja
created_at: 2025-04-25T19:58:01Z
body: Ok, why did you change it to 120 specifically?

_________________________________________
Rajeev


On Fri, Apr 25, 2025, 2:47 PM Philip Chmielowiec ***@***.***>
wrote:

> ***@***.**** commented on this pull request.
> ------------------------------
>
> In docs/conf.py
> <https://github.com/UXARRAY/uxarray/pull/1223#discussion_r2060802675>:
>
> > @@ -80,6 +80,10 @@ def __getattr__(cls, name):
>      "xarray": ("http://xarray.pydata.org/en/stable/", None),
>  }
>
> +
> +# Notebook execution (per cell)
> +nb_execution_timeout = 120
>
> The size of the notebook or dataset doesn't have an impact on the Numba
> compilation.
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/UXARRAY/uxarray/pull/1223#discussion_r2060802675>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AALF6AXNYODC3YXFK2W47W323KGO5AVCNFSM6AAAAAB3ZGXFTKVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDOOJVGE2DGNZVGM>
> .
> You are receiving this because your review was requested.Message ID:
> ***@***.***>
>

author_association: CONTRIBUTOR
user: login: philipc2
created_at: 2025-04-25T20:05:47Z
body: > Ok, why did you change it to 120 specifically?
> […](#)
> _________________________________________ Rajeev
> On Fri, Apr 25, 2025, 2:47 PM Philip Chmielowiec ***@***.***> wrote: ***@***.**** commented on this pull request. ------------------------------ In docs/conf.py <[#1223 (comment)](https://github.com/UXARRAY/uxarray/pull/1223#discussion_r2060802675)>: > @@ -80,6 +80,10 @@ def __getattr__(cls, name): "xarray": ("http://xarray.pydata.org/en/stable/", None), } + +# Notebook execution (per cell) +nb_execution_timeout = 120 The size of the notebook or dataset doesn't have an impact on the Numba compilation. — Reply to this email directly, view it on GitHub <[#1223 (comment)](https://github.com/UXARRAY/uxarray/pull/1223#discussion_r2060802675)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AALF6AXNYODC3YXFK2W47W323KGO5AVCNFSM6AAAAAB3ZGXFTKVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDOOJVGE2DGNZVGM> . You are receiving this because your review was requested.Message ID: ***@***.***>

Previous default was 30 seconds. 120 is large enough (2 mins) felt like a good maximum for any cell (if it takes longer it shouldn't be in a notebook anyways) 
author_association: MEMBER